@maudecode/talaria-web 1.20.0 → 1.22.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/automation-router.d.ts +319 -14
- package/dist/api/automation-router.js +21 -1
- package/dist/api/automation-router.js.map +1 -1
- package/dist/api/chat-router.d.ts +615 -69
- package/dist/api/chat-router.js +22 -170
- package/dist/api/chat-router.js.map +1 -1
- package/dist/api/git-router.d.ts +50 -0
- package/dist/api/git-router.js +17 -4
- package/dist/api/git-router.js.map +1 -1
- package/dist/api/groups-router.d.ts +764 -0
- package/dist/api/groups-router.js +79 -0
- package/dist/api/groups-router.js.map +1 -0
- package/dist/api/raw-routes.js +3 -1
- package/dist/api/raw-routes.js.map +1 -1
- package/dist/api/router.d.ts +1 -1
- package/dist/api/sessions-router.d.ts +1675 -167
- package/dist/api/sessions-router.js +67 -53
- package/dist/api/sessions-router.js.map +1 -1
- package/dist/api/settings-router.d.ts +911 -1
- package/dist/api/settings-router.js +53 -2
- package/dist/api/settings-router.js.map +1 -1
- package/dist/api/sse-routes.d.ts +1 -1
- package/dist/api/sse-routes.js +15 -5
- package/dist/api/sse-routes.js.map +1 -1
- package/dist/api/tools-raw.js +27 -136
- package/dist/api/tools-raw.js.map +1 -1
- package/dist/api/tools-router.d.ts +588 -51
- package/dist/api/tools-router.js +98 -16
- package/dist/api/tools-router.js.map +1 -1
- package/dist/app.js +5 -1
- package/dist/app.js.map +1 -1
- package/dist/auth/gate.js +5 -1
- package/dist/auth/gate.js.map +1 -1
- package/dist/config/agent-config.d.ts +6 -1
- package/dist/config/agent-config.js +75 -3
- package/dist/config/agent-config.js.map +1 -1
- package/dist/feedback.d.ts +18 -0
- package/dist/feedback.js +145 -0
- package/dist/feedback.js.map +1 -0
- package/dist/fs/stat.d.ts +2 -0
- package/dist/fs/stat.js +4 -0
- package/dist/fs/stat.js.map +1 -1
- package/dist/http/context.d.ts +9 -0
- package/dist/http/context.js +0 -6
- package/dist/http/context.js.map +1 -1
- package/dist/http/pinned.js +19 -8
- package/dist/http/pinned.js.map +1 -1
- package/dist/providers/catalog.d.ts +9 -1
- package/dist/providers/catalog.js +86 -6
- package/dist/providers/catalog.js.map +1 -1
- package/dist/redact.d.ts +2 -0
- package/dist/redact.js +26 -5
- package/dist/redact.js.map +1 -1
- package/dist/runtime.js +62 -11
- package/dist/runtime.js.map +1 -1
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -1
- package/dist/sessions/admission.d.ts +21 -0
- package/dist/sessions/admission.js +176 -0
- package/dist/sessions/admission.js.map +1 -0
- package/dist/sessions/anchor.d.ts +5 -2
- package/dist/sessions/anchor.js +14 -13
- package/dist/sessions/anchor.js.map +1 -1
- package/dist/sessions/background-tasks.d.ts +19 -1
- package/dist/sessions/background-tasks.js +36 -6
- package/dist/sessions/background-tasks.js.map +1 -1
- package/dist/sessions/cli-sessions.js +11 -6
- package/dist/sessions/cli-sessions.js.map +1 -1
- package/dist/sessions/compress.d.ts +10 -9
- package/dist/sessions/compress.js +31 -20
- package/dist/sessions/compress.js.map +1 -1
- package/dist/sessions/events.d.ts +3 -0
- package/dist/sessions/events.js +4 -0
- package/dist/sessions/events.js.map +1 -1
- package/dist/sessions/gateway-sessions.d.ts +61 -2
- package/dist/sessions/gateway-sessions.js +223 -35
- package/dist/sessions/gateway-sessions.js.map +1 -1
- package/dist/sessions/gateway-watcher.js +8 -4
- package/dist/sessions/gateway-watcher.js.map +1 -1
- package/dist/sessions/groups.d.ts +60 -0
- package/dist/sessions/groups.js +339 -0
- package/dist/sessions/groups.js.map +1 -0
- package/dist/sessions/list.d.ts +7 -2
- package/dist/sessions/list.js +13 -4
- package/dist/sessions/list.js.map +1 -1
- package/dist/sessions/merge.d.ts +15 -5
- package/dist/sessions/merge.js +49 -15
- package/dist/sessions/merge.js.map +1 -1
- package/dist/sessions/pending.d.ts +1 -1
- package/dist/sessions/pending.js +15 -6
- package/dist/sessions/pending.js.map +1 -1
- package/dist/sessions/prefix-index.d.ts +9 -14
- package/dist/sessions/prefix-index.js +14 -52
- package/dist/sessions/prefix-index.js.map +1 -1
- package/dist/sessions/prompt-queues.d.ts +36 -0
- package/dist/sessions/prompt-queues.js +318 -0
- package/dist/sessions/prompt-queues.js.map +1 -0
- package/dist/sessions/reasoning-display.d.ts +2 -0
- package/dist/sessions/reasoning-display.js +31 -0
- package/dist/sessions/reasoning-display.js.map +1 -0
- package/dist/sessions/relay.d.ts +16 -2
- package/dist/sessions/relay.js +119 -24
- package/dist/sessions/relay.js.map +1 -1
- package/dist/sessions/service.d.ts +33 -3
- package/dist/sessions/service.js +304 -70
- package/dist/sessions/service.js.map +1 -1
- package/dist/sessions/session.d.ts +6 -0
- package/dist/sessions/session.js +14 -0
- package/dist/sessions/session.js.map +1 -1
- package/dist/sessions/shares.d.ts +1 -1
- package/dist/sessions/shares.js +13 -4
- package/dist/sessions/shares.js.map +1 -1
- package/dist/sessions/state-db.d.ts +2 -1
- package/dist/sessions/state-db.js +7 -3
- package/dist/sessions/state-db.js.map +1 -1
- package/dist/sessions/storage/json-documents.js +3 -0
- package/dist/sessions/storage/json-documents.js.map +1 -1
- package/dist/sessions/store.d.ts +2 -0
- package/dist/sessions/store.js +11 -3
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/streams.d.ts +4 -0
- package/dist/sessions/streams.js +12 -0
- package/dist/sessions/streams.js.map +1 -1
- package/dist/sessions/todo.js +10 -1
- package/dist/sessions/todo.js.map +1 -1
- package/dist/sessions/tool-display.d.ts +8 -1
- package/dist/sessions/tool-display.js +39 -4
- package/dist/sessions/tool-display.js.map +1 -1
- package/dist/sessions/turn.d.ts +4 -1
- package/dist/sessions/turn.js +53 -22
- package/dist/sessions/turn.js.map +1 -1
- package/dist/settings.js +2 -1
- package/dist/settings.js.map +1 -1
- package/dist/spa.js +1 -1
- package/dist/spa.js.map +1 -1
- package/dist/test/group-fixture.d.ts +66 -0
- package/dist/test/group-fixture.js +89 -0
- package/dist/test/group-fixture.js.map +1 -0
- package/dist/test/harness.d.ts +3 -0
- package/dist/test/harness.js +3 -0
- package/dist/test/harness.js.map +1 -1
- package/dist/tools/connectors.d.ts +9 -1
- package/dist/tools/connectors.js +48 -0
- package/dist/tools/connectors.js.map +1 -1
- package/dist/tools/kanban.d.ts +10 -1
- package/dist/tools/kanban.js +73 -1
- package/dist/tools/kanban.js.map +1 -1
- package/dist/tools/mcp.d.ts +3 -1
- package/dist/tools/mcp.js +73 -0
- package/dist/tools/mcp.js.map +1 -1
- package/dist/tools/memory.d.ts +28 -0
- package/dist/tools/memory.js +120 -14
- package/dist/tools/memory.js.map +1 -1
- package/dist/tools/skills.d.ts +6 -0
- package/dist/tools/skills.js +17 -0
- package/dist/tools/skills.js.map +1 -1
- package/dist/tools/update-notifications.d.ts +12 -10
- package/dist/tools/update-notifications.js +124 -14
- package/dist/tools/update-notifications.js.map +1 -1
- package/dist/tools/updates.d.ts +38 -12
- package/dist/tools/updates.js +180 -44
- package/dist/tools/updates.js.map +1 -1
- package/dist/workspace/fs.d.ts +2 -0
- package/dist/workspace/fs.js +63 -1
- package/dist/workspace/fs.js.map +1 -1
- package/dist/workspace/managed-buffers.d.ts +58 -0
- package/dist/workspace/managed-buffers.js +76 -0
- package/dist/workspace/managed-buffers.js.map +1 -0
- package/dist/workspace/rollback.js +1 -1
- package/dist/workspace/rollback.js.map +1 -1
- package/dist/workspace/upload.d.ts +1 -1
- package/dist/workspace/upload.js +52 -37
- package/dist/workspace/upload.js.map +1 -1
- package/dist/workspace/workspaces.d.ts +5 -1
- package/dist/workspace/workspaces.js +32 -6
- package/dist/workspace/workspaces.js.map +1 -1
- package/package.json +2 -2
- package/sidecar/agent_dependency.json +4 -4
- package/sidecar/agent_importer.json +8 -0
- package/sidecar/agent_support.json +20 -8
- package/sidecar/scripts/agent_importer_contract.py +19 -0
- package/sidecar/scripts/test.sh +3 -1
- package/sidecar/talaria_sidecar/__init__.py +1 -1
- package/sidecar/talaria_sidecar/agent_mutation.py +87 -9
- package/sidecar/talaria_sidecar/agent_services.py +83 -23
- package/sidecar/talaria_sidecar/home.py +12 -5
- package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
- package/sidecar/talaria_sidecar/methods/agent_imports.py +346 -0
- package/sidecar/talaria_sidecar/methods/chat.py +141 -58
- package/sidecar/talaria_sidecar/methods/commands.py +6 -4
- package/sidecar/talaria_sidecar/methods/config.py +8 -3
- package/sidecar/talaria_sidecar/methods/connectors.py +138 -4
- package/sidecar/talaria_sidecar/methods/dashboard_plugins.py +25 -4
- package/sidecar/talaria_sidecar/methods/delegation.py +126 -0
- package/sidecar/talaria_sidecar/methods/gateway.py +5 -0
- package/sidecar/talaria_sidecar/methods/gateway_sessions.py +142 -23
- package/sidecar/talaria_sidecar/methods/groups.py +120 -0
- package/sidecar/talaria_sidecar/methods/kanban.py +48 -0
- package/sidecar/talaria_sidecar/methods/managed_buffers.py +110 -0
- package/sidecar/talaria_sidecar/methods/mcp.py +55 -0
- package/sidecar/talaria_sidecar/methods/memory.py +27 -3
- package/sidecar/talaria_sidecar/methods/nous_account.py +130 -0
- package/sidecar/talaria_sidecar/methods/oauth.py +25 -4
- package/sidecar/talaria_sidecar/methods/outbound_drafts.py +147 -0
- package/sidecar/talaria_sidecar/methods/plugin_catalog.py +73 -2
- package/sidecar/talaria_sidecar/methods/providers.py +51 -1
- package/sidecar/talaria_sidecar/methods/skill_revisions.py +177 -0
- package/sidecar/talaria_sidecar/methods/skills.py +10 -0
- package/sidecar/talaria_sidecar/methods/tts.py +67 -0
- package/sidecar/talaria_sidecar/rpc.py +11 -2
- package/static/dist/FILES.txt +155 -144
- package/static/dist/THIRD_PARTY_LICENSES.md +1 -1
- package/static/dist/assets/AppShell-hvysbd9x.js +8 -0
- package/static/dist/assets/Button-dlsibkzq.js +1 -0
- package/static/dist/assets/ChatPage-jikwrwfd.js +2 -0
- package/static/dist/assets/Composer-mnke8ss2.js +5 -0
- package/static/dist/assets/ConnectTargets-ejplzo4q.js +1 -0
- package/static/dist/assets/Dialog-rksfyyq5.js +1 -0
- package/static/dist/assets/{ExtensionRoute-zrhjn0wm.js → ExtensionRoute-igk5h0rj.js} +1 -1
- package/static/dist/assets/HubRoute-eooassx4.js +2 -0
- package/static/dist/assets/Markdown-m5pzgvtx.js +2 -0
- package/static/dist/assets/{MarkdownRenderer-fbswsgld.js → MarkdownRenderer-74ysuomr.js} +18 -18
- package/static/dist/assets/OAuthSignIn-i4flsuq2.js +1 -0
- package/static/dist/assets/QueueCard-msz9wd1m.js +1 -0
- package/static/dist/assets/ResourceSwitch-b70zg4xd.js +1 -0
- package/static/dist/assets/RightPanel-f5v61m8j.js +1 -0
- package/static/dist/assets/Select-f3l897pt.js +1 -0
- package/static/dist/assets/SessionListPanel-brnzacw9.js +1 -0
- package/static/dist/assets/SettingsLayout-f4akmrt2.js +1 -0
- package/static/dist/assets/States-msohx3c0.js +1 -0
- package/static/dist/assets/TerminalPanel-bnu5xawo.js +16 -0
- package/static/dist/assets/Toaster-d6col3ch.js +1 -0
- package/static/dist/assets/_app-lrjgufcy.js +1 -0
- package/static/dist/assets/{_app.ext._extensionId-na62087t.js → _app.ext._extensionId-k3xitxr1.js} +1 -1
- package/static/dist/assets/_app.groups-bt4wdwnd.js +1 -0
- package/static/dist/assets/{_app.index-jypgdqoi.js → _app.index-n3otiki0.js} +1 -1
- package/static/dist/assets/{_app.insights-kabejdtm.js → _app.insights-b0mzlh6m.js} +1 -1
- package/static/dist/assets/{_app.kanban-m19kfcmx.js → _app.kanban-d923g7j5.js} +1 -1
- package/static/dist/assets/{_app.logs-iw4m96sz.js → _app.logs-donegue1.js} +1 -1
- package/static/dist/assets/{_app.memory-jq5frwcg.js → _app.memory-hdnled08.js} +1 -1
- package/static/dist/assets/{_app.profiles-kwa3m7rp.js → _app.profiles-fumot3jk.js} +1 -1
- package/static/dist/assets/{_app.session._sessionId-o5lyeipj.js → _app.session._sessionId-crmdl2ux.js} +1 -1
- package/static/dist/assets/{_app.settings-ckl8hdll.js → _app.settings-jui8iesz.js} +1 -1
- package/static/dist/assets/_app.settings._section-do84hsqw.js +3 -0
- package/static/dist/assets/{_app.skills-n016rihd.js → _app.skills-heqcn21m.js} +1 -1
- package/static/dist/assets/_app.tasks-jiudtutt.js +1 -0
- package/static/dist/assets/{_app.todos-btew5v2s.js → _app.todos-bl6kk2zq.js} +1 -1
- package/static/dist/assets/{_app.workspaces-lnfk95ch.js → _app.workspaces-frvh3o7w.js} +1 -1
- package/static/dist/assets/_delete-qnxuo87s.js +1 -0
- package/static/dist/assets/{abnfDiagram-VCTEODGH-dttheegb.js → abnfDiagram-VCTEODGH-dppg3yfx.js} +1 -1
- package/static/dist/assets/{architecture-7GRP2DOG-ic435919.js → architecture-7GRP2DOG-gbajejh3.js} +1 -1
- package/static/dist/assets/{architectureDiagram-5GKGNRK7-8r3glgiq.js → architectureDiagram-5GKGNRK7-bzrxyais.js} +1 -1
- package/static/dist/assets/archive-yhdyz231.js +1 -0
- package/static/dist/assets/autoReadClaim-nlyv8tu9.js +1 -0
- package/static/dist/assets/{blockDiagram-I7D4REHJ-jenyos6c.js → blockDiagram-I7D4REHJ-gmk9koab.js} +1 -1
- package/static/dist/assets/{c4Diagram-7LVT6UL2-nzlx7yc4.js → c4Diagram-7LVT6UL2-bfqiqqcz.js} +1 -1
- package/static/dist/assets/channel-grt3rob4.js +1 -0
- package/static/dist/assets/{chunk-4HAMMTFA-g0cru63b.js → chunk-4HAMMTFA-i9s6h4wv.js} +1 -1
- package/static/dist/assets/{chunk-75Z2AOVW-7rkswkjw.js → chunk-75Z2AOVW-gnt6pnso.js} +1 -1
- package/static/dist/assets/{chunk-DU6HZSFF-fn73jzdo.js → chunk-DU6HZSFF-gq439wot.js} +3 -3
- package/static/dist/assets/{chunk-F27PBJKO-oey8e72m.js → chunk-F27PBJKO-wvx90pbt.js} +1 -1
- package/static/dist/assets/{chunk-GMAD6QVW-l2a32wiy.js → chunk-GMAD6QVW-mc2gu30k.js} +1 -1
- package/static/dist/assets/{chunk-GVQU2GXP-o9dwzh8h.js → chunk-GVQU2GXP-f8fxa2ym.js} +1 -1
- package/static/dist/assets/{chunk-IMKFNOWR-eblwj20b.js → chunk-IMKFNOWR-lnsl31hj.js} +1 -1
- package/static/dist/assets/{chunk-L3NEJ4N5-o2mufspb.js → chunk-L3NEJ4N5-kbfdidwu.js} +1 -1
- package/static/dist/assets/{chunk-OSK3NFVY-ijp9pw29.js → chunk-OSK3NFVY-dvxsduj6.js} +1 -1
- package/static/dist/assets/{chunk-P2QGCYS3-hs9hqwl4.js → chunk-P2QGCYS3-ivo3i1wf.js} +1 -1
- package/static/dist/assets/{chunk-POPQ4Y6H-bp9rsqez.js → chunk-POPQ4Y6H-i0gfu0hx.js} +1 -1
- package/static/dist/assets/{chunk-PWAF6VOD-brkprov6.js → chunk-PWAF6VOD-jb0fdyb0.js} +1 -1
- package/static/dist/assets/{chunk-SHT3W25Y-gmpv0pxz.js → chunk-SHT3W25Y-b7ou2xsp.js} +1 -1
- package/static/dist/assets/{chunk-SVP7TREG-oldm08fu.js → chunk-SVP7TREG-e2v7me5v.js} +1 -1
- package/static/dist/assets/{chunk-TICWLB2K-ooqilfv7.js → chunk-TICWLB2K-e5zlai62.js} +1 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-nnsp49jr.js +1 -0
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-nnsp49jr.js +1 -0
- package/static/dist/assets/completionAudio-c5at041z.js +1 -0
- package/static/dist/assets/{copy-jo006coq.js → copy-jj3oiw13.js} +1 -1
- package/static/dist/assets/{cynefin-OW5HDTMX-d47op7qs.js → cynefin-OW5HDTMX-n5n1ck70.js} +1 -1
- package/static/dist/assets/{cynefinDiagram-5FMLGOSQ-doa7594y.js → cynefinDiagram-5FMLGOSQ-b33npu4f.js} +1 -1
- package/static/dist/assets/{dagre-GXQ25YYZ-os768dp4.js → dagre-GXQ25YYZ-miwvae07.js} +1 -1
- package/static/dist/assets/{diagram-S7CK7UJ4-fyi81nxd.js → diagram-S7CK7UJ4-j8fphsp4.js} +1 -1
- package/static/dist/assets/{diagram-UQ7AKVKN-j3exggaq.js → diagram-UQ7AKVKN-5cixo166.js} +1 -1
- package/static/dist/assets/{diagram-VSXAHHWV-omo1en2l.js → diagram-VSXAHHWV-ii3bf92m.js} +1 -1
- package/static/dist/assets/{diagram-VX7I27RA-oro2cyu0.js → diagram-VX7I27RA-b3cfgx81.js} +1 -1
- package/static/dist/assets/{diagram-Z3DM3KII-byt9vdb7.js → diagram-Z3DM3KII-bey9lqr8.js} +1 -1
- package/static/dist/assets/{dist-etpoyscq.js → dist-cb8um5dh.js} +4 -4
- package/static/dist/assets/{dist-crc46di9.js → dist-kpg5ccm9.js} +1 -1
- package/static/dist/assets/{ebnfDiagram-PWID7BFC-ee3haugh.js → ebnfDiagram-PWID7BFC-2m4wrnqc.js} +1 -1
- package/static/dist/assets/{erDiagram-RLTQ6QDP-d1e93yff.js → erDiagram-RLTQ6QDP-kak5te0n.js} +1 -1
- package/static/dist/assets/{eventmodeling-NTZA5JFV-i1ihb40c.js → eventmodeling-NTZA5JFV-ojcc486t.js} +1 -1
- package/static/dist/assets/flowDiagram-HODETNUW-kxr9sicu.js +1 -0
- package/static/dist/assets/folder-plus-fk6j7tlv.js +1 -0
- package/static/dist/assets/{ganttDiagram-EL5Y4UJY-m7g0jud4.js → ganttDiagram-EL5Y4UJY-k6nfmhrh.js} +1 -1
- package/static/dist/assets/getPseudoElementBounds-mwj3vqni.js +1 -0
- package/static/dist/assets/{gitGraph-4MIJSDKK-hzdj07yy.js → gitGraph-4MIJSDKK-bxq1lbhy.js} +1 -1
- package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-dm9agbna.js → gitGraphDiagram-WWUBYQGX-ehvoankt.js} +1 -1
- package/static/dist/assets/group_discussions-fk5hry4l.js +1 -0
- package/static/dist/assets/{highlighted-body-KPVGNVTW-mmgz2czu.js → highlighted-body-KPVGNVTW-nr4nfdq7.js} +1 -1
- package/static/dist/assets/{host-fr6lni1p.js → host-dhgqiozp.js} +1 -1
- package/static/dist/assets/index-hx7z4wdj.js +13 -0
- package/static/dist/assets/index-o8ebuc5x.css +2 -0
- package/static/dist/assets/{info-A6RAGUB7-lll1dqmm.js → info-A6RAGUB7-dtsj0ybw.js} +1 -1
- package/static/dist/assets/{infoDiagram-27XIBGKW-k7esc639.js → infoDiagram-27XIBGKW-jena90ao.js} +1 -1
- package/static/dist/assets/{ishikawaDiagram-5VMMS53U-lgr6k9wo.js → ishikawaDiagram-5VMMS53U-kia6bn5u.js} +1 -1
- package/static/dist/assets/{journeyDiagram-3NMN7TZE-ndmbxuqk.js → journeyDiagram-3NMN7TZE-ipsa6icb.js} +1 -1
- package/static/dist/assets/{kanban-definition-UXKFOSKX-mjxym0jp.js → kanban-definition-UXKFOSKX-moxx59kp.js} +1 -1
- package/static/dist/assets/katex-ic33v820.js +257 -0
- package/static/dist/assets/katex-qcv7xo0t.css +1 -0
- package/static/dist/assets/{lazyRouteComponent-cwb6l7xh.js → lazyRouteComponent-i74ujrfk.js} +1 -1
- package/static/dist/assets/{line-mtr5k6il.js → line-lgrkg9no.js} +1 -1
- package/static/dist/assets/link-2-fp49mwl2.js +1 -0
- package/static/dist/assets/{link-iadw4ghw.js → link-es18mse1.js} +2 -2
- package/static/dist/assets/{locale-cs-n41hptse.js → locale-cs-brltdkcp.js} +1 -1
- package/static/dist/assets/{locale-de-k7ht47ew.js → locale-de-h6e9oq6v.js} +1 -1
- package/static/dist/assets/{locale-es-ih078lco.js → locale-es-oklmh80f.js} +1 -1
- package/static/dist/assets/{locale-fr-ojabnf41.js → locale-fr-b17ozoi2.js} +1 -1
- package/static/dist/assets/{locale-it-kb96jufy.js → locale-it-whe01eef.js} +1 -1
- package/static/dist/assets/{locale-ja-jpsp3xs1.js → locale-ja-g1s0rtpc.js} +1 -1
- package/static/dist/assets/{locale-pl-dbap4leu.js → locale-pl-d9p3lqcb.js} +1 -1
- package/static/dist/assets/{locale-pt-nci7w72x.js → locale-pt-l75on74f.js} +1 -1
- package/static/dist/assets/{locale-ru-soghe4cs.js → locale-ru-wl3mbsaw.js} +1 -1
- package/static/dist/assets/{locale-tr-ks00mu68.js → locale-tr-cz87itrq.js} +1 -1
- package/static/dist/assets/{locale-vi-ij7twfm6.js → locale-vi-elqj1y4k.js} +1 -1
- package/static/dist/assets/{locale-zh-Hant-feakwr7a.js → locale-zh-Hant-hf8gqm7d.js} +1 -1
- package/static/dist/assets/{locale-zh-ren0vjyv.js → locale-zh-cdckwb0u.js} +1 -1
- package/static/dist/assets/login-o6gfl4gy.js +1 -0
- package/static/dist/assets/mermaid-HWGCJPDP-n2kbzsao.js +1 -0
- package/static/dist/assets/{mermaid-parser.core-k91vdnvi.js → mermaid-parser.core-fflovwf2.js} +3 -3
- package/static/dist/assets/{mindmap-definition-YA3MSWOX-ehztfea4.js → mindmap-definition-YA3MSWOX-ic8l9whi.js} +1 -1
- package/static/dist/assets/onboarding-bxm7gdrr.js +1 -0
- package/static/dist/assets/{packet-AYTQ26CC-ok2xrblz.js → packet-AYTQ26CC-ntci3088.js} +1 -1
- package/static/dist/assets/{pegDiagram-XKGWAZYB-ec3rpj0m.js → pegDiagram-XKGWAZYB-e3btz04w.js} +1 -1
- package/static/dist/assets/{pie-WAS4IAKB-iwkir23u.js → pie-WAS4IAKB-o2dc7l36.js} +1 -1
- package/static/dist/assets/{pieDiagram-E7YTZNPT-fcpqpekh.js → pieDiagram-E7YTZNPT-gro55rrw.js} +1 -1
- package/static/dist/assets/presence-lq6m12ga.js +1 -0
- package/static/dist/assets/prompt_queue_cancelled-cebcuagu.js +1 -0
- package/static/dist/assets/{quadrantDiagram-AXDQQJYC-lqsync43.js → quadrantDiagram-AXDQQJYC-fxulmd7d.js} +1 -1
- package/static/dist/assets/queryKeys-cnvn6pea.js +9 -0
- package/static/dist/assets/{radar-RG4KPBEZ-hje4jbk6.js → radar-RG4KPBEZ-9pcospra.js} +1 -1
- package/static/dist/assets/{railroad-74A4TZTK-gll9n6qi.js → railroad-74A4TZTK-nzdga12j.js} +1 -1
- package/static/dist/assets/{railroad-abnf-HS5TGJTU-o6h6lpn4.js → railroad-abnf-HS5TGJTU-ep3ytel0.js} +1 -1
- package/static/dist/assets/{railroad-ebnf-LZEXJU2U-juaefj6o.js → railroad-ebnf-LZEXJU2U-iw7uc1wy.js} +1 -1
- package/static/dist/assets/{railroad-peg-WCYAUIDC-cgfhvpah.js → railroad-peg-WCYAUIDC-fo3b3gme.js} +1 -1
- package/static/dist/assets/{railroadDiagram-O6MQD6OU-lp3w7awf.js → railroadDiagram-O6MQD6OU-lxpxf8f0.js} +1 -1
- package/static/dist/assets/{refresh-cw-iccm7a4e.js → refresh-cw-d14h79x5.js} +1 -1
- package/static/dist/assets/rename-ccd52yws.js +1 -0
- package/static/dist/assets/{requirementDiagram-BXWQKSXE-ha8eibcf.js → requirementDiagram-BXWQKSXE-lrozucd2.js} +1 -1
- package/static/dist/assets/{sankeyDiagram-P5KCCOFB-oxf31pr9.js → sankeyDiagram-P5KCCOFB-iusxy9mq.js} +1 -1
- package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-jiq8lhyo.js → sequenceDiagram-WJ2MYXX4-o987q8ti.js} +1 -1
- package/static/dist/assets/{share._token-o76ki0ly.js → share._token-bfw7f9m5.js} +1 -1
- package/static/dist/assets/sliders-horizontal-l65hoa3x.js +1 -0
- package/static/dist/assets/{stateDiagram-D77RDMKH-f3fslnon.js → stateDiagram-D77RDMKH-hh23v7y5.js} +1 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-jukr0d8h.js +1 -0
- package/static/dist/assets/{swimlanes-42K2YHIH-k1hmk7jf.js → swimlanes-42K2YHIH-gj2t3rm8.js} +1 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-ik9m9j2m.js +8 -0
- package/static/dist/assets/{timeline-definition-24CTP7MA-n3ncfy9r.js → timeline-definition-24CTP7MA-84s2w2sr.js} +1 -1
- package/static/dist/assets/toast-gqqcvxiy.js +56 -0
- package/static/dist/assets/{treeView-Q6P3EWNA-l3y2pejt.js → treeView-Q6P3EWNA-cmuj50l7.js} +1 -1
- package/static/dist/assets/{treemap-WGGIJYW6-jown9axh.js → treemap-WGGIJYW6-dpjlg0xc.js} +1 -1
- package/static/dist/assets/tts-jw84jlqy.js +1 -0
- package/static/dist/assets/{useForm-o4uu74mx.js → useForm-lxzhiqao.js} +1 -1
- package/static/dist/assets/{useParams-ftsveu84.js → useParams-dt6gkoq7.js} +1 -1
- package/static/dist/assets/{useSearch-crqueqga.js → useSearch-o8t49csk.js} +1 -1
- package/static/dist/assets/useTranscript-gx9umcc2.js +1 -0
- package/static/dist/assets/{vennDiagram-4TSXK5OY-dh59uq1c.js → vennDiagram-4TSXK5OY-g9g5o8vy.js} +1 -1
- package/static/dist/assets/{wardley-WFR3VGLG-e6d74b0j.js → wardley-WFR3VGLG-ij35obrl.js} +1 -1
- package/static/dist/assets/{wardleyDiagram-VM6X3IG4-hnofh78f.js → wardleyDiagram-VM6X3IG4-f9my7q7w.js} +1 -1
- package/static/dist/assets/{xychartDiagram-S5SC5T6Z-bpymjelb.js → xychartDiagram-S5SC5T6Z-olqx1s1p.js} +1 -1
- package/static/dist/index.html +1 -1
- package/static/dist/sw.js +1 -1
- package/static/dist/assets/AppShell-3isgvoro.js +0 -8
- package/static/dist/assets/Button-f4n6dapf.js +0 -1
- package/static/dist/assets/ChatPage-k7b6xfax.js +0 -4
- package/static/dist/assets/ConnectTargets-juqvt5lm.js +0 -1
- package/static/dist/assets/Dialog-hta5utr3.js +0 -1
- package/static/dist/assets/Field-b6ez48oz.js +0 -1
- package/static/dist/assets/HubRoute-iwvso2tz.js +0 -2
- package/static/dist/assets/Markdown-jdeth7zq.js +0 -2
- package/static/dist/assets/OAuthSignIn-bpd8hom3.js +0 -1
- package/static/dist/assets/ResourceSwitch-odi6dy2o.js +0 -1
- package/static/dist/assets/RightPanel-eu6enlo6.js +0 -1
- package/static/dist/assets/Select-kr07928w.js +0 -1
- package/static/dist/assets/SessionListPanel-etb2i54l.js +0 -1
- package/static/dist/assets/SettingsLayout-eu3xxp23.js +0 -1
- package/static/dist/assets/States-icab19yg.js +0 -1
- package/static/dist/assets/TerminalPanel-hngmsr8b.js +0 -16
- package/static/dist/assets/Toaster-nb2uzjw1.js +0 -1
- package/static/dist/assets/_app-ga1moszl.js +0 -1
- package/static/dist/assets/_app.settings._section-dtdjk98a.js +0 -3
- package/static/dist/assets/_app.tasks-n8zuqsqe.js +0 -1
- package/static/dist/assets/archive-il7c6053.js +0 -1
- package/static/dist/assets/cancel-bsnfo36u.js +0 -1
- package/static/dist/assets/channel-dsbtk01y.js +0 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-fvgcv24g.js +0 -1
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-fvgcv24g.js +0 -1
- package/static/dist/assets/flowDiagram-HODETNUW-jahfpiod.js +0 -1
- package/static/dist/assets/folder-plus-ivoglq98.js +0 -1
- package/static/dist/assets/index-73649w7o.js +0 -10
- package/static/dist/assets/index-lhf1fsdf.css +0 -2
- package/static/dist/assets/katex-cbdd1ohw.css +0 -1
- package/static/dist/assets/katex-pbij2oo6.js +0 -257
- package/static/dist/assets/login-lkhtzfcl.js +0 -1
- package/static/dist/assets/mermaid-HWGCJPDP-jx0q5dm2.js +0 -1
- package/static/dist/assets/onboarding-f67z0a2r.js +0 -1
- package/static/dist/assets/queryKeys-ed4n2egc.js +0 -9
- package/static/dist/assets/refresh-i9ya9dvl.js +0 -1
- package/static/dist/assets/sliders-horizontal-ddcs88av.js +0 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-hlt6yphw.js +0 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-hd5t9tnt.js +0 -8
- package/static/dist/assets/toast-liparz2j.js +0 -56
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type ContextDetail } from '@maudecode/talaria-web-contracts';
|
|
1
|
+
import { type CheckpointDiff, type SessionActivityPhase, type ContextDetail } from '@maudecode/talaria-web-contracts';
|
|
2
2
|
/** One native-owner seam. Talaria observes its history and never settles it into a local Session. */
|
|
3
|
+
import type { QueueAdmissionFence } from './admission.js';
|
|
3
4
|
import type { StartupTiming } from '../startup-timing.js';
|
|
4
5
|
import { type ExecutionModes, type GatewayCreateParams, type GatewaySessionParams, type GatewaySessionResult } from '@maudecode/talaria-web-contracts';
|
|
5
6
|
import type { SidecarLike } from '../sidecar/client.js';
|
|
@@ -8,6 +9,12 @@ import type { SessionChannels, StreamRegistry } from './streams.js';
|
|
|
8
9
|
import type { RunJournal } from './journal.js';
|
|
9
10
|
import { SessionEventBus } from './events.js';
|
|
10
11
|
type Row = Record<string, unknown>;
|
|
12
|
+
interface Target {
|
|
13
|
+
sid: string;
|
|
14
|
+
profile: string;
|
|
15
|
+
home: string;
|
|
16
|
+
key: string;
|
|
17
|
+
}
|
|
11
18
|
/** The scope remains verifiable after a server restart, before a journal lookup or stream subscription. */
|
|
12
19
|
export declare const gatewayStreamVisible: (stream: string, home: string) => boolean;
|
|
13
20
|
export declare class GatewaySessions {
|
|
@@ -22,6 +29,7 @@ export declare class GatewaySessions {
|
|
|
22
29
|
private rememberModelChange;
|
|
23
30
|
private currentModelChange;
|
|
24
31
|
constructor(deps: {
|
|
32
|
+
onWebCompletion?: (profile: string, sessionId: string, identity: string) => void;
|
|
25
33
|
service: SessionService;
|
|
26
34
|
sidecar: () => SidecarLike | null;
|
|
27
35
|
registry: StreamRegistry;
|
|
@@ -39,6 +47,7 @@ export declare class GatewaySessions {
|
|
|
39
47
|
private noticeState;
|
|
40
48
|
private nativeNotices;
|
|
41
49
|
private changed;
|
|
50
|
+
private nativeTodo;
|
|
42
51
|
/** One shared connection, acquired by viewers and run projections, with no local Agent admission. */
|
|
43
52
|
private transport;
|
|
44
53
|
private lease;
|
|
@@ -49,7 +58,56 @@ export declare class GatewaySessions {
|
|
|
49
58
|
} | null>;
|
|
50
59
|
private target;
|
|
51
60
|
contextDetail(sid: string, expectedKey: string): Promise<ContextDetail>;
|
|
61
|
+
private activityPhaseFor;
|
|
62
|
+
activityPhase(sid: string, profile: string): Promise<SessionActivityPhase | null | undefined>;
|
|
52
63
|
isOwned(sid: string): Promise<boolean>;
|
|
64
|
+
/** Exact native receipt lookup for a durable queue step, never another submit. */
|
|
65
|
+
queueReceipt(sid: string, admissionId?: string): Promise<GatewaySessionResult | null>;
|
|
66
|
+
checkpointDiff(sid: string): Promise<CheckpointDiff | null>;
|
|
67
|
+
private terminalKey;
|
|
68
|
+
terminal(sid: string): Promise<{
|
|
69
|
+
target: Target;
|
|
70
|
+
snap: {
|
|
71
|
+
session_id: string;
|
|
72
|
+
stored_session_id: string;
|
|
73
|
+
messages: Record<string, unknown>[];
|
|
74
|
+
message_count: number;
|
|
75
|
+
running: boolean;
|
|
76
|
+
authority_epoch: number;
|
|
77
|
+
replay_epoch: string;
|
|
78
|
+
last_sequence: number;
|
|
79
|
+
subscription_id: string;
|
|
80
|
+
revision: number;
|
|
81
|
+
execution_generation: number;
|
|
82
|
+
pending: {
|
|
83
|
+
admission_id: string;
|
|
84
|
+
sequence: number;
|
|
85
|
+
status: "unknown" | "terminal" | "queued" | "started";
|
|
86
|
+
outcome: string | null;
|
|
87
|
+
authority_epoch: number;
|
|
88
|
+
execution_generation: number | null;
|
|
89
|
+
controls?: string[] | undefined;
|
|
90
|
+
steering?: boolean | undefined;
|
|
91
|
+
text?: string | undefined;
|
|
92
|
+
input_id?: string | undefined;
|
|
93
|
+
}[];
|
|
94
|
+
prompts: Record<string, unknown>[];
|
|
95
|
+
info: Record<string, unknown>;
|
|
96
|
+
plan_gauge?: {
|
|
97
|
+
id: string;
|
|
98
|
+
label: string;
|
|
99
|
+
used_bp: number;
|
|
100
|
+
resets_at_ms: number | null;
|
|
101
|
+
} | null | undefined;
|
|
102
|
+
reactions_supported?: boolean | undefined;
|
|
103
|
+
todo_state?: {
|
|
104
|
+
todos: Record<string, unknown>[];
|
|
105
|
+
revision?: number | undefined;
|
|
106
|
+
} | null | undefined;
|
|
107
|
+
};
|
|
108
|
+
key: string;
|
|
109
|
+
} | null>;
|
|
110
|
+
capturedCommand(sid: string, key: string, command: string): Promise<NonNullable<GatewaySessionResult['shell']>>;
|
|
53
111
|
export(sid: string, format: NonNullable<GatewaySessionParams['format']>): Promise<NonNullable<GatewaySessionResult['export']> | null>;
|
|
54
112
|
private createCall;
|
|
55
113
|
/** TAL-1040: normal always runs; the bypass modes need an owner that freezes them before any Agent import. */
|
|
@@ -62,10 +120,11 @@ export declare class GatewaySessions {
|
|
|
62
120
|
private call;
|
|
63
121
|
private attachment;
|
|
64
122
|
private contextDetailKey;
|
|
123
|
+
private reactionView;
|
|
65
124
|
private view;
|
|
66
125
|
project(base: Row, limit?: number | null, before?: number | null, withMessages?: boolean): Promise<Row>;
|
|
67
126
|
/** Called before the direct-chat admission path, including for an already materialized foreign session. */
|
|
68
|
-
submit(sid: string, body: Row, timing?: StartupTiming): Promise<Row | null>;
|
|
127
|
+
submit(sid: string, body: Row, timing?: StartupTiming, fence?: QueueAdmissionFence): Promise<Row | null>;
|
|
69
128
|
action(sid: string, params: Omit<GatewaySessionParams, 'session_id' | 'profile_home'>): Promise<GatewaySessionResult>;
|
|
70
129
|
/** The display preview is redacted; an explicit retry returns the original text for review, like direct-chat retry. */
|
|
71
130
|
retry(sid: string, admissionId: string, generation: number): Promise<string>;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { applyPlanGauge } from './session.js';
|
|
2
|
+
import { reasoningProjection } from './reasoning-display.js';
|
|
3
|
+
import { CHECKPOINT_DIFF_MAX_BYTES, ReactionEmojiSchema, unavailableContextDetail } from '@maudecode/talaria-web-contracts';
|
|
4
|
+
import { checkpointDiffFiles } from '../workspace/rollback.js';
|
|
2
5
|
import { createHash, randomUUID } from 'node:crypto';
|
|
3
6
|
import { OWNER_EXPORT_MAX_BYTES, SessionNoticeSchema, GatewayClarifyBatchSchema, GatewaySessionResultSchema } from '@maudecode/talaria-web-contracts';
|
|
4
7
|
import { redactNestedMessageContainers, publicToolFrame, redactString } from '../redact.js';
|
|
5
8
|
import { str } from '../util.js';
|
|
6
9
|
import { PendingPrompts } from './pending.js';
|
|
7
|
-
import { wrapExportHtml } from './export.js';
|
|
10
|
+
import { wrapExportHtml, renderSessionHtml, renderSessionMarkdown } from './export.js';
|
|
8
11
|
import { clarifyReply } from './pending.js';
|
|
9
12
|
import { HttpFailure } from './service.js';
|
|
10
13
|
import { SessionNotices } from './notices.js';
|
|
@@ -14,6 +17,7 @@ import { pendingUserRow } from './merge.js';
|
|
|
14
17
|
import { ReasoningTitleTracker, reasoningEventPayload } from './reasoning-titles.js';
|
|
15
18
|
import { CANONICAL_READ_ONLY_REASON, WEB_DIAGNOSTIC_REQUEST_PREFIX } from './state-db.js';
|
|
16
19
|
import { toolProgress } from './tool-display.js';
|
|
20
|
+
import { deriveTodoState, normalizeTodoSnapshot } from './todo.js';
|
|
17
21
|
const ownerStreamPrefix = (home) => `owner-${createHash('sha256').update(home).digest('hex').slice(0, 16)}-`;
|
|
18
22
|
const ownerStateId = (identity) => `owner-${createHash('sha256').update(identity).digest('hex')}`;
|
|
19
23
|
/** The scope remains verifiable after a server restart, before a journal lookup or stream subscription. */
|
|
@@ -36,8 +40,12 @@ function retryText(admission) {
|
|
|
36
40
|
/** Steering belongs to the current turn; it must never replace that turn's transcript anchor. */
|
|
37
41
|
const runningAdmission = (snapshot) => snapshot.pending.find((p) => p.status === 'started' && !p.steering);
|
|
38
42
|
const sameExecution = (a, b) => a.authority_epoch === b.authority_epoch && a.replay_epoch === b.replay_epoch && a.execution_generation === b.execution_generation;
|
|
43
|
+
/** Todo revisions belong to a single owner execution; sequence also fences explicit null clears. */
|
|
44
|
+
const newerTodo = (a, b) => Object.hasOwn(a, 'todo_state') && sameExecution(a, b)
|
|
45
|
+
&& (a.last_sequence > b.last_sequence || !Object.hasOwn(b, 'todo_state') || a.todo_state != null && b.todo_state != null && (a.todo_state.revision ?? 0) > (b.todo_state.revision ?? 0));
|
|
39
46
|
/** Native counters and the owner's compact turn-end usage share one existing Web usage shape. */
|
|
40
|
-
function ownerUsage(
|
|
47
|
+
function ownerUsage(payload, complete = false) {
|
|
48
|
+
const data = payload.usage && typeof payload.usage === 'object' ? { ...payload, ...payload.usage } : payload;
|
|
41
49
|
const fields = {
|
|
42
50
|
input_tokens: ['prompt_tokens', 'prompt', 'input_tokens', 'input'], output_tokens: ['completion_tokens', 'completion', 'output_tokens', 'output'],
|
|
43
51
|
cache_read_tokens: ['cache_read_tokens'], cache_write_tokens: ['cache_write_tokens'],
|
|
@@ -45,6 +53,7 @@ function ownerUsage(data) {
|
|
|
45
53
|
context_length: ['context_length', 'context_max'], cache_hit_percent: ['cache_hit_pct'], tps: ['tokens_per_s', 'avg_tps'],
|
|
46
54
|
};
|
|
47
55
|
const usage = {};
|
|
56
|
+
applyPlanGauge(usage, data, complete || typeof data.calls === 'number' || typeof data.api_calls === 'number');
|
|
48
57
|
for (const [field, keys] of Object.entries(fields)) {
|
|
49
58
|
const value = keys.map((key) => data[key]).find((value) => typeof value === 'number' && Number.isFinite(value) && value >= 0);
|
|
50
59
|
if (value !== undefined)
|
|
@@ -121,20 +130,27 @@ export class GatewaySessions {
|
|
|
121
130
|
changed(target) {
|
|
122
131
|
this.deps.channels.emit(target.sid, 'session-updated', { session_id: target.sid, source: 'native_owner' }, target.profile);
|
|
123
132
|
}
|
|
133
|
+
nativeTodo(target, snapshot) {
|
|
134
|
+
const observed = this.observations.get(target.key)?.snapshot;
|
|
135
|
+
const current = observed && (newerTodo(observed, snapshot) || observed.authority_epoch > snapshot.authority_epoch
|
|
136
|
+
|| observed.authority_epoch === snapshot.authority_epoch && observed.replay_epoch === snapshot.replay_epoch && observed.execution_generation > snapshot.execution_generation) ? observed : snapshot;
|
|
137
|
+
return Object.hasOwn(current, 'todo_state')
|
|
138
|
+
? normalizeTodoSnapshot(current.todo_state ?? { todos: [] }) : deriveTodoState(current.messages);
|
|
139
|
+
}
|
|
124
140
|
/** One shared connection, acquired by viewers and run projections, with no local Agent admission. */
|
|
125
141
|
transport(target, base, snapshot) {
|
|
126
142
|
const prior = this.observations.get(target.key);
|
|
127
143
|
if (prior && !prior.controller.signal.aborted)
|
|
128
144
|
return prior;
|
|
129
|
-
const observation = { controller: new AbortController(), snapshot, replaying: true, completion: null, listeners: new Set(), leases: 0, ended: Promise.resolve({ state: 'unavailable', reason: 'owner_connection_lost', snapshot: null, receipt: null }) };
|
|
145
|
+
const observation = { controller: new AbortController(), snapshot, todoSequence: 0, replaying: true, completion: null, listeners: new Set(), leases: 0, ended: Promise.resolve({ state: 'unavailable', reason: 'owner_connection_lost', snapshot: null, receipt: null }) };
|
|
130
146
|
this.observations.set(target.key, observation);
|
|
131
147
|
this.noticeState(target, snapshot);
|
|
132
148
|
observation.ended = (async () => {
|
|
133
|
-
const showReasoning = await this.deps.showReasoning(target.home).catch(() => false);
|
|
134
149
|
const sidecar = this.deps.sidecar();
|
|
135
150
|
if (!sidecar || observation.controller.signal.aborted)
|
|
136
151
|
return { state: 'unavailable', reason: 'sidecar_unavailable', snapshot: null, receipt: null };
|
|
137
|
-
|
|
152
|
+
// Keep reasoning available when Show changes during this observation; delivery applies the current preference.
|
|
153
|
+
return sidecar.call('gateway.session', { profile_home: target.home, session_id: target.sid, action: 'watch', show_reasoning: true }, {
|
|
138
154
|
signal: observation.controller.signal, timeoutMs: 0,
|
|
139
155
|
onStream: (frame) => {
|
|
140
156
|
if (observation.controller.signal.aborted || this.observations.get(target.key) !== observation)
|
|
@@ -143,10 +159,18 @@ export class GatewaySessions {
|
|
|
143
159
|
const result = GatewaySessionResultSchema.parse(frame.data);
|
|
144
160
|
if (result.snapshot?.session_id !== target.sid)
|
|
145
161
|
return;
|
|
162
|
+
// Reaction readback invalidates display data only. Queued native turn events still own settlement.
|
|
163
|
+
if (frame.data.reaction_only === true) {
|
|
164
|
+
this.changed(target);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
146
167
|
const completed = observation.completion?.data;
|
|
147
168
|
if (result.replay_gap || completed && (completed.authority_epoch !== result.snapshot.authority_epoch || completed.replay_epoch !== result.snapshot.replay_epoch))
|
|
148
169
|
observation.completion = null;
|
|
149
|
-
|
|
170
|
+
const prior = observation.snapshot;
|
|
171
|
+
if (!sameExecution(prior, result.snapshot))
|
|
172
|
+
observation.todoSequence = 0;
|
|
173
|
+
observation.snapshot = newerTodo(prior, result.snapshot) ? { ...result.snapshot, todo_state: prior.todo_state, last_sequence: prior.last_sequence } : result.snapshot;
|
|
150
174
|
observation.replaying = frame.data.replaying === true;
|
|
151
175
|
this.noticeState(target, result.snapshot, result.replay_gap === true);
|
|
152
176
|
if ((result.snapshot.running || result.snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started')) && !this.watches.has(target.key))
|
|
@@ -159,7 +183,23 @@ export class GatewaySessions {
|
|
|
159
183
|
else if (frame.event === 'event') {
|
|
160
184
|
const event = frame.data;
|
|
161
185
|
const data = (event.payload ?? {});
|
|
162
|
-
if (event.type === '
|
|
186
|
+
if (event.type === 'todo.updated') {
|
|
187
|
+
const snap = observation.snapshot;
|
|
188
|
+
if (event.session_id !== target.sid || event.replay_epoch !== snap.replay_epoch
|
|
189
|
+
|| event.authority_epoch !== snap.authority_epoch || event.execution_generation !== snap.execution_generation
|
|
190
|
+
|| !Number.isSafeInteger(event.seq) || Number(event.seq) <= observation.todoSequence
|
|
191
|
+
|| !Array.isArray(data.todos) || !Number.isSafeInteger(data.revision) || Number(data.revision) < 0
|
|
192
|
+
|| snap.todo_state != null && Number(data.revision) <= (snap.todo_state.revision ?? -1))
|
|
193
|
+
return;
|
|
194
|
+
// A retained event may be newer than the transcript-derived plan in an attach snapshot.
|
|
195
|
+
// Explicit null still fences all events at or before that snapshot's sequence.
|
|
196
|
+
if (Number(event.seq) <= snap.last_sequence && snap.todo_state === null)
|
|
197
|
+
return;
|
|
198
|
+
observation.todoSequence = Number(event.seq);
|
|
199
|
+
observation.snapshot = { ...snap, todo_state: { todos: data.todos, revision: Number(data.revision) }, last_sequence: Math.max(snap.last_sequence, Number(event.seq)) };
|
|
200
|
+
this.changed(target);
|
|
201
|
+
}
|
|
202
|
+
else if (event.type === 'notification.show' || event.type === 'notification.clear') {
|
|
163
203
|
const snap = observation.snapshot;
|
|
164
204
|
const state = this.noticeState(target, snap);
|
|
165
205
|
if (event.session_id !== target.sid || event.replay_epoch !== snap.replay_epoch
|
|
@@ -180,7 +220,12 @@ export class GatewaySessions {
|
|
|
180
220
|
else if (event.type === 'session.info') {
|
|
181
221
|
if (data.authority_epoch !== observation.snapshot.authority_epoch || Number(data.execution_generation) < observation.snapshot.execution_generation)
|
|
182
222
|
return;
|
|
183
|
-
|
|
223
|
+
const nextGeneration = Number(data.execution_generation) > observation.snapshot.execution_generation;
|
|
224
|
+
if (nextGeneration)
|
|
225
|
+
observation.todoSequence = 0;
|
|
226
|
+
observation.snapshot = { ...observation.snapshot, ...data,
|
|
227
|
+
...(nextGeneration && observation.snapshot.todo_state ? { todo_state: { ...observation.snapshot.todo_state, revision: 0 } } : {}),
|
|
228
|
+
};
|
|
184
229
|
if ((observation.snapshot.running || observation.snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started')) && !this.watches.has(target.key))
|
|
185
230
|
this.watch(target, base, observation.snapshot);
|
|
186
231
|
this.changed(target);
|
|
@@ -228,14 +273,20 @@ export class GatewaySessions {
|
|
|
228
273
|
signal.addEventListener('abort', release, { once: true });
|
|
229
274
|
return { release: () => { signal.removeEventListener('abort', release); release(); }, ended: observation.ended };
|
|
230
275
|
}
|
|
231
|
-
async target(sid, profile = this.deps.activeProfile()) {
|
|
276
|
+
async target(sid, profile = this.deps.activeProfile(), requireKnownOwnership = false) {
|
|
232
277
|
if (sid.length === 0 || sid !== sid.trim())
|
|
233
278
|
return null;
|
|
234
|
-
const
|
|
279
|
+
const sources = await this.deps.service.stateDbSources([sid], profile);
|
|
280
|
+
if (requireKnownOwnership && !sources)
|
|
281
|
+
throw new HttpFailure(503, 'Agent session ownership could not be verified');
|
|
282
|
+
const owner = sources?.get(sid);
|
|
235
283
|
if (typeof owner !== 'object')
|
|
236
284
|
return null;
|
|
237
|
-
if (owner.reason)
|
|
285
|
+
if (owner.reason) {
|
|
286
|
+
if (requireKnownOwnership)
|
|
287
|
+
throw new HttpFailure(403, owner.reason);
|
|
238
288
|
return null;
|
|
289
|
+
}
|
|
239
290
|
const home = this.deps.profileHome(profile);
|
|
240
291
|
return { sid, profile, home, key: JSON.stringify([home, sid]) };
|
|
241
292
|
}
|
|
@@ -247,17 +298,87 @@ export class GatewaySessions {
|
|
|
247
298
|
const result = await this.call(target, { action: 'context_detail' });
|
|
248
299
|
return profile === this.deps.activeProfile() && result.state === 'attached' && this.contextDetailKey(target, result.snapshot) === expectedKey ? result.context_detail ?? unavailableContextDetail('unsupported') : unavailableContextDetail('changed');
|
|
249
300
|
}
|
|
301
|
+
activityPhaseFor(result, target) {
|
|
302
|
+
if (result.state !== 'attached' || !result.snapshot)
|
|
303
|
+
return 'stale';
|
|
304
|
+
const pending = this.prompts(result.snapshot, target.sid, this.batch(target));
|
|
305
|
+
if (pending.approvalPending(target.sid).pending)
|
|
306
|
+
return 'waiting_for_approval';
|
|
307
|
+
if (pending.clarifyPending(target.sid).pending)
|
|
308
|
+
return 'waiting_for_input';
|
|
309
|
+
if (result.snapshot.running || result.snapshot.pending.some((entry) => entry.status === 'queued' || entry.status === 'started'))
|
|
310
|
+
return 'running';
|
|
311
|
+
return result.snapshot.pending.some((entry) => entry.status === 'unknown') ? 'stale' : null;
|
|
312
|
+
}
|
|
313
|
+
async activityPhase(sid, profile) {
|
|
314
|
+
const target = await this.target(sid, profile);
|
|
315
|
+
return target ? this.activityPhaseFor(await this.call(target, { action: 'snapshot' }), target) : undefined;
|
|
316
|
+
}
|
|
250
317
|
async isOwned(sid) { return (await this.target(sid)) !== null; }
|
|
318
|
+
/** Exact native receipt lookup for a durable queue step, never another submit. */
|
|
319
|
+
async queueReceipt(sid, admissionId) {
|
|
320
|
+
const target = await this.target(sid);
|
|
321
|
+
return target ? this.call(target, admissionId ? { action: 'receipt', admission_id: admissionId } : { action: 'snapshot' }) : null;
|
|
322
|
+
}
|
|
323
|
+
async checkpointDiff(sid) {
|
|
324
|
+
const profile = this.deps.activeProfile();
|
|
325
|
+
const target = await this.target(sid, profile);
|
|
326
|
+
if (!target)
|
|
327
|
+
return null;
|
|
328
|
+
const result = await this.call(target, { action: 'checkpoint_diff' });
|
|
329
|
+
const read = profile === this.deps.activeProfile() && result.state === 'attached' ? result.checkpoint_diff : undefined;
|
|
330
|
+
const comparison = read ? { ...read.comparison } : { provenance: 'native_owner', baseline: 'earliest_retained_project_checkpoint', available: false, reason: 'owner_unavailable', truncated: false };
|
|
331
|
+
if (read && (Buffer.byteLength(JSON.stringify(read.diff), 'utf8') + Buffer.byteLength(JSON.stringify(read.stat), 'utf8') - 4 > CHECKPOINT_DIFF_MAX_BYTES)) {
|
|
332
|
+
comparison.available = false;
|
|
333
|
+
comparison.reason = 'payload_too_large';
|
|
334
|
+
}
|
|
335
|
+
const diff = comparison.available ? read?.diff ?? '' : '';
|
|
336
|
+
const files = checkpointDiffFiles(diff);
|
|
337
|
+
return { checkpoint: 'earliest-retained', workspace: '', diff: diff.trimEnd(), files_changed: files, total_changes: files.length, comparison };
|
|
338
|
+
}
|
|
339
|
+
terminalKey(target, snap) {
|
|
340
|
+
return ownerStateId(JSON.stringify([target.key, snap.session_id, snap.authority_epoch, snap.replay_epoch, snap.info.cwd]));
|
|
341
|
+
}
|
|
342
|
+
async terminal(sid) {
|
|
343
|
+
const target = await this.target(sid, this.deps.activeProfile(), true);
|
|
344
|
+
if (!target)
|
|
345
|
+
return null;
|
|
346
|
+
const result = await this.call(target, { action: 'terminal_info' });
|
|
347
|
+
const snap = result.snapshot;
|
|
348
|
+
if (target.profile !== this.deps.activeProfile() || result.state !== 'attached' || snap?.session_id !== sid)
|
|
349
|
+
throw new HttpFailure(409, 'The native owner cannot run captured commands. Reopen the terminal after checking the gateway.', { code: 'owner_shell_unavailable' });
|
|
350
|
+
return { target, snap, key: this.terminalKey(target, snap) };
|
|
351
|
+
}
|
|
352
|
+
async capturedCommand(sid, key, command) {
|
|
353
|
+
const selected = await this.terminal(sid);
|
|
354
|
+
if (key !== selected?.key)
|
|
355
|
+
throw new HttpFailure(409, 'The native owner changed. Reopen the terminal before running a command.');
|
|
356
|
+
const { target, snap } = selected;
|
|
357
|
+
const result = await this.call(target, { action: 'shell_exec', command, authority_epoch: snap.authority_epoch, replay_epoch: snap.replay_epoch });
|
|
358
|
+
if (result.state !== 'attached' || !result.shell) {
|
|
359
|
+
// Only allowlisted native policy refusals are safe to show. A transport failure may have executed.
|
|
360
|
+
const messages = {
|
|
361
|
+
unsupported_terminal_backend: 'Captured commands require the native owner’s local terminal backend.',
|
|
362
|
+
cwd_unavailable: 'The native workspace no longer exists.', dangerous_command: 'The native owner refused this command.',
|
|
363
|
+
permission_denied: 'The native owner denied this command.', command_timeout: 'The command timed out on the native owner.',
|
|
364
|
+
owner_changed: 'The native owner changed. Reopen the terminal.',
|
|
365
|
+
};
|
|
366
|
+
throw new HttpFailure(409, messages[result.reason ?? ''] ?? 'The command outcome is unknown. Check the native workspace before running it again.', { code: 'owner_shell_failed' });
|
|
367
|
+
}
|
|
368
|
+
return { stdout: redactString(result.shell.stdout, true), stderr: redactString(result.shell.stderr, true), code: result.shell.code };
|
|
369
|
+
}
|
|
251
370
|
async export(sid, format) {
|
|
252
371
|
const target = await this.target(sid);
|
|
253
372
|
if (!target)
|
|
254
373
|
return null;
|
|
255
374
|
const redact = this.deps.redactEnabled();
|
|
256
|
-
const
|
|
375
|
+
const show = await this.deps.showReasoning(target.home).catch(() => false);
|
|
376
|
+
const requestedFormat = show ? format : 'json';
|
|
377
|
+
const result = await this.call(target, { action: 'export', format: requestedFormat, redact });
|
|
257
378
|
const value = result.export;
|
|
258
379
|
if (result.reason === 'export_too_large')
|
|
259
380
|
throw new HttpFailure(413, 'The owner transcript exceeds the export limit');
|
|
260
|
-
if (result.state !== 'attached' || value?.format !==
|
|
381
|
+
if (result.state !== 'attached' || value?.format !== requestedFormat) {
|
|
261
382
|
throw new HttpFailure(409, 'The Agent owner cannot export this chat. Check that its gateway is running and supports transcript export.', { code: 'owner_export_unavailable' });
|
|
262
383
|
}
|
|
263
384
|
if (Buffer.byteLength(value.content, 'utf8') > OWNER_EXPORT_MAX_BYTES)
|
|
@@ -265,16 +386,21 @@ export class GatewaySessions {
|
|
|
265
386
|
let content;
|
|
266
387
|
try {
|
|
267
388
|
// The owner redacts HTML's structured transcript before rendering. A shell/text redactor corrupts its markup.
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
:
|
|
389
|
+
if (!show) {
|
|
390
|
+
const document = reasoningProjection(redactNestedMessageContainers(JSON.parse(value.content), redact), false);
|
|
391
|
+
content = format === 'html' ? renderSessionHtml(document) : format === 'markdown' ? renderSessionMarkdown(document) : JSON.stringify(document, null, 2);
|
|
392
|
+
}
|
|
393
|
+
else
|
|
394
|
+
content = format === 'html' ? wrapExportHtml(value.content) : format === 'json'
|
|
395
|
+
? JSON.stringify(redactNestedMessageContainers(JSON.parse(value.content), redact), null, 2)
|
|
396
|
+
: redactString(value.content, redact);
|
|
271
397
|
}
|
|
272
398
|
catch {
|
|
273
399
|
throw new HttpFailure(409, 'The Agent owner returned an invalid transcript export', { code: 'owner_export_invalid' });
|
|
274
400
|
}
|
|
275
401
|
if (Buffer.byteLength(content, 'utf8') > OWNER_EXPORT_MAX_BYTES)
|
|
276
402
|
throw new HttpFailure(413, 'The owner transcript exceeds the export limit');
|
|
277
|
-
return { ...value, content };
|
|
403
|
+
return { ...value, format, content };
|
|
278
404
|
}
|
|
279
405
|
async createCall(params) {
|
|
280
406
|
const sidecar = this.deps.sidecar();
|
|
@@ -292,7 +418,7 @@ export class GatewaySessions {
|
|
|
292
418
|
const result = await this.createCall({ profile_home: this.deps.profileHome(profile), probe: true });
|
|
293
419
|
const reason = result.state === 'attached' ? null : unavailableReason(result);
|
|
294
420
|
// Owner chats take no file attachments (`submit` refuses them), so a fresh chat in either bypass mode cannot attach.
|
|
295
|
-
return { modes: [{ mode: 'normal', available: true, reason: null, can_attach: true }, ...['ignore_config', 'safe'].map((mode) => ({ mode, available: reason === null, reason, can_attach: false }))] };
|
|
421
|
+
return { modes: [{ mode: 'normal', available: true, reason: null, can_attach: true, can_reference: true }, ...['ignore_config', 'safe'].map((mode) => ({ mode, available: reason === null, reason, can_attach: false, can_reference: false }))] };
|
|
296
422
|
}
|
|
297
423
|
/**
|
|
298
424
|
* TAL-1040: the owner mints a diagnostic chat, freezes its bypass in the creation receipt and runs each turn in a fresh
|
|
@@ -315,7 +441,7 @@ export class GatewaySessions {
|
|
|
315
441
|
if (modelMutation)
|
|
316
442
|
this.modelMutations.set(target.key, (this.modelMutations.get(target.key) ?? 0) + 1);
|
|
317
443
|
try {
|
|
318
|
-
const result = await sidecar.call('gateway.session', { ...params, profile_home: target.home, session_id: target.sid }, { timeoutMs: params.action === 'mutate' ? 675_000 : 35_000, ...(signal ? { signal } : {}) });
|
|
444
|
+
const result = await sidecar.call('gateway.session', { ...params, profile_home: target.home, session_id: target.sid }, { timeoutMs: params.action === 'mutate' ? 675_000 : params.action === 'shell_exec' ? 40_000 : 35_000, ...(signal ? { signal } : {}) });
|
|
319
445
|
if (params.action === 'mutate' && params.operation === 'model' && result.snapshot) {
|
|
320
446
|
const change = modelChange(result.receipt ?? {}, params.payload);
|
|
321
447
|
// The stream can resolve a deferred pick before its HTTP ACK returns. Keep the later observation.
|
|
@@ -362,13 +488,39 @@ export class GatewaySessions {
|
|
|
362
488
|
contextDetailKey(target, snapshot) {
|
|
363
489
|
return snapshot ? ownerStateId(JSON.stringify([target.key, snapshot.authority_epoch, snapshot.replay_epoch, snapshot.revision, snapshot.execution_generation, snapshot.info, snapshot.last_sequence])) : null;
|
|
364
490
|
}
|
|
491
|
+
reactionView(row, allowed) {
|
|
492
|
+
if (!Number.isSafeInteger(row.row_id) || Number(row.row_id) <= 0 || !['user', 'assistant'].includes(str(row.role)))
|
|
493
|
+
return undefined;
|
|
494
|
+
const authors = new Map();
|
|
495
|
+
for (const raw of Array.isArray(row.reactions) ? row.reactions : []) {
|
|
496
|
+
const reaction = raw;
|
|
497
|
+
const emoji = ReactionEmojiSchema.safeParse(reaction?.emoji);
|
|
498
|
+
if (emoji.success && (reaction.author === 'user' || reaction.author === 'agent'))
|
|
499
|
+
authors.set(reaction.author, emoji.data);
|
|
500
|
+
}
|
|
501
|
+
const state = (selected) => {
|
|
502
|
+
const values = [authors.get('agent'), selected].filter((emoji) => emoji !== undefined && emoji !== null);
|
|
503
|
+
return { selected, items: ReactionEmojiSchema.options.flatMap((emoji) => {
|
|
504
|
+
const count = values.filter((value) => value === emoji).length;
|
|
505
|
+
return count ? [{ emoji, count, mine: selected === emoji }] : [];
|
|
506
|
+
}) };
|
|
507
|
+
};
|
|
508
|
+
const selected = authors.get('user') ?? null;
|
|
509
|
+
return { row_id: Number(row.row_id), state: state(selected), actions: allowed
|
|
510
|
+
? [...ReactionEmojiSchema.options, ...(selected ? [null] : [])].map((emoji) => ({ emoji, result: state(emoji === selected ? null : emoji) })) : [] };
|
|
511
|
+
}
|
|
365
512
|
async view(base, result, stream, target, limit = 120, before = null, withMessages = true) {
|
|
366
513
|
const snapshot = result.snapshot;
|
|
367
|
-
const
|
|
514
|
+
const showReasoning = await this.deps.service.deps.showReasoning?.(target.profile) ?? true;
|
|
515
|
+
const fields = { ...base, plan_gauge: snapshot?.plan_gauge ?? null, show_reasoning: showReasoning, owner_attachment: this.attachment({ ...result, model_change: this.currentModelChange(target, snapshot) }), composer_state_key: ownerStateId(target.key), context_detail_key: this.contextDetailKey(target, snapshot), active_stream_id: stream, is_streaming: Boolean(stream) };
|
|
368
516
|
if (snapshot) {
|
|
369
517
|
fields.notices = this.nativeNotices(target, snapshot);
|
|
518
|
+
fields.todo_state = this.nativeTodo(target, snapshot) ?? normalizeTodoSnapshot({ todos: [] });
|
|
370
519
|
const observed = this.watches.get(target.key)?.snapshot;
|
|
371
|
-
const
|
|
520
|
+
const canReact = snapshot.reactions_supported === true && this.attachment(result).can_submit;
|
|
521
|
+
const nativeRows = snapshot.messages.map(({ reactions, ...row }) => ({ ...row,
|
|
522
|
+
reaction_view: this.reactionView({ ...row, reactions }, canReact),
|
|
523
|
+
}));
|
|
372
524
|
const active = stream ? runningAdmission(snapshot) : null;
|
|
373
525
|
let start = active ? nativeRows.findIndex((m) => m.role === 'user' && m.message_id === active.admission_id) : -1;
|
|
374
526
|
if (active && stream && start < 0) {
|
|
@@ -376,7 +528,7 @@ export class GatewaySessions {
|
|
|
376
528
|
nativeRows.push({ ...pendingUserRow(active.text ?? '', [], null, str(snapshot.info.source) || 'gateway', stream), message_id: active.admission_id });
|
|
377
529
|
}
|
|
378
530
|
const messages = start < 0 ? nativeRows : nativeRows.map((row, index) => index >= start ? { ...row, _turn_id: stream } : row);
|
|
379
|
-
const projected = withMessages ? this.deps.service.foreignMessages(messages, base) : [];
|
|
531
|
+
const projected = withMessages ? this.deps.service.foreignMessages(messages, base, showReasoning) : [];
|
|
380
532
|
const [rows, offset] = messageWindowForDisplay(projected, limit, before);
|
|
381
533
|
const model = str(snapshot.info.model) || str(base.model) || null;
|
|
382
534
|
const provider = Object.hasOwn(snapshot.info, 'provider')
|
|
@@ -411,7 +563,7 @@ export class GatewaySessions {
|
|
|
411
563
|
return this.view(base, result, watch?.stream ?? null, target, limit, before, withMessages);
|
|
412
564
|
}
|
|
413
565
|
/** Called before the direct-chat admission path, including for an already materialized foreign session. */
|
|
414
|
-
async submit(sid, body, timing) {
|
|
566
|
+
async submit(sid, body, timing, fence) {
|
|
415
567
|
const target = await this.target(sid);
|
|
416
568
|
if (!target)
|
|
417
569
|
return null;
|
|
@@ -431,6 +583,8 @@ export class GatewaySessions {
|
|
|
431
583
|
throw new HttpFailure(400, 'File attachments are unavailable through this owner connection', { code: 'owner_attachments_unavailable' });
|
|
432
584
|
// Resolve display state before admission; a failed post-ACK read must never turn accepted work into a refusal.
|
|
433
585
|
const base = await (timing ? timing.measure('owner_detail', () => this.deps.service.detail(sid, {})) : this.deps.service.detail(sid, {}));
|
|
586
|
+
if (fence && (!this.deps.service.deps.profilesMatch(str(base.profile) || null, fence.profile) || (str(base.project_id) || null) !== fence.project_id || before.snapshot?.authority_epoch !== fence.authority_epoch || before.snapshot.running || before.snapshot.pending.some((p) => p.status !== 'terminal')))
|
|
587
|
+
throw new HttpFailure(409, 'Queue target changed or is busy');
|
|
434
588
|
const closeSubmit = timing?.begin('owner_submit');
|
|
435
589
|
const result = await this.call(target, { action: 'submit', request_id: body.submission_id, text });
|
|
436
590
|
closeSubmit?.(result.receipt ? 'ok' : result.state === 'unavailable' ? 'unknown' : 'refused');
|
|
@@ -461,9 +615,24 @@ export class GatewaySessions {
|
|
|
461
615
|
throw new HttpFailure(400, 'The workspace must be trusted before selecting it');
|
|
462
616
|
}
|
|
463
617
|
}
|
|
464
|
-
|
|
618
|
+
if (params.action === 'react') {
|
|
619
|
+
const current = await this.call(target, { action: 'snapshot' });
|
|
620
|
+
const row = current.snapshot?.messages.find((row) => row.row_id === params.row_id);
|
|
621
|
+
if (!row || current.snapshot?.reactions_supported !== true || !this.attachment(current).can_submit
|
|
622
|
+
|| !['user', 'assistant'].includes(str(row.role)))
|
|
623
|
+
throw new HttpFailure(409, 'Reactions are unavailable for this message');
|
|
624
|
+
}
|
|
625
|
+
let result = await this.call(target, params);
|
|
626
|
+
if (params.action === 'react' && result.state === 'unavailable') {
|
|
627
|
+
// A toggle has no idempotency key. Read the owner after a lost ACK; never replay the write.
|
|
628
|
+
result = await this.call(target, { action: 'snapshot' });
|
|
629
|
+
if (result.state !== 'attached' || !result.snapshot)
|
|
630
|
+
throw new HttpFailure(503, 'Could not confirm the reaction. Reconnect to read its current value.', { outcome_unknown: true });
|
|
631
|
+
}
|
|
465
632
|
if (result.state !== 'attached' || !result.snapshot)
|
|
466
633
|
throw new HttpFailure(409, 'The owning Agent refused the action', { owner_attachment: this.attachment(result) });
|
|
634
|
+
if (params.action === 'react')
|
|
635
|
+
this.changed(target);
|
|
467
636
|
this.deps.events.publish('owner_changed', { profile: target.profile, sessionId: sid });
|
|
468
637
|
return result;
|
|
469
638
|
}
|
|
@@ -600,6 +769,8 @@ export class GatewaySessions {
|
|
|
600
769
|
const registry = this.deps.registry;
|
|
601
770
|
const channel = registry.create(watch.stream, target.sid);
|
|
602
771
|
registry.registerActiveRun({ stream_id: watch.stream, session_id: target.sid, phase: 'running', started_at: this.deps.now(), workspace: str(base.workspace), model: str(base.model) || null, provider: null, ephemeral: false, origin: 'user' });
|
|
772
|
+
// TAL-1564: the sidebar row turns streaming now, including for an idle observation whose owner just started a run.
|
|
773
|
+
this.deps.events.publish('owner_changed', { profile: target.profile, sessionId: target.sid });
|
|
603
774
|
let chain = Promise.resolve();
|
|
604
775
|
let terminal = false;
|
|
605
776
|
let streamError = null;
|
|
@@ -615,9 +786,9 @@ export class GatewaySessions {
|
|
|
615
786
|
const journalSession = ownerStateId(target.key);
|
|
616
787
|
const writer = await this.deps.journal.writer(journalSession, watch.stream);
|
|
617
788
|
closeWriter = writer;
|
|
618
|
-
const showReasoning = await this.deps.showReasoning(target.home).catch(() => false);
|
|
619
789
|
let completion = null;
|
|
620
790
|
let replaying = true;
|
|
791
|
+
let liveRunning = false;
|
|
621
792
|
let usage = {};
|
|
622
793
|
let reasoning = '';
|
|
623
794
|
let titles = new ReasoningTitleTracker();
|
|
@@ -638,9 +809,9 @@ export class GatewaySessions {
|
|
|
638
809
|
await put('tool_progress', { id: call.tid, progress: null });
|
|
639
810
|
calls.length = 0;
|
|
640
811
|
};
|
|
641
|
-
const resetProjection = async () => { await clearTools(); reasoning = ''; usage = {}; completion = null; titles = new ReasoningTitleTracker(); };
|
|
642
|
-
const meter = async (data) => {
|
|
643
|
-
usage = { ...usage, ...ownerUsage(data) };
|
|
812
|
+
const resetProjection = async () => { await clearTools(); liveRunning = false; reasoning = ''; usage = {}; completion = null; titles = new ReasoningTitleTracker(); };
|
|
813
|
+
const meter = async (data, complete = false) => {
|
|
814
|
+
usage = { ...usage, ...ownerUsage(data, complete) };
|
|
644
815
|
if (['input_tokens', 'output_tokens', 'cache_read_tokens', 'cache_write_tokens'].every((key) => typeof usage[key] === 'number'))
|
|
645
816
|
await put('metering', { session_id: target.sid, usage: { ...usage, estimated_cost: usage.estimated_cost ?? null }, tps: usage.tps ?? null, tps_available: usage.tps !== undefined, estimated: false });
|
|
646
817
|
};
|
|
@@ -652,7 +823,7 @@ export class GatewaySessions {
|
|
|
652
823
|
// A new claim may arrive while this turn's receipt is being read. Give it its own projection immediately.
|
|
653
824
|
if (this.watches.get(target.key) === watch)
|
|
654
825
|
this.watches.delete(target.key);
|
|
655
|
-
registry.
|
|
826
|
+
registry.activeRuns.delete(watch.stream);
|
|
656
827
|
await clearTools();
|
|
657
828
|
const current = await this.call(target, { action: 'snapshot' });
|
|
658
829
|
const rawReceipt = activeAdmission ? (await this.call(target, { action: 'receipt', admission_id: activeAdmission })).receipt : null;
|
|
@@ -666,11 +837,17 @@ export class GatewaySessions {
|
|
|
666
837
|
// A terminal frame for the previous generation must not overwrite the newer turn's state.
|
|
667
838
|
const session = current.snapshot && !sameExecution(current.snapshot, observation.snapshot)
|
|
668
839
|
? undefined : { ...await this.view(base, current, null, target), ...usage };
|
|
840
|
+
if (session)
|
|
841
|
+
session.activity_phase = await this.deps.service.deps.sessionActivity?.(target.sid, target.profile, { terminalPhase: cancelled ? 'cancelled' : failed ? 'failed' : 'completed' });
|
|
669
842
|
await put(cancelled ? 'cancel' : failed ? 'apperror' : 'done', { session_id: target.sid,
|
|
670
843
|
terminal_state: cancelled ? 'cancelled' : failed ? 'error' : 'completed',
|
|
671
844
|
...(failed ? refusal ?? { message: 'The owning Agent could not complete this turn', type: current.reason ?? 'owner_turn_failed' } : {}),
|
|
672
845
|
...(Object.keys(usage).length ? { usage } : {}),
|
|
673
846
|
...(session ? { session } : {}) });
|
|
847
|
+
if (liveRunning && !cancelled && !failed && receipt?.admission_id === activeAdmission && receipt?.authority_epoch === watch.snapshot.authority_epoch
|
|
848
|
+
&& receipt.execution_generation === watch.snapshot.execution_generation) {
|
|
849
|
+
this.deps.onWebCompletion?.(target.profile, target.sid, JSON.stringify(['owner', target.sid, watch.snapshot.authority_epoch, watch.snapshot.replay_epoch, watch.snapshot.execution_generation, receipt.admission_id]));
|
|
850
|
+
}
|
|
674
851
|
await put('stream_end', { session_id: target.sid });
|
|
675
852
|
watch.controller.abort();
|
|
676
853
|
};
|
|
@@ -700,6 +877,7 @@ export class GatewaySessions {
|
|
|
700
877
|
enqueue(async () => {
|
|
701
878
|
if (frame.event === 'replay_complete') {
|
|
702
879
|
replaying = false;
|
|
880
|
+
liveRunning ||= watch.snapshot.running;
|
|
703
881
|
if (!watch.snapshot.running && !watch.snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started'))
|
|
704
882
|
await finish();
|
|
705
883
|
return;
|
|
@@ -719,12 +897,15 @@ export class GatewaySessions {
|
|
|
719
897
|
if (frame.event === 'snapshot') {
|
|
720
898
|
const result = GatewaySessionResultSchema.parse(frame.data);
|
|
721
899
|
replaying = frame.data.replaying === true;
|
|
900
|
+
if (replaying)
|
|
901
|
+
liveRunning = false;
|
|
722
902
|
if (!result.snapshot)
|
|
723
903
|
return;
|
|
724
904
|
if (result.replay_gap || !sameExecution(result.snapshot, watch.snapshot))
|
|
725
905
|
await resetProjection();
|
|
726
906
|
await put('session_snapshot', { session: await this.view(base, result, watch.stream, target), replay_gap: result.replay_gap === true });
|
|
727
907
|
await prompts(result.snapshot);
|
|
908
|
+
liveRunning ||= !replaying && result.snapshot.running;
|
|
728
909
|
if (!result.snapshot.running && !result.snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started'))
|
|
729
910
|
await finish();
|
|
730
911
|
return;
|
|
@@ -736,6 +917,10 @@ export class GatewaySessions {
|
|
|
736
917
|
await put('notices', { session_id: target.sid, notices: this.nativeNotices(target, observation.snapshot) });
|
|
737
918
|
return;
|
|
738
919
|
}
|
|
920
|
+
if (kind === 'todo.updated') {
|
|
921
|
+
await put('todo_state', { ...normalizeTodoSnapshot(data), session_id: target.sid, stream_id: watch.stream, source: 'live' });
|
|
922
|
+
return;
|
|
923
|
+
}
|
|
739
924
|
if (kind === 'request.cancel') {
|
|
740
925
|
// The owner withdraws a settled, timed-out or interrupted batch from every viewer.
|
|
741
926
|
if (!watch.batch || watch.batch.request_id !== data.id)
|
|
@@ -776,6 +961,7 @@ export class GatewaySessions {
|
|
|
776
961
|
if (firstClaim && claimed)
|
|
777
962
|
activeAdmission = claimed.admission_id;
|
|
778
963
|
ran ||= data.running === true;
|
|
964
|
+
liveRunning ||= !replaying && data.running === true;
|
|
779
965
|
if (firstClaim)
|
|
780
966
|
await put('session_snapshot', { session: await this.view(base, { state: 'attached', reason: null, snapshot: watch.snapshot, receipt: null, restarting: watch.restarting }, watch.stream, target) });
|
|
781
967
|
if (data.running === false && (ran || !watch.snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started')))
|
|
@@ -786,18 +972,20 @@ export class GatewaySessions {
|
|
|
786
972
|
return;
|
|
787
973
|
if (kind === 'message.delta') {
|
|
788
974
|
const stable = titles.stableSnapshot(reasoning);
|
|
789
|
-
if (stable !== null)
|
|
975
|
+
if (stable !== null && await this.deps.showReasoning(target.home).catch(() => false))
|
|
790
976
|
await put('reasoning', { text: '', titles: stable });
|
|
791
977
|
await put('token', { text: str(data.text || data.delta || data.content) });
|
|
792
978
|
}
|
|
793
|
-
else if (kind === 'reasoning.delta'
|
|
979
|
+
else if (kind === 'reasoning.delta') {
|
|
794
980
|
reasoning += str(data.text);
|
|
795
|
-
|
|
981
|
+
if (await this.deps.showReasoning(target.home).catch(() => false))
|
|
982
|
+
await put('reasoning', titles.prepare(reasoningEventPayload(data.text, reasoning)));
|
|
796
983
|
}
|
|
797
984
|
else if (kind.startsWith('subagent.') && str(data.subagent_id)) {
|
|
798
985
|
// Reuse the delegate activity row; each child keeps one identity through progress and completion.
|
|
799
986
|
const complete = kind === 'subagent.complete';
|
|
800
|
-
const
|
|
987
|
+
const visible = kind !== 'subagent.thinking' || await this.deps.showReasoning(target.home).catch(() => false);
|
|
988
|
+
const preview = visible ? str(data.summary || data.tool_preview || data.text) : '';
|
|
801
989
|
await put(complete ? 'tool_complete' : 'tool', { id: `owner-subagent-${str(data.subagent_id)}`, name: 'subagent_progress',
|
|
802
990
|
args: { task: str(data.goal) }, preview: preview || null,
|
|
803
991
|
...(complete ? { is_error: data.status !== 'completed', duration: data.duration_seconds } : {}) });
|
|
@@ -815,7 +1003,7 @@ export class GatewaySessions {
|
|
|
815
1003
|
completion = { admission: activeAdmission, message: data.text, type: 'cron_session_read_only', code: 'cron_session_read_only', retryable: false };
|
|
816
1004
|
}
|
|
817
1005
|
if (data.usage && typeof data.usage === 'object')
|
|
818
|
-
await meter(data.usage);
|
|
1006
|
+
await meter(data.usage, true);
|
|
819
1007
|
}
|
|
820
1008
|
else if (kind === 'tool.start' || kind === 'tool.progress' || kind === 'tool.complete') {
|
|
821
1009
|
if (event.session_id !== target.sid || event.replay_epoch !== undefined && event.replay_epoch !== watch.snapshot.replay_epoch)
|