pim-agent 0.13.0 → 0.14.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/package.json +3 -3
- package/packages/core/src/attachments/AttachmentStore.ts +8 -13
- package/packages/core/src/attachments/Attachments.ts +2 -4
- package/packages/core/src/extensions/CoreExtensions.ts +1 -1
- package/packages/core/src/extensions/apply-patch/coordinator.ts +1 -1
- package/packages/core/src/extensions/apply-patch/executor.ts +21 -25
- package/packages/core/src/extensions/apply-patch/matcher.ts +1 -1
- package/packages/core/src/extensions/apply-patch/model.ts +2 -6
- package/packages/core/src/extensions/apply-patch/parser.ts +60 -162
- package/packages/core/src/extensions/apply-patch/schema.ts +0 -1
- package/packages/core/src/extensions/bash/MemoryCap.ts +5 -4
- package/packages/core/src/extensions/bash/capture.ts +16 -23
- package/packages/core/src/extensions/bash/format.ts +2 -2
- package/packages/core/src/extensions/bash/image.ts +4 -8
- package/packages/core/src/extensions/bash/index.ts +1 -1
- package/packages/core/src/extensions/bash/render.ts +1 -1
- package/packages/core/src/extensions/bash/run.ts +9 -15
- package/packages/core/src/extensions/bash/schema.ts +4 -4
- package/packages/core/src/extensions/edit/edit.ts +14 -33
- package/packages/core/src/extensions/glob/glob.ts +1 -3
- package/packages/core/src/extensions/glob/index.ts +7 -9
- package/packages/core/src/extensions/glob/render.ts +2 -4
- package/packages/core/src/extensions/glob/schema.ts +1 -1
- package/packages/core/src/extensions/grep/grep.ts +7 -7
- package/packages/core/src/extensions/grep/render.ts +5 -6
- package/packages/core/src/extensions/grep/schema.ts +3 -7
- package/packages/core/src/extensions/read/ImageMemory.ts +2 -8
- package/packages/core/src/extensions/read/image.ts +3 -3
- package/packages/core/src/extensions/read/index.ts +2 -14
- package/packages/core/src/extensions/read/read.ts +5 -6
- package/packages/core/src/extensions/read/render.ts +1 -1
- package/packages/core/src/extensions/read/schema.ts +2 -2
- package/packages/core/src/extensions/subagent/render.ts +2 -2
- package/packages/core/src/extensions/subagent/subagent.ts +10 -21
- package/packages/core/src/extensions/system-prompt/index.ts +1 -2
- package/packages/core/src/extensions/system-prompt/prompt.ts +2 -4
- package/packages/core/src/extensions/todo/render.ts +1 -4
- package/packages/core/src/extensions/todo/todo.ts +16 -23
- package/packages/core/src/extensions/web-fetch/JinaReaderClient.ts +3 -11
- package/packages/core/src/extensions/web-fetch/WebViewFetchClient.ts +1 -3
- package/packages/core/src/extensions/web-fetch/fetch.ts +4 -12
- package/packages/core/src/extensions/web-fetch/image.ts +3 -4
- package/packages/core/src/extensions/web-fetch/index.ts +2 -13
- package/packages/core/src/extensions/web-fetch/render.ts +3 -4
- package/packages/core/src/extensions/web-fetch/schema.ts +3 -4
- package/packages/core/src/extensions/web-search/ExaMcpClient.ts +23 -31
- package/packages/core/src/extensions/web-search/SearchBreaker.ts +1 -1
- package/packages/core/src/extensions/web-search/SearchChain.ts +6 -5
- package/packages/core/src/extensions/web-search/providers/DuckDuckGoProvider.ts +2 -2
- package/packages/core/src/extensions/web-search/providers/FirecrawlProvider.ts +1 -2
- package/packages/core/src/extensions/web-search/providers/SearchProvider.ts +3 -3
- package/packages/core/src/extensions/write/write.ts +1 -1
- package/packages/core/src/picker/InProcessFilePickerSuggestionEngine.ts +1 -3
- package/packages/core/src/picker/PickerItem.ts +1 -1
- package/packages/core/src/picker/PickerService.ts +3 -7
- package/packages/core/src/picker/RemoteFilePickerSuggestionEngine.ts +1 -2
- package/packages/core/src/picker/catalog.ts +7 -15
- package/packages/core/src/picker/filePickerWorker.ts +1 -3
- package/packages/core/src/picker/ranker.ts +1 -1
- package/packages/core/src/picker/token.ts +3 -4
- package/packages/core/src/session/AgentRuntime.ts +5 -8
- package/packages/core/src/session/EventLog.ts +6 -12
- package/packages/core/src/session/ReadCursors.ts +3 -4
- package/packages/core/src/session/SearchIndex.ts +49 -86
- package/packages/core/src/session/SearchTokens.ts +4 -7
- package/packages/core/src/session/SessionCache.ts +8 -6
- package/packages/core/src/session/SessionDigest.ts +10 -19
- package/packages/core/src/session/SessionHost.ts +53 -83
- package/packages/core/src/session/SessionLease.ts +12 -15
- package/packages/core/src/session/SessionMeta.ts +16 -32
- package/packages/core/src/session/SessionName.ts +3 -7
- package/packages/core/src/session/SessionRegistry.ts +13 -29
- package/packages/core/src/session/SessionUi.ts +12 -16
- package/packages/core/src/session/WriteMark.ts +7 -16
- package/packages/core/src/shared/Cli.ts +1 -1
- package/packages/core/src/shared/DaemonUnit.ts +1 -2
- package/packages/core/src/shared/DiffLines.ts +16 -34
- package/packages/core/src/shared/DiffRenderer.ts +8 -27
- package/packages/core/src/shared/Directories.ts +4 -4
- package/packages/core/src/shared/EditMatcher.ts +18 -50
- package/packages/core/src/shared/ExtensionToggles.ts +3 -6
- package/packages/core/src/shared/FileEnumerator.ts +73 -57
- package/packages/core/src/shared/FileScanner.ts +5 -13
- package/packages/core/src/shared/FileWatch.ts +13 -17
- package/packages/core/src/shared/Format.ts +2 -3
- package/packages/core/src/shared/FuzzyMatcher.ts +18 -19
- package/packages/core/src/shared/Git.ts +22 -47
- package/packages/core/src/shared/GitMonitor.ts +12 -23
- package/packages/core/src/shared/GlobExclusions.ts +0 -4
- package/packages/core/src/shared/Http.ts +1 -1
- package/packages/core/src/shared/ImageMime.ts +3 -5
- package/packages/core/src/shared/Images.ts +17 -27
- package/packages/core/src/shared/Languages.ts +2 -2
- package/packages/core/src/shared/Levenshtein.ts +1 -6
- package/packages/core/src/shared/Lines.ts +1 -1
- package/packages/core/src/shared/McpClient.ts +2 -2
- package/packages/core/src/shared/PatchSummary.ts +1 -1
- package/packages/core/src/shared/Paths.ts +4 -1
- package/packages/core/src/shared/PiExtensions.ts +5 -12
- package/packages/core/src/shared/PimSettings.ts +14 -15
- package/packages/core/src/shared/Proc.ts +2 -3
- package/packages/core/src/shared/RateLimiter.ts +1 -1
- package/packages/core/src/shared/Renderer.ts +1 -3
- package/packages/core/src/shared/RepoDiff.ts +24 -46
- package/packages/core/src/shared/SearchRender.ts +3 -4
- package/packages/core/src/shared/SpillCache.ts +2 -3
- package/packages/core/src/shared/SubagentLogs.ts +4 -6
- package/packages/core/src/shared/Supervisor.ts +19 -32
- package/packages/core/src/shared/Surface.ts +1 -1
- package/packages/core/src/shared/Sweeper.ts +1 -1
- package/packages/core/src/shared/Tools.ts +17 -30
- package/packages/core/src/shared/Updater.ts +15 -15
- package/packages/core/src/view/BodyRenderer.ts +1 -1
- package/packages/core/src/view/DiffBlocks.ts +0 -1
- package/packages/core/src/view/DiffExpand.ts +10 -25
- package/packages/core/src/view/DiffLayout.ts +2 -2
- package/packages/core/src/view/DiffPairs.ts +2 -2
- package/packages/core/src/view/MarkdownPainter.ts +2 -19
- package/packages/core/src/view/MovePath.ts +4 -17
- package/packages/core/src/view/Painting.ts +4 -4
- package/packages/core/src/view/ViewBlock.ts +11 -12
- package/packages/daemon/src/Daemon.ts +2 -7
- package/packages/daemon/src/DaemonInstall.ts +5 -12
- package/packages/daemon/src/Surfaces.ts +3 -12
- package/packages/daemon/src/TelegramSurface.ts +0 -1
- package/packages/daemon/src/index.ts +0 -1
- package/packages/protocol/src/Command.ts +33 -41
- package/packages/protocol/src/Diff.ts +0 -5
- package/packages/protocol/src/ImageRoute.ts +2 -5
- package/packages/protocol/src/ServerEvent.ts +68 -105
- package/packages/server/src/AttachmentEndpoint.ts +45 -19
- package/packages/server/src/ClientConnection.ts +11 -12
- package/packages/server/src/ImageEndpoint.ts +3 -4
- package/packages/server/src/ProbeClient.ts +26 -59
- package/packages/server/src/Reloader.ts +4 -7
- package/packages/server/src/SendFileTool.ts +1 -1
- package/packages/server/src/SessionCatalogue.ts +35 -47
- package/packages/server/src/SessionProjection.ts +7 -12
- package/packages/server/src/SessionStream.ts +33 -80
- package/packages/server/src/StaticClient.ts +7 -8
- package/packages/server/src/WebOptions.ts +2 -6
- package/packages/server/src/WsGateway.ts +35 -96
- package/packages/server/src/probe.ts +6 -18
- package/packages/telegram/src/Bot.ts +2 -2
- package/packages/telegram/src/Commands.ts +108 -65
- package/packages/telegram/src/Config.ts +1 -6
- package/packages/telegram/src/Markdown.ts +4 -13
- package/packages/telegram/src/Renderer.ts +1 -1
- package/packages/telegram/src/Session.ts +3 -10
- package/packages/telegram/src/TaskScheduler.ts +31 -10
- package/packages/telegram/src/TaskStore.ts +11 -1
- package/packages/telegram/src/TaskTool.ts +1 -1
- package/packages/telegram/src/UpdateConfirm.ts +2 -2
- package/packages/tui/src/extensions/_init/index.ts +2 -5
- package/packages/tui/src/extensions/file-picker/index.ts +2 -6
- package/packages/tui/src/extensions/footer/index.ts +0 -1
- package/packages/tui/src/extensions/footer/powerline.ts +16 -28
- package/packages/tui/src/extensions/pim/index.ts +1 -1
- package/packages/tui/src/extensions/session-lease/index.ts +5 -6
- package/packages/tui/src/extensions/working-indicator/index.ts +1 -2
- package/packages/tui/src/themes/themeCliArgs.ts +1 -1
- package/packages/web/dist/client/assets/{abnfDiagram-O67JEVCF-CZ7V84ot.js → abnfDiagram-O67JEVCF-WweOU5DK.js} +1 -1
- package/packages/web/dist/client/assets/{arc-DiHGkUvc.js → arc-O2PmZXWt.js} +1 -1
- package/packages/web/dist/client/assets/architecture-7GRP2DOG-COBxVilU.js +1 -0
- package/packages/web/dist/client/assets/{architectureDiagram-NJMV4G6O-XS5DhfJB.js → architectureDiagram-NJMV4G6O-DwYq1YaM.js} +1 -1
- package/packages/web/dist/client/assets/{blockDiagram-BEXU5L5S-BCsgLvy1.js → blockDiagram-BEXU5L5S-CVab041n.js} +1 -1
- package/packages/web/dist/client/assets/{c4Diagram-YGBWAQC7-Bj9LcWNm.js → c4Diagram-YGBWAQC7-BmotHez3.js} +1 -1
- package/packages/web/dist/client/assets/channel-BKV-IcTA.js +1 -0
- package/packages/web/dist/client/assets/{chunk-3FUC2YCW-BmDurFxp.js → chunk-3FUC2YCW-CWNS7-n4.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-5DYCD2WN-DAjG-pqn.js → chunk-5DYCD2WN-DflvXohu.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-742MDFTN-Bmxs5puY.js → chunk-742MDFTN-B_0t6_RE.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-7INBJB4K-Di7kIxrQ.js → chunk-7INBJB4K-wKj0Q3Kv.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-7M6MHVWA-CSc8sR0b.js → chunk-7M6MHVWA-BMvUghc8.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-7PRAP22T-C8kd5QvY.js → chunk-7PRAP22T-BY41wkcT.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-GTNCS2PH-DG2b2LYE.js → chunk-GTNCS2PH-PqY_YoS0.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-GWA4HPMP-DdLaLQCu.js → chunk-GWA4HPMP-fozSU5ty.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-MBY4JIJT-C1j0yQlk.js → chunk-MBY4JIJT-CrHrC3jw.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-NETBCI7D-Bfq9H74p.js → chunk-NETBCI7D-DWdAxieG.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-O7XYJQB3-ZHvBmBO-.js → chunk-O7XYJQB3-B6uOn9iS.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-UA2S7LBM-ku1JeHSK.js → chunk-UA2S7LBM-BxYSHqyy.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-WEXAMYUT-BP1iga_7.js → chunk-WEXAMYUT-CtwIaQDa.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-XXDRQBXY-BBeccPcX.js → chunk-XXDRQBXY-fgBFe-PX.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-Z7XXMR3K-SMHZugaR.js → chunk-Z7XXMR3K-CPonoV3p.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-ZIGJFQKS-CFU_JLG4.js → chunk-ZIGJFQKS-Cdu87cTj.js} +1 -1
- package/packages/web/dist/client/assets/{classDiagram-v2-NBCMYWYE-CYviuQzJ.js → classDiagram-v2-NBCMYWYE-DSWsPaa7.js} +1 -1
- package/packages/web/dist/client/assets/{core-DyHsgs5k.js → core-CBoS7AST.js} +1 -1
- package/packages/web/dist/client/assets/{cose-bilkent-JH36ORCC-9v2ZkJzo.js → cose-bilkent-JH36ORCC-CTwlldtJ.js} +1 -1
- package/packages/web/dist/client/assets/{cynefin-OW5HDTMX-Bx5xRadi.js → cynefin-OW5HDTMX-CZQ4EPNJ.js} +1 -1
- package/packages/web/dist/client/assets/{cynefinDiagram-VND7K2PF-BRfGDKqa.js → cynefinDiagram-VND7K2PF-C2gp6H_Q.js} +1 -1
- package/packages/web/dist/client/assets/{dagre-6A5THRUB-C4l-2L2e.js → dagre-6A5THRUB-CDxTP47t.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-22UHCM2B-d_hQ3kyi.js → diagram-22UHCM2B-BIohE1lI.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-3UASUU5V-DrEeguPI.js → diagram-3UASUU5V-TwAUir-w.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-ATOU4E4O-BmfQ22pD.js → diagram-ATOU4E4O-BM1JQrIu.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-CDSNMT55-BjVWjuPF.js → diagram-CDSNMT55-BKIqhxSI.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-MLGK6HIB-wDjk-O8i.js → diagram-MLGK6HIB-CVe3QDHr.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-MPIPVDR6-DqXQFE1s.js → diagram-MPIPVDR6-Bj-MQIFI.js} +1 -1
- package/packages/web/dist/client/assets/{dist-BddGOpie.js → dist-DlZpcyc2.js} +1 -1
- package/packages/web/dist/client/assets/{ebnfDiagram-ZINNZB2B-UB8kOITM.js → ebnfDiagram-ZINNZB2B-C06mmvmz.js} +1 -1
- package/packages/web/dist/client/assets/{elk-276RUBZZ-D4miYQnD.js → elk-276RUBZZ-CizJSNEj.js} +1 -1
- package/packages/web/dist/client/assets/{erDiagram-OPXOYQCR--RXKv7KH.js → erDiagram-OPXOYQCR-M3FQkKI1.js} +1 -1
- package/packages/web/dist/client/assets/eventmodeling-NTZA5JFV-D_UXLpIu.js +1 -0
- package/packages/web/dist/client/assets/flowDiagram-KWPJA3E3-BT4eEEVm.js +1 -0
- package/packages/web/dist/client/assets/{ganttDiagram-FUAMR5RP-C0CFpE5x.js → ganttDiagram-FUAMR5RP-CojF9Q16.js} +1 -1
- package/packages/web/dist/client/assets/{gitGraph-4MIJSDKK-VPL7nv2c.js → gitGraph-4MIJSDKK-YvKqGEPk.js} +1 -1
- package/packages/web/dist/client/assets/{gitGraphDiagram-X574FWY7-CgxJA-T8.js → gitGraphDiagram-X574FWY7-XqNqIFo9.js} +1 -1
- package/packages/web/dist/client/assets/index--2CDtzvY.css +1 -0
- package/packages/web/dist/client/assets/{index-XTlTnQmx.js → index-bT6QPJZs.js} +7 -7
- package/packages/web/dist/client/assets/{info-A6RAGUB7-P0-o68pj.js → info-A6RAGUB7-B_1BCzM2.js} +1 -1
- package/packages/web/dist/client/assets/{infoDiagram-VRGFBTTK-DFJZNRUP.js → infoDiagram-VRGFBTTK-zFX8B-dP.js} +1 -1
- package/packages/web/dist/client/assets/{ishikawaDiagram-OU5B5YK6-ZkyhNd1T.js → ishikawaDiagram-OU5B5YK6-DLzQ_Uyf.js} +1 -1
- package/packages/web/dist/client/assets/{journeyDiagram-ZHPQQLJL-DFevH8my.js → journeyDiagram-ZHPQQLJL-S3WRMmoa.js} +1 -1
- package/packages/web/dist/client/assets/{kanban-definition-PNTS6WVX-l7e7ZZDC.js → kanban-definition-PNTS6WVX-B5Z8I-kM.js} +1 -1
- package/packages/web/dist/client/assets/{line-DO_s6Ujd.js → line-BGMH-i2X.js} +1 -1
- package/packages/web/dist/client/assets/{linear-C4xH5PPc.js → linear-KsrestXG.js} +1 -1
- package/packages/web/dist/client/assets/{mermaid-parser.core-nQaTP3VY.js → mermaid-parser.core-DNffyJJA.js} +3 -3
- package/packages/web/dist/client/assets/{mermaid.core-Cz05yTZh.js → mermaid.core-Cz3vJeQG.js} +4 -4
- package/packages/web/dist/client/assets/{mindmap-definition-NLK3R4M7-CHOEuHm2.js → mindmap-definition-NLK3R4M7-CzA61XUf.js} +1 -1
- package/packages/web/dist/client/assets/{packet-AYTQ26CC-BH3ehPMo.js → packet-AYTQ26CC-BO55e7cR.js} +1 -1
- package/packages/web/dist/client/assets/{pegDiagram-GJSIUBJH-CkWBLtad.js → pegDiagram-GJSIUBJH-DeRiXYNd.js} +1 -1
- package/packages/web/dist/client/assets/{pie-WAS4IAKB-nNVEq3dx.js → pie-WAS4IAKB-D9ibrQRe.js} +1 -1
- package/packages/web/dist/client/assets/{pieDiagram-5QR66LMP-DimUBAgN.js → pieDiagram-5QR66LMP-BaBpPP33.js} +1 -1
- package/packages/web/dist/client/assets/{quadrantDiagram-O4NWA36T-BR0XpRGQ.js → quadrantDiagram-O4NWA36T-DIfn4GjM.js} +1 -1
- package/packages/web/dist/client/assets/{radar-RG4KPBEZ-paA-H3mb.js → radar-RG4KPBEZ-Dmn5-nJq.js} +1 -1
- package/packages/web/dist/client/assets/{railroad-74A4TZTK-yEiKB3rz.js → railroad-74A4TZTK-ZCWNEd2Z.js} +1 -1
- package/packages/web/dist/client/assets/railroad-abnf-HS5TGJTU-_swqhy0y.js +1 -0
- package/packages/web/dist/client/assets/railroad-ebnf-LZEXJU2U-CytbazPx.js +1 -0
- package/packages/web/dist/client/assets/railroad-peg-WCYAUIDC-Bg8QW17T.js +1 -0
- package/packages/web/dist/client/assets/{railroadDiagram-XR7U4H2S--TXe6rdU.js → railroadDiagram-XR7U4H2S-CDPZ39sy.js} +1 -1
- package/packages/web/dist/client/assets/{requirementDiagram-PLB6GJNP-DyqH36Za.js → requirementDiagram-PLB6GJNP-CyCI8Yul.js} +1 -1
- package/packages/web/dist/client/assets/{sankeyDiagram-IPEJSGJF-Bg6e3BlM.js → sankeyDiagram-IPEJSGJF-p_XAPv72.js} +1 -1
- package/packages/web/dist/client/assets/{sequenceDiagram-PO4LG4MO-ClGf85My.js → sequenceDiagram-PO4LG4MO-DmR6IP_o.js} +1 -1
- package/packages/web/dist/client/assets/{src-DF7hQfMh.js → src-gnv7pJ1z.js} +1 -1
- package/packages/web/dist/client/assets/{stateDiagram-v2-GCMORJYK-BK8TpxNo.js → stateDiagram-v2-GCMORJYK-7ZTHl6ih.js} +1 -1
- package/packages/web/dist/client/assets/{swimlanes-2SLR337P-DDnTIT9M.js → swimlanes-2SLR337P-N6bj71pw.js} +1 -1
- package/packages/web/dist/client/assets/swimlanesDiagram-TC7HE7FX-BJQ2CBsp.js +8 -0
- package/packages/web/dist/client/assets/{timeline-definition-EJHVYXUP-mBBbH3bk.js → timeline-definition-EJHVYXUP-GNez0kW8.js} +1 -1
- package/packages/web/dist/client/assets/{treeView-Q6P3EWNA-CTK7tRwR.js → treeView-Q6P3EWNA-DyQZkboR.js} +1 -1
- package/packages/web/dist/client/assets/{treemap-WGGIJYW6-vOI-Ef_m.js → treemap-WGGIJYW6-_J8Pw2TM.js} +1 -1
- package/packages/web/dist/client/assets/{usecaseDiagram-POWQR4AR-COcii8x-.js → usecaseDiagram-POWQR4AR-Bg-CzKjl.js} +1 -1
- package/packages/web/dist/client/assets/{vennDiagram-UO4OBE2U-D6kmDGpM.js → vennDiagram-UO4OBE2U-DBQKHXhK.js} +1 -1
- package/packages/web/dist/client/assets/{wardley-WFR3VGLG-CtE2KI9r.js → wardley-WFR3VGLG-B5aAsQ3F.js} +1 -1
- package/packages/web/dist/client/assets/{wardleyDiagram-VNRHLVJA-ncxNGWnW.js → wardleyDiagram-VNRHLVJA-BKUQ1LK6.js} +1 -1
- package/packages/web/dist/client/assets/{xychartDiagram-PMCCYNJV-DUvd2Qze.js → xychartDiagram-PMCCYNJV-BI2sVbks.js} +1 -1
- package/packages/web/dist/client/index.html +2 -2
- package/packages/web/dist/client/assets/architecture-7GRP2DOG-HIzEIkwQ.js +0 -1
- package/packages/web/dist/client/assets/channel-BCA6qe9I.js +0 -1
- package/packages/web/dist/client/assets/eventmodeling-NTZA5JFV-l6SYFw1s.js +0 -1
- package/packages/web/dist/client/assets/flowDiagram-KWPJA3E3-CWW9qnqm.js +0 -1
- package/packages/web/dist/client/assets/index-D9_XJLSc.css +0 -1
- package/packages/web/dist/client/assets/railroad-abnf-HS5TGJTU-mVQx9aVM.js +0 -1
- package/packages/web/dist/client/assets/railroad-ebnf-LZEXJU2U-CllXx1OJ.js +0 -1
- package/packages/web/dist/client/assets/railroad-peg-WCYAUIDC-BBD2Q5W_.js +0 -1
- package/packages/web/dist/client/assets/swimlanesDiagram-TC7HE7FX-CM8UnP5t.js +0 -8
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
/** One indexable word and where it sits in the string it came from. */
|
|
2
1
|
export type SearchToken = {
|
|
3
|
-
/** Lowercased
|
|
2
|
+
/** Lowercased. */
|
|
4
3
|
readonly text: string;
|
|
5
4
|
readonly start: number;
|
|
6
5
|
readonly end: number;
|
|
@@ -33,10 +32,8 @@ function scan(text: string): readonly SearchToken[] {
|
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* for `SessionLease` and for `session lease` alike; asking for `sessionlease`
|
|
39
|
-
* too would AND away the second.
|
|
35
|
+
* Query pieces only, never the whole identifier: `SessionLease` asks for
|
|
36
|
+
* `session` and `lease`, so it also matches "session lease".
|
|
40
37
|
*/
|
|
41
38
|
function words(query: string): readonly string[] {
|
|
42
39
|
const found: string[] = [];
|
|
@@ -51,7 +48,7 @@ function words(query: string): readonly string[] {
|
|
|
51
48
|
return found;
|
|
52
49
|
}
|
|
53
50
|
|
|
54
|
-
/** Half-open slices
|
|
51
|
+
/** Half-open slices: `WsGateway` → `ws`, `gateway`; `read_file` → `read`, `file`. */
|
|
55
52
|
function piecesOf(run: string): readonly (readonly [number, number])[] {
|
|
56
53
|
const pieces: (readonly [number, number])[] = [];
|
|
57
54
|
let start = -1;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/** What a cache entry has to offer: a recency stamp and a way to let go. */
|
|
2
1
|
export type CachedSession = {
|
|
3
2
|
lastUsed: number;
|
|
4
3
|
dispose(): Promise<void>;
|
|
@@ -6,7 +5,7 @@ export type CachedSession = {
|
|
|
6
5
|
|
|
7
6
|
const CAPACITY = 16;
|
|
8
7
|
|
|
9
|
-
/**
|
|
8
|
+
/** LRU cache of live sessions; evicted entries are disposed. */
|
|
10
9
|
export class SessionCache<T extends CachedSession> {
|
|
11
10
|
private readonly capacity: number;
|
|
12
11
|
private readonly entries = new Map<string, T>();
|
|
@@ -19,12 +18,11 @@ export class SessionCache<T extends CachedSession> {
|
|
|
19
18
|
return this.entries.size;
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
/**
|
|
21
|
+
/** Does not count as a use. */
|
|
23
22
|
public peek(key: string): T | undefined {
|
|
24
23
|
return this.entries.get(key);
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
/** The live entry, marked used now so eviction passes over it. */
|
|
28
26
|
public touch(key: string): T | undefined {
|
|
29
27
|
const entry = this.entries.get(key);
|
|
30
28
|
if (entry) {
|
|
@@ -33,7 +31,6 @@ export class SessionCache<T extends CachedSession> {
|
|
|
33
31
|
return entry;
|
|
34
32
|
}
|
|
35
33
|
|
|
36
|
-
/** Store `value`, disposing the least recently used entry first when full. */
|
|
37
34
|
public adopt(key: string, value: T): T {
|
|
38
35
|
this.evictIfNeeded();
|
|
39
36
|
this.entries.set(key, value);
|
|
@@ -63,6 +60,11 @@ export class SessionCache<T extends CachedSession> {
|
|
|
63
60
|
}
|
|
64
61
|
const evicted = this.entries.get(oldestKey)!;
|
|
65
62
|
this.entries.delete(oldestKey);
|
|
66
|
-
|
|
63
|
+
evicted.dispose().catch((err: unknown) => {
|
|
64
|
+
console.warn(
|
|
65
|
+
`[pim] failed to dispose evicted session ${oldestKey}:`,
|
|
66
|
+
err
|
|
67
|
+
);
|
|
68
|
+
});
|
|
67
69
|
}
|
|
68
70
|
}
|
|
@@ -3,35 +3,27 @@ import { parseSessionEntries } from "@earendil-works/pi-coding-agent";
|
|
|
3
3
|
import { Attachments } from "../attachments/Attachments";
|
|
4
4
|
import { MessageText } from "./MessageText";
|
|
5
5
|
|
|
6
|
-
/**
|
|
6
|
+
/** Catalogue summary of a session file. */
|
|
7
7
|
export type SessionDigest = {
|
|
8
|
-
/** The session
|
|
8
|
+
/** The session name, else the first user message. */
|
|
9
9
|
readonly title?: string;
|
|
10
|
-
/**
|
|
10
|
+
/** Set when `title` is a session name. */
|
|
11
11
|
readonly named?: true;
|
|
12
|
-
/** When the agent last wrote
|
|
12
|
+
/** When the agent last wrote. Moves during a turn, so read it before starting one. */
|
|
13
13
|
readonly settledAt?: number;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
/**
|
|
17
|
-
* The digest before it is clamped, so a reader that tails an appended region
|
|
18
|
-
* can fold that region into what an earlier read of the same file found.
|
|
19
|
-
*/
|
|
16
|
+
/** The unclamped digest, so a tail read can be merged into an earlier one. */
|
|
20
17
|
export type DigestParts = {
|
|
21
18
|
readonly name?: string;
|
|
22
|
-
/** The opening ask, unclamped. */
|
|
23
19
|
readonly opening?: string;
|
|
24
20
|
readonly settledAt?: number;
|
|
25
21
|
};
|
|
26
22
|
|
|
27
|
-
/**
|
|
28
|
-
* A session file's durable bytes, undecoded: a whole session is megabytes of
|
|
29
|
-
* tool output and the digest wants a handful of lines of it, so the search
|
|
30
|
-
* runs over the bytes and only the lines it keeps become strings.
|
|
31
|
-
*/
|
|
23
|
+
/** A session file's bytes, kept undecoded so only the lines used become strings. */
|
|
32
24
|
export type Durable = {
|
|
33
25
|
readonly bytes: Buffer;
|
|
34
|
-
/**
|
|
26
|
+
/** Just past the last newline; a trailing partial line is excluded. */
|
|
35
27
|
readonly end: number;
|
|
36
28
|
};
|
|
37
29
|
|
|
@@ -41,7 +33,7 @@ const TAIL_LINES = 10;
|
|
|
41
33
|
|
|
42
34
|
const TITLE_LIMIT = 120;
|
|
43
35
|
|
|
44
|
-
/**
|
|
36
|
+
/** Searched in raw bytes before decoding a line. */
|
|
45
37
|
const NAMED = Buffer.from('"session_info"');
|
|
46
38
|
|
|
47
39
|
export const NEWLINE = 0x0a;
|
|
@@ -60,7 +52,7 @@ function partsOf(body: Durable): DigestParts {
|
|
|
60
52
|
};
|
|
61
53
|
}
|
|
62
54
|
|
|
63
|
-
/**
|
|
55
|
+
/** Keeps the earlier opening; a later name or settle time wins. */
|
|
64
56
|
function merge(before: DigestParts, appended: DigestParts): DigestParts {
|
|
65
57
|
return {
|
|
66
58
|
name: appended.name ?? before.name,
|
|
@@ -78,7 +70,7 @@ function of({ name, opening, settledAt }: DigestParts): SessionDigest {
|
|
|
78
70
|
};
|
|
79
71
|
}
|
|
80
72
|
|
|
81
|
-
/** The last `session_info`
|
|
73
|
+
/** The last `session_info` entry's name. Skips lines that merely quote the marker. */
|
|
82
74
|
function nameOf({ bytes, end }: Durable): string | undefined {
|
|
83
75
|
let at = end - 1;
|
|
84
76
|
while (at >= 0) {
|
|
@@ -140,7 +132,6 @@ function clamp(text: string): string {
|
|
|
140
132
|
: text;
|
|
141
133
|
}
|
|
142
134
|
|
|
143
|
-
/** Over the head window the caller has already cut, not the whole file. */
|
|
144
135
|
function firstUserMessage(lines: readonly string[]): string | undefined {
|
|
145
136
|
for (const line of lines) {
|
|
146
137
|
const entry = parseSessionEntries(line)[0];
|
|
@@ -34,10 +34,8 @@ import { SessionName } from "./SessionName";
|
|
|
34
34
|
import { adaptSessionUi, type SessionUi } from "./SessionUi";
|
|
35
35
|
import { WriteMark } from "./WriteMark";
|
|
36
36
|
|
|
37
|
-
/** What the agent is doing right now. */
|
|
38
37
|
export type SessionStatus = "idle" | "thinking" | "streaming" | "tool";
|
|
39
38
|
|
|
40
|
-
/** Everything the host persists about a session; frontend-specific settings stay with the adapter. */
|
|
41
39
|
export type HostSettings = {
|
|
42
40
|
readonly cwd?: string;
|
|
43
41
|
readonly model?: string;
|
|
@@ -63,13 +61,12 @@ export type SessionCompactResult = {
|
|
|
63
61
|
readonly activeMessages: number;
|
|
64
62
|
};
|
|
65
63
|
|
|
66
|
-
/**
|
|
64
|
+
/** `restored` are the queued messages taken back from pi. */
|
|
67
65
|
export type CancelResult = {
|
|
68
66
|
readonly cancelled: boolean;
|
|
69
67
|
readonly restored: readonly string[];
|
|
70
68
|
};
|
|
71
69
|
|
|
72
|
-
/** Whether this host can mutate its session file right now, and who is stopping it. */
|
|
73
70
|
export type LeaseState = {
|
|
74
71
|
readonly writable: boolean;
|
|
75
72
|
readonly heldBy?: {
|
|
@@ -79,7 +76,7 @@ export type LeaseState = {
|
|
|
79
76
|
};
|
|
80
77
|
|
|
81
78
|
export type SessionHostDeps = {
|
|
82
|
-
/**
|
|
79
|
+
/** Log prefix. */
|
|
83
80
|
readonly label: string;
|
|
84
81
|
readonly settings: HostSettings;
|
|
85
82
|
readonly defaults: { readonly cwd: string; readonly model?: string };
|
|
@@ -88,36 +85,25 @@ export type SessionHostDeps = {
|
|
|
88
85
|
readonly modelRegistry: ModelRegistry;
|
|
89
86
|
readonly settingsManagerFor: (cwd: string) => SettingsManager;
|
|
90
87
|
readonly persistSettings: (patch: Partial<HostSettings>) => Promise<void>;
|
|
91
|
-
/**
|
|
92
|
-
* Take the session file's turn lease around every mutation, as this frontend.
|
|
93
|
-
* Leave unset where nothing else can open the file.
|
|
94
|
-
*/
|
|
88
|
+
/** Takes the turn lease around every mutation. Omit when no other process can open the file. */
|
|
95
89
|
readonly lease?: LeaseFrontend;
|
|
96
|
-
/** Omit to let pi
|
|
90
|
+
/** Omit to let pi choose the file path. */
|
|
97
91
|
readonly mainSessionPath?: () => string;
|
|
98
92
|
readonly isolatedSessionPath?: () => string;
|
|
99
93
|
readonly systemInstruction?: () => Promise<string | undefined>;
|
|
100
|
-
/** Where this host's human is reading; surfaces in the system prompt's environment block. */
|
|
101
94
|
readonly surface?: Surface;
|
|
102
95
|
readonly customTools?: (
|
|
103
96
|
context: CustomToolContext
|
|
104
97
|
) => readonly ToolDefinition[];
|
|
105
|
-
/** Runs after the agent is disposed, before
|
|
98
|
+
/** Runs after the agent is disposed, before `sessionPath` is cleared. */
|
|
106
99
|
readonly onRetire?: (sessionPath: string) => Promise<void>;
|
|
107
|
-
/**
|
|
108
|
-
* Where this host's extensions say things, resolved per call so an agent
|
|
109
|
-
* rebuilt under the host follows its live target. Omit to leave pi's no-op
|
|
110
|
-
* UI in place: pi freezes the mode at `bindExtensions`, so this is a dep
|
|
111
|
-
* rather than something a caller can turn on once a session exists.
|
|
112
|
-
*/
|
|
100
|
+
/** Extension UI sink, read per call. Omit for pi's no-op UI; pi fixes the mode at bind time. */
|
|
113
101
|
readonly ui?: () => SessionUi | undefined;
|
|
114
102
|
};
|
|
115
103
|
|
|
116
|
-
/** What a frontend's own tools are built against. */
|
|
117
104
|
export type CustomToolContext = {
|
|
118
|
-
/** Where this session's tools resolve relative paths. */
|
|
119
105
|
readonly cwd: string;
|
|
120
|
-
/**
|
|
106
|
+
/** Undefined until the agent exists. */
|
|
121
107
|
readonly sessionId: () => string | undefined;
|
|
122
108
|
};
|
|
123
109
|
|
|
@@ -126,7 +112,7 @@ type ModelResolveResult =
|
|
|
126
112
|
| { readonly kind: "ambiguous"; readonly candidates: readonly string[] }
|
|
127
113
|
| { readonly kind: "none"; readonly candidates: readonly string[] };
|
|
128
114
|
|
|
129
|
-
/**
|
|
115
|
+
/** `holder` is absent when the lease file is unreadable. */
|
|
130
116
|
type LeaseWait = { readonly holder?: LeaseRecord };
|
|
131
117
|
|
|
132
118
|
const FOREIGN_POLL_MS = 2_000;
|
|
@@ -150,7 +136,7 @@ function isOutput(event: AssistantMessageEvent): boolean {
|
|
|
150
136
|
}
|
|
151
137
|
}
|
|
152
138
|
|
|
153
|
-
/**
|
|
139
|
+
/** One in-process pi agent session, its settings and a serialized turn queue. */
|
|
154
140
|
export class SessionHost {
|
|
155
141
|
public readonly label: string;
|
|
156
142
|
public lastUsed = Date.now();
|
|
@@ -162,12 +148,12 @@ export class SessionHost {
|
|
|
162
148
|
private cachedLog: EventLog | undefined;
|
|
163
149
|
private queue: Promise<unknown> = Promise.resolve();
|
|
164
150
|
private seqLog: EventLog | undefined;
|
|
165
|
-
/**
|
|
151
|
+
/** File head after this host's last write. */
|
|
166
152
|
private lastSeen: { readonly path: string; readonly seq: number } | undefined;
|
|
167
153
|
private blockedBy: LeaseWait | undefined;
|
|
168
154
|
private readonly leaseListeners = new Set<() => void>();
|
|
169
155
|
private readonly foreignListeners = new Set<() => void>();
|
|
170
|
-
/** Set only while a held turn is watching
|
|
156
|
+
/** Set only while a held turn is watching for foreign writes. */
|
|
171
157
|
private sampleWrites: (() => Promise<void>) | undefined;
|
|
172
158
|
private readonly agentListeners = new Set<
|
|
173
159
|
(event: AgentSessionEvent) => void
|
|
@@ -204,12 +190,12 @@ export class SessionHost {
|
|
|
204
190
|
return this.cached?.sessionId;
|
|
205
191
|
}
|
|
206
192
|
|
|
207
|
-
/**
|
|
193
|
+
/** Undefined until the agent is built. */
|
|
208
194
|
public get eventLog(): EventLog | undefined {
|
|
209
195
|
return this.cachedLog;
|
|
210
196
|
}
|
|
211
197
|
|
|
212
|
-
/**
|
|
198
|
+
/** Not writable only while one of our mutations waits on another process's lease. */
|
|
213
199
|
public get leaseState(): LeaseState {
|
|
214
200
|
const blocked = this.blockedBy;
|
|
215
201
|
if (blocked === undefined) {
|
|
@@ -232,7 +218,7 @@ export class SessionHost {
|
|
|
232
218
|
};
|
|
233
219
|
}
|
|
234
220
|
|
|
235
|
-
/** Fires once per turn in which another process appended to
|
|
221
|
+
/** Fires at most once per turn in which another process appended to the file. */
|
|
236
222
|
public onForeignWrite(listener: () => void): () => void {
|
|
237
223
|
this.foreignListeners.add(listener);
|
|
238
224
|
return () => {
|
|
@@ -240,7 +226,7 @@ export class SessionHost {
|
|
|
240
226
|
};
|
|
241
227
|
}
|
|
242
228
|
|
|
243
|
-
/**
|
|
229
|
+
/** Survives agent rebuilds. */
|
|
244
230
|
public subscribe(listener: (event: AgentSessionEvent) => void): () => void {
|
|
245
231
|
this.agentListeners.add(listener);
|
|
246
232
|
return () => {
|
|
@@ -280,17 +266,17 @@ export class SessionHost {
|
|
|
280
266
|
}
|
|
281
267
|
|
|
282
268
|
public get currentModelId(): string | undefined {
|
|
283
|
-
const model = this.
|
|
269
|
+
const model = this.currentModel();
|
|
284
270
|
return model ? qualifiedModelId(model) : undefined;
|
|
285
271
|
}
|
|
286
272
|
|
|
287
|
-
/**
|
|
273
|
+
/** Display name, e.g. "Claude Opus 5.0". */
|
|
288
274
|
public get currentModelLabel(): string | undefined {
|
|
289
|
-
return
|
|
275
|
+
return this.currentModel()?.name;
|
|
290
276
|
}
|
|
291
277
|
|
|
292
278
|
public get supportedThinkingLevels(): readonly ThinkingLevel[] {
|
|
293
|
-
const model = this.
|
|
279
|
+
const model = this.currentModel();
|
|
294
280
|
return model ? getSupportedThinkingLevels(model) : [];
|
|
295
281
|
}
|
|
296
282
|
|
|
@@ -303,17 +289,16 @@ export class SessionHost {
|
|
|
303
289
|
return (sm.getDefaultThinkingLevel() as ThinkingLevel) ?? "medium";
|
|
304
290
|
}
|
|
305
291
|
|
|
306
|
-
/**
|
|
292
|
+
/** Undefined when only the directory's default applies. */
|
|
307
293
|
public get chosenThinkingLevel(): ThinkingLevel | undefined {
|
|
308
294
|
return this.currentSettings.thinkingLevel ?? this.cached?.thinkingLevel;
|
|
309
295
|
}
|
|
310
296
|
|
|
311
|
-
/**
|
|
297
|
+
/** Runs `work` as a queued turn. `isolated` uses a throwaway agent and file, without the lease. */
|
|
312
298
|
public run(
|
|
313
299
|
work: (agent: AgentSession) => Promise<void>,
|
|
314
300
|
opts?: { readonly isolated?: boolean }
|
|
315
301
|
): Promise<void> {
|
|
316
|
-
// An isolated run owns a throwaway file nobody else can name, so it takes no lease.
|
|
317
302
|
if (opts?.isolated) {
|
|
318
303
|
return this.enqueue(async () => {
|
|
319
304
|
const { agent, sessionPath } = await this.buildIsolatedAgent();
|
|
@@ -335,28 +320,28 @@ export class SessionHost {
|
|
|
335
320
|
});
|
|
336
321
|
}
|
|
337
322
|
|
|
338
|
-
/**
|
|
323
|
+
/** Builds or reuses the agent inside the turn queue. */
|
|
339
324
|
public ensureAgent(): Promise<AgentSession> {
|
|
340
325
|
return this.enqueue(() => this.ensureCached());
|
|
341
326
|
}
|
|
342
327
|
|
|
343
|
-
/**
|
|
328
|
+
/** Runs `work` in the turn queue without touching the agent. */
|
|
344
329
|
public serialize<T>(work: () => Promise<T>): Promise<T> {
|
|
345
330
|
return this.enqueue(work);
|
|
346
331
|
}
|
|
347
332
|
|
|
348
|
-
/**
|
|
333
|
+
/** Aborts the running turn and takes back its queued messages. */
|
|
349
334
|
public async cancel(): Promise<CancelResult> {
|
|
350
335
|
if (!this.cached || !this.cached.isStreaming) {
|
|
351
336
|
return { cancelled: false, restored: [] };
|
|
352
337
|
}
|
|
353
|
-
//
|
|
338
|
+
// Before aborting, or pi delivers the queue to the next turn.
|
|
354
339
|
const restored = this.takeBack();
|
|
355
340
|
await this.cached.abort();
|
|
356
341
|
return { cancelled: true, restored };
|
|
357
342
|
}
|
|
358
343
|
|
|
359
|
-
/**
|
|
344
|
+
/** Takes back messages queued behind the running turn. Not queued: the turn holds the queue. */
|
|
360
345
|
public takeBack(): readonly string[] {
|
|
361
346
|
if (!this.cached || !this.cached.isStreaming) {
|
|
362
347
|
return [];
|
|
@@ -412,10 +397,7 @@ export class SessionHost {
|
|
|
412
397
|
});
|
|
413
398
|
}
|
|
414
399
|
|
|
415
|
-
/**
|
|
416
|
-
* Rename this session through pi's own session name, so its `/resume` picker
|
|
417
|
-
* shows it too; `null` clears it. Answers with the name pi kept.
|
|
418
|
-
*/
|
|
400
|
+
/** Sets pi's session name; `null` clears it. Returns the stored name. */
|
|
419
401
|
public setName(name: string | null): Promise<string | undefined> {
|
|
420
402
|
return this.withLease(async () => {
|
|
421
403
|
const agent = await this.ensureCached();
|
|
@@ -432,7 +414,7 @@ export class SessionHost {
|
|
|
432
414
|
});
|
|
433
415
|
}
|
|
434
416
|
|
|
435
|
-
/**
|
|
417
|
+
/** Drops the agent so the next turn rebuilds it from the file. */
|
|
436
418
|
public async invalidate(): Promise<void> {
|
|
437
419
|
if (!this.cached) {
|
|
438
420
|
return;
|
|
@@ -449,7 +431,7 @@ export class SessionHost {
|
|
|
449
431
|
|
|
450
432
|
private enqueue<T>(work: () => Promise<T>): Promise<T> {
|
|
451
433
|
const next = this.queue.then(work);
|
|
452
|
-
//
|
|
434
|
+
// Keep the chain alive; callers still get their own rejection.
|
|
453
435
|
this.queue = next.catch((err: unknown) => {
|
|
454
436
|
console.error(`[${this.label}] work failed:`, err);
|
|
455
437
|
});
|
|
@@ -457,7 +439,6 @@ export class SessionHost {
|
|
|
457
439
|
return next;
|
|
458
440
|
}
|
|
459
441
|
|
|
460
|
-
/** Where this session's turn lease lives, once anything has named the file. */
|
|
461
442
|
private get leasePath(): string | undefined {
|
|
462
443
|
return (
|
|
463
444
|
this.cached?.sessionFile ??
|
|
@@ -466,11 +447,7 @@ export class SessionHost {
|
|
|
466
447
|
);
|
|
467
448
|
}
|
|
468
449
|
|
|
469
|
-
/**
|
|
470
|
-
* Serialize `work` behind the session file's turn lease, with a rehydration on
|
|
471
|
-
* either side of the acquire: waiting for the lease is exactly the window in
|
|
472
|
-
* which the other surface appends.
|
|
473
|
-
*/
|
|
450
|
+
/** Queues `work` under the turn lease, rehydrating before and after waiting for it. */
|
|
474
451
|
private withLease<T>(work: () => Promise<T>): Promise<T> {
|
|
475
452
|
return this.enqueue(async () => {
|
|
476
453
|
const frontend = this.deps.lease;
|
|
@@ -478,7 +455,7 @@ export class SessionHost {
|
|
|
478
455
|
return await work();
|
|
479
456
|
}
|
|
480
457
|
await this.rehydrateIfStale();
|
|
481
|
-
//
|
|
458
|
+
// A new session's path is only known once pi builds the agent.
|
|
482
459
|
const path = this.leasePath ?? (await this.ensureCached()).sessionFile;
|
|
483
460
|
if (path === undefined) {
|
|
484
461
|
return await work();
|
|
@@ -494,8 +471,7 @@ export class SessionHost {
|
|
|
494
471
|
try {
|
|
495
472
|
return await work();
|
|
496
473
|
} finally {
|
|
497
|
-
//
|
|
498
|
-
// agent: leave `lastSeen` behind the head so the next turn rebuilds.
|
|
474
|
+
// After a foreign write, leave `lastSeen` stale so the next turn rebuilds.
|
|
499
475
|
if (!(await settle())) {
|
|
500
476
|
await this.markSeen(path);
|
|
501
477
|
}
|
|
@@ -513,10 +489,8 @@ export class SessionHost {
|
|
|
513
489
|
}
|
|
514
490
|
|
|
515
491
|
/**
|
|
516
|
-
*
|
|
517
|
-
*
|
|
518
|
-
* aborts — the work in flight is worth more than the inconsistency it races.
|
|
519
|
-
* Resolves to whether anything foreign landed.
|
|
492
|
+
* Polls for lines another process appended during a held turn. Warns at most
|
|
493
|
+
* once and never aborts. The returned stop function resolves to whether any landed.
|
|
520
494
|
*/
|
|
521
495
|
private async watchForeignWrites(
|
|
522
496
|
path: string
|
|
@@ -531,8 +505,7 @@ export class SessionHost {
|
|
|
531
505
|
return;
|
|
532
506
|
}
|
|
533
507
|
const agent = this.cached;
|
|
534
|
-
// A rebuilt agent
|
|
535
|
-
// on migration, so its own accounting starts from whatever it just read.
|
|
508
|
+
// A rebuilt agent may have rewritten the file, so restart accounting from it.
|
|
536
509
|
if (agent?.sessionFile !== path) {
|
|
537
510
|
base = undefined;
|
|
538
511
|
return;
|
|
@@ -579,7 +552,7 @@ export class SessionHost {
|
|
|
579
552
|
}
|
|
580
553
|
}
|
|
581
554
|
|
|
582
|
-
/**
|
|
555
|
+
/** Drops the agent if the file grew since our last write. */
|
|
583
556
|
private async rehydrateIfStale(): Promise<void> {
|
|
584
557
|
const path = this.cached?.sessionFile;
|
|
585
558
|
const seen = this.lastSeen;
|
|
@@ -591,8 +564,6 @@ export class SessionHost {
|
|
|
591
564
|
}
|
|
592
565
|
}
|
|
593
566
|
|
|
594
|
-
// Reading the head is how our own writes stop looking foreign: pi repairs a torn tail and
|
|
595
|
-
// rewrites on migration, so a rebuild moves the head without anyone else touching the file.
|
|
596
567
|
private async markSeen(path: string): Promise<void> {
|
|
597
568
|
this.lastSeen = { path, seq: await this.logFor(path).head() };
|
|
598
569
|
}
|
|
@@ -626,8 +597,7 @@ export class SessionHost {
|
|
|
626
597
|
if (this.deps.lease !== undefined && agent.sessionFile) {
|
|
627
598
|
await this.markSeen(agent.sessionFile);
|
|
628
599
|
}
|
|
629
|
-
//
|
|
630
|
-
// it was before this rebuild read it.
|
|
600
|
+
// Re-anchor a watching turn on the new agent.
|
|
631
601
|
await this.sampleWrites?.();
|
|
632
602
|
await this.patchSettings({ cwd, sessionPath: agent.sessionFile });
|
|
633
603
|
return agent;
|
|
@@ -740,7 +710,7 @@ export class SessionHost {
|
|
|
740
710
|
cwd,
|
|
741
711
|
agentDir: this.deps.agentDir,
|
|
742
712
|
settingsManager,
|
|
743
|
-
//
|
|
713
|
+
// In-process: a disk-loaded copy would register views into a second `Tools`.
|
|
744
714
|
extensionFactories: CoreExtensions.gated(this.deps.surface),
|
|
745
715
|
appendSystemPromptOverride: (base) => {
|
|
746
716
|
return promptRef.wrapped ? [...base, promptRef.wrapped] : base;
|
|
@@ -784,8 +754,7 @@ export class SessionHost {
|
|
|
784
754
|
`[${this.label}] extension ${err.extensionPath} (${err.event}):`,
|
|
785
755
|
err.error
|
|
786
756
|
);
|
|
787
|
-
// Pi
|
|
788
|
-
// without this the user's message vanishes and only stderr says why.
|
|
757
|
+
// Pi treats a throwing command as success, so tell the user.
|
|
789
758
|
this.deps
|
|
790
759
|
.ui?.()
|
|
791
760
|
?.notify(
|
|
@@ -794,11 +763,10 @@ export class SessionHost {
|
|
|
794
763
|
);
|
|
795
764
|
};
|
|
796
765
|
const ui = this.deps.ui;
|
|
797
|
-
// Emits session_start;
|
|
766
|
+
// Emits session_start; extension tools are unusable without it.
|
|
798
767
|
await agent.bindExtensions(
|
|
799
768
|
ui
|
|
800
|
-
? // Any
|
|
801
|
-
// runner.js:318); "rpc" is its own name for dialog-capable but not a terminal.
|
|
769
|
+
? // Any uiContext makes pi's `hasUI()` true; "rpc" means dialogs but no terminal.
|
|
802
770
|
{
|
|
803
771
|
uiContext: adaptSessionUi(ui),
|
|
804
772
|
mode: "rpc",
|
|
@@ -834,6 +802,10 @@ export class SessionHost {
|
|
|
834
802
|
await this.deps.persistSettings(patch);
|
|
835
803
|
}
|
|
836
804
|
|
|
805
|
+
private currentModel(): Model<ModelApi> | undefined {
|
|
806
|
+
return this.cached?.model ?? this.resolveDefaultModel();
|
|
807
|
+
}
|
|
808
|
+
|
|
837
809
|
private resolveDefaultModel(): Model<ModelApi> | undefined {
|
|
838
810
|
this.deps.modelRegistry.refresh();
|
|
839
811
|
for (const candidate of [
|
|
@@ -862,23 +834,21 @@ export class SessionHost {
|
|
|
862
834
|
private resolveModel(pattern: string): ModelResolveResult {
|
|
863
835
|
this.deps.modelRegistry.refresh();
|
|
864
836
|
const available = this.deps.modelRegistry.getAvailable();
|
|
865
|
-
const
|
|
866
|
-
(m) => ({
|
|
867
|
-
item: m,
|
|
868
|
-
haystacks: [qualifiedModelId(m), m.id, m.name],
|
|
869
|
-
})
|
|
870
|
-
);
|
|
871
|
-
|
|
837
|
+
const wanted = pattern.trim();
|
|
872
838
|
const exact = available.find(
|
|
873
839
|
(m) =>
|
|
874
|
-
qualifiedModelId(m) ===
|
|
875
|
-
m.id === pattern.trim() ||
|
|
876
|
-
m.name === pattern.trim()
|
|
840
|
+
qualifiedModelId(m) === wanted || m.id === wanted || m.name === wanted
|
|
877
841
|
);
|
|
878
842
|
if (exact) {
|
|
879
843
|
return { kind: "ok", model: exact };
|
|
880
844
|
}
|
|
881
845
|
|
|
846
|
+
const candidates: FuzzyCandidate<Model<ModelApi>>[] = available.map(
|
|
847
|
+
(m) => ({
|
|
848
|
+
item: m,
|
|
849
|
+
haystacks: [qualifiedModelId(m), m.id, m.name],
|
|
850
|
+
})
|
|
851
|
+
);
|
|
882
852
|
const hits = FuzzyMatcher.rank(pattern, candidates, { limit: 5 });
|
|
883
853
|
if (hits.length === 0) {
|
|
884
854
|
return {
|