@maudecode/talaria-web 1.17.2 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_release.json +8 -8
- package/dist/api/auth-raw.d.ts +1 -1
- package/dist/api/auth-raw.js +4 -4
- package/dist/api/auth-raw.js.map +1 -1
- package/dist/api/automation-raw.d.ts +6 -0
- package/dist/api/automation-raw.js +53 -6
- package/dist/api/automation-raw.js.map +1 -1
- package/dist/api/automation-router.d.ts +26 -1
- package/dist/api/automation-router.js +16 -2
- package/dist/api/automation-router.js.map +1 -1
- package/dist/api/chat-router.d.ts +649 -15
- package/dist/api/chat-router.js +52 -50
- package/dist/api/chat-router.js.map +1 -1
- package/dist/api/git-router.d.ts +35 -1
- package/dist/api/git-router.js +18 -19
- package/dist/api/git-router.js.map +1 -1
- package/dist/api/raw-routes.d.ts +8 -0
- package/dist/api/raw-routes.js +247 -36
- package/dist/api/raw-routes.js.map +1 -1
- package/dist/api/router.d.ts +10 -0
- package/dist/api/router.js +10 -8
- package/dist/api/router.js.map +1 -1
- package/dist/api/sessions-router.d.ts +1492 -115
- package/dist/api/sessions-router.js +134 -8
- package/dist/api/sessions-router.js.map +1 -1
- package/dist/api/settings-router.d.ts +31 -0
- package/dist/api/settings-router.js +8 -3
- package/dist/api/settings-router.js.map +1 -1
- package/dist/api/sse-routes.d.ts +5 -0
- package/dist/api/sse-routes.js +50 -3
- package/dist/api/sse-routes.js.map +1 -1
- package/dist/api/tools-raw.js +6 -23
- package/dist/api/tools-raw.js.map +1 -1
- package/dist/api/tools-router.d.ts +356 -15
- package/dist/api/tools-router.js +148 -19
- package/dist/api/tools-router.js.map +1 -1
- package/dist/app.js +35 -15
- package/dist/app.js.map +1 -1
- package/dist/auth/gate.js +5 -2
- package/dist/auth/gate.js.map +1 -1
- package/dist/auth/oidc.d.ts +5 -2
- package/dist/auth/oidc.js +8 -7
- package/dist/auth/oidc.js.map +1 -1
- package/dist/bin/talaria-web.js +1 -1
- package/dist/bin/talaria-web.js.map +1 -1
- package/dist/cli/dotenv.js +1 -0
- package/dist/cli/dotenv.js.map +1 -1
- package/dist/config/agent-config.js +3 -2
- package/dist/config/agent-config.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.js +5 -1
- package/dist/config.js.map +1 -1
- package/dist/http/context.d.ts +17 -3
- package/dist/http/context.js +31 -4
- package/dist/http/context.js.map +1 -1
- package/dist/http/csp.d.ts +2 -1
- package/dist/http/csp.js +3 -2
- package/dist/http/csp.js.map +1 -1
- package/dist/profiles/profiles.d.ts +10 -0
- package/dist/profiles/profiles.js +40 -2
- package/dist/profiles/profiles.js.map +1 -1
- package/dist/providers/catalog.d.ts +6 -2
- package/dist/providers/catalog.js +30 -11
- package/dist/providers/catalog.js.map +1 -1
- package/dist/raster-image.d.ts +7 -0
- package/dist/raster-image.js +267 -0
- package/dist/raster-image.js.map +1 -0
- package/dist/redact.js +327 -40
- package/dist/redact.js.map +1 -1
- package/dist/runtime.js +89 -23
- package/dist/runtime.js.map +1 -1
- package/dist/server.js +5 -0
- package/dist/server.js.map +1 -1
- package/dist/sessions/background-tasks.d.ts +2 -9
- package/dist/sessions/background-tasks.js +2 -12
- package/dist/sessions/background-tasks.js.map +1 -1
- package/dist/sessions/cli-sessions.d.ts +15 -4
- package/dist/sessions/cli-sessions.js +120 -29
- package/dist/sessions/cli-sessions.js.map +1 -1
- package/dist/sessions/completions.d.ts +48 -8
- package/dist/sessions/completions.js +222 -26
- package/dist/sessions/completions.js.map +1 -1
- package/dist/sessions/export.d.ts +5 -0
- package/dist/sessions/export.js +30 -0
- package/dist/sessions/export.js.map +1 -1
- package/dist/sessions/gateway-watcher.d.ts +7 -3
- package/dist/sessions/gateway-watcher.js +31 -19
- package/dist/sessions/gateway-watcher.js.map +1 -1
- package/dist/sessions/handoff.d.ts +32 -0
- package/dist/sessions/handoff.js +114 -0
- package/dist/sessions/handoff.js.map +1 -0
- package/dist/sessions/list.d.ts +7 -1
- package/dist/sessions/list.js +13 -5
- package/dist/sessions/list.js.map +1 -1
- package/dist/sessions/merge.d.ts +2 -4
- package/dist/sessions/merge.js +8 -15
- package/dist/sessions/merge.js.map +1 -1
- package/dist/sessions/recovery.d.ts +22 -0
- package/dist/sessions/recovery.js +506 -0
- package/dist/sessions/recovery.js.map +1 -0
- package/dist/sessions/relay.d.ts +21 -2
- package/dist/sessions/relay.js +156 -11
- package/dist/sessions/relay.js.map +1 -1
- package/dist/sessions/service.d.ts +108 -6
- package/dist/sessions/service.js +403 -29
- package/dist/sessions/service.js.map +1 -1
- package/dist/sessions/session.d.ts +6 -0
- package/dist/sessions/session.js +40 -2
- package/dist/sessions/session.js.map +1 -1
- package/dist/sessions/state-db-worker.d.ts +1 -0
- package/dist/sessions/state-db-worker.js +33 -0
- package/dist/sessions/state-db-worker.js.map +1 -0
- package/dist/sessions/state-db.d.ts +61 -0
- package/dist/sessions/state-db.js +291 -0
- package/dist/sessions/state-db.js.map +1 -1
- package/dist/sessions/store.d.ts +7 -0
- package/dist/sessions/store.js +31 -22
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/titles.d.ts +2 -0
- package/dist/sessions/titles.js +4 -0
- package/dist/sessions/titles.js.map +1 -1
- package/dist/sessions/tool-display.d.ts +3 -3
- package/dist/sessions/tool-display.js +11 -37
- package/dist/sessions/tool-display.js.map +1 -1
- package/dist/sessions/turn-context.d.ts +1 -1
- package/dist/sessions/turn-context.js +11 -7
- package/dist/sessions/turn-context.js.map +1 -1
- package/dist/sessions/turn.d.ts +37 -2
- package/dist/sessions/turn.js +182 -49
- package/dist/sessions/turn.js.map +1 -1
- package/dist/sessions/wakeup-pause.d.ts +59 -0
- package/dist/sessions/wakeup-pause.js +181 -0
- package/dist/sessions/wakeup-pause.js.map +1 -0
- package/dist/settings.js +5 -7
- package/dist/settings.js.map +1 -1
- package/dist/sidecar/fake.d.ts +2 -2
- package/dist/sidecar/fake.js.map +1 -1
- package/dist/startup.d.ts +13 -5
- package/dist/startup.js +48 -0
- package/dist/startup.js.map +1 -1
- package/dist/test/ts-worker-hooks.d.ts +1 -0
- package/dist/test/ts-worker-hooks.js +24 -0
- package/dist/test/ts-worker-hooks.js.map +1 -0
- package/dist/text/diff.d.ts +9 -14
- package/dist/text/diff.js +74 -108
- package/dist/text/diff.js.map +1 -1
- package/dist/tools/crons.js +45 -8
- package/dist/tools/crons.js.map +1 -1
- package/dist/tools/dashboard-plugins.d.ts +53 -0
- package/dist/tools/dashboard-plugins.js +188 -0
- package/dist/tools/dashboard-plugins.js.map +1 -0
- package/dist/tools/extensions.d.ts +13 -1
- package/dist/tools/extensions.js +132 -60
- package/dist/tools/extensions.js.map +1 -1
- package/dist/tools/health.d.ts +32 -0
- package/dist/tools/health.js +111 -19
- package/dist/tools/health.js.map +1 -1
- package/dist/tools/mcp.d.ts +13 -0
- package/dist/tools/mcp.js +88 -0
- package/dist/tools/mcp.js.map +1 -1
- package/dist/tools/project-os.d.ts +11 -0
- package/dist/tools/project-os.js +267 -0
- package/dist/tools/project-os.js.map +1 -0
- package/dist/tools/skills.d.ts +5 -1
- package/dist/tools/skills.js +5 -3
- package/dist/tools/skills.js.map +1 -1
- package/dist/tools/updates.d.ts +27 -9
- package/dist/tools/updates.js +163 -51
- package/dist/tools/updates.js.map +1 -1
- package/dist/tools/wiki.d.ts +68 -0
- package/dist/tools/wiki.js +413 -0
- package/dist/tools/wiki.js.map +1 -0
- package/dist/workspace/escape.d.ts +61 -0
- package/dist/workspace/escape.js +149 -0
- package/dist/workspace/escape.js.map +1 -0
- package/dist/workspace/extract.d.ts +22 -0
- package/dist/workspace/extract.js +308 -0
- package/dist/workspace/extract.js.map +1 -0
- package/dist/workspace/fs.d.ts +12 -0
- package/dist/workspace/fs.js +92 -23
- package/dist/workspace/fs.js.map +1 -1
- package/dist/workspace/git.d.ts +18 -0
- package/dist/workspace/git.js +38 -25
- package/dist/workspace/git.js.map +1 -1
- package/dist/workspace/media.d.ts +4 -4
- package/dist/workspace/media.js +16 -45
- package/dist/workspace/media.js.map +1 -1
- package/dist/workspace/rollback.d.ts +34 -20
- package/dist/workspace/rollback.js +171 -265
- package/dist/workspace/rollback.js.map +1 -1
- package/dist/workspace/unzip.js +4 -1
- package/dist/workspace/unzip.js.map +1 -1
- package/dist/workspace/upload.d.ts +7 -4
- package/dist/workspace/upload.js +5 -2
- package/dist/workspace/upload.js.map +1 -1
- package/dist/workspace/worktrees.d.ts +2 -1
- package/dist/workspace/worktrees.js +14 -15
- package/dist/workspace/worktrees.js.map +1 -1
- package/package.json +4 -2
- package/sidecar/agent_dependency.json +4 -4
- package/sidecar/scripts/replay_sidecar.py +24 -0
- package/sidecar/talaria_sidecar/__init__.py +1 -1
- package/sidecar/talaria_sidecar/home.py +13 -2
- package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
- package/sidecar/talaria_sidecar/methods/aux.py +39 -5
- package/sidecar/talaria_sidecar/methods/chat.py +9 -5
- package/sidecar/talaria_sidecar/methods/checkpoints.py +89 -0
- package/sidecar/talaria_sidecar/methods/commands.py +81 -0
- package/sidecar/talaria_sidecar/methods/cron.py +29 -2
- package/sidecar/talaria_sidecar/methods/gateway.py +32 -15
- package/sidecar/talaria_sidecar/methods/kanban.py +28 -7
- package/sidecar/talaria_sidecar/methods/mcp.py +1 -1
- package/sidecar/talaria_sidecar/methods/process.py +58 -4
- package/sidecar/talaria_sidecar/methods/profiles.py +77 -7
- package/sidecar/talaria_sidecar/methods/providers.py +27 -8
- package/sidecar/talaria_sidecar/methods/state_db.py +39 -5
- package/sidecar/talaria_sidecar/runtime.py +17 -1
- package/static/dist/FILES.txt +127 -126
- package/static/dist/assets/AppShell-g3bkgnvt.js +1 -0
- package/static/dist/assets/ChatPage-oo7bdan6.js +25 -0
- package/static/dist/assets/Dialog-g355qxhp.js +1 -0
- package/static/dist/assets/ExtensionRoute-i2y9fvjm.js +1 -0
- package/static/dist/assets/HubRoute-lmkrbw47.js +2 -0
- package/static/dist/assets/{Markdown-mdwlvj3w.js → Markdown-j4kut4j2.js} +114 -114
- package/static/dist/assets/{RightPanel-ftvrjlcp.js → RightPanel-ohlsdzfl.js} +1 -1
- package/static/dist/assets/Select-kddq75qc.js +1 -0
- package/static/dist/assets/SessionListPanel-lu3oy0hw.js +1 -0
- package/static/dist/assets/{SettingsLayout-jonjefmj.js → SettingsLayout-o9bv4mgb.js} +1 -1
- package/static/dist/assets/{States-nmejrwrm.js → States-eq6fe29m.js} +1 -1
- package/static/dist/assets/Toaster-pc247u9f.js +1 -0
- package/static/dist/assets/{_app-gdidzd94.js → _app-f8n1i0m1.js} +1 -1
- package/static/dist/assets/{_app.ext._extensionId-opyh9y0v.js → _app.ext._extensionId-gfbzpoou.js} +1 -1
- package/static/dist/assets/_app.index-bzzv80hk.js +1 -0
- package/static/dist/assets/_app.insights-dzixbryi.js +1 -0
- package/static/dist/assets/_app.kanban-c6hep2us.js +1 -0
- package/static/dist/assets/_app.logs-i69qds98.js +1 -0
- package/static/dist/assets/_app.memory-kl4vf0gd.js +1 -0
- package/static/dist/assets/_app.profiles-b8zinmyp.js +1 -0
- package/static/dist/assets/{_app.session._sessionId-bfd4h3id.js → _app.session._sessionId-fn1bhde6.js} +1 -1
- package/static/dist/assets/_app.settings-cg8plwmf.js +1 -0
- package/static/dist/assets/_app.settings._section-bkwbi9zn.js +3 -0
- package/static/dist/assets/_app.skills-cs47sbvs.js +1 -0
- package/static/dist/assets/_app.tasks-dwvk64tc.js +1 -0
- package/static/dist/assets/_app.todos-c8xjm8p3.js +1 -0
- package/static/dist/assets/_app.workspaces-ehvd1gds.js +1 -0
- package/static/dist/assets/{abnfDiagram-VCTEODGH-b2x1lqot.js → abnfDiagram-VCTEODGH-c8kdixke.js} +1 -1
- package/static/dist/assets/architecture-7GRP2DOG-6crvnylg.js +1 -0
- package/static/dist/assets/{architectureDiagram-5GKGNRK7-h38o5l7b.js → architectureDiagram-5GKGNRK7-cku06x1p.js} +1 -1
- package/static/dist/assets/{back-bemaer09.js → back-h7aun7ew.js} +1 -1
- package/static/dist/assets/{blockDiagram-I7D4REHJ-bqquxv2u.js → blockDiagram-I7D4REHJ-jzthp1wa.js} +1 -1
- package/static/dist/assets/{c4Diagram-7LVT6UL2-f3fb8w6z.js → c4Diagram-7LVT6UL2-mwr67mt8.js} +1 -1
- package/static/dist/assets/{cancel-drd0g6d9.js → cancel-fhi0vcnu.js} +1 -1
- package/static/dist/assets/channel-b2zo73z1.js +1 -0
- package/static/dist/assets/{chunk-4HAMMTFA-bzfyyzp3.js → chunk-4HAMMTFA-gpq1y228.js} +1 -1
- package/static/dist/assets/{chunk-75Z2AOVW-ly99rfx5.js → chunk-75Z2AOVW-ktje58c4.js} +1 -1
- package/static/dist/assets/{chunk-DU6HZSFF-bg6ecfqf.js → chunk-DU6HZSFF-ofajdixh.js} +3 -3
- package/static/dist/assets/{chunk-F27PBJKO-e8k7mmqw.js → chunk-F27PBJKO-cmev85ti.js} +1 -1
- package/static/dist/assets/{chunk-GMAD6QVW-cmalnoaj.js → chunk-GMAD6QVW-htjgt22y.js} +1 -1
- package/static/dist/assets/{chunk-GVQU2GXP-gmif5o01.js → chunk-GVQU2GXP-qndvoxl7.js} +1 -1
- package/static/dist/assets/{chunk-IMKFNOWR-f1nwwh6u.js → chunk-IMKFNOWR-e5bkd5q6.js} +1 -1
- package/static/dist/assets/{chunk-L3NEJ4N5-oktfh5v7.js → chunk-L3NEJ4N5-mj1155r6.js} +1 -1
- package/static/dist/assets/{chunk-OSK3NFVY-b1sdx96z.js → chunk-OSK3NFVY-e7gkikcw.js} +1 -1
- package/static/dist/assets/{chunk-P2QGCYS3-fhu4nzxt.js → chunk-P2QGCYS3-f7t54xfm.js} +1 -1
- package/static/dist/assets/{chunk-POPQ4Y6H-em31rnef.js → chunk-POPQ4Y6H-i927v9oa.js} +1 -1
- package/static/dist/assets/{chunk-PWAF6VOD-bxhhyftw.js → chunk-PWAF6VOD-m84lmnyt.js} +1 -1
- package/static/dist/assets/{chunk-SHT3W25Y-fmrvwcav.js → chunk-SHT3W25Y-mi0tlcu9.js} +1 -1
- package/static/dist/assets/{chunk-SVP7TREG-lymukl2j.js → chunk-SVP7TREG-dnau702j.js} +1 -1
- package/static/dist/assets/{chunk-TICWLB2K-lmza6k23.js → chunk-TICWLB2K-edem1gkg.js} +1 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-oe99st8x.js +1 -0
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-oe99st8x.js +1 -0
- package/static/dist/assets/{copied-ima3pysb.js → copied-hcplv46p.js} +1 -1
- package/static/dist/assets/{copy-fw5b1pc6.js → copy-magtofyp.js} +1 -1
- package/static/dist/assets/{cynefin-OW5HDTMX-czlhbyhs.js → cynefin-OW5HDTMX-siqlulkl.js} +1 -1
- package/static/dist/assets/{cynefinDiagram-5FMLGOSQ-gq7mvswb.js → cynefinDiagram-5FMLGOSQ-i648tah9.js} +1 -1
- package/static/dist/assets/{dagre-GXQ25YYZ-cqdbf7dr.js → dagre-GXQ25YYZ-mwn6uc17.js} +1 -1
- package/static/dist/assets/{diagram-S7CK7UJ4-o6arxa58.js → diagram-S7CK7UJ4-l8abxaes.js} +1 -1
- package/static/dist/assets/{diagram-UQ7AKVKN-nhnd68tz.js → diagram-UQ7AKVKN-mekq7zgq.js} +1 -1
- package/static/dist/assets/{diagram-VSXAHHWV-dk2sclzn.js → diagram-VSXAHHWV-fnky6lvc.js} +1 -1
- package/static/dist/assets/{diagram-VX7I27RA-n3k5nyx3.js → diagram-VX7I27RA-xe6r5qfw.js} +1 -1
- package/static/dist/assets/{diagram-Z3DM3KII-m6q9cwdh.js → diagram-Z3DM3KII-nq07dg7k.js} +1 -1
- package/static/dist/assets/{ebnfDiagram-PWID7BFC-lsa5641p.js → ebnfDiagram-PWID7BFC-c62ipm3g.js} +1 -1
- package/static/dist/assets/endpoints-klbxod4t.js +64 -0
- package/static/dist/assets/{erDiagram-RLTQ6QDP-fo2ckbe6.js → erDiagram-RLTQ6QDP-h39kmnzy.js} +1 -1
- package/static/dist/assets/eventmodeling-NTZA5JFV-obfede4u.js +1 -0
- package/static/dist/assets/flowDiagram-HODETNUW-kdpsp1je.js +1 -0
- package/static/dist/assets/{ganttDiagram-EL5Y4UJY-nzqz6x9g.js → ganttDiagram-EL5Y4UJY-ngbsyp37.js} +1 -1
- package/static/dist/assets/{gitGraph-4MIJSDKK-gukvcxe6.js → gitGraph-4MIJSDKK-fr2i7caa.js} +1 -1
- package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-lqhdp8f0.js → gitGraphDiagram-WWUBYQGX-eravdti4.js} +1 -1
- package/static/dist/assets/{highlighted-body-KPVGNVTW-igw6cp39.js → highlighted-body-KPVGNVTW-jwpop9p8.js} +1 -1
- package/static/dist/assets/host-i828xuo7.js +1 -0
- package/static/dist/assets/index-eh8zilnv.css +2 -0
- package/static/dist/assets/{index-cxq58xb1.js → index-r648f4o1.js} +5 -5
- package/static/dist/assets/{info-A6RAGUB7-gvu7a93l.js → info-A6RAGUB7-h11x0dxo.js} +1 -1
- package/static/dist/assets/{infoDiagram-27XIBGKW-m8t8g6w1.js → infoDiagram-27XIBGKW-dfh47dw9.js} +1 -1
- package/static/dist/assets/{ishikawaDiagram-5VMMS53U-l07vkbgj.js → ishikawaDiagram-5VMMS53U-i6ypq351.js} +1 -1
- package/static/dist/assets/{journeyDiagram-3NMN7TZE-hybkgj8l.js → journeyDiagram-3NMN7TZE-lduf1z95.js} +1 -1
- package/static/dist/assets/{kanban-definition-UXKFOSKX-by13uvtn.js → kanban-definition-UXKFOSKX-e18bu4pg.js} +1 -1
- package/static/dist/assets/{lazyRouteComponent-af0lvgjx.js → lazyRouteComponent-e1y4t2i9.js} +1 -1
- package/static/dist/assets/{line-osxq6fq7.js → line-meizqsvn.js} +1 -1
- package/static/dist/assets/{link-jyxicdhg.js → link-oot2yn73.js} +1 -1
- package/static/dist/assets/login-gu28l9ou.js +1 -0
- package/static/dist/assets/mermaid-HWGCJPDP-mtwrj8fn.js +1 -0
- package/static/dist/assets/{mermaid-parser.core-i91oxmou.js → mermaid-parser.core-ntne45i9.js} +3 -3
- package/static/dist/assets/{mindmap-definition-YA3MSWOX-m82mx8ww.js → mindmap-definition-YA3MSWOX-27b26eok.js} +1 -1
- package/static/dist/assets/onboarding-lkphzu1s.js +1 -0
- package/static/dist/assets/{onboarding_model_label-dp7xffoh.js → onboarding_model_label-ftpjdwqk.js} +1 -1
- package/static/dist/assets/{packet-AYTQ26CC-nbtgge2o.js → packet-AYTQ26CC-l6jdka8p.js} +1 -1
- package/static/dist/assets/{pegDiagram-XKGWAZYB-f1zxzga1.js → pegDiagram-XKGWAZYB-g1er3bxj.js} +1 -1
- package/static/dist/assets/{pie-WAS4IAKB-of8vuhxs.js → pie-WAS4IAKB-i0ylcrt9.js} +1 -1
- package/static/dist/assets/{pieDiagram-E7YTZNPT-o7y8ftio.js → pieDiagram-E7YTZNPT-fbz1e55z.js} +1 -1
- package/static/dist/assets/{quadrantDiagram-AXDQQJYC-iqiwia1t.js → quadrantDiagram-AXDQQJYC-hhue7d8o.js} +1 -1
- package/static/dist/assets/{radar-RG4KPBEZ-delnsy2v.js → radar-RG4KPBEZ-f9b70aa4.js} +1 -1
- package/static/dist/assets/{railroad-74A4TZTK-nspnyq9u.js → railroad-74A4TZTK-lgsuoeda.js} +1 -1
- package/static/dist/assets/railroad-abnf-HS5TGJTU-nf9d6pdx.js +1 -0
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-f7ummkt5.js +1 -0
- package/static/dist/assets/railroad-peg-WCYAUIDC-oczq5tqs.js +1 -0
- package/static/dist/assets/{railroadDiagram-O6MQD6OU-z41tqx5z.js → railroadDiagram-O6MQD6OU-eqpy9fnz.js} +1 -1
- package/static/dist/assets/{refresh-b4uams1i.js → refresh-abtu93ke.js} +1 -1
- package/static/dist/assets/{refresh-cw-nt1dtsx4.js → refresh-cw-hlwb02qv.js} +1 -1
- package/static/dist/assets/{requirementDiagram-BXWQKSXE-bdvif194.js → requirementDiagram-BXWQKSXE-ogf6puhi.js} +1 -1
- package/static/dist/assets/{sankeyDiagram-P5KCCOFB-h73e0rol.js → sankeyDiagram-P5KCCOFB-fqb8xcjf.js} +1 -1
- package/static/dist/assets/{saved-kg52csy7.js → saved-girnabkf.js} +1 -1
- package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-iv95mb1z.js → sequenceDiagram-WJ2MYXX4-dlcz6qjz.js} +1 -1
- package/static/dist/assets/{settings_section_extensions_title-ej0iapxe.js → settings_section_extensions_title-h14cwk6f.js} +1 -1
- package/static/dist/assets/share._token-kl0r7ido.js +2 -0
- package/static/dist/assets/{sliders-horizontal-fj18it47.js → sliders-horizontal-n1zm34qq.js} +1 -1
- package/static/dist/assets/sse-iwku0sjo.js +1 -0
- package/static/dist/assets/{stateDiagram-D77RDMKH-k417ixmf.js → stateDiagram-D77RDMKH-fyoznpcs.js} +1 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-ixhx8r46.js +1 -0
- package/static/dist/assets/{swimlanes-42K2YHIH-esola70w.js → swimlanes-42K2YHIH-oefldhfy.js} +1 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-h9ersk2e.js +8 -0
- package/static/dist/assets/{timeline-definition-24CTP7MA-getrz2y8.js → timeline-definition-24CTP7MA-b1vl2zil.js} +1 -1
- package/static/dist/assets/todoStore-jjr5yr78.js +1 -0
- package/static/dist/assets/{treeView-Q6P3EWNA-hc7ap1q7.js → treeView-Q6P3EWNA-f7hcci5o.js} +1 -1
- package/static/dist/assets/{treemap-WGGIJYW6-b7k1syy5.js → treemap-WGGIJYW6-nl85071a.js} +1 -1
- package/static/dist/assets/{tts-lxdxnmjd.js → units-kgxzxfhi.js} +1 -1
- package/static/dist/assets/{untitled-ovpfthg4.js → untitled-cikfjntn.js} +1 -1
- package/static/dist/assets/{useForm-bcblv1rx.js → useForm-kqoqg0k9.js} +1 -1
- package/static/dist/assets/useLocale-o59tbiea.js +1 -0
- package/static/dist/assets/{useParams-lhg566ew.js → useParams-b4dq6n4q.js} +1 -1
- package/static/dist/assets/{useSearch-lbrh6ejn.js → useSearch-ipfmv3he.js} +1 -1
- package/static/dist/assets/{vennDiagram-4TSXK5OY-n6pcy5qb.js → vennDiagram-4TSXK5OY-h5hzbk0n.js} +1 -1
- package/static/dist/assets/{wardley-WFR3VGLG-lpa18vz1.js → wardley-WFR3VGLG-jftvpm3e.js} +1 -1
- package/static/dist/assets/{wardleyDiagram-VM6X3IG4-kpclwwg7.js → wardleyDiagram-VM6X3IG4-hedh85ge.js} +1 -1
- package/static/dist/assets/{xychartDiagram-S5SC5T6Z-paa2n8y0.js → xychartDiagram-S5SC5T6Z-e49523ab.js} +1 -1
- package/static/dist/index.html +1 -1
- package/static/dist/sw.js +1 -1
- package/static/dist/assets/AppShell-fb2td9zi.js +0 -1
- package/static/dist/assets/ChatPage-cj96kiy9.js +0 -25
- package/static/dist/assets/Dialog-kxcg7ard.js +0 -1
- package/static/dist/assets/ExtensionRoute-jf7h0754.js +0 -1
- package/static/dist/assets/HubRoute-gmanpd5y.js +0 -2
- package/static/dist/assets/Select-bilaypej.js +0 -1
- package/static/dist/assets/SessionListPanel-og8n36qs.js +0 -1
- package/static/dist/assets/Toaster-nnl8zkt9.js +0 -1
- package/static/dist/assets/_app.index-hbarzbjx.js +0 -1
- package/static/dist/assets/_app.insights-luywlarz.js +0 -1
- package/static/dist/assets/_app.kanban-kincnbr8.js +0 -1
- package/static/dist/assets/_app.logs-oi2gr3gs.js +0 -1
- package/static/dist/assets/_app.memory-b6jfivt6.js +0 -1
- package/static/dist/assets/_app.profiles-lpvixmqp.js +0 -1
- package/static/dist/assets/_app.settings-vowx3iq0.js +0 -1
- package/static/dist/assets/_app.settings._section-cnntg1tu.js +0 -3
- package/static/dist/assets/_app.skills-fb57lpau.js +0 -1
- package/static/dist/assets/_app.tasks-eszpx1q7.js +0 -2
- package/static/dist/assets/_app.todos-nr05ac6w.js +0 -1
- package/static/dist/assets/_app.workspaces-d2luomu6.js +0 -1
- package/static/dist/assets/architecture-7GRP2DOG-hd0o7bde.js +0 -1
- package/static/dist/assets/channel-cpdgf867.js +0 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-ko09sguk.js +0 -1
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-ko09sguk.js +0 -1
- package/static/dist/assets/endpoints-d33siokx.js +0 -64
- package/static/dist/assets/eventmodeling-NTZA5JFV-emctlo64.js +0 -1
- package/static/dist/assets/flowDiagram-HODETNUW-bfi3moqa.js +0 -1
- package/static/dist/assets/index-hgtx08n5.css +0 -2
- package/static/dist/assets/login-ec21t39x.js +0 -1
- package/static/dist/assets/mermaid-HWGCJPDP-gfl8z3ep.js +0 -1
- package/static/dist/assets/onboarding-btnltvyz.js +0 -1
- package/static/dist/assets/railroad-abnf-HS5TGJTU-nst1qxyn.js +0 -1
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-ci37x8qy.js +0 -1
- package/static/dist/assets/railroad-peg-WCYAUIDC-aimkk07z.js +0 -1
- package/static/dist/assets/share._token-f97e94r0.js +0 -2
- package/static/dist/assets/sse-fwpqtzbg.js +0 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-hwn4apct.js +0 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-d1h97oyg.js +0 -8
- package/static/dist/assets/todoStore-eginf9h4.js +0 -1
- package/static/dist/assets/useLocale-fi5jb8ma.js +0 -1
package/dist/sessions/turn.js
CHANGED
|
@@ -15,7 +15,7 @@ import { StreamRegistry, SessionChannels } from './streams.js';
|
|
|
15
15
|
import { ChatUsageSchema } from '@maudecode/talaria-web-contracts';
|
|
16
16
|
import { PendingPrompts, clarifyReply } from './pending.js';
|
|
17
17
|
import { RunJournal } from './journal.js';
|
|
18
|
-
import { CONTEXT_USAGE_FIELDS, Session, contextUsage, titleFrom } from './session.js';
|
|
18
|
+
import { COMPRESSION_RECOVERY_ACTION_START_FOCUSED, COMPRESSION_RECOVERY_TERMINAL_STATE, CONTEXT_USAGE_FIELDS, Session, contextUsage, titleFrom } from './session.js';
|
|
19
19
|
import { anchorMessageKey, compressionReference, markerSummary, visibleMessagesForAnchor } from './compress.js';
|
|
20
20
|
import { buildActiveTurnToken, completedToolIndex, publicToolFrame, redactNestedMessageContainers, redactSessionData, redactString, withToolId } from '../redact.js';
|
|
21
21
|
import { dict } from '../config/agent-config.js';
|
|
@@ -26,12 +26,14 @@ import { withSessionWireFlags } from './list.js';
|
|
|
26
26
|
import { hydrateAnchorActivityScenes, turnTerminalState, withTurnIds } from './anchor.js';
|
|
27
27
|
import { persistentStateChanges, persistentStateSnapshot } from './state-saved.js';
|
|
28
28
|
import { maxIterationsFromConfig, maxTokensFromConfig, processWakeupMaxIterations, reasoningConfigFromConfig, webuiEphemeralSystemPrompt, workspaceSystemMessage } from './turn-context.js';
|
|
29
|
-
import { agentSteerText, assistantReplyAddedAfterCurrentTurn, attachedFilesPrompt, buildPartialMessage, dedupeContext, checkpointTurnStart, extractToolCallsFromMessages, hasNativeImages, injectMaxIterationSummaryFallback, isDict, mergeDisplayMessagesAfterAgentResult, messageIdentity, messageText, pendingUserRow, sanitizeMessagesForApi, sessionLacksFinalAssistantAnswer, splitDisplayText, stateDbSeenId, joinReasoning, reasoningFieldsText,
|
|
29
|
+
import { agentSteerText, assistantReplyAddedAfterCurrentTurn, attachedFilesPrompt, buildPartialMessage, dedupeContext, checkpointTurnStart, extractToolCallsFromMessages, hasNativeImages, injectMaxIterationSummaryFallback, isDict, mergeDisplayMessagesAfterAgentResult, messageIdentity, messageText, pendingUserRow, sanitizeMessagesForApi, sessionLacksFinalAssistantAnswer, splitDisplayText, stateDbSeenId, joinReasoning, reasoningFieldsText, toolOutcome, withAttachmentObjects, withBodyExcerpts, withDisplayMedia, withMarkerKinds, withToolCallOutcomes, withoutMaxIterationSummaryRequest, withNativeImagesRestored, withoutNativeImages, withoutToolImages } from './merge.js';
|
|
30
30
|
import { mayBecomeSilentReply, turnOrigin, withBackgroundUpdates } from './background-updates.js';
|
|
31
|
-
import { fallbackTitleFromExchange, firstExchangeSnippets, isGenericFallbackTitle, latestExchangeSnippets, looksInvalidGeneratedTitle, looksLikeDefaultCliTitle, sanitizeGeneratedTitle, titleLanguageMismatch, titlePrompts } from './titles.js';
|
|
31
|
+
import { countExchanges, fallbackTitleFromExchange, firstExchangeSnippets, isGenericFallbackTitle, latestExchangeSnippets, looksInvalidGeneratedTitle, looksLikeDefaultCliTitle, sanitizeGeneratedTitle, titleLanguageMismatch, titlePrompts } from './titles.js';
|
|
32
32
|
import { WORKSPACE_BUSY_MESSAGE } from '../workspace/git.js';
|
|
33
|
+
import { CHECKPOINT_STORE_BUSY_MESSAGE } from '../workspace/rollback.js';
|
|
33
34
|
import { str } from '../util.js';
|
|
34
35
|
import { toolEditDiff } from './tool-display.js';
|
|
36
|
+
import { recordWakeupPause } from './wakeup-pause.js';
|
|
35
37
|
export const CHAT_LOCK_WAIT_SECONDS = 2;
|
|
36
38
|
const IMAGE_MODE_TIMEOUT_MS = 15_000;
|
|
37
39
|
const TERMINAL_SSE_VISIBLE_MESSAGE_LIMIT = 80;
|
|
@@ -71,7 +73,7 @@ export function classifyProviderError(errStr, opts = {}) {
|
|
|
71
73
|
if (['interrupted by user', 'response interrupted', 'operation interrupted', 'operation was interrupted', 'operation aborted', 'request was aborted', 'aborterror'].some((k) => lower.includes(k))) {
|
|
72
74
|
return { label: 'Response interrupted', type: 'interrupted', hint: 'The run stopped before a provider response completed. If you did not cancel it, try again.' };
|
|
73
75
|
}
|
|
74
|
-
const quota = ['insufficient_quota', 'insufficient credits', 'out of credits', 'credits exhausted', 'quota exceeded', 'usage limit', 'plan limit', 'billing'].some((k) => lower.includes(k));
|
|
76
|
+
const quota = ['insufficient_quota', 'insufficient credits', 'out of credits', 'credits exhausted', 'quota exceeded', 'usage limit', 'plan limit', 'billing', 'more credits', 'can only afford', 'fewer max_tokens', 'credit balance', 'exceeded your current quota', 'usage_limit_exceeded', 'reached the limit of messages', 'used up your usage'].some((k) => lower.includes(k));
|
|
75
77
|
const poolEmpty = lower.includes('credential(s) exhausted') || lower.includes('credentials exhausted') || (lower.includes('credential') && lower.includes('exhausted'));
|
|
76
78
|
const auth = !quota && !poolEmpty && (errStr.includes('401') || lower.includes('authentication') || lower.includes('unauthorized') || lower.includes('invalid api key') || lower.includes('invalid_api_key') || lower.includes('no cookie auth credentials'));
|
|
77
79
|
const notFound = errStr.includes('404') || lower.includes('not found') || lower.includes('does not exist') || lower.includes('model_not_found') || lower.includes('invalid model') || lower.includes('does not match any known model') || lower.includes('unknown model');
|
|
@@ -125,8 +127,6 @@ export function sniffImageMime(bytes, declared = '') {
|
|
|
125
127
|
return 'image/bmp';
|
|
126
128
|
return null;
|
|
127
129
|
}
|
|
128
|
-
const COMPRESSION_RECOVERY_TERMINAL_STATE = 'compression_exhausted';
|
|
129
|
-
const COMPRESSION_RECOVERY_ACTION_START_FOCUSED = 'start_focused_continuation';
|
|
130
130
|
/** Python `build_compression_recovery_payload` + `stamp_compression_exhausted_recovery`. */
|
|
131
131
|
export function stampCompressionExhaustedRecovery(s, message, details) {
|
|
132
132
|
const positive = (v) => { const n = Math.trunc(Number(v) || 0); return n > 0 ? n : 0; };
|
|
@@ -211,6 +211,8 @@ export class TurnRunner {
|
|
|
211
211
|
liveTodos = new Map();
|
|
212
212
|
/** Streams whose run completed (`done` emitted) and only await title work; a late cancel is a no-op for these. */
|
|
213
213
|
settledStreams = new Set();
|
|
214
|
+
/** The last adaptive title refresh per session; a successor turn's refresh runs after it (TAL-589). */
|
|
215
|
+
titleRefreshes = new Map();
|
|
214
216
|
/**
|
|
215
217
|
* TAL-364: what a Stop needs to write the turn's model context: its starting context, the prompt the Agent got, and
|
|
216
218
|
* whether a settlement already used a canonical checkpoint (which marks the stop boundary; later work never replaces it).
|
|
@@ -234,6 +236,8 @@ export class TurnRunner {
|
|
|
234
236
|
return { error: `Profile '${str(s.profile)}' is being deleted.`, _status: 409 };
|
|
235
237
|
if (this.deps.workspaceBusy?.(opts.workspace))
|
|
236
238
|
return { error: WORKSPACE_BUSY_MESSAGE, _status: 409 };
|
|
239
|
+
if (this.deps.checkpointStoreBusy?.(s.profile ?? null))
|
|
240
|
+
return { error: CHECKPOINT_STORE_BUSY_MESSAGE, _status: 409 };
|
|
237
241
|
const locked = s.active_stream_id;
|
|
238
242
|
if (locked) {
|
|
239
243
|
if (this.registry.liveIds.has(locked) || this.registry.activeRuns.has(locked))
|
|
@@ -291,6 +295,10 @@ export class TurnRunner {
|
|
|
291
295
|
response.effective_model_provider = opts.modelProvider;
|
|
292
296
|
return response;
|
|
293
297
|
}
|
|
298
|
+
/** Resolves once the stream's worker has ended (settled, failed, or torn down); it never rejects. */
|
|
299
|
+
finished(streamId) {
|
|
300
|
+
return this.workers.get(streamId) ?? Promise.resolve();
|
|
301
|
+
}
|
|
294
302
|
/** Python `_checkpoint_user_message_for_eager_session_save`. */
|
|
295
303
|
checkpointUserMessage(s, msg, attachments, startedAt, source, turnId) {
|
|
296
304
|
const latest = s.messages[s.messages.length - 1];
|
|
@@ -309,7 +317,12 @@ export class TurnRunner {
|
|
|
309
317
|
catch (error) {
|
|
310
318
|
deps.log(`[webui] WARNING: run journal degraded for stream ${streamId}: ${error.message}`);
|
|
311
319
|
}
|
|
320
|
+
const failure = { apperror: null, cancelled: false };
|
|
312
321
|
const put = (event, data, meta = {}) => {
|
|
322
|
+
if (event === 'apperror')
|
|
323
|
+
failure.apperror = data;
|
|
324
|
+
else if (event === 'cancel')
|
|
325
|
+
failure.cancelled = true;
|
|
313
326
|
for (const steerEvent of this.takeSteerEventsBefore(streamId, event))
|
|
314
327
|
put(steerEvent[0], steerEvent[1]);
|
|
315
328
|
if (this.registry.cancelled.has(streamId) && !['cancel', 'apperror', 'steer_consumed', 'steer_withdrawn'].includes(event))
|
|
@@ -358,14 +371,14 @@ export class TurnRunner {
|
|
|
358
371
|
const previousMessages = structuredClone(s.messages);
|
|
359
372
|
// TAL-493: one state.db read builds the history and marks where this turn's own rows begin.
|
|
360
373
|
const startRead = deps.service().stateDbRead(s);
|
|
361
|
-
|
|
374
|
+
// TAL-578: an eager save already put this turn's prompt in the transcript; `user_message` carries it, so the history
|
|
375
|
+
// leaves it out.
|
|
376
|
+
const previousContext = structuredClone(deps.service().modelContext(s, startRead.rows)).filter((m) => m._turn_id !== streamId);
|
|
362
377
|
// Python `_sanitize_messages_for_agent`: the model never sees display-only rows or a replayed cancelled prompt, and
|
|
363
378
|
// the Agent gets back the exact bytes it sent (TAL-541).
|
|
364
379
|
const apiHistory = sanitizeMessagesForApi(previousContext, { preserveApiContent: true });
|
|
365
|
-
const workspaceCtx = workspaceContextPrefix(opts.workspace);
|
|
366
380
|
// Before the first await: a Stop can land at any point after admission.
|
|
367
|
-
|
|
368
|
-
this.stopContexts.set(streamId, { previousContext: previousContext.filter((m) => m._turn_id !== streamId), historyLength: apiHistory.length, prompt: workspaceCtx + msgText, msgText, checkpointed: false, stateDbStartId: startRead.ok ? stateDbSeenId(startRead.rows) ?? 0 : null });
|
|
381
|
+
this.stopContexts.set(streamId, { previousContext, historyLength: apiHistory.length, prompt: msgText, msgText, checkpointed: false, stateDbStartId: startRead.ok ? stateDbSeenId(startRead.rows) ?? 0 : null });
|
|
369
382
|
const activeTurnToken = buildActiveTurnToken(streamId, s.pending_started_at);
|
|
370
383
|
const sidecar = deps.sidecar();
|
|
371
384
|
const partialText = this.registry.partialText.get(streamId) ?? [];
|
|
@@ -411,7 +424,7 @@ export class TurnRunner {
|
|
|
411
424
|
// TAL-545: one image mode decides both this turn's upload and the replayed history, which a text-mode turn sends
|
|
412
425
|
// without native images; only a turn with an image on either side asks for it.
|
|
413
426
|
const imageMode = attachments.some(isImageAttachment) || hasNativeImages(apiHistory) ? await this.imageInputMode(sessionId, s, opts, controller.signal) : null;
|
|
414
|
-
const userMessage = this.buildUserMessage(
|
|
427
|
+
const userMessage = this.buildUserMessage(msgText, attachments, opts.workspace, sessionId, imageMode);
|
|
415
428
|
const conversationHistory = imageMode === 'text' ? withoutNativeImages(apiHistory) : apiHistory;
|
|
416
429
|
// The prompt the Agent actually gets, native image parts included.
|
|
417
430
|
const stop = this.stopContexts.get(streamId);
|
|
@@ -420,14 +433,15 @@ export class TurnRunner {
|
|
|
420
433
|
if (activeRun)
|
|
421
434
|
activeRun.phase = 'running';
|
|
422
435
|
const settledAt = { value: false };
|
|
423
|
-
let
|
|
436
|
+
let succeeded = false;
|
|
424
437
|
// TAL-424: steers an errored turn ended without taking, sent as one follow-up turn once this one is torn down.
|
|
425
438
|
let followUp = [];
|
|
426
439
|
try {
|
|
427
440
|
if (!sidecar)
|
|
428
441
|
throw new SidecarError('The Agent sidecar is not running; chat is unavailable until it starts.', { condition: 'sidecar_unavailable' });
|
|
429
442
|
// Python: budgets, reasoning config, personality and delivery context come from the profile's config.yaml; the
|
|
430
|
-
// system message carries the frozen session workspace, the WebUI guidance rides as the ephemeral prompt
|
|
443
|
+
// system message carries the frozen session workspace, the WebUI guidance rides as the ephemeral prompt with this
|
|
444
|
+
// turn's workspace (TAL-710: never a tag on the user's message, which the Agent can persist from memory).
|
|
431
445
|
const cfg = (await deps.profileConfig?.(s.profile ?? null)) ?? {};
|
|
432
446
|
// The sidecar's per-session YOLO state does not survive its restarts: push the local flag (either way) before
|
|
433
447
|
// the turn so a stale sidecar-side enable cannot auto-approve a session the UI reports as guarded.
|
|
@@ -442,10 +456,9 @@ export class TurnRunner {
|
|
|
442
456
|
put('cancel', this.cancelFrame(sessionId));
|
|
443
457
|
return;
|
|
444
458
|
}
|
|
445
|
-
const frozenWorkspace = str(s.created_workspace) || str(s.workspace);
|
|
446
459
|
const turnContext = {
|
|
447
|
-
system_message: workspaceSystemMessage(
|
|
448
|
-
ephemeral_system_prompt: webuiEphemeralSystemPrompt({ config: cfg, personality: str(s.personality) || null, sessionId, profile: s.profile ?? null, workspace:
|
|
460
|
+
system_message: workspaceSystemMessage(str(s.created_workspace) || str(s.workspace)),
|
|
461
|
+
ephemeral_system_prompt: webuiEphemeralSystemPrompt({ config: cfg, personality: str(s.personality) || null, sessionId, profile: s.profile ?? null, workspace: opts.workspace, hermesHome: deps.profileHome(s.profile), homeDisplay: deps.homeDisplay?.() ?? '~/.hermes', background: turnOrigin(opts.source) === 'background' }),
|
|
449
462
|
max_iterations: processWakeupMaxIterations(maxIterationsFromConfig(cfg), opts.source ?? 'webui', deps.env ?? {}),
|
|
450
463
|
max_tokens: maxTokensFromConfig(cfg),
|
|
451
464
|
reasoning_config: reasoningConfigFromConfig(cfg, opts.modelProvider ?? s.model_provider ?? null),
|
|
@@ -641,16 +654,15 @@ export class TurnRunner {
|
|
|
641
654
|
await this.steerRewrites.get(streamId);
|
|
642
655
|
const { events: steerEvents, leftovers } = this.finalizeSteers(streamId, str(result.pending_steer), 'followup');
|
|
643
656
|
followUp = leftovers;
|
|
644
|
-
this.persistError(s, streamId, classification.label, payload, activeTurnToken, resultMessages);
|
|
657
|
+
this.persistError(s, streamId, classification.label, payload, activeTurnToken, resultMessages, result.provider);
|
|
645
658
|
// TAL-512: a btw error carries no session: its journaled frame must not keep a copy of the parent conversation.
|
|
646
659
|
if (!opts.ephemeral)
|
|
647
|
-
payload.session =
|
|
660
|
+
payload.session = this.publicTerminalSession(s);
|
|
648
661
|
payload.session_id = s.session_id;
|
|
649
662
|
payload.old_session_id = sessionId;
|
|
650
663
|
for (const [event, data] of steerEvents)
|
|
651
664
|
put(event, data);
|
|
652
665
|
put('apperror', payload);
|
|
653
|
-
failed = true;
|
|
654
666
|
return;
|
|
655
667
|
}
|
|
656
668
|
// TAL-512: a btw turn passes the failure check above first, so its last assistant row is this turn's reply.
|
|
@@ -663,6 +675,7 @@ export class TurnRunner {
|
|
|
663
675
|
break;
|
|
664
676
|
}
|
|
665
677
|
}
|
|
678
|
+
succeeded = true;
|
|
666
679
|
opts.onDone?.(answer);
|
|
667
680
|
// Python `_ephemeral_session_payload`: only role and content leave the server for a btw turn.
|
|
668
681
|
put('done', { session: { session_id: sessionId, messages: resultMessages.map((m) => ({ role: m.role, content: m.content })) }, usage: { input_tokens: 0, output_tokens: 0 }, ephemeral: true, answer, terminal_state: answer.trim() ? 'completed' : 'no_response' });
|
|
@@ -734,6 +747,8 @@ export class TurnRunner {
|
|
|
734
747
|
s.pending_attachments = [];
|
|
735
748
|
s.pending_started_at = null;
|
|
736
749
|
s.pending_user_source = null;
|
|
750
|
+
// TAL-576: a turn that ran means the provider has usable credentials again.
|
|
751
|
+
s.process_wakeup_pause = null;
|
|
737
752
|
const attachments = opts.attachments ?? [];
|
|
738
753
|
if (attachments.length) {
|
|
739
754
|
for (let i = s.messages.length - 1; i >= 0; i -= 1) {
|
|
@@ -813,7 +828,7 @@ export class TurnRunner {
|
|
|
813
828
|
cache_hit_percent: cacheHit(cacheReadTokens, inputTokens), turn_cache_hit_percent: cacheHit(turnCacheRead, turnInput), duration_seconds: Math.round(duration * 1000) / 1000,
|
|
814
829
|
context_length: s.context_length ?? 0, threshold_tokens: s.threshold_tokens ?? 0, last_prompt_tokens: s.last_prompt_tokens ?? 0,
|
|
815
830
|
};
|
|
816
|
-
const doneSession =
|
|
831
|
+
const doneSession = this.publicTerminalSession(s);
|
|
817
832
|
// TAL-299: the ring's figures match the terminal session's (and a detail reload's).
|
|
818
833
|
for (const key of CONTEXT_USAGE_FIELDS)
|
|
819
834
|
doneUsage[key] = doneSession[key];
|
|
@@ -850,14 +865,13 @@ export class TurnRunner {
|
|
|
850
865
|
for (const r of work)
|
|
851
866
|
if (r.status === 'rejected')
|
|
852
867
|
throw r.reason;
|
|
853
|
-
|
|
854
|
-
opts.onDone?.(lastAnswer(s.messages)
|
|
868
|
+
succeeded = true;
|
|
869
|
+
opts.onDone?.(lastAnswer(s.messages));
|
|
855
870
|
}
|
|
856
871
|
catch (error) {
|
|
857
872
|
if (settledAt.value && !(error instanceof SidecarError)) {
|
|
858
873
|
deps.log(`[webui] ERROR settling turn ${streamId}\n${error instanceof Error ? (error.stack ?? error.message) : String(error)}`);
|
|
859
874
|
}
|
|
860
|
-
failed = true;
|
|
861
875
|
if (this.registry.cancelled.has(streamId)) {
|
|
862
876
|
this.finalizeCancelled(s, streamId, opts.ephemeral);
|
|
863
877
|
put('cancel', this.cancelFrame(sessionId));
|
|
@@ -884,7 +898,7 @@ export class TurnRunner {
|
|
|
884
898
|
put(event, data);
|
|
885
899
|
this.persistError(current, streamId, classification.label, payload, activeTurnToken);
|
|
886
900
|
if (!opts.ephemeral)
|
|
887
|
-
payload.session =
|
|
901
|
+
payload.session = this.publicTerminalSession(current);
|
|
888
902
|
}
|
|
889
903
|
}
|
|
890
904
|
catch (persistError) {
|
|
@@ -898,8 +912,8 @@ export class TurnRunner {
|
|
|
898
912
|
this.teardown(sessionId, streamId);
|
|
899
913
|
// After persistence and teardown: a background route's failure cleanup deletes the hidden session, which must
|
|
900
914
|
// not race the error writeback above (a re-saved session would resurface in the sidebar).
|
|
901
|
-
if (
|
|
902
|
-
opts.onFailed?.();
|
|
915
|
+
if (!succeeded)
|
|
916
|
+
opts.onFailed?.(failure);
|
|
903
917
|
this.startSteerFollowUp(sessionId, followUp);
|
|
904
918
|
}
|
|
905
919
|
}
|
|
@@ -941,9 +955,8 @@ export class TurnRunner {
|
|
|
941
955
|
* after the text (TAL-276), so an attachment-only turn still gives the model a request and its transcript row a
|
|
942
956
|
* distinct identity.
|
|
943
957
|
*/
|
|
944
|
-
buildUserMessage(
|
|
945
|
-
const
|
|
946
|
-
const withFiles = () => attachedFilesPrompt(text, attachments);
|
|
958
|
+
buildUserMessage(msgText, attachments, workspace, sessionId, imageMode) {
|
|
959
|
+
const withFiles = () => attachedFilesPrompt(msgText, attachments);
|
|
947
960
|
const candidates = attachments.filter(isImageAttachment);
|
|
948
961
|
if (!candidates.length || imageMode !== 'native')
|
|
949
962
|
return withFiles();
|
|
@@ -981,6 +994,10 @@ export class TurnRunner {
|
|
|
981
994
|
}
|
|
982
995
|
return images ? [{ type: 'text', text: withFiles() }, ...parts] : withFiles();
|
|
983
996
|
}
|
|
997
|
+
/** The settled session as a terminal frame carries it: the display window, redacted. */
|
|
998
|
+
publicTerminalSession(s) {
|
|
999
|
+
return redactSessionData(this.terminalSessionPayload(s), this.deps.redactEnabled());
|
|
1000
|
+
}
|
|
984
1001
|
/**
|
|
985
1002
|
* Python `_session_payload_with_terminal_window`: the same visible-message window contract as `GET /api/session?
|
|
986
1003
|
* msg_limit=` (renderable rows, limited payload shape, windowed tool calls, todo state) with the full count.
|
|
@@ -1003,8 +1020,22 @@ export class TurnRunner {
|
|
|
1003
1020
|
return payload;
|
|
1004
1021
|
}
|
|
1005
1022
|
/** Python `_materialize_pending_user_turn_before_error` + error message append + save. */
|
|
1006
|
-
|
|
1023
|
+
/** `runtimeProvider`: the provider the Agent resolved for the turn, when it reported one. */
|
|
1024
|
+
persistError(s, streamId, label, payload, activeTurnToken, agentRows = [], runtimeProvider = '') {
|
|
1007
1025
|
const startedAt = s.pending_started_at;
|
|
1026
|
+
// TAL-576: an automatic wakeup with no usable credentials pauses the next ones instead of failing each.
|
|
1027
|
+
if (s.pending_user_source === 'process_wakeup' && payload.type === 'credential_pool_empty') {
|
|
1028
|
+
// A profile whose home now escapes the profiles root (`profileHome` throws) records no pause; the error still persists.
|
|
1029
|
+
let home = null;
|
|
1030
|
+
try {
|
|
1031
|
+
home = this.deps.profileHome(s.profile);
|
|
1032
|
+
}
|
|
1033
|
+
catch {
|
|
1034
|
+
home = null;
|
|
1035
|
+
}
|
|
1036
|
+
if (home !== null)
|
|
1037
|
+
recordWakeupPause(s, home, this.deps.now(), runtimeProvider, this.deps.configPath?.(home));
|
|
1038
|
+
}
|
|
1008
1039
|
this.materializePendingUserTurn(s, activeTurnToken, streamId);
|
|
1009
1040
|
const duration = typeof startedAt === 'number' && startedAt > 0 ? Math.max(0, this.deps.now() - startedAt) : null;
|
|
1010
1041
|
s.active_stream_id = null;
|
|
@@ -1035,8 +1066,14 @@ export class TurnRunner {
|
|
|
1035
1066
|
s.messages.push(errorMessage);
|
|
1036
1067
|
this.keepLiveState(s, streamId);
|
|
1037
1068
|
this.persistConsumedSteers(s, streamId, startedAt, this.deps.now());
|
|
1069
|
+
// TAL-921: the next prompt remembers the turn's work; an exhausted compression's work would only overflow again. One
|
|
1070
|
+
// read builds the context and settles, so a row committed in between is never covered without reaching either.
|
|
1071
|
+
const read = this.deps.service().stateDbRead(s);
|
|
1072
|
+
const context = payload.type === 'compression_exhausted' ? null : this.unsettledContext(streamId, agentRows, read);
|
|
1073
|
+
if (context)
|
|
1074
|
+
s.context_messages = context;
|
|
1038
1075
|
const stop = this.stopContexts.get(streamId);
|
|
1039
|
-
this.deps.service().settleStateDb(s, { turnId: streamId, previousContext: stop?.previousContext ?? [], agentRows, startId: stop?.stateDbStartId ?? null });
|
|
1076
|
+
this.deps.service().settleStateDb(s, { turnId: streamId, previousContext: stop?.previousContext ?? [], agentRows, startId: stop?.stateDbStartId ?? null, read });
|
|
1040
1077
|
try {
|
|
1041
1078
|
this.deps.store.save(s);
|
|
1042
1079
|
}
|
|
@@ -1049,6 +1086,18 @@ export class TurnRunner {
|
|
|
1049
1086
|
this.deps.pending.clearClarifies(s.session_id);
|
|
1050
1087
|
this.deps.events.publish('session_error', { profile: s.profile, sessionId: s.session_id });
|
|
1051
1088
|
}
|
|
1089
|
+
/**
|
|
1090
|
+
* TAL-921: the model context a turn that ends without its settled result leaves: the work its Agent reported, else the
|
|
1091
|
+
* rows it committed past its starting read in `read`, the read its settlement uses.
|
|
1092
|
+
*/
|
|
1093
|
+
unsettledContext(streamId, agentRows, read) {
|
|
1094
|
+
const stop = this.stopContexts.get(streamId);
|
|
1095
|
+
if (!stop)
|
|
1096
|
+
return null;
|
|
1097
|
+
const after = stop.stateDbStartId;
|
|
1098
|
+
const stateRows = after === null ? [] : read.rows.filter((m) => typeof m._state_db_row_id === 'number' && m._state_db_row_id > after);
|
|
1099
|
+
return this.deps.service().unsettledTurnContext({ ...stop, streamedText: (this.registry.partialText.get(streamId) ?? []).join(''), agentRows, stateRows });
|
|
1100
|
+
}
|
|
1052
1101
|
materializePendingUserTurn(s, activeTurnToken, turnId) {
|
|
1053
1102
|
const pendingText = str(s.pending_user_message);
|
|
1054
1103
|
if (!s.hasPendingPrompt)
|
|
@@ -1098,7 +1147,7 @@ export class TurnRunner {
|
|
|
1098
1147
|
let snapshot = null;
|
|
1099
1148
|
if (sessionId)
|
|
1100
1149
|
try {
|
|
1101
|
-
snapshot =
|
|
1150
|
+
snapshot = this.publicTerminalSession(this.deps.store.get(sessionId));
|
|
1102
1151
|
}
|
|
1103
1152
|
catch {
|
|
1104
1153
|
snapshot = null;
|
|
@@ -1148,24 +1197,26 @@ export class TurnRunner {
|
|
|
1148
1197
|
}
|
|
1149
1198
|
const stop = this.stopContexts.get(streamId);
|
|
1150
1199
|
const canonical = stop !== undefined && checkpoint !== null && checkpointTurnStart(checkpoint, stop.msgText, stop.historyLength) !== null;
|
|
1151
|
-
|
|
1200
|
+
// TAL-921: one state.db read builds the context and settles the turn.
|
|
1201
|
+
const settle = (read) => {
|
|
1152
1202
|
if (!stop)
|
|
1153
1203
|
return null;
|
|
1154
1204
|
if (canonical)
|
|
1155
1205
|
stop.checkpointed = true;
|
|
1156
|
-
return
|
|
1206
|
+
return this.unsettledContext(streamId, checkpoint, read);
|
|
1157
1207
|
};
|
|
1158
1208
|
if (current.messages.some((m) => isCancelMarker(m)) && current.active_stream_id === null && !current.pending_user_message) {
|
|
1159
1209
|
// The worker's canonical result can arrive after cancel() settled without a checkpoint (the interrupt reply failed
|
|
1160
1210
|
// or timed out): it replaces this stream's context and never adds a second Stop row. A settlement that already had
|
|
1161
1211
|
// one keeps it, so work the Agent finished after the Stop stays out.
|
|
1162
1212
|
const ownStop = current.messages.some((m) => isCancelMarker(m) && m._turn_id === streamId);
|
|
1163
|
-
const late = canonical && !stop.checkpointed && ownStop ? settle() : null;
|
|
1164
|
-
if (late)
|
|
1165
|
-
current.context_messages = dedupeContext(late);
|
|
1166
1213
|
// TAL-493: the worker's rows committed after the first settlement are covered by what it reports; others are kept.
|
|
1167
|
-
if (
|
|
1168
|
-
this.deps.service().
|
|
1214
|
+
if (ownStop && checkpoint) {
|
|
1215
|
+
const read = this.deps.service().stateDbRead(current);
|
|
1216
|
+
const late = canonical && !stop.checkpointed ? settle(read) : null;
|
|
1217
|
+
if (late)
|
|
1218
|
+
current.context_messages = dedupeContext(late);
|
|
1219
|
+
this.deps.service().settleStateDb(current, { turnId: streamId, previousContext: stop?.previousContext ?? [], agentRows: checkpoint, startId: stop?.stateDbStartId ?? null, read });
|
|
1169
1220
|
try {
|
|
1170
1221
|
this.deps.store.save(current);
|
|
1171
1222
|
}
|
|
@@ -1177,7 +1228,8 @@ export class TurnRunner {
|
|
|
1177
1228
|
}
|
|
1178
1229
|
const startedAt = current.pending_started_at;
|
|
1179
1230
|
this.materializePendingUserTurn(current, buildActiveTurnToken(streamId, current.pending_started_at), streamId);
|
|
1180
|
-
const
|
|
1231
|
+
const read = this.deps.service().stateDbRead(current);
|
|
1232
|
+
const context = settle(read);
|
|
1181
1233
|
if (context)
|
|
1182
1234
|
current.context_messages = dedupeContext(context);
|
|
1183
1235
|
current.active_stream_id = null;
|
|
@@ -1191,7 +1243,7 @@ export class TurnRunner {
|
|
|
1191
1243
|
}
|
|
1192
1244
|
this.keepLiveState(current, streamId);
|
|
1193
1245
|
this.persistConsumedSteers(current, streamId, startedAt, this.deps.now());
|
|
1194
|
-
this.deps.service().settleStateDb(current, { turnId: streamId, previousContext: stop?.previousContext ?? [], agentRows: checkpoint, startId: stop?.stateDbStartId ?? null });
|
|
1246
|
+
this.deps.service().settleStateDb(current, { turnId: streamId, previousContext: stop?.previousContext ?? [], agentRows: checkpoint, startId: stop?.stateDbStartId ?? null, read });
|
|
1195
1247
|
try {
|
|
1196
1248
|
this.deps.store.save(current);
|
|
1197
1249
|
}
|
|
@@ -1307,6 +1359,15 @@ export class TurnRunner {
|
|
|
1307
1359
|
return { title: fallback, status: `local_summary:${llmStatus}`, rawPreview };
|
|
1308
1360
|
return { title: null, status: llmStatus || 'empty_title', rawPreview };
|
|
1309
1361
|
}
|
|
1362
|
+
/**
|
|
1363
|
+
* TAL-591 (Python `_queue_generated_title_for_imported_session`): a CLI session a mutation claims while it still
|
|
1364
|
+
* carries its default title gets the background title job at once instead of after its first WebUI turn.
|
|
1365
|
+
*/
|
|
1366
|
+
async titleClaimed(s) {
|
|
1367
|
+
if (!looksLikeDefaultCliTitle({ title: s.title, source_tag: s.source_tag, raw_source: s.raw_source, session_source: s.session_source, source_label: s.source_label }))
|
|
1368
|
+
return;
|
|
1369
|
+
await this.backgroundTitle(s, () => undefined).catch((error) => { this.deps.log(`[webui] imported session title failed for ${s.session_id}: ${error.message}`); });
|
|
1370
|
+
}
|
|
1310
1371
|
/** Python `_run_background_title_update` (spawned only when `_background_title_generation_inputs` is eligible). */
|
|
1311
1372
|
async backgroundTitle(s, put) {
|
|
1312
1373
|
const sessionId = s.session_id;
|
|
@@ -1320,8 +1381,11 @@ export class TurnRunner {
|
|
|
1320
1381
|
const status = (status, reason = '', title = '', rawPreview = '') => {
|
|
1321
1382
|
put('title_status', { session_id: sessionId, status, ...(reason ? { reason } : {}), ...(title ? { title } : {}), ...(rawPreview ? { raw_preview: rawPreview } : {}) });
|
|
1322
1383
|
};
|
|
1323
|
-
|
|
1384
|
+
// Python ran the adaptive refresh only when the first-title job was not eligible.
|
|
1385
|
+
if (!eligible || (s.llm_title_generated && !invalidExisting) || !userText || !assistantText) {
|
|
1386
|
+
await this.refreshTitle(s, put, status);
|
|
1324
1387
|
return;
|
|
1388
|
+
}
|
|
1325
1389
|
if (s.manual_title) {
|
|
1326
1390
|
status('skipped', 'manual_title', placeholder);
|
|
1327
1391
|
return;
|
|
@@ -1353,6 +1417,9 @@ export class TurnRunner {
|
|
|
1353
1417
|
current = this.deps.store.get(sessionId);
|
|
1354
1418
|
}
|
|
1355
1419
|
catch {
|
|
1420
|
+
// A session deleted while the title prompt ran stays deleted.
|
|
1421
|
+
if (this.deps.store.wasDeleted(sessionId))
|
|
1422
|
+
return;
|
|
1356
1423
|
current = s;
|
|
1357
1424
|
}
|
|
1358
1425
|
let effective = str(current.title).trim();
|
|
@@ -1381,6 +1448,71 @@ export class TurnRunner {
|
|
|
1381
1448
|
else
|
|
1382
1449
|
status('skipped', source || 'unchanged', effective, rawPreview);
|
|
1383
1450
|
}
|
|
1451
|
+
/**
|
|
1452
|
+
* Python `_maybe_schedule_title_refresh` + `_run_background_title_refresh`: every N exchanges a generated title is
|
|
1453
|
+
* regenerated from the latest exchange; a manual title is never touched.
|
|
1454
|
+
*/
|
|
1455
|
+
async refreshTitle(s, put, status) {
|
|
1456
|
+
const every = this.deps.titleRefreshEvery?.() ?? 0;
|
|
1457
|
+
const exchanges = countExchanges(s.messages);
|
|
1458
|
+
if (every <= 0 || exchanges <= 0 || exchanges % every !== 0)
|
|
1459
|
+
return;
|
|
1460
|
+
const [userText, assistantText] = latestExchangeSnippets(s.messages);
|
|
1461
|
+
if (!userText || !assistantText)
|
|
1462
|
+
return;
|
|
1463
|
+
// Admission is released before title work, so an earlier turn's refresh may still be running: refreshes apply in
|
|
1464
|
+
// turn order and each reads the title its predecessor wrote.
|
|
1465
|
+
const sessionId = s.session_id;
|
|
1466
|
+
const run = (this.titleRefreshes.get(sessionId) ?? Promise.resolve()).catch(() => undefined).then(() => this.applyTitleRefresh(sessionId, s, userText, assistantText, put, status));
|
|
1467
|
+
this.titleRefreshes.set(sessionId, run);
|
|
1468
|
+
try {
|
|
1469
|
+
await run;
|
|
1470
|
+
}
|
|
1471
|
+
finally {
|
|
1472
|
+
if (this.titleRefreshes.get(sessionId) === run)
|
|
1473
|
+
this.titleRefreshes.delete(sessionId);
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
async applyTitleRefresh(sessionId, s, userText, assistantText, put, status) {
|
|
1477
|
+
const read = () => { try {
|
|
1478
|
+
return this.deps.store.get(sessionId);
|
|
1479
|
+
}
|
|
1480
|
+
catch {
|
|
1481
|
+
return s;
|
|
1482
|
+
} };
|
|
1483
|
+
const latest = read();
|
|
1484
|
+
const placeholder = str(latest.title).trim();
|
|
1485
|
+
if (['Untitled', 'New Chat', ''].includes(placeholder) || latest.manual_title || !latest.llm_title_generated)
|
|
1486
|
+
return;
|
|
1487
|
+
const cfg = await this.deps.profileConfig?.(latest.profile ?? null);
|
|
1488
|
+
if (!cfg || !titleGenerationEnabled(cfg)) {
|
|
1489
|
+
status('refresh_skipped', cfg ? 'title_generation_disabled' : 'config_unavailable', placeholder);
|
|
1490
|
+
return;
|
|
1491
|
+
}
|
|
1492
|
+
const { title: next, status: llmStatus, rawPreview } = await this.llmTitle(latest, userText, assistantText);
|
|
1493
|
+
if (!next) {
|
|
1494
|
+
status('refresh_skipped', llmStatus || 'empty', placeholder, rawPreview);
|
|
1495
|
+
return;
|
|
1496
|
+
}
|
|
1497
|
+
const normalize = (value) => value.replace(/\s+/g, ' ').trim().toLowerCase();
|
|
1498
|
+
if (normalize(next) === normalize(placeholder)) {
|
|
1499
|
+
status('refresh_skipped', 'same_title', placeholder, rawPreview);
|
|
1500
|
+
return;
|
|
1501
|
+
}
|
|
1502
|
+
const current = read();
|
|
1503
|
+
// The user may have renamed the session while the title prompt ran.
|
|
1504
|
+
if (current.manual_title || str(current.title).trim() !== placeholder) {
|
|
1505
|
+
status('skipped', 'manual_title', str(current.title).trim());
|
|
1506
|
+
return;
|
|
1507
|
+
}
|
|
1508
|
+
current.title = next;
|
|
1509
|
+
markSessionTitleGenerated(current);
|
|
1510
|
+
this.deps.store.save(current, { touchUpdatedAt: false });
|
|
1511
|
+
await this.deps.syncTitle?.(current);
|
|
1512
|
+
this.deps.events.publish('title', { profile: current.profile, sessionId });
|
|
1513
|
+
status('refreshed', llmStatus, next, rawPreview);
|
|
1514
|
+
put('title', { session_id: sessionId, title: next });
|
|
1515
|
+
}
|
|
1384
1516
|
// ── cancel / steer ───────────────────────────────────────────────────────
|
|
1385
1517
|
/**
|
|
1386
1518
|
* Python `cancel_stream`: persist the partial, mark cancelled, interrupt the Agent, release admission. `withdrawn` is the
|
|
@@ -1658,12 +1790,6 @@ export class TurnRunner {
|
|
|
1658
1790
|
return { events, leftovers: [...(unmatched ? [unmatched] : []), ...left.map((r) => r.text)] };
|
|
1659
1791
|
if (unmatched)
|
|
1660
1792
|
events.push(['steer_withdrawn', { steer_id: null, reason: 'stopped', text: unmatched }]);
|
|
1661
|
-
// ponytail: legacy `pending_steer_leftover` keeps today's Web and App from losing a stopped steer (they requeue it);
|
|
1662
|
-
// drop it once TAL-425 / TAL-426 put `steer_withdrawn` text back in the composer.
|
|
1663
|
-
for (const r of left)
|
|
1664
|
-
events.push(['pending_steer_leftover', { steer_id: r.steer_id, stream_id: streamId, text: r.text, display_text: r.display_text, leftover_at: this.deps.now() }]);
|
|
1665
|
-
if (unmatched)
|
|
1666
|
-
events.push(['pending_steer_leftover', { stream_id: streamId, text: unmatched }]);
|
|
1667
1793
|
return { events, leftovers: [] };
|
|
1668
1794
|
}
|
|
1669
1795
|
/**
|
|
@@ -1890,7 +2016,9 @@ export class TurnRunner {
|
|
|
1890
2016
|
const profileHome = this.deps.profileHome(s?.profile ?? null);
|
|
1891
2017
|
let resolved = false;
|
|
1892
2018
|
let withdrawn = false;
|
|
1893
|
-
if (entry)
|
|
2019
|
+
if (entry?._injected === true)
|
|
2020
|
+
resolved = Boolean(this.deps.pending.resolveApproval(sessionId, str(entry.approval_id)).entry);
|
|
2021
|
+
else if (entry) {
|
|
1894
2022
|
if (!sidecar)
|
|
1895
2023
|
return relayFailure('not running');
|
|
1896
2024
|
try {
|
|
@@ -1992,6 +2120,11 @@ export class TurnRunner {
|
|
|
1992
2120
|
const response = typeof reply === 'string' ? reply : clarifyReply(entry, reply);
|
|
1993
2121
|
if (response === null)
|
|
1994
2122
|
return { ok: false, invalid: true };
|
|
2123
|
+
// A test-hook prompt has no parked Agent waiter: it is answered here.
|
|
2124
|
+
if (entry._injected === true) {
|
|
2125
|
+
this.deps.pending.resolveClarify(sessionId, str(entry.clarify_id));
|
|
2126
|
+
return { ok: true, response };
|
|
2127
|
+
}
|
|
1995
2128
|
const sidecar = this.deps.sidecar();
|
|
1996
2129
|
if (!sidecar)
|
|
1997
2130
|
return { ok: false, error: 'The Agent sidecar is not running; retry in a moment.' };
|