@pasko70/pibo 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-runtime/capabilities.js +68 -0
- package/dist/agent-runtime/context-build.js +13 -5
- package/dist/agent-runtime/portable-history.js +526 -0
- package/dist/agent-runtime/profile-validation.js +13 -7
- package/dist/agent-runtime/resource-files.js +26 -10
- package/dist/agent-runtime/resource-service.js +216 -13
- package/dist/agent-runtimes/codex-native/adapter.js +38 -1
- package/dist/agent-runtimes/codex-native/auth.js +24 -3
- package/dist/agent-runtimes/codex-native/portable-history.js +73 -0
- package/dist/agent-runtimes/codex-native/process.js +38 -27
- package/dist/agent-runtimes/codex-native/resource-delivery.js +39 -16
- package/dist/agent-runtimes/codex-native/turn.js +68 -5
- package/dist/agent-runtimes/omp/adapter.js +43 -8
- package/dist/agent-runtimes/omp/process.js +26 -10
- package/dist/agent-runtimes/omp/resource-delivery.js +150 -84
- package/dist/agent-runtimes/pi/adapter.js +32 -1
- package/dist/agent-runtimes/pi/auth.js +34 -29
- package/dist/agent-runtimes/pi/credentials.js +43 -0
- package/dist/agent-runtimes/pi/model-catalog.js +7 -3
- package/dist/agent-runtimes/pi/portable-history.js +99 -0
- package/dist/agent-runtimes/pi/routed-session.js +1 -1
- package/dist/agent-runtimes/pi/runtime.js +31 -15
- package/dist/apps/chat/agent-profiles.js +1 -0
- package/dist/apps/chat/agent-store.js +20 -7
- package/dist/apps/chat/chat-files.js +19 -6
- package/dist/apps/chat/chat-request-normalizers.js +13 -0
- package/dist/apps/chat/web-app.js +55 -6
- package/dist/apps/chat-ui/assets/{apl-14BqhLYK.js → apl-gfMMiTNf.js} +1 -1
- package/dist/apps/chat-ui/assets/asciiarmor-C_eisQCp.js +1 -0
- package/dist/apps/{context-files-ui/assets/asn1-Bg4FbdCg.js → chat-ui/assets/asn1-DCl_8MCW.js} +1 -1
- package/dist/apps/{context-files-ui/assets/asterisk-B2MO-X4d.js → chat-ui/assets/asterisk-BEn0Cwpx.js} +1 -1
- package/dist/apps/chat-ui/assets/clike-D_6L3tnO.js +1 -0
- package/dist/apps/chat-ui/assets/cmake-84nbDH0I.js +1 -0
- package/dist/apps/chat-ui/assets/cobol-DHLQUbN7.js +1 -0
- package/dist/apps/chat-ui/assets/coffeescript-De_zI4J0.js +1 -0
- package/dist/apps/chat-ui/assets/commonlisp-DgAKBe0r.js +1 -0
- package/dist/apps/chat-ui/assets/crystal-Bsdphhtm.js +1 -0
- package/dist/apps/chat-ui/assets/css-CnaYoQib.js +1 -0
- package/dist/apps/chat-ui/assets/{d-TPqSVaHM.js → d-DWkQyNnU.js} +1 -1
- package/dist/apps/{context-files-ui/assets/dist-DxEGebCR.js → chat-ui/assets/dist-BB8loWTa.js} +1 -1
- package/dist/apps/chat-ui/assets/dist-BJ-TIk3N.js +1 -0
- package/dist/apps/chat-ui/assets/dist-CBPDkWd4.js +1 -0
- package/dist/apps/chat-ui/assets/dist-CHInEWhr.js +1 -0
- package/dist/apps/chat-ui/assets/dist-CqM4On9D.js +13 -0
- package/dist/apps/chat-ui/assets/dist-CswnpKik.js +1 -0
- package/dist/apps/{context-files-ui/assets/dist-B7gXtTZC.js → chat-ui/assets/dist-CwS16H7k.js} +1 -1
- package/dist/apps/chat-ui/assets/dist-DHvUPfrF.js +1 -0
- package/dist/apps/chat-ui/assets/dist-DLJCGrGQ.js +1 -0
- package/dist/apps/chat-ui/assets/{dist-DLMjd26T.js → dist-DMiglryg.js} +1 -1
- package/dist/apps/chat-ui/assets/dist-DTeLDijr.js +9 -0
- package/dist/apps/chat-ui/assets/{dist-DKoyMSNr.js → dist-DpF08Yd7.js} +1 -1
- package/dist/apps/chat-ui/assets/dist-LCx98fA_.js +11 -0
- package/dist/apps/chat-ui/assets/{dist-DotDq_kD.js → dist-RKTRnzGb.js} +1 -1
- package/dist/apps/chat-ui/assets/dist-S3zJGntM.js +1 -0
- package/dist/apps/{context-files-ui/assets/dist-BkUONE3N.js → chat-ui/assets/dist-XVYGiB-c.js} +1 -1
- package/dist/apps/chat-ui/assets/dist-eddbbGyw.js +1 -0
- package/dist/apps/chat-ui/assets/dist-fPhZsAUX.js +1 -0
- package/dist/apps/chat-ui/assets/dist-mpRGeo_R.js +2 -0
- package/dist/apps/chat-ui/assets/{dist-sZgJkWZb.js → dist-nU3BVpFi.js} +1 -1
- package/dist/apps/chat-ui/assets/{dockerfile-CJb2sekW.js → dockerfile-DJkHQgkl.js} +1 -1
- package/dist/apps/chat-ui/assets/{dylan-08Azy1NK.js → dylan-BCDoL_-p.js} +1 -1
- package/dist/apps/chat-ui/assets/{ecl-dhxjHL8y.js → ecl-BVIeWmwY.js} +1 -1
- package/dist/apps/{context-files-ui/assets/erlang-BD5LkVkR.js → chat-ui/assets/erlang-BV0c4Hdn.js} +1 -1
- package/dist/apps/chat-ui/assets/{factor-B2EMQZkP.js → factor-LKH5gN8L.js} +1 -1
- package/dist/apps/chat-ui/assets/groovy-CUpZ7dEl.js +1 -0
- package/dist/apps/chat-ui/assets/{haxe-BJVKtprM.js → haxe-DjVOVvNP.js} +1 -1
- package/dist/apps/chat-ui/assets/index-CQuka3bs.js +226 -0
- package/dist/apps/chat-ui/assets/index-DUXboQnI.css +1 -0
- package/dist/apps/chat-ui/assets/javascript-DoL9Wb-Q.js +1 -0
- package/dist/apps/chat-ui/assets/{lua-BxuTHaF7.js → lua-CiA1ziua.js} +1 -1
- package/dist/apps/chat-ui/assets/{mumps-Ds_ZaumL.js → mumps-BSzj6Xyz.js} +1 -1
- package/dist/apps/{context-files-ui/assets/nsis-DOo3SJmd.js → chat-ui/assets/nsis-CfSuhXs5.js} +1 -1
- package/dist/apps/chat-ui/assets/{ntriples-DLHGTvHs.js → ntriples-B9h1VB_g.js} +1 -1
- package/dist/apps/chat-ui/assets/perl-BkSkiI9m.js +1 -0
- package/dist/apps/chat-ui/assets/{powershell-B4IPkVxR.js → powershell-BcIto6Sf.js} +1 -1
- package/dist/apps/{context-files-ui/assets/pug-QU72BPAa.js → chat-ui/assets/pug-Gsm0M45u.js} +1 -1
- package/dist/apps/chat-ui/assets/puppet-BZyAS7I4.js +1 -0
- package/dist/apps/chat-ui/assets/python-B_1Jd8HM.js +1 -0
- package/dist/apps/chat-ui/assets/r-CxDmU1I4.js +1 -0
- package/dist/apps/chat-ui/assets/ruby-BjXV7-Qa.js +1 -0
- package/dist/apps/chat-ui/assets/scheme-D9qYN0V5.js +1 -0
- package/dist/apps/chat-ui/assets/{shell-BjiMLAaM.js → shell-DwuoZtxw.js} +1 -1
- package/dist/apps/chat-ui/assets/{simple-mode-DnMbQuKW.js → simple-mode-DXiLM1-G.js} +1 -1
- package/dist/apps/chat-ui/assets/sql-DuQMFDvy.js +1 -0
- package/dist/apps/chat-ui/assets/{stex-BCRT8IJ3.js → stex-DNzd62Q_.js} +1 -1
- package/dist/apps/chat-ui/assets/{stylus-CARoeVE9.js → stylus-BOVgKnng.js} +1 -1
- package/dist/apps/chat-ui/assets/textile-C4jVoHG1.js +1 -0
- package/dist/apps/chat-ui/assets/tiki-AK6FwT8q.js +1 -0
- package/dist/apps/chat-ui/assets/toml-BPTmHmyx.js +1 -0
- package/dist/apps/chat-ui/assets/{ttcn-GvRgs2AT.js → ttcn-PPSTk1ow.js} +1 -1
- package/dist/apps/chat-ui/assets/{ttcn-cfg-CGCXz7Vo.js → ttcn-cfg-2b4Gb5sE.js} +1 -1
- package/dist/apps/chat-ui/assets/turtle-Cx3rYX2g.js +1 -0
- package/dist/apps/chat-ui/assets/{verilog-DVCHmufx.js → verilog-7LoJAqYT.js} +1 -1
- package/dist/apps/chat-ui/assets/vhdl-kS471soi.js +1 -0
- package/dist/apps/{context-files-ui/assets/xquery-5f0hn7cg.js → chat-ui/assets/xquery-BKJx4mf9.js} +1 -1
- package/dist/apps/chat-ui/assets/z80-Co3PbHdE.js +1 -0
- package/dist/apps/chat-ui/index.html +5 -3
- package/dist/apps/chat-vscode-web/assets/index-CF1-9PKU.css +2 -0
- package/dist/apps/chat-vscode-web/assets/index-Dp1TzeRL.js +41 -0
- package/dist/apps/chat-vscode-web/index.html +2 -2
- package/dist/apps/context-files-ui/assets/{apl-14BqhLYK.js → apl-gfMMiTNf.js} +1 -1
- package/dist/apps/context-files-ui/assets/asciiarmor-C_eisQCp.js +1 -0
- package/dist/apps/{chat-ui/assets/asn1-Bg4FbdCg.js → context-files-ui/assets/asn1-DCl_8MCW.js} +1 -1
- package/dist/apps/{chat-ui/assets/asterisk-B2MO-X4d.js → context-files-ui/assets/asterisk-BEn0Cwpx.js} +1 -1
- package/dist/apps/context-files-ui/assets/clike-D_6L3tnO.js +1 -0
- package/dist/apps/context-files-ui/assets/cmake-84nbDH0I.js +1 -0
- package/dist/apps/context-files-ui/assets/cobol-DHLQUbN7.js +1 -0
- package/dist/apps/context-files-ui/assets/coffeescript-De_zI4J0.js +1 -0
- package/dist/apps/context-files-ui/assets/commonlisp-DgAKBe0r.js +1 -0
- package/dist/apps/context-files-ui/assets/crystal-Bsdphhtm.js +1 -0
- package/dist/apps/context-files-ui/assets/css-CnaYoQib.js +1 -0
- package/dist/apps/context-files-ui/assets/{d-TPqSVaHM.js → d-DWkQyNnU.js} +1 -1
- package/dist/apps/{chat-ui/assets/dist-C6LPDFXU.js → context-files-ui/assets/dist-BAqbgxUS.js} +1 -1
- package/dist/apps/context-files-ui/assets/dist-BJ-TIk3N.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-BcauuFwf.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-BecMXs79.js +1 -0
- package/dist/apps/context-files-ui/assets/{dist-C-Jm45P4.js → dist-Ci2NSlf1.js} +1 -1
- package/dist/apps/context-files-ui/assets/dist-CqM4On9D.js +13 -0
- package/dist/apps/context-files-ui/assets/dist-CswnpKik.js +1 -0
- package/dist/apps/{chat-ui/assets/dist-I26VB0QO.js → context-files-ui/assets/dist-D-xpsbZI.js} +1 -1
- package/dist/apps/context-files-ui/assets/dist-DHvUPfrF.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-DLJCGrGQ.js +1 -0
- package/dist/apps/context-files-ui/assets/{dist-DLMjd26T.js → dist-DMiglryg.js} +1 -1
- package/dist/apps/context-files-ui/assets/dist-DTeLDijr.js +9 -0
- package/dist/apps/context-files-ui/assets/{dist-DKoyMSNr.js → dist-DpF08Yd7.js} +1 -1
- package/dist/apps/context-files-ui/assets/dist-LCx98fA_.js +11 -0
- package/dist/apps/context-files-ui/assets/{dist-DotDq_kD.js → dist-RKTRnzGb.js} +1 -1
- package/dist/apps/context-files-ui/assets/dist-S3zJGntM.js +1 -0
- package/dist/apps/{chat-ui/assets/dist-BkUONE3N.js → context-files-ui/assets/dist-XVYGiB-c.js} +1 -1
- package/dist/apps/context-files-ui/assets/dist-eddbbGyw.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-fPhZsAUX.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-mpRGeo_R.js +2 -0
- package/dist/apps/context-files-ui/assets/{dockerfile-CJb2sekW.js → dockerfile-DJkHQgkl.js} +1 -1
- package/dist/apps/context-files-ui/assets/{dylan-08Azy1NK.js → dylan-BCDoL_-p.js} +1 -1
- package/dist/apps/context-files-ui/assets/{ecl-dhxjHL8y.js → ecl-BVIeWmwY.js} +1 -1
- package/dist/apps/{chat-ui/assets/erlang-BD5LkVkR.js → context-files-ui/assets/erlang-BV0c4Hdn.js} +1 -1
- package/dist/apps/context-files-ui/assets/{factor-B2EMQZkP.js → factor-LKH5gN8L.js} +1 -1
- package/dist/apps/context-files-ui/assets/groovy-CUpZ7dEl.js +1 -0
- package/dist/apps/context-files-ui/assets/{haxe-BJVKtprM.js → haxe-DjVOVvNP.js} +1 -1
- package/dist/apps/context-files-ui/assets/index-CkWXlBNn.js +191 -0
- package/dist/apps/context-files-ui/assets/{index-Cs4XQITe.css → index-D8TsUizd.css} +1 -1
- package/dist/apps/context-files-ui/assets/javascript-DoL9Wb-Q.js +1 -0
- package/dist/apps/context-files-ui/assets/{lua-BxuTHaF7.js → lua-CiA1ziua.js} +1 -1
- package/dist/apps/context-files-ui/assets/{mumps-Ds_ZaumL.js → mumps-BSzj6Xyz.js} +1 -1
- package/dist/apps/{chat-ui/assets/nsis-DOo3SJmd.js → context-files-ui/assets/nsis-CfSuhXs5.js} +1 -1
- package/dist/apps/context-files-ui/assets/{ntriples-DLHGTvHs.js → ntriples-B9h1VB_g.js} +1 -1
- package/dist/apps/context-files-ui/assets/perl-BkSkiI9m.js +1 -0
- package/dist/apps/context-files-ui/assets/{powershell-B4IPkVxR.js → powershell-BcIto6Sf.js} +1 -1
- package/dist/apps/{chat-ui/assets/pug-QU72BPAa.js → context-files-ui/assets/pug-Gsm0M45u.js} +1 -1
- package/dist/apps/context-files-ui/assets/puppet-BZyAS7I4.js +1 -0
- package/dist/apps/context-files-ui/assets/python-B_1Jd8HM.js +1 -0
- package/dist/apps/context-files-ui/assets/r-CxDmU1I4.js +1 -0
- package/dist/apps/context-files-ui/assets/ruby-BjXV7-Qa.js +1 -0
- package/dist/apps/context-files-ui/assets/scheme-D9qYN0V5.js +1 -0
- package/dist/apps/context-files-ui/assets/{shell-BjiMLAaM.js → shell-DwuoZtxw.js} +1 -1
- package/dist/apps/context-files-ui/assets/{simple-mode-DnMbQuKW.js → simple-mode-DXiLM1-G.js} +1 -1
- package/dist/apps/context-files-ui/assets/sql-DuQMFDvy.js +1 -0
- package/dist/apps/context-files-ui/assets/{stex-BCRT8IJ3.js → stex-DNzd62Q_.js} +1 -1
- package/dist/apps/context-files-ui/assets/{stylus-CARoeVE9.js → stylus-BOVgKnng.js} +1 -1
- package/dist/apps/context-files-ui/assets/textile-C4jVoHG1.js +1 -0
- package/dist/apps/context-files-ui/assets/tiki-AK6FwT8q.js +1 -0
- package/dist/apps/context-files-ui/assets/toml-BPTmHmyx.js +1 -0
- package/dist/apps/context-files-ui/assets/{ttcn-GvRgs2AT.js → ttcn-PPSTk1ow.js} +1 -1
- package/dist/apps/context-files-ui/assets/{ttcn-cfg-CGCXz7Vo.js → ttcn-cfg-2b4Gb5sE.js} +1 -1
- package/dist/apps/context-files-ui/assets/turtle-Cx3rYX2g.js +1 -0
- package/dist/apps/context-files-ui/assets/{verilog-DVCHmufx.js → verilog-7LoJAqYT.js} +1 -1
- package/dist/apps/context-files-ui/assets/vhdl-kS471soi.js +1 -0
- package/dist/apps/{chat-ui/assets/xquery-5f0hn7cg.js → context-files-ui/assets/xquery-BKJx4mf9.js} +1 -1
- package/dist/apps/context-files-ui/assets/z80-Co3PbHdE.js +1 -0
- package/dist/apps/context-files-ui/index.html +5 -3
- package/dist/apps/vscode-artifacts/latest.vsix +0 -0
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-2.2.0.vsix +0 -0
- package/dist/auth/better-auth.js +223 -30
- package/dist/auth/cli.js +10 -1
- package/dist/auth/machine-keys.js +8 -4
- package/dist/auth/openai-codex-usage.js +4 -4
- package/dist/cli-session/fakeSessionSource.js +2 -2
- package/dist/cli-session/localSessionSource.js +2 -2
- package/dist/cli.js +3 -1
- package/dist/config/config.js +9 -4
- package/dist/core/compaction-prompt.js +3 -1
- package/dist/core/context-build.js +1 -0
- package/dist/core/pibo-home.js +24 -1
- package/dist/core/private-path.js +146 -0
- package/dist/core/profiles.js +8 -0
- package/dist/core/sensitive-data-redaction.js +36 -0
- package/dist/core/session-model.js +1 -0
- package/dist/core/session-router.js +219 -29
- package/dist/data/pibo-store.js +5 -1
- package/dist/gateway/server.js +9 -0
- package/dist/plugins/context-files.js +11 -0
- package/dist/plugins/registry.js +1 -0
- package/dist/providers/openai-gpt56.js +0 -11
- package/dist/reliability/store.js +5 -1
- package/dist/resources/lifecycle.js +13 -3
- package/dist/runs/resource-isolation.js +159 -8
- package/dist/runs/tools.js +44 -1
- package/dist/sessions/pibo-data-store.js +3 -0
- package/dist/tools/codex-browser-node-repl.js +4 -2
- package/dist/tools/codex-browser.js +1 -1
- package/dist/tools/codex-image-generation.js +4 -4
- package/dist/tools/runtime/node-backend.js +4 -1
- package/dist/tools/runtime/python-backend.js +4 -1
- package/dist/web-annotations/api.js +22 -2
- package/npm-shrinkwrap.json +16707 -0
- package/package.json +19 -14
- package/dist/apps/chat-ui/assets/asciiarmor-WLvjqI7d.js +0 -1
- package/dist/apps/chat-ui/assets/clike-CjmcUpt6.js +0 -1
- package/dist/apps/chat-ui/assets/cmake-i2VDNaRq.js +0 -1
- package/dist/apps/chat-ui/assets/cobol-BwO6DF08.js +0 -1
- package/dist/apps/chat-ui/assets/coffeescript-BtivDvRz.js +0 -1
- package/dist/apps/chat-ui/assets/commonlisp-DFkEQdLP.js +0 -1
- package/dist/apps/chat-ui/assets/crystal-CU0NkcVL.js +0 -1
- package/dist/apps/chat-ui/assets/css-CbMZAQ1W.js +0 -1
- package/dist/apps/chat-ui/assets/dist-9v2ZXT6V.js +0 -11
- package/dist/apps/chat-ui/assets/dist-B1LVAytl.js +0 -9
- package/dist/apps/chat-ui/assets/dist-B5PTVnox.js +0 -1
- package/dist/apps/chat-ui/assets/dist-B5ZAfwf5.js +0 -1
- package/dist/apps/chat-ui/assets/dist-D1KyNDg5.js +0 -13
- package/dist/apps/chat-ui/assets/dist-DVtXxfHc.js +0 -1
- package/dist/apps/chat-ui/assets/dist-DW4Qrfbd.js +0 -2
- package/dist/apps/chat-ui/assets/dist-DmbsHdMC.js +0 -1
- package/dist/apps/chat-ui/assets/dist-DyvwuSFO.js +0 -1
- package/dist/apps/chat-ui/assets/dist-QQuDy4KA.js +0 -1
- package/dist/apps/chat-ui/assets/dist-RtHbJRPV.js +0 -1
- package/dist/apps/chat-ui/assets/groovy-Cmduloe1.js +0 -1
- package/dist/apps/chat-ui/assets/index-BPbNvcZe.css +0 -1
- package/dist/apps/chat-ui/assets/index-CIOf2uL2.js +0 -237
- package/dist/apps/chat-ui/assets/javascript-C5pDVaoP.js +0 -1
- package/dist/apps/chat-ui/assets/perl-D6YJObi_.js +0 -1
- package/dist/apps/chat-ui/assets/puppet-B_0GFuyD.js +0 -1
- package/dist/apps/chat-ui/assets/python-Cs7sNzy_.js +0 -1
- package/dist/apps/chat-ui/assets/r-CN5s4f3o.js +0 -1
- package/dist/apps/chat-ui/assets/ruby-BVPradRk.js +0 -1
- package/dist/apps/chat-ui/assets/scheme-CvNgHAnh.js +0 -1
- package/dist/apps/chat-ui/assets/sql-DYI2GwJR.js +0 -1
- package/dist/apps/chat-ui/assets/textile-Yg_UWn-t.js +0 -1
- package/dist/apps/chat-ui/assets/tiki-CC_ic8g0.js +0 -1
- package/dist/apps/chat-ui/assets/toml-B7gGzVkJ.js +0 -1
- package/dist/apps/chat-ui/assets/turtle-CwIpz2yy.js +0 -1
- package/dist/apps/chat-ui/assets/vhdl-BGDk4f1d.js +0 -1
- package/dist/apps/chat-ui/assets/z80-B7Dfb4UO.js +0 -1
- package/dist/apps/chat-vscode-web/assets/index-1ivRyjFs.js +0 -41
- package/dist/apps/chat-vscode-web/assets/index-Dupu1DzQ.css +0 -2
- package/dist/apps/context-files-ui/assets/asciiarmor-WLvjqI7d.js +0 -1
- package/dist/apps/context-files-ui/assets/clike-CjmcUpt6.js +0 -1
- package/dist/apps/context-files-ui/assets/cmake-i2VDNaRq.js +0 -1
- package/dist/apps/context-files-ui/assets/cobol-BwO6DF08.js +0 -1
- package/dist/apps/context-files-ui/assets/coffeescript-BtivDvRz.js +0 -1
- package/dist/apps/context-files-ui/assets/commonlisp-DFkEQdLP.js +0 -1
- package/dist/apps/context-files-ui/assets/crystal-CU0NkcVL.js +0 -1
- package/dist/apps/context-files-ui/assets/css-CbMZAQ1W.js +0 -1
- package/dist/apps/context-files-ui/assets/dist-B5PTVnox.js +0 -1
- package/dist/apps/context-files-ui/assets/dist-B5ZAfwf5.js +0 -1
- package/dist/apps/context-files-ui/assets/dist-BD262Ouw.js +0 -1
- package/dist/apps/context-files-ui/assets/dist-BKuGdcnX.js +0 -9
- package/dist/apps/context-files-ui/assets/dist-CHdx1Jri.js +0 -1
- package/dist/apps/context-files-ui/assets/dist-CULMH-fB.js +0 -11
- package/dist/apps/context-files-ui/assets/dist-Cjq6RWEt.js +0 -1
- package/dist/apps/context-files-ui/assets/dist-CntqFySz.js +0 -1
- package/dist/apps/context-files-ui/assets/dist-D1KyNDg5.js +0 -13
- package/dist/apps/context-files-ui/assets/dist-QQuDy4KA.js +0 -1
- package/dist/apps/context-files-ui/assets/dist-kPuQud7t.js +0 -2
- package/dist/apps/context-files-ui/assets/groovy-Cmduloe1.js +0 -1
- package/dist/apps/context-files-ui/assets/index-DZWsbuvg.js +0 -202
- package/dist/apps/context-files-ui/assets/javascript-C5pDVaoP.js +0 -1
- package/dist/apps/context-files-ui/assets/perl-D6YJObi_.js +0 -1
- package/dist/apps/context-files-ui/assets/puppet-B_0GFuyD.js +0 -1
- package/dist/apps/context-files-ui/assets/python-Cs7sNzy_.js +0 -1
- package/dist/apps/context-files-ui/assets/r-CN5s4f3o.js +0 -1
- package/dist/apps/context-files-ui/assets/ruby-BVPradRk.js +0 -1
- package/dist/apps/context-files-ui/assets/scheme-CvNgHAnh.js +0 -1
- package/dist/apps/context-files-ui/assets/sql-DYI2GwJR.js +0 -1
- package/dist/apps/context-files-ui/assets/textile-Yg_UWn-t.js +0 -1
- package/dist/apps/context-files-ui/assets/tiki-CC_ic8g0.js +0 -1
- package/dist/apps/context-files-ui/assets/toml-B7gGzVkJ.js +0 -1
- package/dist/apps/context-files-ui/assets/turtle-CwIpz2yy.js +0 -1
- package/dist/apps/context-files-ui/assets/vhdl-BGDk4f1d.js +0 -1
- package/dist/apps/context-files-ui/assets/z80-B7Dfb4UO.js +0 -1
- /package/dist/apps/chat-ui/assets/{brainfuck-CV9kufud.js → brainfuck-D5EjA2JK.js} +0 -0
- /package/dist/apps/chat-ui/assets/{clojure-De3QGfx6.js → clojure-BflJGmDX.js} +0 -0
- /package/dist/apps/chat-ui/assets/{cypher-Dke5QOzv.js → cypher-p9eYesGn.js} +0 -0
- /package/dist/apps/chat-ui/assets/{diff-B365LSoZ.js → diff-ChtP43wD.js} +0 -0
- /package/dist/apps/chat-ui/assets/{dtd-CBMymJ7O.js → dtd-DTF72YNO.js} +0 -0
- /package/dist/apps/chat-ui/assets/{ebnf-Dkum_1J8.js → ebnf-D4c0_ac3.js} +0 -0
- /package/dist/apps/chat-ui/assets/{eiffel-C446m6dI.js → eiffel-BEjRio4Q.js} +0 -0
- /package/dist/apps/chat-ui/assets/{elm-po1E9de0.js → elm-Cshzl8qu.js} +0 -0
- /package/dist/apps/chat-ui/assets/{fcl-DkEOamHd.js → fcl-ClOhbFR7.js} +0 -0
- /package/dist/apps/chat-ui/assets/{forth-dCg2_HVB.js → forth-Cezjo90N.js} +0 -0
- /package/dist/apps/chat-ui/assets/{fortran-3ZpXLFh1.js → fortran-Bt6PBEDR.js} +0 -0
- /package/dist/apps/chat-ui/assets/{gas-DMmxLZRI.js → gas-BHEdbvp9.js} +0 -0
- /package/dist/apps/chat-ui/assets/{gherkin-DUSFg2R6.js → gherkin-oBAE_ms0.js} +0 -0
- /package/dist/apps/chat-ui/assets/{haskell-Cyr255R9.js → haskell-BRsoo5mP.js} +0 -0
- /package/dist/apps/chat-ui/assets/{http-DszHFpc-.js → http-CLVgA2GD.js} +0 -0
- /package/dist/apps/chat-ui/assets/{idl-Cati9Nrv.js → idl-BUZw3wgd.js} +0 -0
- /package/dist/apps/chat-ui/assets/{julia-DlqY1cTU.js → julia-CQfgDRfP.js} +0 -0
- /package/dist/apps/chat-ui/assets/{livescript-C6p8-2W1.js → livescript-BXxG0Yva.js} +0 -0
- /package/dist/apps/chat-ui/assets/{mathematica-nDHZUMJT.js → mathematica-u8YMmbU0.js} +0 -0
- /package/dist/apps/chat-ui/assets/{mbox-DAaR0Hcz.js → mbox-BEMVcqjs.js} +0 -0
- /package/dist/apps/chat-ui/assets/{mirc-CCA0FRfl.js → mirc-C9zpzAZU.js} +0 -0
- /package/dist/apps/chat-ui/assets/{mllike-Cw3Iccsb.js → mllike-B45xgp2S.js} +0 -0
- /package/dist/apps/chat-ui/assets/{modelica-Czx80fNR.js → modelica-CqHI_q-D.js} +0 -0
- /package/dist/apps/chat-ui/assets/{mscgen-BmfuTbzG.js → mscgen-qgSLujhx.js} +0 -0
- /package/dist/apps/chat-ui/assets/{nginx-D9M2PQ4U.js → nginx-BMaDbqW3.js} +0 -0
- /package/dist/apps/chat-ui/assets/{octave-8jj96JiC.js → octave-D2Q8cUp1.js} +0 -0
- /package/dist/apps/chat-ui/assets/{oz-BmMq7iC4.js → oz-BwTct_5T.js} +0 -0
- /package/dist/apps/chat-ui/assets/{pascal-BgMr6XpT.js → pascal-Dp_KdFgX.js} +0 -0
- /package/dist/apps/chat-ui/assets/{pig-nx7uchs8.js → pig-AF4Hwhju.js} +0 -0
- /package/dist/apps/chat-ui/assets/{properties-CoavQdLC.js → properties-C357ku5U.js} +0 -0
- /package/dist/apps/chat-ui/assets/{protobuf-D5EWhcmc.js → protobuf-D1ij_kNL.js} +0 -0
- /package/dist/apps/chat-ui/assets/{q-BIB9pPtI.js → q-B9NhS7L_.js} +0 -0
- /package/dist/apps/chat-ui/assets/{rpm-Ct_Ck8mQ.js → rpm-gpDK5sbt.js} +0 -0
- /package/dist/apps/chat-ui/assets/{sas-DN4j74IF.js → sas-C2OyD2Y6.js} +0 -0
- /package/dist/apps/chat-ui/assets/{sieve-C2U1O5Z4.js → sieve-BAxa3IjF.js} +0 -0
- /package/dist/apps/chat-ui/assets/{smalltalk-DkYwYufV.js → smalltalk-BLp5-jwC.js} +0 -0
- /package/dist/apps/chat-ui/assets/{solr-BopnSD-v.js → solr-BBopId9w.js} +0 -0
- /package/dist/apps/chat-ui/assets/{sparql-Cpg3YQfd.js → sparql-Dz-mlCAC.js} +0 -0
- /package/dist/apps/chat-ui/assets/{spreadsheet-kRxtVt9J.js → spreadsheet-CTIncYxj.js} +0 -0
- /package/dist/apps/chat-ui/assets/{swift-DKNaLAK6.js → swift-DKB6_1j6.js} +0 -0
- /package/dist/apps/chat-ui/assets/{tcl-CQyXkgMH.js → tcl-BGfruO1u.js} +0 -0
- /package/dist/apps/chat-ui/assets/{tiddlywiki-dqVbkfX4.js → tiddlywiki-VlUiK86J.js} +0 -0
- /package/dist/apps/chat-ui/assets/{troff-Bq3z6oAu.js → troff-C2dAgh7P.js} +0 -0
- /package/dist/apps/chat-ui/assets/{vb-BmcHUM2C.js → vb-BthdM_4N.js} +0 -0
- /package/dist/apps/chat-ui/assets/{vbscript-Cs9dylre.js → vbscript-D9f6rSsU.js} +0 -0
- /package/dist/apps/chat-ui/assets/{velocity-CBWU0VCy.js → velocity-CqftRsjg.js} +0 -0
- /package/dist/apps/chat-ui/assets/{webidl-egXQEWlC.js → webidl-D5jiJvOU.js} +0 -0
- /package/dist/apps/chat-ui/assets/{yacas-DNs9XkmQ.js → yacas-CXXgtw0p.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{brainfuck-CV9kufud.js → brainfuck-D5EjA2JK.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{clojure-De3QGfx6.js → clojure-BflJGmDX.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{cypher-Dke5QOzv.js → cypher-p9eYesGn.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{diff-B365LSoZ.js → diff-ChtP43wD.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{dtd-CBMymJ7O.js → dtd-DTF72YNO.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{ebnf-Dkum_1J8.js → ebnf-D4c0_ac3.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{eiffel-C446m6dI.js → eiffel-BEjRio4Q.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{elm-po1E9de0.js → elm-Cshzl8qu.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{fcl-DkEOamHd.js → fcl-ClOhbFR7.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{forth-dCg2_HVB.js → forth-Cezjo90N.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{fortran-3ZpXLFh1.js → fortran-Bt6PBEDR.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{gas-DMmxLZRI.js → gas-BHEdbvp9.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{gherkin-DUSFg2R6.js → gherkin-oBAE_ms0.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{haskell-Cyr255R9.js → haskell-BRsoo5mP.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{http-DszHFpc-.js → http-CLVgA2GD.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{idl-Cati9Nrv.js → idl-BUZw3wgd.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{julia-DlqY1cTU.js → julia-CQfgDRfP.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{livescript-C6p8-2W1.js → livescript-BXxG0Yva.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{mathematica-nDHZUMJT.js → mathematica-u8YMmbU0.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{mbox-DAaR0Hcz.js → mbox-BEMVcqjs.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{mirc-CCA0FRfl.js → mirc-C9zpzAZU.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{mllike-Cw3Iccsb.js → mllike-B45xgp2S.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{modelica-Czx80fNR.js → modelica-CqHI_q-D.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{mscgen-BmfuTbzG.js → mscgen-qgSLujhx.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{nginx-D9M2PQ4U.js → nginx-BMaDbqW3.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{octave-8jj96JiC.js → octave-D2Q8cUp1.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{oz-BmMq7iC4.js → oz-BwTct_5T.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{pascal-BgMr6XpT.js → pascal-Dp_KdFgX.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{pig-nx7uchs8.js → pig-AF4Hwhju.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{properties-CoavQdLC.js → properties-C357ku5U.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{protobuf-D5EWhcmc.js → protobuf-D1ij_kNL.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{q-BIB9pPtI.js → q-B9NhS7L_.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{rpm-Ct_Ck8mQ.js → rpm-gpDK5sbt.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{sas-DN4j74IF.js → sas-C2OyD2Y6.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{sieve-C2U1O5Z4.js → sieve-BAxa3IjF.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{smalltalk-DkYwYufV.js → smalltalk-BLp5-jwC.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{solr-BopnSD-v.js → solr-BBopId9w.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{sparql-Cpg3YQfd.js → sparql-Dz-mlCAC.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{spreadsheet-kRxtVt9J.js → spreadsheet-CTIncYxj.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{swift-DKNaLAK6.js → swift-DKB6_1j6.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{tcl-CQyXkgMH.js → tcl-BGfruO1u.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{tiddlywiki-dqVbkfX4.js → tiddlywiki-VlUiK86J.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{troff-Bq3z6oAu.js → troff-C2dAgh7P.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{vb-BmcHUM2C.js → vb-BthdM_4N.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{vbscript-Cs9dylre.js → vbscript-D9f6rSsU.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{velocity-CBWU0VCy.js → velocity-CqftRsjg.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{webidl-egXQEWlC.js → webidl-D5jiJvOU.js} +0 -0
- /package/dist/apps/context-files-ui/assets/{yacas-DNs9XkmQ.js → yacas-CXXgtw0p.js} +0 -0
|
@@ -21,6 +21,13 @@ const BOOLEAN_CAPABILITY_PATHS = [
|
|
|
21
21
|
"output.diffs",
|
|
22
22
|
"output.rawNativeEvents",
|
|
23
23
|
"mcp.statusInspection",
|
|
24
|
+
"contextDiscovery.supported",
|
|
25
|
+
"contextDiscovery.configurable",
|
|
26
|
+
"contextDiscovery.enabledByDefault",
|
|
27
|
+
"nativeSubagents.supported",
|
|
28
|
+
"nativeSubagents.configurable",
|
|
29
|
+
"nativeSubagents.enabledByDefault",
|
|
30
|
+
"historyImport",
|
|
24
31
|
"auth.status",
|
|
25
32
|
"auth.cancel",
|
|
26
33
|
"auth.logout",
|
|
@@ -51,6 +58,13 @@ function readPath(value, path) {
|
|
|
51
58
|
}
|
|
52
59
|
return current;
|
|
53
60
|
}
|
|
61
|
+
function safeDeclaredRelativePath(value) {
|
|
62
|
+
const normalized = value.replaceAll("\\", "/");
|
|
63
|
+
return !normalized.startsWith("/")
|
|
64
|
+
&& !/^[A-Za-z]:/.test(normalized)
|
|
65
|
+
&& !normalized.includes("\0")
|
|
66
|
+
&& normalized.split("/").every((segment) => segment !== "..");
|
|
67
|
+
}
|
|
54
68
|
function validateDelivery(path, value, errors) {
|
|
55
69
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
56
70
|
errors.push(`${path} must be a capability-delivery object`);
|
|
@@ -107,6 +121,49 @@ export function validateAgentRuntimeCapabilities(value) {
|
|
|
107
121
|
if (reasoningSupported === false && Array.isArray(reasoningValues) && reasoningValues.length > 0) {
|
|
108
122
|
errors.push("reasoning.values must be omitted or empty when reasoning is unsupported");
|
|
109
123
|
}
|
|
124
|
+
for (const feature of ["contextDiscovery", "nativeSubagents"]) {
|
|
125
|
+
const supported = readPath(value, `${feature}.supported`);
|
|
126
|
+
const configurable = readPath(value, `${feature}.configurable`);
|
|
127
|
+
const enabledByDefault = readPath(value, `${feature}.enabledByDefault`);
|
|
128
|
+
if (configurable === true && supported !== true) {
|
|
129
|
+
errors.push(`${feature}.configurable requires ${feature}.supported`);
|
|
130
|
+
}
|
|
131
|
+
if (enabledByDefault === true && supported !== true) {
|
|
132
|
+
errors.push(`${feature}.enabledByDefault requires ${feature}.supported`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const contextDiscoveryStrategy = readPath(value, "contextDiscovery.strategy");
|
|
136
|
+
if (contextDiscoveryStrategy !== undefined
|
|
137
|
+
&& !["filesystem-ancestors", "codex-project", "omp-project"].includes(String(contextDiscoveryStrategy))) {
|
|
138
|
+
errors.push("contextDiscovery.strategy must be filesystem-ancestors, codex-project, or omp-project when provided");
|
|
139
|
+
}
|
|
140
|
+
if (contextDiscoveryStrategy !== undefined && readPath(value, "contextDiscovery.supported") !== true) {
|
|
141
|
+
errors.push("contextDiscovery.strategy requires contextDiscovery.supported");
|
|
142
|
+
}
|
|
143
|
+
for (const field of ["knownFileNames", "knownUserRelativePaths", "knownCwdRelativePaths", "knownRelativePaths", "knownAncestorRelativePaths"]) {
|
|
144
|
+
const knownContextPaths = readPath(value, `contextDiscovery.${field}`);
|
|
145
|
+
if (knownContextPaths === undefined)
|
|
146
|
+
continue;
|
|
147
|
+
if (!Array.isArray(knownContextPaths)) {
|
|
148
|
+
errors.push(`contextDiscovery.${field} must be an array of non-empty strings when provided`);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (knownContextPaths.some((name) => typeof name !== "string" || !name.trim())) {
|
|
152
|
+
errors.push(`contextDiscovery.${field} must be an array of non-empty strings when provided`);
|
|
153
|
+
}
|
|
154
|
+
else if (new Set(knownContextPaths).size !== knownContextPaths.length) {
|
|
155
|
+
errors.push(`contextDiscovery.${field} must not contain duplicates`);
|
|
156
|
+
}
|
|
157
|
+
else if (field === "knownFileNames" && knownContextPaths.some((name) => name.includes("/") || name.includes("\\") || name === "." || name === "..")) {
|
|
158
|
+
errors.push("contextDiscovery.knownFileNames entries must be plain filenames");
|
|
159
|
+
}
|
|
160
|
+
else if (field !== "knownFileNames" && knownContextPaths.some((path) => !safeDeclaredRelativePath(path))) {
|
|
161
|
+
errors.push(`contextDiscovery.${field} entries must be safe relative paths`);
|
|
162
|
+
}
|
|
163
|
+
if (readPath(value, "contextDiscovery.supported") !== true && knownContextPaths.length > 0) {
|
|
164
|
+
errors.push(`contextDiscovery.${field} requires contextDiscovery.supported`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
110
167
|
const authMethods = readPath(value, "auth.methods");
|
|
111
168
|
if (!Array.isArray(authMethods)) {
|
|
112
169
|
errors.push("auth.methods must be an array");
|
|
@@ -193,6 +250,17 @@ export function createMinimalAgentRuntimeCapabilities() {
|
|
|
193
250
|
},
|
|
194
251
|
skills: unavailable,
|
|
195
252
|
context: unavailable,
|
|
253
|
+
contextDiscovery: {
|
|
254
|
+
supported: false,
|
|
255
|
+
configurable: false,
|
|
256
|
+
enabledByDefault: false,
|
|
257
|
+
},
|
|
258
|
+
nativeSubagents: {
|
|
259
|
+
supported: false,
|
|
260
|
+
configurable: false,
|
|
261
|
+
enabledByDefault: false,
|
|
262
|
+
},
|
|
263
|
+
historyImport: false,
|
|
196
264
|
auth: {
|
|
197
265
|
status: false,
|
|
198
266
|
methods: [],
|
|
@@ -5,12 +5,12 @@ export function profileWithRuntimeInstance(profile, runtimeInstanceId) {
|
|
|
5
5
|
return new InitialSessionContext({
|
|
6
6
|
profileName: profile.profileName,
|
|
7
7
|
runtimeInstanceId,
|
|
8
|
-
runtimeOptions:
|
|
8
|
+
runtimeOptions: {},
|
|
9
9
|
sessionId: profile.sessionId,
|
|
10
10
|
parentSessionId: profile.parentSessionId,
|
|
11
|
-
model:
|
|
12
|
-
mainModel:
|
|
13
|
-
subagentModel:
|
|
11
|
+
model: undefined,
|
|
12
|
+
mainModel: undefined,
|
|
13
|
+
subagentModel: undefined,
|
|
14
14
|
thinkingLevel: profile.thinkingLevel,
|
|
15
15
|
mainThinkingLevel: profile.mainThinkingLevel,
|
|
16
16
|
subagentThinkingLevel: profile.subagentThinkingLevel,
|
|
@@ -26,6 +26,7 @@ export function profileWithRuntimeInstance(profile, runtimeInstanceId) {
|
|
|
26
26
|
builtinTools: profile.builtinTools,
|
|
27
27
|
builtinToolNames: profile.builtinToolNames,
|
|
28
28
|
autoContextFiles: profile.autoContextFiles,
|
|
29
|
+
nativeSubagents: undefined,
|
|
29
30
|
toolPackages: profile.toolPackages,
|
|
30
31
|
});
|
|
31
32
|
}
|
|
@@ -105,7 +106,12 @@ export function buildPortableRuntimeContextSnapshot(input) {
|
|
|
105
106
|
else {
|
|
106
107
|
addRuntimeContributionGroup(nodes, "skills", "Skills", profile.skills.filter((skill) => skill.enabled !== false).map((skill) => skill.name), input.runtime.capabilities.skills);
|
|
107
108
|
addRuntimeContributionGroup(nodes, "context", "Context", [
|
|
108
|
-
...(
|
|
109
|
+
...(input.runtime.capabilities.contextDiscovery.supported
|
|
110
|
+
&& (input.runtime.capabilities.contextDiscovery.configurable
|
|
111
|
+
? profile.autoContextFiles
|
|
112
|
+
: input.runtime.capabilities.contextDiscovery.enabledByDefault)
|
|
113
|
+
? ["automatic:runtime project context discovery"]
|
|
114
|
+
: []),
|
|
109
115
|
...profile.contextFiles.filter((file) => file.enabled !== false).map((file) => file.key ?? file.path),
|
|
110
116
|
], input.runtime.capabilities.context);
|
|
111
117
|
addRuntimeContributionGroup(nodes, "mcp", "External MCP Servers", [...profile.mcpServers], input.runtime.capabilities.mcp.externalServers);
|
|
@@ -138,6 +144,8 @@ export function buildPortableRuntimeContextSnapshot(input) {
|
|
|
138
144
|
subagentFast: profile.subagentFast ?? profile.fast,
|
|
139
145
|
builtinTools: profile.builtinTools,
|
|
140
146
|
builtinToolNames: profile.builtinToolNames,
|
|
147
|
+
nativeSubagents: profile.nativeSubagents
|
|
148
|
+
?? input.runtime.capabilities.nativeSubagents.enabledByDefault,
|
|
141
149
|
},
|
|
142
150
|
});
|
|
143
151
|
for (const [index, diagnostic] of input.runtime.diagnostics.entries()) {
|
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { redactSensitiveText, redactSensitiveValue } from "../core/sensitive-data-redaction.js";
|
|
3
|
+
export const PORTABLE_HISTORY_HANDOFF_METADATA_KEY = "portableHistoryHandoff";
|
|
4
|
+
export const PORTABLE_HISTORY_LAST_IMPORT_METADATA_KEY = "portableHistoryLastImport";
|
|
5
|
+
const PORTABLE_HISTORY_VERSION = 1;
|
|
6
|
+
const MAX_SOURCE_ROWS = 4_000;
|
|
7
|
+
const MAX_HISTORY_ENTRIES = 1_000;
|
|
8
|
+
const MAX_HISTORY_BYTES = 1024 * 1024;
|
|
9
|
+
const MAX_ENTRY_BYTES = 256 * 1024;
|
|
10
|
+
const MAX_HISTORY_ENVELOPE_RESERVE_BYTES = 16 * 1024;
|
|
11
|
+
function validBoundedIdentifier(value) {
|
|
12
|
+
return typeof value === "string" && value.trim().length > 0 && value.length <= 256;
|
|
13
|
+
}
|
|
14
|
+
function validTimestamp(value) {
|
|
15
|
+
return typeof value === "string" && value.length <= 128 && Number.isFinite(Date.parse(value));
|
|
16
|
+
}
|
|
17
|
+
function parseObject(value) {
|
|
18
|
+
try {
|
|
19
|
+
const parsed = JSON.parse(value);
|
|
20
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
21
|
+
? parsed
|
|
22
|
+
: {};
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function jsonValue(value) {
|
|
29
|
+
if (value === undefined)
|
|
30
|
+
return undefined;
|
|
31
|
+
try {
|
|
32
|
+
return JSON.parse(JSON.stringify(redactSensitiveValue(value)));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function boundedIdentifierText(value, fallback, maxLength = 512) {
|
|
39
|
+
const normalized = value.trim();
|
|
40
|
+
const redacted = redactSensitiveText(normalized).replace(/[\r\n]+/g, " ").trim();
|
|
41
|
+
const needsHash = redacted !== normalized || redacted.length > maxLength;
|
|
42
|
+
const suffix = needsHash ? `-${createHash("sha256").update(value).digest("hex").slice(0, 12)}` : "";
|
|
43
|
+
const selected = (redacted || fallback).slice(0, Math.max(1, maxLength - suffix.length));
|
|
44
|
+
return `${selected}${suffix}`;
|
|
45
|
+
}
|
|
46
|
+
function optionalBoundedIdentifierText(value) {
|
|
47
|
+
return value ? boundedIdentifierText(value, "portable-id") : undefined;
|
|
48
|
+
}
|
|
49
|
+
function boundedText(value, maxBytes = MAX_ENTRY_BYTES) {
|
|
50
|
+
if (Buffer.byteLength(value, "utf8") <= maxBytes)
|
|
51
|
+
return value;
|
|
52
|
+
const suffix = "\n\n[Portable history entry truncated by Pibo.]";
|
|
53
|
+
const suffixBytes = Buffer.byteLength(suffix, "utf8");
|
|
54
|
+
const buffer = Buffer.from(value, "utf8");
|
|
55
|
+
return `${buffer.subarray(0, Math.max(0, maxBytes - suffixBytes)).toString("utf8")}${suffix}`;
|
|
56
|
+
}
|
|
57
|
+
function stringContent(entry) {
|
|
58
|
+
if (entry.type !== "message")
|
|
59
|
+
return entry.name;
|
|
60
|
+
if (typeof entry.content === "string")
|
|
61
|
+
return entry.content;
|
|
62
|
+
return entry.content.map((part) => {
|
|
63
|
+
if (part.type === "text" || part.type === "reasoning")
|
|
64
|
+
return part.text;
|
|
65
|
+
return `${part.toolName}:${JSON.stringify(part.input ?? null)}`;
|
|
66
|
+
}).join("\n");
|
|
67
|
+
}
|
|
68
|
+
function entryBytes(entry) {
|
|
69
|
+
return Buffer.byteLength(JSON.stringify(entry), "utf8");
|
|
70
|
+
}
|
|
71
|
+
function historyRole(value) {
|
|
72
|
+
return value === "user" || value === "assistant" || value === "system" ? value : undefined;
|
|
73
|
+
}
|
|
74
|
+
function historyStatus(value) {
|
|
75
|
+
if (value === "running" || value === "streaming" || value === "in_progress")
|
|
76
|
+
return "running";
|
|
77
|
+
if (value === "error" || value === "failed")
|
|
78
|
+
return "error";
|
|
79
|
+
return "complete";
|
|
80
|
+
}
|
|
81
|
+
export class PiboDataPortableHistoryProvider {
|
|
82
|
+
store;
|
|
83
|
+
constructor(store) {
|
|
84
|
+
this.store = store;
|
|
85
|
+
}
|
|
86
|
+
createCheckpoint(piboSessionId) {
|
|
87
|
+
const row = this.store.db.prepare(`
|
|
88
|
+
SELECT COALESCE(MAX(session_sequence), 0) AS max_sequence
|
|
89
|
+
FROM event_log
|
|
90
|
+
WHERE session_id = ?
|
|
91
|
+
`).get(piboSessionId);
|
|
92
|
+
return {
|
|
93
|
+
maxSessionSequence: Number(row.max_sequence ?? 0),
|
|
94
|
+
createdAt: new Date().toISOString(),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
read(input) {
|
|
98
|
+
const messages = this.readMessages(input.piboSession.id, input.checkpoint, this.readRoutedUserMessages(input.piboSession.id, input.checkpoint));
|
|
99
|
+
const tools = this.readToolEntries(input.piboSession.id, input.checkpoint);
|
|
100
|
+
const nonPortableCount = this.nonPortableEntryCount(input.piboSession.id, input.checkpoint);
|
|
101
|
+
const modelEntries = [...messages, ...tools]
|
|
102
|
+
.sort((left, right) => (left.sequence ?? 0) - (right.sequence ?? 0) || left.createdAt.localeCompare(right.createdAt));
|
|
103
|
+
const contextEntry = {
|
|
104
|
+
id: "portable:pibo-context",
|
|
105
|
+
type: "message",
|
|
106
|
+
source: "product",
|
|
107
|
+
createdAt: input.checkpoint.createdAt,
|
|
108
|
+
sequence: 0,
|
|
109
|
+
role: "system",
|
|
110
|
+
content: [
|
|
111
|
+
"Pibo portable conversation handoff.",
|
|
112
|
+
`Pibo Session ID: ${input.piboSession.id}`,
|
|
113
|
+
`Pibo Room ID: ${typeof input.piboSession.metadata?.chatRoomId === "string" ? input.piboSession.metadata.chatRoomId : "unknown"}`,
|
|
114
|
+
`Profile: ${input.piboSession.profile}`,
|
|
115
|
+
`Source runtime: ${input.sourceBinding.runtimeInstanceId} (${input.sourceBinding.adapterId})`,
|
|
116
|
+
"The following entries are model-relevant product history. Private reasoning and runtime-private metadata are intentionally omitted.",
|
|
117
|
+
].join("\n"),
|
|
118
|
+
status: "complete",
|
|
119
|
+
};
|
|
120
|
+
const nonPortableEntry = nonPortableCount > 0
|
|
121
|
+
? {
|
|
122
|
+
id: "portable:nonportable-fallback",
|
|
123
|
+
type: "message",
|
|
124
|
+
source: "product",
|
|
125
|
+
createdAt: input.checkpoint.createdAt,
|
|
126
|
+
sequence: 0,
|
|
127
|
+
role: "system",
|
|
128
|
+
content: `${nonPortableCount} runtime-specific history entr${nonPortableCount === 1 ? "y was" : "ies were"} retained by Pibo but omitted from the portable model context because no safe cross-runtime representation exists.`,
|
|
129
|
+
status: "complete",
|
|
130
|
+
}
|
|
131
|
+
: undefined;
|
|
132
|
+
const bounded = boundEntries(modelEntries, {
|
|
133
|
+
maxEntries: MAX_HISTORY_ENTRIES - (nonPortableEntry ? 3 : 2),
|
|
134
|
+
maxBytes: Math.max(0, MAX_HISTORY_BYTES
|
|
135
|
+
- entryBytes(contextEntry)
|
|
136
|
+
- (nonPortableEntry ? entryBytes(nonPortableEntry) : 0)
|
|
137
|
+
- MAX_HISTORY_ENVELOPE_RESERVE_BYTES),
|
|
138
|
+
});
|
|
139
|
+
const retained = [...bounded.entries];
|
|
140
|
+
let additionallyOmitted = 0;
|
|
141
|
+
while (true) {
|
|
142
|
+
const omittedEntries = bounded.omittedEntries + additionallyOmitted;
|
|
143
|
+
const entries = [contextEntry];
|
|
144
|
+
if (nonPortableEntry)
|
|
145
|
+
entries.push(nonPortableEntry);
|
|
146
|
+
if (omittedEntries > 0) {
|
|
147
|
+
entries.push({
|
|
148
|
+
id: "portable:bounded-fallback",
|
|
149
|
+
type: "message",
|
|
150
|
+
source: "product",
|
|
151
|
+
createdAt: input.checkpoint.createdAt,
|
|
152
|
+
sequence: 0,
|
|
153
|
+
role: "system",
|
|
154
|
+
content: `${omittedEntries} older portable history entr${omittedEntries === 1 ? "y was" : "ies were"} omitted to stay within the bounded cross-runtime handoff limit. The most recent conversation context follows.`,
|
|
155
|
+
status: "complete",
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
entries.push(...normalizeToolPairs(retained));
|
|
159
|
+
const history = {
|
|
160
|
+
version: PORTABLE_HISTORY_VERSION,
|
|
161
|
+
piboSessionId: input.piboSession.id,
|
|
162
|
+
sourceRuntimeInstanceId: input.sourceBinding.runtimeInstanceId,
|
|
163
|
+
sourceAdapterId: input.sourceBinding.adapterId,
|
|
164
|
+
checkpoint: { ...input.checkpoint },
|
|
165
|
+
entries,
|
|
166
|
+
truncated: omittedEntries > 0,
|
|
167
|
+
omittedEntries,
|
|
168
|
+
};
|
|
169
|
+
const serializedBytes = Buffer.byteLength(JSON.stringify(history), "utf8");
|
|
170
|
+
if (serializedBytes <= MAX_HISTORY_BYTES)
|
|
171
|
+
return history;
|
|
172
|
+
if (retained.length === 0) {
|
|
173
|
+
throw new Error("Portable history metadata exceeds the aggregate handoff limit.");
|
|
174
|
+
}
|
|
175
|
+
const excessBytes = serializedBytes - MAX_HISTORY_BYTES;
|
|
176
|
+
const averageEntryBytes = Math.max(1, Math.floor(retained.reduce((sum, entry) => sum + entryBytes(entry), 0) / retained.length));
|
|
177
|
+
const removeCount = Math.min(retained.length, Math.max(1, Math.ceil(excessBytes / averageEntryBytes)));
|
|
178
|
+
retained.splice(0, removeCount);
|
|
179
|
+
additionallyOmitted += removeCount;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
readMessages(piboSessionId, checkpoint, routedUserMessages) {
|
|
183
|
+
const rows = this.store.db.prepare(`
|
|
184
|
+
SELECT m.*, e.session_sequence AS event_sequence
|
|
185
|
+
FROM chat_messages m
|
|
186
|
+
LEFT JOIN event_log e ON e.stream_id = m.source_stream_id
|
|
187
|
+
WHERE m.session_id = ?
|
|
188
|
+
AND m.role IN ('user', 'assistant', 'system')
|
|
189
|
+
AND ((e.session_sequence IS NOT NULL AND e.session_sequence <= ?) OR (e.session_sequence IS NULL AND m.created_at <= ?))
|
|
190
|
+
ORDER BY COALESCE(e.session_sequence, m.sequence) DESC
|
|
191
|
+
LIMIT ?
|
|
192
|
+
`).all(piboSessionId, checkpoint.maxSessionSequence, checkpoint.createdAt, MAX_SOURCE_ROWS);
|
|
193
|
+
return rows.reverse().flatMap((row) => {
|
|
194
|
+
const role = historyRole(row.role);
|
|
195
|
+
if (!role)
|
|
196
|
+
return [];
|
|
197
|
+
const attributes = parseObject(row.attributes_json);
|
|
198
|
+
const clientTxnId = typeof attributes.clientTxnId === "string" ? attributes.clientTxnId : undefined;
|
|
199
|
+
if (role === "user") {
|
|
200
|
+
if (clientTxnId && !routedUserMessages.turnIds.has(clientTxnId))
|
|
201
|
+
return [];
|
|
202
|
+
if (!clientTxnId && row.source_stream_id !== null && !routedUserMessages.sourceStreamIds.has(row.source_stream_id))
|
|
203
|
+
return [];
|
|
204
|
+
}
|
|
205
|
+
let text = typeof attributes.inlineText === "string" ? attributes.inlineText : row.content_preview ?? "";
|
|
206
|
+
if (row.content_payload_ref) {
|
|
207
|
+
const payload = this.store.payloads.getPayload(row.content_payload_ref);
|
|
208
|
+
if (payload && payload.byteSize <= MAX_ENTRY_BYTES) {
|
|
209
|
+
text = this.store.payloads.readPayloadText(row.content_payload_ref);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return [{
|
|
213
|
+
id: `portable:message:${row.id}`,
|
|
214
|
+
type: "message",
|
|
215
|
+
source: "product",
|
|
216
|
+
createdAt: row.created_at,
|
|
217
|
+
sequence: row.event_sequence ?? row.sequence,
|
|
218
|
+
turnId: optionalBoundedIdentifierText(row.turn_id),
|
|
219
|
+
role,
|
|
220
|
+
content: boundedText(redactSensitiveText(text)),
|
|
221
|
+
status: historyStatus(row.status),
|
|
222
|
+
}];
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
readRoutedUserMessages(piboSessionId, checkpoint) {
|
|
226
|
+
const routedRows = this.store.db.prepare(`
|
|
227
|
+
SELECT DISTINCT turn_id
|
|
228
|
+
FROM event_log
|
|
229
|
+
WHERE session_id = ?
|
|
230
|
+
AND session_sequence <= ?
|
|
231
|
+
AND turn_id IS NOT NULL
|
|
232
|
+
AND type IN ('message_queued', 'message_steered', 'message_started')
|
|
233
|
+
`).all(piboSessionId, checkpoint.maxSessionSequence);
|
|
234
|
+
const acceptedRows = this.store.db.prepare(`
|
|
235
|
+
SELECT accepted.stream_id
|
|
236
|
+
FROM event_log accepted
|
|
237
|
+
WHERE accepted.session_id = ?
|
|
238
|
+
AND accepted.type = 'user.message.accepted'
|
|
239
|
+
AND accepted.session_sequence <= ?
|
|
240
|
+
AND EXISTS (
|
|
241
|
+
SELECT 1
|
|
242
|
+
FROM event_log routed
|
|
243
|
+
WHERE routed.session_id = accepted.session_id
|
|
244
|
+
AND routed.session_sequence > accepted.session_sequence
|
|
245
|
+
AND routed.session_sequence <= ?
|
|
246
|
+
AND routed.type IN ('message_queued', 'message_steered', 'message_started')
|
|
247
|
+
AND NOT EXISTS (
|
|
248
|
+
SELECT 1
|
|
249
|
+
FROM event_log next_user
|
|
250
|
+
WHERE next_user.session_id = accepted.session_id
|
|
251
|
+
AND next_user.type = 'user.message.accepted'
|
|
252
|
+
AND next_user.session_sequence > accepted.session_sequence
|
|
253
|
+
AND next_user.session_sequence < routed.session_sequence
|
|
254
|
+
)
|
|
255
|
+
)
|
|
256
|
+
`).all(piboSessionId, checkpoint.maxSessionSequence, checkpoint.maxSessionSequence);
|
|
257
|
+
return {
|
|
258
|
+
turnIds: new Set(routedRows.map((row) => row.turn_id)),
|
|
259
|
+
sourceStreamIds: new Set(acceptedRows.map((row) => row.stream_id)),
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
readToolEntries(piboSessionId, checkpoint) {
|
|
263
|
+
const rows = this.store.db.prepare(`
|
|
264
|
+
SELECT stream_id, session_sequence, type, turn_id, tool_call_id, payload_ref, preview_text, attributes_json, created_at
|
|
265
|
+
FROM event_log
|
|
266
|
+
WHERE session_id = ?
|
|
267
|
+
AND session_sequence <= ?
|
|
268
|
+
AND type IN ('tool_call', 'tool_execution_finished')
|
|
269
|
+
ORDER BY session_sequence DESC
|
|
270
|
+
LIMIT ?
|
|
271
|
+
`).all(piboSessionId, checkpoint.maxSessionSequence, MAX_SOURCE_ROWS).reverse();
|
|
272
|
+
const calls = new Map();
|
|
273
|
+
const results = new Map();
|
|
274
|
+
for (const row of rows) {
|
|
275
|
+
if (!row.tool_call_id)
|
|
276
|
+
continue;
|
|
277
|
+
if (row.type === "tool_call") {
|
|
278
|
+
const attributes = parseObject(row.attributes_json);
|
|
279
|
+
const existing = calls.get(row.tool_call_id);
|
|
280
|
+
if (!existing || attributes.argsComplete === true)
|
|
281
|
+
calls.set(row.tool_call_id, row);
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
results.set(row.tool_call_id, row);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const entries = [];
|
|
288
|
+
for (const [toolCallId, row] of calls) {
|
|
289
|
+
const attributes = parseObject(row.attributes_json);
|
|
290
|
+
const portableToolCallId = boundedIdentifierText(toolCallId, `tool-call-${row.stream_id}`);
|
|
291
|
+
const toolName = boundedIdentifierText(typeof attributes.toolName === "string" ? attributes.toolName : row.preview_text ?? "tool", "tool", 256);
|
|
292
|
+
const part = {
|
|
293
|
+
type: "tool_call",
|
|
294
|
+
toolCallId: portableToolCallId,
|
|
295
|
+
toolName,
|
|
296
|
+
input: this.readEventPayload(row),
|
|
297
|
+
};
|
|
298
|
+
entries.push({
|
|
299
|
+
id: `portable:tool-call:${row.stream_id}`,
|
|
300
|
+
type: "message",
|
|
301
|
+
source: "product",
|
|
302
|
+
createdAt: row.created_at,
|
|
303
|
+
sequence: row.session_sequence,
|
|
304
|
+
turnId: optionalBoundedIdentifierText(row.turn_id),
|
|
305
|
+
role: "assistant",
|
|
306
|
+
content: [part],
|
|
307
|
+
status: "complete",
|
|
308
|
+
toolCallId: portableToolCallId,
|
|
309
|
+
toolName,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
for (const [toolCallId, row] of results) {
|
|
313
|
+
const attributes = parseObject(row.attributes_json);
|
|
314
|
+
const portableToolCallId = boundedIdentifierText(toolCallId, `tool-call-${row.stream_id}`);
|
|
315
|
+
const toolName = boundedIdentifierText(typeof attributes.toolName === "string" ? attributes.toolName : row.preview_text ?? "tool", "tool", 256);
|
|
316
|
+
const result = this.readEventPayload(row) ?? null;
|
|
317
|
+
entries.push({
|
|
318
|
+
id: `portable:tool-result:${row.stream_id}`,
|
|
319
|
+
type: "message",
|
|
320
|
+
source: "product",
|
|
321
|
+
createdAt: row.created_at,
|
|
322
|
+
sequence: row.session_sequence,
|
|
323
|
+
turnId: optionalBoundedIdentifierText(row.turn_id),
|
|
324
|
+
role: "tool",
|
|
325
|
+
content: boundedText(JSON.stringify(result)),
|
|
326
|
+
status: attributes.isError === true ? "error" : "complete",
|
|
327
|
+
toolCallId: portableToolCallId,
|
|
328
|
+
toolName,
|
|
329
|
+
result,
|
|
330
|
+
isError: attributes.isError === true,
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
return entries;
|
|
334
|
+
}
|
|
335
|
+
readEventPayload(row) {
|
|
336
|
+
const attributes = parseObject(row.attributes_json);
|
|
337
|
+
if (attributes.inlinePayload !== undefined)
|
|
338
|
+
return jsonValue(attributes.inlinePayload);
|
|
339
|
+
if (!row.payload_ref)
|
|
340
|
+
return undefined;
|
|
341
|
+
const payload = this.store.payloads.getPayload(row.payload_ref);
|
|
342
|
+
if (!payload)
|
|
343
|
+
return { portableFallback: "Tool payload is no longer available in Pibo history." };
|
|
344
|
+
if (payload.byteSize > MAX_ENTRY_BYTES) {
|
|
345
|
+
return {
|
|
346
|
+
portableFallback: "Tool payload exceeded the per-entry portable history limit.",
|
|
347
|
+
preview: redactSensitiveText(payload.previewText ?? row.preview_text ?? ""),
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
try {
|
|
351
|
+
return jsonValue(payload.contentType.includes("json")
|
|
352
|
+
? this.store.payloads.readPayloadJson(row.payload_ref)
|
|
353
|
+
: this.store.payloads.readPayloadText(row.payload_ref));
|
|
354
|
+
}
|
|
355
|
+
catch {
|
|
356
|
+
return { portableFallback: "Tool payload could not be read from Pibo history." };
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
nonPortableEntryCount(piboSessionId, checkpoint) {
|
|
360
|
+
const row = this.store.db.prepare(`
|
|
361
|
+
SELECT COUNT(*) AS count
|
|
362
|
+
FROM event_log
|
|
363
|
+
WHERE session_id = ?
|
|
364
|
+
AND session_sequence <= ?
|
|
365
|
+
AND (type = 'pi_event' OR type LIKE 'thinking_%' OR type = 'subagent_session')
|
|
366
|
+
`).get(piboSessionId, checkpoint.maxSessionSequence);
|
|
367
|
+
return Number(row.count ?? 0);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
function normalizeToolPairs(entries) {
|
|
371
|
+
const callIds = new Set();
|
|
372
|
+
const resultIds = new Set();
|
|
373
|
+
for (const entry of entries) {
|
|
374
|
+
if (entry.type !== "message")
|
|
375
|
+
continue;
|
|
376
|
+
if (entry.role === "tool" && entry.toolCallId)
|
|
377
|
+
resultIds.add(entry.toolCallId);
|
|
378
|
+
if (!Array.isArray(entry.content))
|
|
379
|
+
continue;
|
|
380
|
+
for (const part of entry.content) {
|
|
381
|
+
if (part.type === "tool_call")
|
|
382
|
+
callIds.add(part.toolCallId);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return entries.map((entry) => {
|
|
386
|
+
if (entry.type !== "message")
|
|
387
|
+
return entry;
|
|
388
|
+
if (entry.role === "tool" && entry.toolCallId && !callIds.has(entry.toolCallId)) {
|
|
389
|
+
return {
|
|
390
|
+
...entry,
|
|
391
|
+
role: "user",
|
|
392
|
+
content: [
|
|
393
|
+
`[Portable fallback: result from tool "${entry.toolName ?? "tool"}" had no retained matching call.]`,
|
|
394
|
+
typeof entry.content === "string" ? entry.content : JSON.stringify(entry.result ?? null),
|
|
395
|
+
].join("\n"),
|
|
396
|
+
toolCallId: undefined,
|
|
397
|
+
toolName: undefined,
|
|
398
|
+
result: undefined,
|
|
399
|
+
isError: undefined,
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
if (entry.role !== "assistant" || !Array.isArray(entry.content))
|
|
403
|
+
return entry;
|
|
404
|
+
const content = entry.content.map((part) => {
|
|
405
|
+
if (part.type !== "tool_call" || resultIds.has(part.toolCallId))
|
|
406
|
+
return part;
|
|
407
|
+
return {
|
|
408
|
+
type: "text",
|
|
409
|
+
text: `[Portable fallback: tool call "${part.toolName}" had no retained result.]\nInput: ${JSON.stringify(part.input ?? null)}`,
|
|
410
|
+
};
|
|
411
|
+
});
|
|
412
|
+
return content.some((part) => part.type === "tool_call")
|
|
413
|
+
? { ...entry, content }
|
|
414
|
+
: { ...entry, content, toolCallId: undefined, toolName: undefined };
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
function boundEntries(entries, limits) {
|
|
418
|
+
const selected = [];
|
|
419
|
+
let bytes = 0;
|
|
420
|
+
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
421
|
+
const entry = entries[index];
|
|
422
|
+
const normalized = normalizeEntrySize(entry);
|
|
423
|
+
const size = entryBytes(normalized);
|
|
424
|
+
if (selected.length >= limits.maxEntries || bytes + size > limits.maxBytes)
|
|
425
|
+
continue;
|
|
426
|
+
selected.push(normalized);
|
|
427
|
+
bytes += size;
|
|
428
|
+
}
|
|
429
|
+
selected.reverse();
|
|
430
|
+
return { entries: selected, omittedEntries: entries.length - selected.length };
|
|
431
|
+
}
|
|
432
|
+
function normalizeEntrySize(entry) {
|
|
433
|
+
if (entry.type !== "message")
|
|
434
|
+
return entry;
|
|
435
|
+
if (typeof entry.content === "string")
|
|
436
|
+
return { ...entry, content: boundedText(entry.content) };
|
|
437
|
+
if (entryBytes(entry) <= MAX_ENTRY_BYTES)
|
|
438
|
+
return entry;
|
|
439
|
+
return {
|
|
440
|
+
...entry,
|
|
441
|
+
content: boundedText(stringContent(entry)),
|
|
442
|
+
result: entry.result === undefined ? undefined : {
|
|
443
|
+
portableFallback: "Structured history content exceeded the per-entry limit.",
|
|
444
|
+
},
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
export function createPortableHistoryHandoffMetadata(input) {
|
|
448
|
+
return {
|
|
449
|
+
version: PORTABLE_HISTORY_VERSION,
|
|
450
|
+
status: "pending",
|
|
451
|
+
mode: input.mode,
|
|
452
|
+
sourceRuntimeInstanceId: input.sourceBinding.runtimeInstanceId,
|
|
453
|
+
sourceAdapterId: input.sourceBinding.adapterId,
|
|
454
|
+
targetRuntimeInstanceId: input.targetBinding.runtimeInstanceId,
|
|
455
|
+
targetAdapterId: input.targetBinding.adapterId,
|
|
456
|
+
requestedAt: new Date().toISOString(),
|
|
457
|
+
...(input.checkpoint ? { checkpoint: { ...input.checkpoint } } : {}),
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
export function readPortableHistoryHandoffMetadata(metadata) {
|
|
461
|
+
const value = metadata?.[PORTABLE_HISTORY_HANDOFF_METADATA_KEY];
|
|
462
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
463
|
+
return undefined;
|
|
464
|
+
const record = value;
|
|
465
|
+
if (record.version !== PORTABLE_HISTORY_VERSION || record.status !== "pending" || (record.mode !== "import" && record.mode !== "fresh"))
|
|
466
|
+
return undefined;
|
|
467
|
+
if (!validBoundedIdentifier(record.sourceRuntimeInstanceId)
|
|
468
|
+
|| !validBoundedIdentifier(record.sourceAdapterId)
|
|
469
|
+
|| !validBoundedIdentifier(record.targetRuntimeInstanceId)
|
|
470
|
+
|| !validBoundedIdentifier(record.targetAdapterId)
|
|
471
|
+
|| !validTimestamp(record.requestedAt))
|
|
472
|
+
return undefined;
|
|
473
|
+
let checkpoint;
|
|
474
|
+
if (record.mode === "import") {
|
|
475
|
+
const raw = record.checkpoint;
|
|
476
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
477
|
+
return undefined;
|
|
478
|
+
const selected = raw;
|
|
479
|
+
if (!Number.isSafeInteger(selected.maxSessionSequence) || Number(selected.maxSessionSequence) < 0 || !validTimestamp(selected.createdAt))
|
|
480
|
+
return undefined;
|
|
481
|
+
checkpoint = {
|
|
482
|
+
maxSessionSequence: Number(selected.maxSessionSequence),
|
|
483
|
+
createdAt: selected.createdAt,
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
return {
|
|
487
|
+
version: PORTABLE_HISTORY_VERSION,
|
|
488
|
+
status: "pending",
|
|
489
|
+
mode: record.mode,
|
|
490
|
+
sourceRuntimeInstanceId: record.sourceRuntimeInstanceId,
|
|
491
|
+
sourceAdapterId: record.sourceAdapterId,
|
|
492
|
+
targetRuntimeInstanceId: record.targetRuntimeInstanceId,
|
|
493
|
+
targetAdapterId: record.targetAdapterId,
|
|
494
|
+
requestedAt: record.requestedAt,
|
|
495
|
+
...(checkpoint ? { checkpoint } : {}),
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
export function withPortableHistoryHandoffMetadata(metadata, handoff) {
|
|
499
|
+
return {
|
|
500
|
+
...(metadata ?? {}),
|
|
501
|
+
[PORTABLE_HISTORY_HANDOFF_METADATA_KEY]: handoff,
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
export function withoutPortableHistoryHandoffMetadata(input) {
|
|
505
|
+
const { [PORTABLE_HISTORY_HANDOFF_METADATA_KEY]: _handoff, ...metadata } = input.metadata ?? {};
|
|
506
|
+
return {
|
|
507
|
+
...metadata,
|
|
508
|
+
[PORTABLE_HISTORY_LAST_IMPORT_METADATA_KEY]: {
|
|
509
|
+
version: PORTABLE_HISTORY_VERSION,
|
|
510
|
+
status: "completed",
|
|
511
|
+
mode: input.handoff.mode,
|
|
512
|
+
sourceRuntimeInstanceId: input.handoff.sourceRuntimeInstanceId,
|
|
513
|
+
sourceAdapterId: input.handoff.sourceAdapterId,
|
|
514
|
+
targetRuntimeInstanceId: input.handoff.targetRuntimeInstanceId,
|
|
515
|
+
targetAdapterId: input.handoff.targetAdapterId,
|
|
516
|
+
requestedAt: input.handoff.requestedAt,
|
|
517
|
+
...(input.handoff.checkpoint ? { checkpoint: { ...input.handoff.checkpoint } } : {}),
|
|
518
|
+
completedAt: new Date().toISOString(),
|
|
519
|
+
...(input.history ? {
|
|
520
|
+
entryCount: input.history.entries.length,
|
|
521
|
+
truncated: input.history.truncated,
|
|
522
|
+
omittedEntries: input.history.omittedEntries,
|
|
523
|
+
} : {}),
|
|
524
|
+
},
|
|
525
|
+
};
|
|
526
|
+
}
|