@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
|
@@ -164,12 +164,15 @@ def snapshot(entry, *, records=None, expected=None):
|
|
|
164
164
|
from gateway.status import get_process_start_time, _pid_exists
|
|
165
165
|
service, pid = entry.get('service_pid', entry['pid']), entry['pid']
|
|
166
166
|
anchors = {service, pid}
|
|
167
|
-
observed =
|
|
167
|
+
observed = {**entry.get('departed_processes', {}), **(expected or {})}
|
|
168
168
|
seen_parents = {int(p): proof['parent'] for p, proof in observed.items() if 'parent' in proof}
|
|
169
|
-
departed = set()
|
|
169
|
+
departed = set(map(int, entry.get('departed_processes', {})))
|
|
170
170
|
|
|
171
171
|
def exited(p):
|
|
172
|
-
|
|
172
|
+
live = _pid_exists(p)
|
|
173
|
+
if live is None:
|
|
174
|
+
raise RuntimeError(f'{_name(entry)} process {p} liveness is unreadable; source was not changed.')
|
|
175
|
+
if live is False:
|
|
173
176
|
if p in anchors:
|
|
174
177
|
raise RuntimeError(f'{_name(entry)} anchor process {p} disappeared during discovery; source was not changed.')
|
|
175
178
|
departed.add(p)
|
|
@@ -179,7 +182,7 @@ def snapshot(entry, *, records=None, expected=None):
|
|
|
179
182
|
def inventory():
|
|
180
183
|
parents = _process_table()
|
|
181
184
|
if service not in _ancestors(pid, parents):
|
|
182
|
-
raise RuntimeError(f'{_name(entry)} does not own backend/gateway PID {pid}.')
|
|
185
|
+
raise RuntimeError(f'{_name(entry)} identity/ancestry changed: does not own backend/gateway PID {pid}.')
|
|
183
186
|
if service in _ancestors(os.getpid(), parents):
|
|
184
187
|
raise RuntimeError(f'{_name(entry)} owns the updater or an ancestor; source was not changed.')
|
|
185
188
|
for p, parent in seen_parents.items():
|
|
@@ -188,6 +191,10 @@ def snapshot(entry, *, records=None, expected=None):
|
|
|
188
191
|
continue
|
|
189
192
|
raise RuntimeError(f'{_name(entry)} process {p} identity/ancestry changed during discovery; source was not changed.')
|
|
190
193
|
descendants = _descendants(service, parents)
|
|
194
|
+
# Successor retries cannot discard a live writer from a previously observed tree.
|
|
195
|
+
for p in seen_parents.keys() - descendants - departed:
|
|
196
|
+
if not exited(p):
|
|
197
|
+
raise RuntimeError(f'{_name(entry)} process {p} remains live outside the attested tree; recovery remains owed.')
|
|
191
198
|
seen_parents.update({p: parents[p] for p in descendants})
|
|
192
199
|
# Zombies may remain in ps. Recheck departed PIDs at every inventory so
|
|
193
200
|
# neither a recycled PID nor unknown liveness can be silently excluded.
|
|
@@ -205,6 +212,8 @@ def snapshot(entry, *, records=None, expected=None):
|
|
|
205
212
|
if exited(p):
|
|
206
213
|
return None
|
|
207
214
|
raise RuntimeError(f'{_name(entry)} process {p} birth identity is live or unreadable; source was not changed.')
|
|
215
|
+
if exited(p):
|
|
216
|
+
return None
|
|
208
217
|
if any(proof.get(key) != value for key, value in observed.get(str(p), {}).items()):
|
|
209
218
|
raise RuntimeError(f'{_name(entry)} process {p} identity/ancestry changed during discovery; source was not changed.')
|
|
210
219
|
observed[str(p)] = proof
|
|
@@ -219,6 +228,8 @@ def snapshot(entry, *, records=None, expected=None):
|
|
|
219
228
|
_, final = inventory()
|
|
220
229
|
if live & departed or remaining != live or final != live:
|
|
221
230
|
continue
|
|
231
|
+
if departed:
|
|
232
|
+
entry['departed_processes'] = {str(p): observed.get(str(p), {'parent': seen_parents[p]}) for p in departed}
|
|
222
233
|
return proofs
|
|
223
234
|
raise RuntimeError(f'{_name(entry)} process inventory kept changing after {SNAPSHOT_ATTEMPTS} samples; retry when descendants settle. Source was not changed and recovery remains owed.')
|
|
224
235
|
|
|
@@ -403,8 +414,23 @@ def _service_pid(entry):
|
|
|
403
414
|
|
|
404
415
|
def verify_processes(entry, records, *, stopping=False, fenced=False):
|
|
405
416
|
from gateway.status import get_process_start_time, _pid_exists
|
|
417
|
+
if not stopping:
|
|
418
|
+
# Reuse discovery's bounded proof without granting permission to lose an anchor.
|
|
419
|
+
candidate = dict(entry)
|
|
420
|
+
for boundary in range(2):
|
|
421
|
+
_, service_pid = _service_pid(entry)
|
|
422
|
+
if service_pid != entry['service_pid']:
|
|
423
|
+
raise RuntimeError(f'{_name(entry)} supervisor respawned during quiescence; source was not changed.')
|
|
424
|
+
if 'config_stamp' in entry and _config_stamp(entry) != entry['config_stamp']:
|
|
425
|
+
raise RuntimeError(f'{_name(entry)} service configuration changed; recovery remains owed.')
|
|
426
|
+
if boundary == 0:
|
|
427
|
+
candidate['processes'] = snapshot(candidate, records=records, expected=entry['processes'])
|
|
428
|
+
entry.update(processes=candidate['processes'])
|
|
429
|
+
if candidate.get('departed_processes'):
|
|
430
|
+
entry['departed_processes'] = candidate['departed_processes']
|
|
431
|
+
return True
|
|
406
432
|
parents = _process_table()
|
|
407
|
-
departed = set()
|
|
433
|
+
departed = set(map(int, entry.get('departed_processes', {})))
|
|
408
434
|
for pid, expected in entry['processes'].items():
|
|
409
435
|
pid = int(pid)
|
|
410
436
|
if _pid_exists(pid) is False:
|
|
@@ -442,7 +468,6 @@ def verify_processes(entry, records, *, stopping=False, fenced=False):
|
|
|
442
468
|
|
|
443
469
|
def bind_processes(entry, records):
|
|
444
470
|
if entry.get('processes'):
|
|
445
|
-
entry['processes'] = snapshot(entry, records=records, expected=entry['processes'])
|
|
446
471
|
verify_processes(entry, records)
|
|
447
472
|
|
|
448
473
|
|
|
@@ -713,8 +738,20 @@ class ServiceRecovery:
|
|
|
713
738
|
or ('runtime_revision' in transaction and not re.fullmatch(r'[a-f0-9]{40}', str(transaction['runtime_revision'])))):
|
|
714
739
|
raise RuntimeError('Service recovery transaction has an unknown identity or format; its evidence is retained.')
|
|
715
740
|
|
|
741
|
+
operation = self.state.get('update_operation')
|
|
742
|
+
if operation is not None and (
|
|
743
|
+
not isinstance(operation, dict)
|
|
744
|
+
or not re.fullmatch(r'[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}', str(operation.get('operation_id', '')))
|
|
745
|
+
or any(not re.fullmatch(r'[a-f0-9]{40}', str(operation.get(key, ''))) for key in ('baseline_revision', 'target_revision'))
|
|
746
|
+
or ('attempt_error' in operation and (not isinstance(operation['attempt_error'], str) or len(operation['attempt_error']) > 2000))
|
|
747
|
+
or ('source_moved' in operation and not isinstance(operation['source_moved'], bool))
|
|
748
|
+
or ('failed_stage' in operation and operation['failed_stage'] not in {'install', 'gateway_restart', 'agent_ready'})
|
|
749
|
+
or operation.get('stage') not in {'install', 'gateway_restart', 'agent_ready'}
|
|
750
|
+
or ('recovered_revision' in operation and not re.fullmatch(r'[a-f0-9]{40}', str(operation['recovered_revision'])))):
|
|
751
|
+
raise RuntimeError('Update operation correlation is malformed; its evidence is retained.')
|
|
752
|
+
|
|
716
753
|
def save(self, token=None):
|
|
717
|
-
if not self.state['entries'] and not self.state.get('sync_failed') and not self.state.get('transaction'):
|
|
754
|
+
if not self.state['entries'] and not self.state.get('sync_failed') and not self.state.get('transaction') and not self.state.get('update_operation'):
|
|
718
755
|
if self.path.exists():
|
|
719
756
|
self.path.unlink()
|
|
720
757
|
self._sync_directory()
|
|
@@ -734,9 +771,9 @@ class ServiceRecovery:
|
|
|
734
771
|
with contextlib.suppress(FileNotFoundError):
|
|
735
772
|
os.unlink(temporary)
|
|
736
773
|
|
|
737
|
-
def _sync_directory(self):
|
|
774
|
+
def _sync_directory(self, directory=None):
|
|
738
775
|
if os.name != 'nt':
|
|
739
|
-
fd = os.open(self.path.parent, os.O_RDONLY)
|
|
776
|
+
fd = os.open(directory if directory is not None else self.path.parent, os.O_RDONLY)
|
|
740
777
|
try:
|
|
741
778
|
os.fsync(fd)
|
|
742
779
|
finally:
|
|
@@ -767,10 +804,17 @@ class ServiceRecovery:
|
|
|
767
804
|
self.records.write(token)
|
|
768
805
|
self.save(token)
|
|
769
806
|
|
|
807
|
+
def verify_processes(self, entry, **permissions):
|
|
808
|
+
owed = next(e for e in self.state['entries'] if _service_key(e) == _service_key(entry))
|
|
809
|
+
result = verify_processes(owed, self.records, **permissions)
|
|
810
|
+
self.save() # Updated custody must precede the next lifecycle effect.
|
|
811
|
+
return result
|
|
812
|
+
|
|
770
813
|
def stop(self, entry, stopped):
|
|
771
814
|
owed = next(e for e in self.state['entries'] if _service_key(e) == _service_key(entry))
|
|
772
|
-
verify_processes(owed
|
|
815
|
+
self.verify_processes(owed)
|
|
773
816
|
backend_request(owed)
|
|
817
|
+
self.verify_processes(owed)
|
|
774
818
|
permit = backend_request(owed, 'prepare')
|
|
775
819
|
if permit.get('ok') is not True or permit.get('idle') is not True or not isinstance(permit.get('token'), str):
|
|
776
820
|
if owed['phase'] == 'recorded':
|
|
@@ -783,7 +827,7 @@ class ServiceRecovery:
|
|
|
783
827
|
except BaseException:
|
|
784
828
|
backend_request(owed, 'cancel', permit['token'])
|
|
785
829
|
raise
|
|
786
|
-
verify_processes(owed
|
|
830
|
+
self.verify_processes(owed)
|
|
787
831
|
if backend_request(owed, 'commit', permit['token']).get('ok') is not True:
|
|
788
832
|
raise RuntimeError(f'{_name(owed)} did not commit its backend retirement; recovery remains owed.')
|
|
789
833
|
owed['backend_committed'] = True
|
|
@@ -794,14 +838,14 @@ class ServiceRecovery:
|
|
|
794
838
|
# Disarm through the original manager before its KeepAlive can admit a successor.
|
|
795
839
|
owed['backend_stop_requested'] = True
|
|
796
840
|
self.save()
|
|
797
|
-
verify_processes(owed,
|
|
841
|
+
self.verify_processes(owed, stopping=stopping)
|
|
798
842
|
if _config_stamp(owed) != owed['config_stamp']:
|
|
799
843
|
raise RuntimeError(f'{_name(owed)} service configuration changed before backend stop; recovery remains owed.')
|
|
800
844
|
if stopped.is_set():
|
|
801
845
|
raise RuntimeError(f'{_name(owed)} backend stop was cancelled; recovery remains owed.')
|
|
802
846
|
self.pause._disarm(service_entry(owed))
|
|
803
847
|
wait_stopped(owed, self.records, stopped)
|
|
804
|
-
verify_processes(owed,
|
|
848
|
+
self.verify_processes(owed, stopping=True)
|
|
805
849
|
owed['phase'] = 'stopped'
|
|
806
850
|
self.save()
|
|
807
851
|
|
|
@@ -811,15 +855,15 @@ class ServiceRecovery:
|
|
|
811
855
|
raise RuntimeError(f'{_name(entry)} legacy shutdown remains owed; no signal was replayed.')
|
|
812
856
|
if _config_stamp(owed) != owed['config_stamp']:
|
|
813
857
|
raise RuntimeError(f'{_name(entry)} configuration changed before legacy refresh.')
|
|
814
|
-
verify_processes(owed
|
|
858
|
+
self.verify_processes(owed)
|
|
815
859
|
verify_listener(owed)
|
|
816
860
|
owed.update(legacy_refresh=True, phase='refreshing')
|
|
817
861
|
self.save() # Older readers reject this phase and retain debt; no reader replays its signal.
|
|
818
|
-
verify_processes(owed
|
|
862
|
+
self.verify_processes(owed)
|
|
819
863
|
verify_listener(owed)
|
|
820
864
|
if _config_stamp(owed) != owed['config_stamp']:
|
|
821
865
|
raise RuntimeError(f'{_name(owed)} configuration changed before legacy refresh.')
|
|
822
|
-
verify_processes(owed
|
|
866
|
+
self.verify_processes(owed)
|
|
823
867
|
try:
|
|
824
868
|
if stopped.is_set():
|
|
825
869
|
raise InterruptedError('Legacy refresh was cancelled before interruption.')
|
|
@@ -883,6 +927,8 @@ class ServiceRecovery:
|
|
|
883
927
|
if (_config_stamp(candidate) != entry['config_stamp']
|
|
884
928
|
or candidate.get('profile') != entry.get('profile')):
|
|
885
929
|
raise RuntimeError(f'{_name(entry)} successor configuration/profile changed; recovery remains owed.')
|
|
930
|
+
if entry.get('departed_processes'):
|
|
931
|
+
candidate['departed_processes'] = entry['departed_processes']
|
|
886
932
|
bind_processes(candidate, self.records)
|
|
887
933
|
parents = {int(pid): p['parent'] for pid, p in candidate['processes'].items()}
|
|
888
934
|
chain, pid = set(), candidate['pid']
|
|
@@ -894,7 +940,8 @@ class ServiceRecovery:
|
|
|
894
940
|
if chain | _descendants(candidate['pid'], parents) != set(parents):
|
|
895
941
|
raise RuntimeError(f'{_name(entry)} successor has unrelated descendants; recovery remains owed.')
|
|
896
942
|
for pid, process in candidate['processes'].items():
|
|
897
|
-
old = entry['processes'].get(pid) or entry.get('
|
|
943
|
+
old = (entry['processes'].get(pid) or entry.get('departed_processes', {}).get(pid)
|
|
944
|
+
or entry.get('retired_processes', {}).get(pid))
|
|
898
945
|
if old is not None and old != process:
|
|
899
946
|
raise RuntimeError(f'{_name(entry)} successor reused a recorded process identity; recovery remains owed.')
|
|
900
947
|
return candidate
|
|
@@ -966,7 +1013,7 @@ class ServiceRecovery:
|
|
|
966
1013
|
if pending:
|
|
967
1014
|
stopped.wait(.05)
|
|
968
1015
|
continue
|
|
969
|
-
if not verify_processes(entry,
|
|
1016
|
+
if not self.verify_processes(entry, stopping=True, fenced=True):
|
|
970
1017
|
stopped.wait(.05)
|
|
971
1018
|
continue
|
|
972
1019
|
if self._gateway_writers_live(entry) or _config_stamp(entry) != entry['config_stamp']:
|
|
@@ -989,7 +1036,7 @@ class ServiceRecovery:
|
|
|
989
1036
|
entry.update(candidate, retired_processes=retired, phase='retiring',
|
|
990
1037
|
drain_acknowledged=False, drain_acknowledged_at=None, settle_attempts=attempts)
|
|
991
1038
|
self.save() # Successor custody precedes its cooperative lifecycle request.
|
|
992
|
-
verify_processes(entry
|
|
1039
|
+
self.verify_processes(entry)
|
|
993
1040
|
if _config_stamp(entry) != entry['config_stamp']:
|
|
994
1041
|
raise RuntimeError(f'{_name(entry)} service configuration changed; recovery remains owed.')
|
|
995
1042
|
if not self.pause._ask_to_drain(entry):
|
|
@@ -1036,7 +1083,7 @@ class ServiceRecovery:
|
|
|
1036
1083
|
raise RuntimeError(f'{_name(entry)} uncommitted retirement could not yet be cancelled; recovery remains owed.')
|
|
1037
1084
|
self.stop(entry, threading.Event())
|
|
1038
1085
|
elif any(self.records.identity_is_live({'pid': int(pid), 'ct': p['ct']}) for pid, p in entry['processes'].items()):
|
|
1039
|
-
verify_processes(entry,
|
|
1086
|
+
self.verify_processes(entry, stopping=True)
|
|
1040
1087
|
if any(self.records.identity_is_live({'pid': int(pid), 'ct': p['ct']}) for pid, p in entry['processes'].items() if int(pid) != entry['service_pid']):
|
|
1041
1088
|
raise RuntimeError(f'{_name(entry)} still has live writer descendants; recovery remains owed.')
|
|
1042
1089
|
self._stop_backend_supervisor(entry, threading.Event(), stopping=True)
|
|
@@ -1062,6 +1109,18 @@ class ServiceRecovery:
|
|
|
1062
1109
|
raise RuntimeError(f'{_name(entry)} readiness is unverified at its original endpoint; recovery remains owed.')
|
|
1063
1110
|
time.sleep(.1)
|
|
1064
1111
|
|
|
1112
|
+
def _verify_candidate(self, candidate, entry):
|
|
1113
|
+
# Readiness retries must retain both live observations and proved departures.
|
|
1114
|
+
candidate['config_stamp'] = entry['config_stamp']
|
|
1115
|
+
candidate['processes'] = {**candidate['processes'], **entry.get('readiness_processes', {})}
|
|
1116
|
+
candidate['departed_processes'] = {**entry.get('departed_processes', {}),
|
|
1117
|
+
**candidate.get('departed_processes', {})}
|
|
1118
|
+
bind_processes(candidate, self.records)
|
|
1119
|
+
entry['readiness_processes'] = candidate['processes']
|
|
1120
|
+
if candidate['departed_processes']:
|
|
1121
|
+
entry['departed_processes'] = candidate['departed_processes']
|
|
1122
|
+
self.save()
|
|
1123
|
+
|
|
1065
1124
|
def _ready(self, entry, ledger):
|
|
1066
1125
|
if _config_stamp(entry) != entry['config_stamp']:
|
|
1067
1126
|
raise RuntimeError(f'{_name(entry)} service configuration changed; backend recovery remains owed.')
|
|
@@ -1075,8 +1134,9 @@ class ServiceRecovery:
|
|
|
1075
1134
|
candidate = self._gateway_candidate(entry)
|
|
1076
1135
|
if candidate is None:
|
|
1077
1136
|
return False
|
|
1137
|
+
self._verify_candidate(candidate, entry)
|
|
1078
1138
|
ready = _gateway_home_matches(entry['home'], (candidate['pid'], candidate['ct']), self.pause)
|
|
1079
|
-
|
|
1139
|
+
self._verify_candidate(candidate, entry)
|
|
1080
1140
|
return ready
|
|
1081
1141
|
if entry.get('legacy_refresh') and any(self.records.identity_is_live({'pid': int(pid), 'ct': p['ct']})
|
|
1082
1142
|
for pid, p in entry['processes'].items()
|
|
@@ -1095,7 +1155,7 @@ class ServiceRecovery:
|
|
|
1095
1155
|
if (candidate['profile'] != entry['profile'] or _service_key(candidate) != _service_key(entry)
|
|
1096
1156
|
or _config_stamp(candidate) != entry['config_stamp']):
|
|
1097
1157
|
return False
|
|
1098
|
-
|
|
1158
|
+
self._verify_candidate(candidate, entry)
|
|
1099
1159
|
try:
|
|
1100
1160
|
if entry.get('legacy_refresh'):
|
|
1101
1161
|
verify_listener(candidate)
|
|
@@ -1106,7 +1166,7 @@ class ServiceRecovery:
|
|
|
1106
1166
|
return False
|
|
1107
1167
|
if backend_request(candidate, 'cancel', permit['token']).get('ok') is not True:
|
|
1108
1168
|
return False
|
|
1109
|
-
|
|
1169
|
+
self._verify_candidate(candidate, entry)
|
|
1110
1170
|
if self.identity._pid_alive_matches(row['pid'], row['create_time'], strict=True) is not True:
|
|
1111
1171
|
return False
|
|
1112
1172
|
except BackendLifecycleUnsupported:
|
|
@@ -310,8 +310,8 @@ def _recover_processes(home: Path) -> None:
|
|
|
310
310
|
|
|
311
311
|
|
|
312
312
|
@contextlib.contextmanager
|
|
313
|
-
def scoped_home(home: Path, *, load_plugins: bool = True):
|
|
314
|
-
"""
|
|
313
|
+
def scoped_home(home: Path, *, load_plugins: bool = True, recover_processes: bool = True, read_only: bool = False):
|
|
314
|
+
"""Bind the home; read-only inspection skips credential hydration, terminal defaults and recovery."""
|
|
315
315
|
home = Path(home).expanduser()
|
|
316
316
|
stamp = _scope_stamp(home)
|
|
317
317
|
try:
|
|
@@ -321,18 +321,25 @@ def scoped_home(home: Path, *, load_plugins: bool = True):
|
|
|
321
321
|
if set_hermes_home_override is not None:
|
|
322
322
|
token = set_hermes_home_override(home)
|
|
323
323
|
try:
|
|
324
|
-
|
|
325
|
-
_recover_processes(home)
|
|
324
|
+
if read_only:
|
|
326
325
|
yield home
|
|
326
|
+
else:
|
|
327
|
+
with _secret_scope(home, stamp, load_plugins=load_plugins), _terminal_scope(home, stamp):
|
|
328
|
+
if recover_processes:
|
|
329
|
+
_recover_processes(home)
|
|
330
|
+
yield home
|
|
327
331
|
finally:
|
|
328
332
|
reset_hermes_home_override(token)
|
|
329
333
|
return
|
|
334
|
+
if read_only:
|
|
335
|
+
raise RpcError("Read-only profile binding is unavailable", condition="agent_incompatible")
|
|
330
336
|
with _ENV_LOCK:
|
|
331
337
|
previous = os.environ.get("HERMES_HOME")
|
|
332
338
|
os.environ["HERMES_HOME"] = str(home)
|
|
333
339
|
try:
|
|
334
340
|
with _secret_scope(home, stamp, load_plugins=load_plugins), _terminal_scope(home, stamp):
|
|
335
|
-
|
|
341
|
+
if recover_processes:
|
|
342
|
+
_recover_processes(home)
|
|
336
343
|
yield home
|
|
337
344
|
finally:
|
|
338
345
|
if previous is None:
|
|
@@ -29,9 +29,9 @@ class Registry:
|
|
|
29
29
|
|
|
30
30
|
def build_methods(runtime: AgentRuntime) -> dict[str, Handler]:
|
|
31
31
|
registry = Registry(runtime)
|
|
32
|
-
from . import aux, chat, checkpoints, commands, config, connectors, cron, dashboard_plugins, gateway, goals, kanban, mcp, memory, oauth, plugin_oauth, process, profiles, providers, skills, state_db, stt, text, toolsets, usage, worktree, write_approval # noqa: WPS433
|
|
32
|
+
from . import agent_imports, aux, chat, checkpoints, commands, config, connectors, cron, dashboard_plugins, delegation, gateway, goals, kanban, mcp, managed_buffers, memory, oauth, outbound_drafts, plugin_oauth, process, profiles, providers, skills, state_db, stt, tts, text, toolsets, usage, worktree, write_approval # noqa: WPS433
|
|
33
33
|
from . import runtime as runtime_methods
|
|
34
34
|
|
|
35
|
-
for module in (runtime_methods, goals, commands, kanban, state_db, profiles, skills, mcp, stt, cron, providers, oauth, plugin_oauth, aux, text, process, usage, gateway, worktree, checkpoints, memory, chat, config, toolsets, write_approval, connectors, dashboard_plugins):
|
|
35
|
+
for module in (agent_imports, runtime_methods, goals, commands, kanban, state_db, profiles, skills, mcp, stt, tts, cron, providers, oauth, plugin_oauth, aux, delegation, text, process, usage, gateway, worktree, checkpoints, memory, chat, config, toolsets, write_approval, connectors, dashboard_plugins, outbound_drafts, managed_buffers):
|
|
36
36
|
module.register(registry)
|
|
37
37
|
return registry.methods
|