@maudecode/talaria-web 1.19.0 → 1.21.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-raw.js +61 -6
- package/dist/api/automation-raw.js.map +1 -1
- package/dist/api/automation-router.d.ts +309 -2
- package/dist/api/automation-router.js +28 -2
- package/dist/api/automation-router.js.map +1 -1
- package/dist/api/chat-router.d.ts +646 -24
- package/dist/api/chat-router.js +54 -167
- package/dist/api/chat-router.js.map +1 -1
- package/dist/api/git-router.d.ts +54 -0
- package/dist/api/git-router.js +18 -5
- package/dist/api/git-router.js.map +1 -1
- package/dist/api/raw-routes.js +13 -1
- package/dist/api/raw-routes.js.map +1 -1
- package/dist/api/router.d.ts +3 -3
- package/dist/api/session-visibility.js +2 -2
- package/dist/api/session-visibility.js.map +1 -1
- package/dist/api/sessions-router.d.ts +1868 -79
- package/dist/api/sessions-router.js +72 -43
- package/dist/api/sessions-router.js.map +1 -1
- package/dist/api/settings-router.d.ts +34 -13
- package/dist/api/settings-router.js +54 -17
- package/dist/api/settings-router.js.map +1 -1
- package/dist/api/sse-routes.js +45 -21
- package/dist/api/sse-routes.js.map +1 -1
- package/dist/api/tools-router.d.ts +773 -39
- package/dist/api/tools-router.js +167 -45
- package/dist/api/tools-router.js.map +1 -1
- package/dist/app.js +15 -11
- package/dist/app.js.map +1 -1
- package/dist/auth/crypto.d.ts +3 -0
- package/dist/auth/crypto.js +18 -0
- package/dist/auth/crypto.js.map +1 -1
- package/dist/auth/gate.js +5 -1
- package/dist/auth/gate.js.map +1 -1
- package/dist/cli/ctl.js +6 -1
- package/dist/cli/ctl.js.map +1 -1
- package/dist/cli/main.js +23 -18
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/supervise.d.ts +22 -0
- package/dist/cli/supervise.js +80 -2
- package/dist/cli/supervise.js.map +1 -1
- package/dist/config/agent-config.d.ts +3 -0
- package/dist/config/agent-config.js +36 -9
- package/dist/config/agent-config.js.map +1 -1
- package/dist/fs/atomic.d.ts +3 -0
- package/dist/fs/atomic.js +19 -5
- package/dist/fs/atomic.js.map +1 -1
- package/dist/fs/stat.d.ts +6 -0
- package/dist/fs/stat.js +18 -2
- package/dist/fs/stat.js.map +1 -1
- package/dist/http/context.d.ts +16 -0
- package/dist/http/context.js +48 -5
- package/dist/http/context.js.map +1 -1
- package/dist/profiles/profiles.d.ts +2 -0
- package/dist/profiles/profiles.js +1 -0
- package/dist/profiles/profiles.js.map +1 -1
- package/dist/providers/catalog.d.ts +11 -6
- package/dist/providers/catalog.js +76 -24
- package/dist/providers/catalog.js.map +1 -1
- package/dist/redact.d.ts +2 -0
- package/dist/redact.js +55 -16
- package/dist/redact.js.map +1 -1
- package/dist/release.js +5 -3
- package/dist/release.js.map +1 -1
- package/dist/runtime.js +118 -26
- package/dist/runtime.js.map +1 -1
- package/dist/server.js +25 -21
- 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 +4 -1
- package/dist/sessions/anchor.js +9 -5
- package/dist/sessions/anchor.js.map +1 -1
- package/dist/sessions/background-tasks.d.ts +41 -3
- package/dist/sessions/background-tasks.js +110 -10
- package/dist/sessions/background-tasks.js.map +1 -1
- package/dist/sessions/cli-sessions.d.ts +9 -2
- package/dist/sessions/cli-sessions.js +38 -57
- package/dist/sessions/cli-sessions.js.map +1 -1
- package/dist/sessions/completions.d.ts +8 -0
- package/dist/sessions/completions.js +55 -25
- package/dist/sessions/completions.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/export.d.ts +2 -0
- package/dist/sessions/export.js +6 -2
- package/dist/sessions/export.js.map +1 -1
- package/dist/sessions/gateway-sessions.d.ts +92 -4
- package/dist/sessions/gateway-sessions.js +762 -93
- package/dist/sessions/gateway-sessions.js.map +1 -1
- package/dist/sessions/gateway-watcher.d.ts +10 -11
- package/dist/sessions/gateway-watcher.js +25 -21
- package/dist/sessions/gateway-watcher.js.map +1 -1
- package/dist/sessions/list.d.ts +9 -2
- package/dist/sessions/list.js +38 -26
- package/dist/sessions/list.js.map +1 -1
- package/dist/sessions/merge.d.ts +12 -5
- package/dist/sessions/merge.js +65 -18
- package/dist/sessions/merge.js.map +1 -1
- package/dist/sessions/prefix-index.d.ts +15 -4
- package/dist/sessions/prefix-index.js +35 -13
- 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/recovery.d.ts +1 -1
- package/dist/sessions/recovery.js +4 -3
- package/dist/sessions/recovery.js.map +1 -1
- package/dist/sessions/relay.d.ts +12 -1
- package/dist/sessions/relay.js +75 -17
- package/dist/sessions/relay.js.map +1 -1
- package/dist/sessions/service.d.ts +132 -37
- package/dist/sessions/service.js +688 -160
- package/dist/sessions/service.js.map +1 -1
- package/dist/sessions/session.d.ts +2 -0
- package/dist/sessions/session.js +5 -0
- package/dist/sessions/session.js.map +1 -1
- package/dist/sessions/state-db-worker.js +22 -5
- package/dist/sessions/state-db-worker.js.map +1 -1
- package/dist/sessions/state-db.d.ts +106 -15
- package/dist/sessions/state-db.js +651 -236
- package/dist/sessions/state-db.js.map +1 -1
- package/dist/sessions/state-saved.d.ts +1 -1
- package/dist/sessions/state-saved.js +35 -11
- package/dist/sessions/state-saved.js.map +1 -1
- package/dist/sessions/storage/backend.d.ts +10 -1
- package/dist/sessions/storage/backend.js.map +1 -1
- package/dist/sessions/storage/conformance.js +1 -1
- package/dist/sessions/storage/conformance.js.map +1 -1
- package/dist/sessions/storage/json-documents.d.ts +2 -0
- package/dist/sessions/storage/json-documents.js +71 -26
- package/dist/sessions/storage/json-documents.js.map +1 -1
- package/dist/sessions/storage/json-files.d.ts +13 -2
- package/dist/sessions/storage/json-files.js +126 -6
- package/dist/sessions/storage/json-files.js.map +1 -1
- package/dist/sessions/storage/json-journal.d.ts +6 -7
- package/dist/sessions/storage/json-journal.js +143 -73
- package/dist/sessions/storage/json-journal.js.map +1 -1
- package/dist/sessions/storage/json.d.ts +15 -1
- package/dist/sessions/storage/json.js +125 -33
- package/dist/sessions/storage/json.js.map +1 -1
- package/dist/sessions/store.d.ts +6 -1
- package/dist/sessions/store.js +68 -27
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/streams.d.ts +10 -7
- package/dist/sessions/streams.js +49 -14
- package/dist/sessions/streams.js.map +1 -1
- package/dist/sessions/tool-display.d.ts +11 -2
- package/dist/sessions/tool-display.js +45 -4
- package/dist/sessions/tool-display.js.map +1 -1
- package/dist/sessions/turn-context.js +6 -2
- package/dist/sessions/turn-context.js.map +1 -1
- package/dist/sessions/turn.d.ts +27 -6
- package/dist/sessions/turn.js +186 -89
- package/dist/sessions/turn.js.map +1 -1
- package/dist/sidecar/client.d.ts +24 -1
- package/dist/sidecar/client.js +118 -38
- package/dist/sidecar/client.js.map +1 -1
- package/dist/sidecar/fake.d.ts +6 -2
- package/dist/sidecar/fake.js +15 -2
- package/dist/sidecar/fake.js.map +1 -1
- package/dist/spa.d.ts +9 -4
- package/dist/spa.js +36 -12
- package/dist/spa.js.map +1 -1
- package/dist/startup-timing.d.ts +66 -0
- package/dist/startup-timing.js +129 -0
- package/dist/startup-timing.js.map +1 -0
- package/dist/test/fs-handles.d.ts +11 -0
- package/dist/test/fs-handles.js +31 -0
- package/dist/test/fs-handles.js.map +1 -0
- package/dist/tools/connectors.d.ts +1 -1
- package/dist/tools/connectors.js +2 -2
- package/dist/tools/connectors.js.map +1 -1
- package/dist/tools/crons.d.ts +8 -4
- package/dist/tools/crons.js +25 -18
- package/dist/tools/crons.js.map +1 -1
- package/dist/tools/dashboard-plugins.d.ts +29 -0
- package/dist/tools/dashboard-plugins.js +132 -0
- package/dist/tools/dashboard-plugins.js.map +1 -1
- package/dist/tools/gateway-restart.d.ts +25 -5
- package/dist/tools/gateway-restart.js +103 -23
- package/dist/tools/gateway-restart.js.map +1 -1
- package/dist/tools/health.d.ts +13 -1
- package/dist/tools/health.js +80 -22
- package/dist/tools/health.js.map +1 -1
- package/dist/tools/insights.d.ts +1 -1
- package/dist/tools/insights.js +2 -2
- package/dist/tools/insights.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-health.js +74 -24
- package/dist/tools/mcp-health.js.map +1 -1
- package/dist/tools/mcp.d.ts +3 -1
- package/dist/tools/mcp.js +92 -1
- 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/plugin-oauth.d.ts +14 -0
- package/dist/tools/plugin-oauth.js +53 -0
- package/dist/tools/plugin-oauth.js.map +1 -0
- package/dist/tools/prune-advice.d.ts +50 -0
- package/dist/tools/prune-advice.js +114 -0
- package/dist/tools/prune-advice.js.map +1 -0
- package/dist/tools/skills.d.ts +5 -2
- package/dist/tools/skills.js +9 -6
- package/dist/tools/skills.js.map +1 -1
- package/dist/tools/update-notifications.d.ts +77 -9
- package/dist/tools/update-notifications.js +390 -46
- package/dist/tools/update-notifications.js.map +1 -1
- package/dist/tools/updates.d.ts +29 -3
- package/dist/tools/updates.js +166 -34
- package/dist/tools/updates.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/media.js +69 -20
- package/dist/workspace/media.js.map +1 -1
- package/dist/workspace/preview.js +4 -14
- package/dist/workspace/preview.js.map +1 -1
- package/dist/workspace/rollback.d.ts +6 -2
- package/dist/workspace/rollback.js +18 -8
- package/dist/workspace/rollback.js.map +1 -1
- package/package.json +3 -3
- package/sidecar/agent_dependency.json +4 -4
- package/sidecar/agent_support.json +30 -15
- package/sidecar/scripts/suite_runner.py +183 -27
- package/sidecar/scripts/test.sh +5 -7
- package/sidecar/talaria_sidecar/__init__.py +1 -1
- package/sidecar/talaria_sidecar/__main__.py +10 -3
- package/sidecar/talaria_sidecar/agent_mutation.py +246 -32
- package/sidecar/talaria_sidecar/agent_services.py +157 -34
- package/sidecar/talaria_sidecar/context_detail.py +59 -0
- package/sidecar/talaria_sidecar/home.py +97 -20
- package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
- package/sidecar/talaria_sidecar/methods/aux.py +80 -18
- package/sidecar/talaria_sidecar/methods/chat.py +571 -106
- package/sidecar/talaria_sidecar/methods/checkpoints.py +29 -4
- package/sidecar/talaria_sidecar/methods/commands.py +277 -16
- package/sidecar/talaria_sidecar/methods/config.py +73 -3
- package/sidecar/talaria_sidecar/methods/connectors.py +45 -13
- package/sidecar/talaria_sidecar/methods/cron.py +8 -2
- package/sidecar/talaria_sidecar/methods/dashboard_plugins.py +301 -0
- package/sidecar/talaria_sidecar/methods/gateway.py +24 -4
- package/sidecar/talaria_sidecar/methods/gateway_sessions.py +304 -30
- package/sidecar/talaria_sidecar/methods/kanban.py +50 -3
- package/sidecar/talaria_sidecar/methods/managed_buffers.py +110 -0
- package/sidecar/talaria_sidecar/methods/mcp.py +55 -0
- package/sidecar/talaria_sidecar/methods/oauth.py +139 -11
- package/sidecar/talaria_sidecar/methods/outbound_drafts.py +165 -0
- package/sidecar/talaria_sidecar/methods/plugin_catalog.py +198 -0
- package/sidecar/talaria_sidecar/methods/plugin_oauth.py +234 -0
- package/sidecar/talaria_sidecar/methods/process.py +70 -6
- package/sidecar/talaria_sidecar/methods/profiles.py +4 -3
- package/sidecar/talaria_sidecar/methods/runtime.py +2 -0
- package/sidecar/talaria_sidecar/methods/skills.py +22 -7
- package/sidecar/talaria_sidecar/methods/state_db.py +128 -42
- package/sidecar/talaria_sidecar/methods/toolsets.py +4 -2
- package/sidecar/talaria_sidecar/methods/worktree.py +121 -2
- package/sidecar/talaria_sidecar/rpc.py +25 -3
- package/sidecar/talaria_sidecar/runtime.py +42 -3
- package/sidecar/talaria_sidecar/speed.py +13 -1
- package/sidecar/talaria_sidecar/startup_timing.py +119 -0
- package/static/dist/FILES.txt +240 -213
- package/static/dist/THIRD_PARTY_LICENSES.md +6 -22
- package/static/dist/assets/AppShell-c5989995.js +8 -0
- package/static/dist/assets/Button-nuaikybd.js +1 -0
- package/static/dist/assets/ChatPage-bfg4khph.js +6 -0
- package/static/dist/assets/ConnectTargets-k5wo9yo8.js +1 -0
- package/static/dist/assets/Dialog-o8vo2aws.js +1 -0
- package/static/dist/assets/ExtensionRoute-l1yjrso4.js +1 -0
- package/static/dist/assets/Field-j7o8cfps.js +1 -0
- package/static/dist/assets/HubRoute-efnwe4xz.js +2 -0
- package/static/dist/assets/LinkCheckContext-ix6zqqkk.js +1 -0
- package/static/dist/assets/Markdown-clqf5m22.js +2 -0
- package/static/dist/assets/MarkdownRenderer-ccgqrza3.js +302 -0
- package/static/dist/assets/MarkdownRenderer-i9o6nr38.css +1 -0
- package/static/dist/assets/OAuthSignIn-h7bjaqp6.js +1 -0
- package/static/dist/assets/ResourceSwitch-oai2zqaj.js +1 -0
- package/static/dist/assets/RightPanel-ho161a45.js +1 -0
- package/static/dist/assets/Select-d1g5a8bm.js +1 -0
- package/static/dist/assets/SessionListPanel-i7kaokhi.js +1 -0
- package/static/dist/assets/SettingsLayout-lnecm87w.js +1 -0
- package/static/dist/assets/States-easntmry.js +1 -0
- package/static/dist/assets/TerminalPanel-lxhwd4jl.js +16 -0
- package/static/dist/assets/Toaster-l4sciy8t.js +1 -0
- package/static/dist/assets/_app-mqexqbg8.js +1 -0
- package/static/dist/assets/_app.ext._extensionId-n797jp72.js +1 -0
- package/static/dist/assets/_app.index-ne43mdw2.js +1 -0
- package/static/dist/assets/_app.insights-fqonovb4.js +1 -0
- package/static/dist/assets/_app.kanban-kysliv19.js +1 -0
- package/static/dist/assets/_app.logs-febut82r.js +1 -0
- package/static/dist/assets/_app.memory-ha86oj1c.js +1 -0
- package/static/dist/assets/_app.profiles-cnu3gxxq.js +1 -0
- package/static/dist/assets/_app.session._sessionId-ifzjpcgn.js +1 -0
- package/static/dist/assets/_app.settings-nmakdiaf.js +1 -0
- package/static/dist/assets/_app.settings._section-djglnjmi.js +3 -0
- package/static/dist/assets/_app.skills-f3wad8yo.js +1 -0
- package/static/dist/assets/_app.tasks-l10py1c0.js +1 -0
- package/static/dist/assets/_app.todos-bml1m3r1.js +1 -0
- package/static/dist/assets/_app.workspaces-f3d066lx.js +1 -0
- package/static/dist/assets/abnfDiagram-VCTEODGH-i53jc4yp.js +1 -0
- package/static/dist/assets/{angular-html-nu6l31w3.js → angular-html-l28bd5fo.js} +1 -1
- package/static/dist/assets/{angular-ts-fbx4f8mm.js → angular-ts-ffzx1vj0.js} +1 -1
- package/static/dist/assets/{apl-bx2xr7dh.js → apl-b7h7mmy4.js} +1 -1
- package/static/dist/assets/{arc-7popfhbk.js → arc-fk1b21lm.js} +1 -1
- package/static/dist/assets/architecture-7GRP2DOG-e3bv5m6f.js +1 -0
- package/static/dist/assets/architectureDiagram-5GKGNRK7-pakekxu2.js +36 -0
- package/static/dist/assets/archive-ihqi7z2x.js +1 -0
- package/static/dist/assets/{astro-g77i97cb.js → astro-k117fy0t.js} +1 -1
- package/static/dist/assets/back-gu3nu279.js +1 -0
- package/static/dist/assets/{blade-boo0u92y.js → blade-npefsmn8.js} +1 -1
- package/static/dist/assets/{blockDiagram-I7D4REHJ-joedghi3.js → blockDiagram-I7D4REHJ-bc6bo1n6.js} +4 -4
- package/static/dist/assets/{c-cat0w3sc.js → c-2umg6kbn.js} +1 -1
- package/static/dist/assets/{c4Diagram-7LVT6UL2-hyrjrohe.js → c4Diagram-7LVT6UL2-btvwk2qx.js} +1 -1
- package/static/dist/assets/channel-jn4f8443.js +1 -0
- package/static/dist/assets/{chunk-4HAMMTFA-koouqbut.js → chunk-4HAMMTFA-dlwab11c.js} +20 -20
- package/static/dist/assets/{chunk-75Z2AOVW-bl4bhdnt.js → chunk-75Z2AOVW-dp5gh7i8.js} +1 -1
- package/static/dist/assets/chunk-DU6HZSFF-bi06zl1c.js +128 -0
- package/static/dist/assets/{chunk-F27PBJKO-d8xxi0zi.js → chunk-F27PBJKO-kvv1rnlh.js} +1 -1
- package/static/dist/assets/{chunk-FOHPRMQF-opuflp73.js → chunk-FOHPRMQF-ipewusgj.js} +8 -8
- package/static/dist/assets/{chunk-GMAD6QVW-jro0hl73.js → chunk-GMAD6QVW-ji0rx9by.js} +6 -6
- package/static/dist/assets/{chunk-GVQU2GXP-djn6gbyu.js → chunk-GVQU2GXP-nmz0j82p.js} +1 -1
- package/static/dist/assets/{chunk-IMKFNOWR-vw4p5p7o.js → chunk-IMKFNOWR-kmi1qx88.js} +5 -5
- package/static/dist/assets/{chunk-L3NEJ4N5-n1hj77q8.js → chunk-L3NEJ4N5-xhb7mebj.js} +1 -1
- package/static/dist/assets/chunk-OSK3NFVY-5a9sgscq.js +10 -0
- package/static/dist/assets/{chunk-P2QGCYS3-onf1hz6c.js → chunk-P2QGCYS3-dfezp4vu.js} +1 -1
- package/static/dist/assets/{chunk-POPQ4Y6H-m8sqn7cs.js → chunk-POPQ4Y6H-gd2vq3c0.js} +1 -1
- package/static/dist/assets/{chunk-PWAF6VOD-ek4smc8x.js → chunk-PWAF6VOD-wvw2nksf.js} +1 -1
- package/static/dist/assets/{chunk-SHT3W25Y-g9gfvefo.js → chunk-SHT3W25Y-f58q97px.js} +13 -13
- package/static/dist/assets/{chunk-SVP7TREG-f9nfv2cu.js → chunk-SVP7TREG-abgwpyz9.js} +4 -4
- package/static/dist/assets/{chunk-TICWLB2K-bnk3m1mq.js → chunk-TICWLB2K-h4sbs8ds.js} +6 -6
- package/static/dist/assets/{chunk-XXDRQBXY-n40pf9vy.js → chunk-XXDRQBXY-jkmnqu65.js} +1 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-dzrw66se.js +1 -0
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-dzrw66se.js +1 -0
- package/static/dist/assets/{cobol-go622aep.js → cobol-ssf9hkh7.js} +1 -1
- package/static/dist/assets/{coffee-jwo1xjhq.js → coffee-lsi9fwae.js} +1 -1
- package/static/dist/assets/completionAudio-ce86msbu.js +1 -0
- package/static/dist/assets/copied-bz3gkazh.js +1 -0
- package/static/dist/assets/copy-m9h56qa8.js +1 -0
- package/static/dist/assets/cose-bilkent-JH36ORCC-layy2r27.js +1 -0
- package/static/dist/assets/{cpp-nre7j0kq.js → cpp-lfrh4y55.js} +1 -1
- package/static/dist/assets/{crystal-lviso2je.js → crystal-efh4pte7.js} +1 -1
- package/static/dist/assets/{css-ywz9j4hb.js → css-i82qdo89.js} +1 -1
- package/static/dist/assets/cynefin-OW5HDTMX-g081vffs.js +1 -0
- package/static/dist/assets/cynefinDiagram-5FMLGOSQ-odxvjesk.js +62 -0
- package/static/dist/assets/cytoscape.esm-fjn2algp.js +321 -0
- package/static/dist/assets/dagre-GXQ25YYZ-cpdwzjs4.js +4 -0
- package/static/dist/assets/dagre-o5jmjz46.js +1 -0
- package/static/dist/assets/{diagram-S7CK7UJ4-m6aeoe7c.js → diagram-S7CK7UJ4-clv5mxvu.js} +4 -4
- package/static/dist/assets/diagram-UQ7AKVKN-m2ia1mbf.js +41 -0
- package/static/dist/assets/{diagram-VSXAHHWV-hbawi7hn.js → diagram-VSXAHHWV-ea6zv636.js} +1 -1
- package/static/dist/assets/diagram-VX7I27RA-oqlef685.js +24 -0
- package/static/dist/assets/diagram-Z3DM3KII-kjubcbwu.js +24 -0
- package/static/dist/assets/dist-carq1azj.js +44 -0
- package/static/dist/assets/dist-crc46di9.js +7 -0
- package/static/dist/assets/{dist-c4c2m3kv.js → dist-nb670eu6.js} +1 -1
- package/static/dist/assets/ebnfDiagram-PWID7BFC-fg0zri3e.js +1 -0
- package/static/dist/assets/{edge-dvv35byi.js → edge-lrob635n.js} +1 -1
- package/static/dist/assets/{elixir-i2f1ki1g.js → elixir-kdpxeq93.js} +1 -1
- package/static/dist/assets/{elm-cpepyjm4.js → elm-c8irj9uh.js} +1 -1
- package/static/dist/assets/erDiagram-RLTQ6QDP-eb7pmk3x.js +99 -0
- package/static/dist/assets/{erb-idlyfheg.js → erb-flwsv146.js} +1 -1
- package/static/dist/assets/eventmodeling-NTZA5JFV-gvi1fxhn.js +1 -0
- package/static/dist/assets/flowDiagram-HODETNUW-abekab15.js +1 -0
- package/static/dist/assets/folder-plus-ksaons88.js +1 -0
- package/static/dist/assets/{ganttDiagram-EL5Y4UJY-ma6jxj5i.js → ganttDiagram-EL5Y4UJY-jmisowrc.js} +1 -1
- package/static/dist/assets/{git-rebase-d9lpfpbn.js → git-rebase-bli19aoq.js} +1 -1
- package/static/dist/assets/gitGraph-4MIJSDKK-m7kt3u6e.js +1 -0
- package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-hzltvsod.js → gitGraphDiagram-WWUBYQGX-nq7vfzh2.js} +1 -1
- package/static/dist/assets/{glimmer-js-39i0urfb.js → glimmer-js-d4icg38p.js} +1 -1
- package/static/dist/assets/{glimmer-ts-gdtd6n73.js → glimmer-ts-bk75772u.js} +1 -1
- package/static/dist/assets/{glsl-o1djm5pp.js → glsl-lqormp2b.js} +1 -1
- package/static/dist/assets/{graphql-kj6rz55t.js → graphql-hw6s5qzd.js} +1 -1
- package/static/dist/assets/{hack-pe1qqr2i.js → hack-ozrv6l4d.js} +1 -1
- package/static/dist/assets/{haml-cknnbcqs.js → haml-gytfosdt.js} +1 -1
- package/static/dist/assets/{handlebars-hwq64orh.js → handlebars-b6g7jffd.js} +1 -1
- package/static/dist/assets/highlighted-body-KPVGNVTW-gcu017ay.js +1 -0
- package/static/dist/assets/host-ipp4e84c.js +1 -0
- package/static/dist/assets/{html-derivative-h2i2pyjc.js → html-derivative-f1tqcroo.js} +1 -1
- package/static/dist/assets/{html-ha05xtvt.js → html-on6oj6yj.js} +1 -1
- package/static/dist/assets/{http-cf94zu27.js → http-odhufsl7.js} +1 -1
- package/static/dist/assets/{hurl-lslax568.js → hurl-mu680336.js} +1 -1
- package/static/dist/assets/index-d6vbxlra.js +13 -0
- package/static/dist/assets/index-ey6qo0zx.css +2 -0
- package/static/dist/assets/info-A6RAGUB7-idazwfqe.js +1 -0
- package/static/dist/assets/infoDiagram-27XIBGKW-bb9jh8gl.js +2 -0
- package/static/dist/assets/{ishikawaDiagram-5VMMS53U-e7bnwq7h.js → ishikawaDiagram-5VMMS53U-nqc132rv.js} +6 -6
- package/static/dist/assets/{java-ndjf2o89.js → java-nxbe8uju.js} +1 -1
- package/static/dist/assets/{javascript-coftlwy3.js → javascript-lz3kxcyz.js} +1 -1
- package/static/dist/assets/{jinja-etei9wy7.js → jinja-l5pk84gt.js} +1 -1
- package/static/dist/assets/{jison-hyekgft1.js → jison-jdutdwyy.js} +1 -1
- package/static/dist/assets/{journeyDiagram-3NMN7TZE-etd1bi6p.js → journeyDiagram-3NMN7TZE-fpvnhy44.js} +1 -1
- package/static/dist/assets/{json-lok0yaho.js → json-dnge4ssf.js} +1 -1
- package/static/dist/assets/{jsx-b64w0nbx.js → jsx-c3lwhkep.js} +1 -1
- package/static/dist/assets/{jsx-runtime-eu92a5pu.js → jsx-runtime-o40ukmjl.js} +1 -1
- package/static/dist/assets/{julia-jxxzz2yn.js → julia-hwd4rrcb.js} +1 -1
- package/static/dist/assets/{just-mc29iw9t.js → just-nka3oxdx.js} +1 -1
- package/static/dist/assets/{kanban-definition-UXKFOSKX-emb1g9dz.js → kanban-definition-UXKFOSKX-ndzqm6fu.js} +28 -28
- package/static/dist/assets/katex-cbdd1ohw.css +1 -0
- package/static/dist/assets/katex-pbij2oo6.js +257 -0
- package/static/dist/assets/{latex-pafa03ft.js → latex-iqmr7e40.js} +1 -1
- package/static/dist/assets/lazyRouteComponent-javud235.js +1 -0
- package/static/dist/assets/{line-h0ojzsvs.js → line-g625e7cj.js} +1 -1
- package/static/dist/assets/linear-jlwrvvy6.js +1 -0
- package/static/dist/assets/link-gfdaho08.js +2 -0
- package/static/dist/assets/{liquid-hz5c2pov.js → liquid-okmk9tbp.js} +1 -1
- package/static/dist/assets/locale-cs-n41hptse.js +5 -0
- package/static/dist/assets/locale-de-k7ht47ew.js +5 -0
- package/static/dist/assets/locale-es-ih078lco.js +5 -0
- package/static/dist/assets/locale-fr-ojabnf41.js +5 -0
- package/static/dist/assets/locale-it-kb96jufy.js +5 -0
- package/static/dist/assets/locale-ja-jpsp3xs1.js +7 -0
- package/static/dist/assets/locale-ko-cpzuy0n7.js +5 -0
- package/static/dist/assets/locale-pl-dbap4leu.js +5 -0
- package/static/dist/assets/locale-pt-nci7w72x.js +5 -0
- package/static/dist/assets/locale-ru-soghe4cs.js +7 -0
- package/static/dist/assets/locale-tr-ks00mu68.js +5 -0
- package/static/dist/assets/locale-vi-ij7twfm6.js +5 -0
- package/static/dist/assets/locale-zh-Hant-feakwr7a.js +5 -0
- package/static/dist/assets/locale-zh-ren0vjyv.js +7 -0
- package/static/dist/assets/login-iv6yq4xf.js +1 -0
- package/static/dist/assets/{lua-leyf8mlb.js → lua-krx4xj5h.js} +1 -1
- package/static/dist/assets/{marko-cn1fzpdv.js → marko-gbvpfehz.js} +1 -1
- package/static/dist/assets/{mdc-huhy88df.js → mdc-c21zlyi5.js} +1 -1
- package/static/dist/assets/mermaid-HWGCJPDP-cwj5cl6k.js +1 -0
- package/static/dist/assets/mermaid-parser.core-plzkuzov.js +7 -0
- package/static/dist/assets/micromark-factory-space-fnmnpi6s.js +1 -0
- package/static/dist/assets/{mindmap-definition-YA3MSWOX-o1vathns.js → mindmap-definition-YA3MSWOX-ojrgs569.js} +28 -28
- package/static/dist/assets/{nginx-e7lvhsmn.js → nginx-f3d68ed4.js} +1 -1
- package/static/dist/assets/{nim-dun5d8mk.js → nim-dw0jcy70.js} +1 -1
- package/static/dist/assets/onboarding-ff4emacu.js +1 -0
- package/static/dist/assets/packet-AYTQ26CC-gyaf9s8h.js +1 -0
- package/static/dist/assets/pegDiagram-XKGWAZYB-bf6xj8mq.js +1 -0
- package/static/dist/assets/{perl-bj3oqtet.js → perl-3c0r45c8.js} +1 -1
- package/static/dist/assets/{php-buzp12r0.js → php-rznhidvp.js} +1 -1
- package/static/dist/assets/pie-WAS4IAKB-f5ymzelo.js +1 -0
- package/static/dist/assets/pieDiagram-E7YTZNPT-d0qjl3zi.js +39 -0
- package/static/dist/assets/{pug-mjad7he9.js → pug-f2le4f3y.js} +1 -1
- package/static/dist/assets/{qml-d1gdp10s.js → qml-e2wbq9cr.js} +1 -1
- package/static/dist/assets/{quadrantDiagram-AXDQQJYC-owqc4uqn.js → quadrantDiagram-AXDQQJYC-oqy1mras.js} +1 -1
- package/static/dist/assets/queryKeys-x8fjxhut.js +9 -0
- package/static/dist/assets/{r-o3r9c7ao.js → r-epfzuw6q.js} +1 -1
- package/static/dist/assets/radar-RG4KPBEZ-b6jcjvda.js +1 -0
- package/static/dist/assets/railroad-74A4TZTK-e3a6lk5k.js +1 -0
- package/static/dist/assets/railroad-abnf-HS5TGJTU-ff5hocrx.js +1 -0
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-exkhyw4n.js +1 -0
- package/static/dist/assets/railroad-peg-WCYAUIDC-jefk9b7c.js +1 -0
- package/static/dist/assets/railroadDiagram-O6MQD6OU-e4amks1i.js +1 -0
- package/static/dist/assets/{razor-ilc585yr.js → razor-pea1u1d0.js} +1 -1
- package/static/dist/assets/refresh-cw-lfp4u1oh.js +1 -0
- package/static/dist/assets/{regexp-mpjtcvwm.js → regexp-hzte0a5x.js} +1 -1
- package/static/dist/assets/registry-g7w3353u.js +1 -0
- package/static/dist/assets/requirementDiagram-BXWQKSXE-c77k1e2y.js +84 -0
- package/static/dist/assets/rolldown-runtime-bnnw9q4a.js +1 -0
- package/static/dist/assets/{rst-jrkwjdyi.js → rst-m6tugj5o.js} +1 -1
- package/static/dist/assets/{ruby-n4tjcbpz.js → ruby-l19vq3w1.js} +1 -1
- package/static/dist/assets/runtime-nlxpnegr.js +1 -0
- package/static/dist/assets/{sankeyDiagram-P5KCCOFB-iqc02emv.js → sankeyDiagram-P5KCCOFB-oa1cc52s.js} +1 -1
- package/static/dist/assets/{sas-hjo6y93k.js → sas-ktdxo397.js} +1 -1
- package/static/dist/assets/{scss-ncidjv48.js → scss-kn3oxfwf.js} +1 -1
- package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-i0v116q0.js → sequenceDiagram-WJ2MYXX4-j20gqt22.js} +11 -11
- package/static/dist/assets/settings_section_extensions_title-fadc7o65.js +1 -0
- package/static/dist/assets/share._token-kmfoflw6.js +2 -0
- package/static/dist/assets/{shellscript-m8whjpqd.js → shellscript-l100jtrg.js} +1 -1
- package/static/dist/assets/{shellsession-i5bj6syz.js → shellsession-m5qukwow.js} +1 -1
- package/static/dist/assets/sizeCapture-INFHLROL-dk1io13w.js +1 -0
- package/static/dist/assets/sliders-horizontal-g5jkzd9k.js +1 -0
- package/static/dist/assets/{soy-hhh36ysq.js → soy-mexlscur.js} +1 -1
- package/static/dist/assets/{sql-j21bzcl6.js → sql-o0ho5suh.js} +1 -1
- package/static/dist/assets/src-h89s0hs4.js +1 -0
- package/static/dist/assets/{stata-bbu2onh1.js → stata-be9ck1q3.js} +1 -1
- package/static/dist/assets/stateDiagram-D77RDMKH-co2ghkdp.js +1 -0
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-faw1opgh.js +1 -0
- package/static/dist/assets/{surrealql-l5vczuco.js → surrealql-gk1xkkyy.js} +1 -1
- package/static/dist/assets/{svelte-idn422g6.js → svelte-k6ecjilf.js} +1 -1
- package/static/dist/assets/swimlanes-42K2YHIH-m30cktqe.js +1 -0
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-hfil433g.js +8 -0
- package/static/dist/assets/{templ-e22qou3c.js → templ-gf3bftk6.js} +1 -1
- package/static/dist/assets/{tex-deqpc5ee.js → tex-d21fqv1z.js} +1 -1
- package/static/dist/assets/{timeline-definition-24CTP7MA-ol2hnvma.js → timeline-definition-24CTP7MA-liuep6fl.js} +8 -8
- package/static/dist/assets/toast-zmb35u3r.js +56 -0
- package/static/dist/assets/treeView-Q6P3EWNA-np5d2jv2.js +1 -0
- package/static/dist/assets/treemap-WGGIJYW6-cmpltxh1.js +1 -0
- package/static/dist/assets/{ts-tags-ctnibc27.js → ts-tags-n0g61gr6.js} +1 -1
- package/static/dist/assets/{tsx-i163n32g.js → tsx-cvv7wv6q.js} +1 -1
- package/static/dist/assets/{twig-x0fi7wm8.js → twig-n1f67204.js} +1 -1
- package/static/dist/assets/{typescript-g18c34xz.js → typescript-og7o55cx.js} +1 -1
- package/static/dist/assets/untitled-mj86r4gz.js +1 -0
- package/static/dist/assets/useDebounced-g8r0ggve.js +1 -0
- package/static/dist/assets/useForm-f1udzsjf.js +1 -0
- package/static/dist/assets/{useParams-gjc70qru.js → useParams-ierevvts.js} +1 -1
- package/static/dist/assets/{useSearch-e6ae539u.js → useSearch-i7nr9ypl.js} +1 -1
- package/static/dist/assets/vennDiagram-4TSXK5OY-b2g42qrg.js +34 -0
- package/static/dist/assets/{vue-mwu5l1bb.js → vue-ej4xpwqw.js} +1 -1
- package/static/dist/assets/{vue-html-nskj3du0.js → vue-html-d48xsjuo.js} +1 -1
- package/static/dist/assets/{vue-vine-cqe77smq.js → vue-vine-pev88ip6.js} +1 -1
- package/static/dist/assets/wardley-WFR3VGLG-lb0eqbff.js +1 -0
- package/static/dist/assets/wardleyDiagram-VM6X3IG4-ermwaqha.js +78 -0
- package/static/dist/assets/with-selector-nu1b5z0v.js +1 -0
- package/static/dist/assets/{xml-gau7gvrv.js → xml-ifxp6gqb.js} +1 -1
- package/static/dist/assets/{xsl-ew09zq8b.js → xsl-fug2cckc.js} +1 -1
- package/static/dist/assets/{xychartDiagram-S5SC5T6Z-aqbgvujg.js → xychartDiagram-S5SC5T6Z-dll0jldk.js} +6 -6
- package/static/dist/assets/{yaml-ofnrxtvf.js → yaml-fjmafnlo.js} +1 -1
- package/static/dist/extension-sdk.js +1 -1
- package/static/dist/index.html +1 -1
- package/static/dist/sw.js +180 -136
- package/static/dist/assets/AppShell-cey33v9s.js +0 -8
- package/static/dist/assets/ChatPage-i8wnugr7.js +0 -18
- package/static/dist/assets/ConnectTargets-hg19553x.js +0 -1
- package/static/dist/assets/ExtensionRoute-cly4apm5.js +0 -1
- package/static/dist/assets/Field-j8uqoigz.js +0 -9
- package/static/dist/assets/HubRoute-e4bgz41j.js +0 -2
- package/static/dist/assets/Markdown-lahuichm.js +0 -598
- package/static/dist/assets/Markdown-lwviulmg.css +0 -1
- package/static/dist/assets/RightPanel-lbo4i0fn.js +0 -1
- package/static/dist/assets/Select-gqatm2e0.js +0 -1
- package/static/dist/assets/SessionListPanel-mfqayfjh.js +0 -1
- package/static/dist/assets/SettingsLayout-b8980u7k.js +0 -1
- package/static/dist/assets/States-e7dkgtxf.js +0 -1
- package/static/dist/assets/Toaster-bfqqy786.js +0 -1
- package/static/dist/assets/_app-n1n6pfx1.js +0 -1
- package/static/dist/assets/_app.ext._extensionId-buxjxav3.js +0 -1
- package/static/dist/assets/_app.index-jt8zwiu2.js +0 -1
- package/static/dist/assets/_app.insights-cv76ml71.js +0 -1
- package/static/dist/assets/_app.kanban-h6ts53j7.js +0 -1
- package/static/dist/assets/_app.logs-dm873z90.js +0 -1
- package/static/dist/assets/_app.memory-glk5y6m8.js +0 -1
- package/static/dist/assets/_app.profiles-ka6zpstq.js +0 -1
- package/static/dist/assets/_app.session._sessionId-g2vzghvc.js +0 -1
- package/static/dist/assets/_app.settings-hgjdhzcd.js +0 -1
- package/static/dist/assets/_app.settings._section-jf2kmhae.js +0 -3
- package/static/dist/assets/_app.skills-cii852yq.js +0 -1
- package/static/dist/assets/_app.tasks-fp9q7atm.js +0 -1
- package/static/dist/assets/_app.todos-dw94qzue.js +0 -1
- package/static/dist/assets/_app.workspaces-inyygzze.js +0 -1
- package/static/dist/assets/abnfDiagram-VCTEODGH-gjayq3ra.js +0 -1
- package/static/dist/assets/architecture-7GRP2DOG-lp56972r.js +0 -1
- package/static/dist/assets/architectureDiagram-5GKGNRK7-nwb3xovn.js +0 -36
- package/static/dist/assets/archive-b1j004vn.js +0 -1
- package/static/dist/assets/back-g74gkozu.js +0 -1
- package/static/dist/assets/channel-es95o4y8.js +0 -1
- package/static/dist/assets/chunk-DU6HZSFF-gpedttsp.js +0 -128
- package/static/dist/assets/chunk-OSK3NFVY-oy0gwn2n.js +0 -10
- package/static/dist/assets/classDiagram-ZZMXUADV-kmihoqxh.js +0 -1
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-kmihoqxh.js +0 -1
- package/static/dist/assets/copied-bli9tbcx.js +0 -1
- package/static/dist/assets/copy-jamtd1pf.js +0 -1
- package/static/dist/assets/cose-bilkent-JH36ORCC-eclcy6ja.js +0 -1
- package/static/dist/assets/cynefin-OW5HDTMX-f8xfdd3f.js +0 -1
- package/static/dist/assets/cynefinDiagram-5FMLGOSQ-n9lb99h9.js +0 -62
- package/static/dist/assets/cytoscape.esm-bqu53u12.js +0 -321
- package/static/dist/assets/dagre-GXQ25YYZ-dgailddi.js +0 -4
- package/static/dist/assets/dagre-lkoknbjn.js +0 -1
- package/static/dist/assets/diagram-UQ7AKVKN-jall3j0x.js +0 -41
- package/static/dist/assets/diagram-VX7I27RA-hendl2tt.js +0 -24
- package/static/dist/assets/diagram-Z3DM3KII-igwc35p3.js +0 -24
- package/static/dist/assets/ebnfDiagram-PWID7BFC-c64knz08.js +0 -1
- package/static/dist/assets/erDiagram-RLTQ6QDP-brdu9lcm.js +0 -99
- package/static/dist/assets/eventmodeling-NTZA5JFV-njk1j8wl.js +0 -1
- package/static/dist/assets/flowDiagram-HODETNUW-nma6f0ga.js +0 -1
- package/static/dist/assets/folder-plus-lvt9kudb.js +0 -1
- package/static/dist/assets/gitGraph-4MIJSDKK-naa9w6xa.js +0 -1
- package/static/dist/assets/highlighted-body-KPVGNVTW-ghoavj8d.js +0 -1
- package/static/dist/assets/host-hzm8n85n.js +0 -1
- package/static/dist/assets/index-drdcaqeq.css +0 -2
- package/static/dist/assets/index-jzm844he.js +0 -11
- package/static/dist/assets/info-A6RAGUB7-mn2ut5ko.js +0 -1
- package/static/dist/assets/infoDiagram-27XIBGKW-h6kuqvsb.js +0 -2
- package/static/dist/assets/lazyRouteComponent-o816ytzl.js +0 -1
- package/static/dist/assets/linear-becwlnhk.js +0 -1
- package/static/dist/assets/link-k01ryaf9.js +0 -1
- package/static/dist/assets/login-bsae49ew.js +0 -1
- package/static/dist/assets/mermaid-HWGCJPDP-ihl34s74.js +0 -1
- package/static/dist/assets/mermaid-parser.core-bnre27u8.js +0 -7
- package/static/dist/assets/not-found-ccnnac39.js +0 -1
- package/static/dist/assets/onboarding-c65tysya.js +0 -1
- package/static/dist/assets/onboarding_model_label-gpn28uix.js +0 -1
- package/static/dist/assets/packet-AYTQ26CC-hatq7m2e.js +0 -1
- package/static/dist/assets/pegDiagram-XKGWAZYB-gwisz8jv.js +0 -1
- package/static/dist/assets/pie-WAS4IAKB-fpftf0mk.js +0 -1
- package/static/dist/assets/pieDiagram-E7YTZNPT-khm1o9a6.js +0 -39
- package/static/dist/assets/radar-RG4KPBEZ-cntfwjpq.js +0 -1
- package/static/dist/assets/railroad-74A4TZTK-a7t5eibp.js +0 -1
- package/static/dist/assets/railroad-abnf-HS5TGJTU-ol8cdktf.js +0 -1
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-i8vzd429.js +0 -1
- package/static/dist/assets/railroad-peg-WCYAUIDC-nw3ulewz.js +0 -1
- package/static/dist/assets/railroadDiagram-O6MQD6OU-etuh0qa0.js +0 -1
- package/static/dist/assets/refresh-cw-mqbkv2a3.js +0 -1
- package/static/dist/assets/refresh-l29ljp76.js +0 -1
- package/static/dist/assets/requirementDiagram-BXWQKSXE-oq2ulk22.js +0 -84
- package/static/dist/assets/rolldown-runtime-b9miacsj.js +0 -1
- package/static/dist/assets/root-mbklpuv4.js +0 -1
- package/static/dist/assets/saved-ndd4t2xb.js +0 -1
- package/static/dist/assets/settings_section_extensions_title-jhfo6o8z.js +0 -1
- package/static/dist/assets/share._token-c1ri0hy1.js +0 -2
- package/static/dist/assets/sizeCapture-INFHLROL-g612l48j.js +0 -1
- package/static/dist/assets/sliders-horizontal-j3jjt9tv.js +0 -1
- package/static/dist/assets/src-hjyib4mu.js +0 -1
- package/static/dist/assets/stateDiagram-D77RDMKH-dnpt1ato.js +0 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-bxjacpk6.js +0 -1
- package/static/dist/assets/swimlanes-42K2YHIH-loqbdazb.js +0 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-id62p9hz.js +0 -8
- package/static/dist/assets/toast-i3h34v6o.js +0 -64
- package/static/dist/assets/treeView-Q6P3EWNA-idrj6iox.js +0 -1
- package/static/dist/assets/treemap-WGGIJYW6-lzr49vv5.js +0 -1
- package/static/dist/assets/untitled-oaoya4qj.js +0 -1
- package/static/dist/assets/useForm-nfaxgmsk.js +0 -1
- package/static/dist/assets/vennDiagram-4TSXK5OY-bvwr9o2z.js +0 -34
- package/static/dist/assets/wardley-WFR3VGLG-31ui8tma.js +0 -1
- package/static/dist/assets/wardleyDiagram-VM6X3IG4-k5wqtx4b.js +0 -78
- /package/static/dist/assets/{ChatPage-gmu5c7lf.css → TerminalPanel-gmu5c7lf.css} +0 -0
|
@@ -20,7 +20,7 @@ from contextlib import closing, contextmanager
|
|
|
20
20
|
from pathlib import Path
|
|
21
21
|
|
|
22
22
|
from ..errors import InvalidParams, RpcError
|
|
23
|
-
from ..home import profile_home_param
|
|
23
|
+
from ..home import profile_home_param, scoped_home
|
|
24
24
|
from ..rpc import CallContext
|
|
25
25
|
|
|
26
26
|
log = logging.getLogger("talaria_sidecar.state_db")
|
|
@@ -52,30 +52,107 @@ def _session_id(params: dict) -> str:
|
|
|
52
52
|
return sid
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
# TAL-1191: write RPCs borrow the Agent's shared registry handle for the home's state.db (the one cached chat agents
|
|
56
|
+
# hold) instead of a full writer open and close-time checkpoint per call. One extra reference per home stays pinned for
|
|
57
|
+
# _IDLE_RELEASE_S after its last write; the registry hands out a fresh generation once the file is replaced.
|
|
58
|
+
_IDLE_RELEASE_S = 60.0
|
|
59
|
+
_pins_lock = threading.Lock()
|
|
60
|
+
_pins: dict[str, tuple[object, threading.Timer]] = {}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def release_session_db(db) -> None:
|
|
64
|
+
"""Give back a registry reference (a cached agent's or a write pin); the final one closes the handle."""
|
|
65
|
+
if db is None:
|
|
66
|
+
return
|
|
59
67
|
try:
|
|
60
|
-
|
|
61
|
-
|
|
68
|
+
from hermes_state_registry import release_or_close
|
|
69
|
+
|
|
70
|
+
release_or_close(db)
|
|
62
71
|
except Exception: # noqa: BLE001
|
|
63
|
-
log.
|
|
72
|
+
log.warning("releasing a state.db handle failed", exc_info=True)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _write(home: Path, what: str, op, *, level: int = logging.DEBUG) -> bool:
|
|
76
|
+
"""Run ``op(db)`` on the shared handle; False without a state.db or when it fails. A failed write unpins the handle,
|
|
77
|
+
so the next one reopens it unless another holder keeps it."""
|
|
78
|
+
try:
|
|
79
|
+
from hermes_state_registry import acquire
|
|
80
|
+
except ImportError as exc:
|
|
81
|
+
raise RpcError("hermes_state unavailable", condition="state_db_unavailable") from exc
|
|
82
|
+
db_path = home / "state.db"
|
|
83
|
+
if not db_path.exists():
|
|
64
84
|
return False
|
|
65
|
-
|
|
66
|
-
|
|
85
|
+
try:
|
|
86
|
+
db = acquire(db_path)
|
|
87
|
+
except Exception as exc: # noqa: BLE001
|
|
88
|
+
log.debug("Failed to open state.db at %s: %s", db_path, exc)
|
|
89
|
+
return False
|
|
90
|
+
key = os.path.realpath(home)
|
|
91
|
+
# This call's reference keeps the same generation open; a retired one (replaced file) closes before its replacement
|
|
92
|
+
# is written, so its close-time checkpoint cannot carry the new rows into the old inode.
|
|
93
|
+
_pin(key, None)
|
|
94
|
+
ok = False
|
|
95
|
+
try:
|
|
96
|
+
op(db)
|
|
97
|
+
ok = True
|
|
98
|
+
except Exception: # noqa: BLE001
|
|
99
|
+
log.log(level, "Failed to %s", what, exc_info=True)
|
|
100
|
+
if ok and db_path.exists():
|
|
101
|
+
_pin(key, db)
|
|
102
|
+
else:
|
|
103
|
+
release_session_db(db)
|
|
104
|
+
return ok
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _pin(key: str, db) -> None:
|
|
108
|
+
"""Make ``db`` (this call's reference) the home's pin with a fresh idle timer, giving back the previous pin."""
|
|
109
|
+
with _pins_lock:
|
|
110
|
+
previous = _pins.pop(key, None)
|
|
111
|
+
if previous is not None:
|
|
112
|
+
previous[1].cancel()
|
|
113
|
+
if db is not None:
|
|
114
|
+
timer = threading.Timer(_IDLE_RELEASE_S, lambda: _expire(key, timer))
|
|
115
|
+
timer.daemon = True
|
|
116
|
+
_pins[key] = (db, timer)
|
|
117
|
+
timer.start()
|
|
118
|
+
if previous is not None: # outside the lock: a final release checkpoints
|
|
119
|
+
release_session_db(previous[0])
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _expire(key: str, timer: threading.Timer) -> None:
|
|
123
|
+
with _pins_lock:
|
|
124
|
+
pinned = _pins.get(key)
|
|
125
|
+
if pinned is None or pinned[1] is not timer:
|
|
126
|
+
return
|
|
127
|
+
del _pins[key]
|
|
128
|
+
release_session_db(pinned[0])
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def release_home(home) -> None:
|
|
132
|
+
"""Give back the pinned handle for ``home`` before its profile is deleted."""
|
|
133
|
+
_pin(os.path.realpath(home), None)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def release_all() -> None:
|
|
137
|
+
"""Shutdown: give back every pinned handle, so the final release still checkpoints once per process."""
|
|
138
|
+
with _pins_lock:
|
|
139
|
+
keys = list(_pins)
|
|
140
|
+
for key in keys:
|
|
141
|
+
_pin(key, None)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def sync_session_start(home: Path, session_id: str, model=None) -> bool:
|
|
145
|
+
return _write(home, "sync session start", lambda db: db.ensure_session(session_id=session_id, source="webui", model=model))
|
|
67
146
|
|
|
68
147
|
|
|
69
148
|
def sync_session_usage(home: Path, session_id: str, *, input_tokens=0, output_tokens=0, estimated_cost=None, model=None, title=None,
|
|
70
149
|
message_count=None, cache_read_tokens=0, cache_write_tokens=0, api_call_count=None) -> bool:
|
|
71
|
-
db
|
|
72
|
-
|
|
73
|
-
return False
|
|
74
|
-
try:
|
|
75
|
-
db.ensure_session(session_id=session_id, source="webui", model=model)
|
|
150
|
+
def op(db) -> None:
|
|
151
|
+
# The token update's own row guard creates the session with this source, like ``ensure_session``.
|
|
76
152
|
db.update_token_counts(
|
|
77
153
|
session_id=session_id, input_tokens=input_tokens, output_tokens=output_tokens, cache_read_tokens=cache_read_tokens,
|
|
78
154
|
cache_write_tokens=cache_write_tokens, api_call_count=api_call_count or 0, estimated_cost_usd=estimated_cost, model=model, absolute=True,
|
|
155
|
+
source="webui",
|
|
79
156
|
)
|
|
80
157
|
if title:
|
|
81
158
|
try:
|
|
@@ -87,22 +164,16 @@ def sync_session_usage(home: Path, session_id: str, *, input_tokens=0, output_to
|
|
|
87
164
|
db._execute_write(lambda conn: conn.execute("UPDATE sessions SET message_count = ? WHERE id = ?", (message_count, session_id)))
|
|
88
165
|
except Exception: # noqa: BLE001
|
|
89
166
|
log.debug("Failed to sync message count", exc_info=True)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
log.debug("Failed to sync session usage", exc_info=True)
|
|
93
|
-
return False
|
|
94
|
-
finally:
|
|
95
|
-
_close(db)
|
|
167
|
+
|
|
168
|
+
return _write(home, "sync session usage", op)
|
|
96
169
|
|
|
97
170
|
|
|
98
171
|
def sync_session_title(home: Path, session_id: str, title: str, *, manual: bool = False) -> bool:
|
|
99
172
|
"""A manual (user-requested) title lands with ``user`` provenance; an auto title is ``llm`` and never replaces a user name."""
|
|
100
173
|
if not title:
|
|
101
174
|
return False
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return False
|
|
105
|
-
try:
|
|
175
|
+
|
|
176
|
+
def op(db) -> None:
|
|
106
177
|
db.ensure_session(session_id=session_id, source="webui")
|
|
107
178
|
source = getattr(db, "TITLE_SOURCE_LLM", "llm")
|
|
108
179
|
|
|
@@ -118,28 +189,16 @@ def sync_session_title(home: Path, session_id: str, title: str, *, manual: bool
|
|
|
118
189
|
alt = db.get_next_title_in_lineage(title)
|
|
119
190
|
if alt and alt != title:
|
|
120
191
|
write(alt)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
log.debug("Failed to sync session title", exc_info=True)
|
|
124
|
-
return False
|
|
125
|
-
finally:
|
|
126
|
-
_close(db)
|
|
192
|
+
|
|
193
|
+
return _write(home, "sync session title", op)
|
|
127
194
|
|
|
128
195
|
|
|
129
196
|
def append_message(home: Path, session_id: str, *, role: str, content: str, tool_name=None, timestamp=None) -> bool:
|
|
130
197
|
"""TAL-258 (predecessor ``_persist_handoff_summary_to_state_db``): one row through ``SessionDB.append_message``,
|
|
131
198
|
which also bumps the session's ``message_count``. False without a state.db or when the write fails."""
|
|
132
|
-
db
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
try:
|
|
136
|
-
db.append_message(session_id, role, content=content, tool_name=tool_name or None, timestamp=timestamp)
|
|
137
|
-
return True
|
|
138
|
-
except Exception: # noqa: BLE001
|
|
139
|
-
log.warning("Failed to append a %s row to state.db for %s", role, session_id, exc_info=True)
|
|
140
|
-
return False
|
|
141
|
-
finally:
|
|
142
|
-
_close(db)
|
|
199
|
+
return _write(home, f"append a {role} row to state.db for {session_id}",
|
|
200
|
+
lambda db: db.append_message(session_id, role, content=content, tool_name=tool_name or None, timestamp=timestamp),
|
|
201
|
+
level=logging.WARNING)
|
|
143
202
|
|
|
144
203
|
|
|
145
204
|
def _close(db) -> None:
|
|
@@ -437,6 +496,11 @@ def _delete_runtime_rows(requested: str, home: Path, agent_db, guarded, delete_i
|
|
|
437
496
|
return result["deleted_ids"]
|
|
438
497
|
|
|
439
498
|
deleted_ids = agent_db._execute_write(write)
|
|
499
|
+
# Agent v0.22.3+ tells the profile's plugins after the commit, like its own deletes; the emitter is fail-open.
|
|
500
|
+
import hermes_state_common
|
|
501
|
+
emit_session_deleted = getattr(hermes_state_common, "emit_session_deleted", None)
|
|
502
|
+
if emit_session_deleted is not None:
|
|
503
|
+
emit_session_deleted(agent_db, deleted_ids, reason="delete", primary=requested, sessions_dir=home / "sessions")
|
|
440
504
|
try:
|
|
441
505
|
collect_retired_media(agent_db)
|
|
442
506
|
except Exception: # noqa: BLE001 - retirement committed; retain its targets for caller cleanup and manifest retry
|
|
@@ -624,6 +688,22 @@ def delete_cli_session(home: Path, sid: str, include_lineage: bool = False) -> d
|
|
|
624
688
|
return {"ok": False}
|
|
625
689
|
|
|
626
690
|
|
|
691
|
+
def prune_advice(home: Path) -> dict | None:
|
|
692
|
+
"""The Agent's low-disk session auto-prune question for ``home`` (v0.22.3 ``hermes_cli.prune_advisor``) in its own
|
|
693
|
+
words; None while the Agent would not ask (disk not low, ``sessions.auto_prune`` set, snoozed) or has no advisor."""
|
|
694
|
+
try:
|
|
695
|
+
from hermes_cli import prune_advisor
|
|
696
|
+
except ImportError:
|
|
697
|
+
return None
|
|
698
|
+
advice, stale = prune_advisor.cached_advice(home)
|
|
699
|
+
if advice is None and not stale:
|
|
700
|
+
return None
|
|
701
|
+
if advice is None or stale:
|
|
702
|
+
# Measures state.db (seconds on a large store), on this request's own worker thread.
|
|
703
|
+
advice = prune_advisor.advise(home)
|
|
704
|
+
return {"lines": prune_advisor.advice_lines(advice, command_prefix="/")} if advice else None
|
|
705
|
+
|
|
706
|
+
|
|
627
707
|
def register(registry) -> None:
|
|
628
708
|
@registry.method("state_db.sync_start")
|
|
629
709
|
def start(ctx: CallContext, params: dict) -> dict:
|
|
@@ -657,3 +737,9 @@ def register(registry) -> None:
|
|
|
657
737
|
if not _is_safe_session_id(sid):
|
|
658
738
|
raise InvalidParams("unsafe session_id")
|
|
659
739
|
return delete_cli_session(profile_home_param(params).resolve(), sid, params.get("include_compression_lineage") is True)
|
|
740
|
+
|
|
741
|
+
@registry.method("state_db.prune_advice")
|
|
742
|
+
def prune_advice_(ctx: CallContext, params: dict) -> dict:
|
|
743
|
+
home = profile_home_param(params)
|
|
744
|
+
with scoped_home(home):
|
|
745
|
+
return {"advice": prune_advice(home)}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
"""Profile toolset policy and catalog. All callers run under ``scoped_home``."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
from ..home import profile_home_param, scoped_home
|
|
4
6
|
|
|
5
7
|
|
|
6
|
-
def disabled_toolsets() -> list[str]:
|
|
8
|
+
def disabled_toolsets(cfg: dict | None = None) -> list[str]:
|
|
7
9
|
from agent.skill_utils import parse_config_string_list
|
|
8
10
|
from hermes_cli.config import load_config
|
|
9
11
|
|
|
10
|
-
section = (load_config() or {}).get('agent') or {}
|
|
12
|
+
section = ((load_config() or {}) if cfg is None else cfg).get('agent') or {}
|
|
11
13
|
return [name.strip() for name in parse_config_string_list(section.get('disabled_toolsets')) if name.strip()]
|
|
12
14
|
|
|
13
15
|
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
"""``worktree.*``: Hermes Agent git worktree creation (``hermes_cli.worktree_ops._setup_worktree``)."""
|
|
1
|
+
"""``worktree.*``: Hermes Agent git worktree creation (``hermes_cli.worktree_ops._setup_worktree``) and lock retention."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import contextlib
|
|
5
6
|
import io
|
|
6
7
|
import logging
|
|
8
|
+
import os
|
|
9
|
+
import re
|
|
7
10
|
import subprocess
|
|
11
|
+
import uuid
|
|
8
12
|
from contextlib import redirect_stderr, redirect_stdout
|
|
9
13
|
from pathlib import Path
|
|
10
14
|
|
|
@@ -41,6 +45,112 @@ def _refuse_unneutralized_repo_filters(repo_root: str) -> None:
|
|
|
41
45
|
condition="worktree_unsafe_repo")
|
|
42
46
|
|
|
43
47
|
|
|
48
|
+
# The Agent's own lock contract (``worktree_ops._worktree_lock_is_live``): its sweep keeps a tree whose ``hermes pid=`` owner runs.
|
|
49
|
+
_HERMES_PID_LOCK = re.compile(r"hermes pid=(\d+)(?: db=.+)?", re.DOTALL)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _pid_alive(pid: int) -> bool:
|
|
53
|
+
try:
|
|
54
|
+
os.kill(pid, 0)
|
|
55
|
+
except (ProcessLookupError, OverflowError): # gone, or a pid no process can have
|
|
56
|
+
return False
|
|
57
|
+
except OSError:
|
|
58
|
+
return True # exists, owned by someone else
|
|
59
|
+
return True
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# Only these say the tree or its registration is gone; any other read failure leaves the tree unconfirmed (raised).
|
|
63
|
+
_GONE = (FileNotFoundError, NotADirectoryError, IsADirectoryError)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _admin_dir(tree: Path) -> Path | None:
|
|
67
|
+
"""The tree's ``<common-dir>/worktrees/<name>`` entry when git still registers it as a linked worktree."""
|
|
68
|
+
try:
|
|
69
|
+
link = (tree / ".git").read_text(encoding="utf-8-sig")
|
|
70
|
+
except _GONE:
|
|
71
|
+
return None
|
|
72
|
+
if not link.startswith("gitdir:"):
|
|
73
|
+
return None
|
|
74
|
+
admin = (tree / link[len("gitdir:"):].strip()).resolve()
|
|
75
|
+
try:
|
|
76
|
+
registered = Path((admin / "gitdir").read_text(encoding="utf-8-sig").strip()).resolve()
|
|
77
|
+
except _GONE:
|
|
78
|
+
return None
|
|
79
|
+
return admin if admin.parent.name == "worktrees" and registered == (tree / ".git").resolve() else None
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _take_lock(admin: Path, expected: str) -> bool:
|
|
83
|
+
"""Remove the tree's lock only while it still reads ``expected``: it is moved aside first, so a lock written since it
|
|
84
|
+
was read is never deleted; anything else is put back unless a newer lock already holds the tree."""
|
|
85
|
+
lock, aside = admin / "locked", admin / f"locked.talaria-{uuid.uuid4().hex}"
|
|
86
|
+
try:
|
|
87
|
+
os.rename(lock, aside)
|
|
88
|
+
except FileNotFoundError:
|
|
89
|
+
return True
|
|
90
|
+
try:
|
|
91
|
+
stale = aside.read_text(encoding="utf-8-sig", errors="replace").strip(" \t\n\v\f\r") == expected
|
|
92
|
+
except OSError:
|
|
93
|
+
stale = False
|
|
94
|
+
if not stale:
|
|
95
|
+
try:
|
|
96
|
+
os.link(aside, lock)
|
|
97
|
+
except FileExistsError:
|
|
98
|
+
pass # a newer lock holds the tree
|
|
99
|
+
except OSError:
|
|
100
|
+
# No hard link here: move it back whole, never leave the tree unlocked by dropping it.
|
|
101
|
+
with contextlib.suppress(OSError):
|
|
102
|
+
os.rename(aside, lock)
|
|
103
|
+
return False
|
|
104
|
+
aside.unlink(missing_ok=True)
|
|
105
|
+
return stale
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def retain(path: str) -> str:
|
|
109
|
+
"""Lock a Talaria worktree for this process, so the Agent's sweep reads its lock live (TAL-1254).
|
|
110
|
+
|
|
111
|
+
``missing`` when the tree is gone or git no longer registers it; ``foreign_lock`` when a lock that is not a ``hermes
|
|
112
|
+
pid=`` lock (a user's own) holds it, which stays untouched. A ``hermes pid=`` lock of an exited process is replaced;
|
|
113
|
+
one of a live other process (a reused pid, another instance) is left alone and raises, so the caller retries until
|
|
114
|
+
this sidecar holds the lock.
|
|
115
|
+
"""
|
|
116
|
+
tree = Path(path)
|
|
117
|
+
admin = _admin_dir(tree)
|
|
118
|
+
if admin is None:
|
|
119
|
+
return "missing"
|
|
120
|
+
ours = f"hermes pid={os.getpid()}"
|
|
121
|
+
try:
|
|
122
|
+
reason = (admin / "locked").read_text(encoding="utf-8-sig", errors="replace").strip(" \t\n\v\f\r")
|
|
123
|
+
except FileNotFoundError:
|
|
124
|
+
reason = None
|
|
125
|
+
if reason == ours:
|
|
126
|
+
return "retained"
|
|
127
|
+
if reason is not None:
|
|
128
|
+
lock = _HERMES_PID_LOCK.fullmatch(reason)
|
|
129
|
+
if lock is None:
|
|
130
|
+
return "foreign_lock"
|
|
131
|
+
if int(lock.group(1)) != os.getpid() and _pid_alive(int(lock.group(1))):
|
|
132
|
+
raise OSError(f"locked by running pid {lock.group(1)}")
|
|
133
|
+
if not _take_lock(admin, reason):
|
|
134
|
+
raise OSError("the lock changed while it was being replaced")
|
|
135
|
+
# git refuses to lock a tree someone locked meanwhile, so that lock stays too.
|
|
136
|
+
locked = subprocess.run(["git", "-C", str(tree), "worktree", "lock", "--reason", ours, str(tree)],
|
|
137
|
+
capture_output=True, timeout=10, check=False, stdin=subprocess.DEVNULL)
|
|
138
|
+
if locked.returncode != 0:
|
|
139
|
+
raise OSError(locked.stderr.decode(errors="replace").strip() or "git worktree lock failed")
|
|
140
|
+
return "retained"
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def retain_all(paths: list[str]) -> dict[str, str]:
|
|
144
|
+
"""``retain`` per path; a tree this sidecar cannot lock now is left out (unknown), never reported missing."""
|
|
145
|
+
results = {}
|
|
146
|
+
for path in dict.fromkeys(paths):
|
|
147
|
+
try:
|
|
148
|
+
results[path] = retain(path)
|
|
149
|
+
except (OSError, subprocess.SubprocessError) as exc:
|
|
150
|
+
log.warning("Could not retain worktree %s: %s", path, exc)
|
|
151
|
+
return results
|
|
152
|
+
|
|
153
|
+
|
|
44
154
|
def create(repo_root: str) -> dict:
|
|
45
155
|
root = Path(repo_root).expanduser()
|
|
46
156
|
if not root.is_dir():
|
|
@@ -60,8 +170,10 @@ def create(repo_root: str) -> dict:
|
|
|
60
170
|
log.debug("Hermes Agent worktree helper output: %s", emitted)
|
|
61
171
|
if not info or not info.get("path") or not info.get("branch"):
|
|
62
172
|
raise RpcError("Hermes Agent failed to create a git worktree", condition="worktree_failed")
|
|
173
|
+
path = str(Path(info["path"]).expanduser().resolve())
|
|
174
|
+
retain_all([path]) # one owner for Talaria's lock text
|
|
63
175
|
return {
|
|
64
|
-
"path":
|
|
176
|
+
"path": path,
|
|
65
177
|
"branch": str(info["branch"]),
|
|
66
178
|
"repo_root": str(Path(info.get("repo_root") or probe.stdout.strip()).expanduser().resolve()),
|
|
67
179
|
"base": str(info["base"]) if info.get("base") else None,
|
|
@@ -76,3 +188,10 @@ def register(registry) -> None:
|
|
|
76
188
|
raise InvalidParams("repo_root is required")
|
|
77
189
|
with scoped_home(profile_home_param(params)):
|
|
78
190
|
return create(repo_root)
|
|
191
|
+
|
|
192
|
+
@registry.method("worktree.retain")
|
|
193
|
+
def retain_(ctx: CallContext, params: dict) -> dict:
|
|
194
|
+
paths = params.get("paths")
|
|
195
|
+
if not isinstance(paths, list) or not all(isinstance(p, str) and p for p in paths):
|
|
196
|
+
raise InvalidParams("paths must be a list of worktree paths")
|
|
197
|
+
return {"results": retain_all(paths)}
|
|
@@ -21,6 +21,8 @@ import threading
|
|
|
21
21
|
import traceback
|
|
22
22
|
from typing import Any, Callable
|
|
23
23
|
|
|
24
|
+
from .startup_timing import StartupTiming, outcome_for
|
|
25
|
+
|
|
24
26
|
from .errors import (
|
|
25
27
|
APPLICATION_ERROR,
|
|
26
28
|
INTERNAL_ERROR,
|
|
@@ -42,11 +44,12 @@ DEFAULT_MAX_CALLS = 64
|
|
|
42
44
|
class CallContext:
|
|
43
45
|
"""Per-request handle: stream emission and cooperative cancellation."""
|
|
44
46
|
|
|
45
|
-
def __init__(self, server: "RpcServer", request_id: Any, method: str):
|
|
47
|
+
def __init__(self, server: "RpcServer", request_id: Any, method: str, request: dict | None = None):
|
|
46
48
|
self.server = server
|
|
47
49
|
self.id = request_id
|
|
48
50
|
self.method = method
|
|
49
51
|
self.cancel_event = threading.Event()
|
|
52
|
+
self.timing = StartupTiming(request) if method == "chat.start" and request is not None else None
|
|
50
53
|
self._seq = 0
|
|
51
54
|
self._seq_lock = threading.Lock()
|
|
52
55
|
|
|
@@ -63,6 +66,8 @@ class CallContext:
|
|
|
63
66
|
with self._seq_lock:
|
|
64
67
|
self._seq += 1
|
|
65
68
|
seq = self._seq
|
|
69
|
+
if self.timing:
|
|
70
|
+
self.timing.frame(event, data)
|
|
66
71
|
self.server.notify("stream", {"id": self.id, "seq": seq, "event": event, "data": data if data is not None else {}})
|
|
67
72
|
|
|
68
73
|
|
|
@@ -127,6 +132,8 @@ class RpcServer:
|
|
|
127
132
|
with self._active_lock:
|
|
128
133
|
for ctx in self._active.values():
|
|
129
134
|
ctx.cancel_event.set()
|
|
135
|
+
if ctx.timing:
|
|
136
|
+
ctx.timing.finish("unknown")
|
|
130
137
|
|
|
131
138
|
# ── dispatch ──────────────────────────────────────────────────────────
|
|
132
139
|
def _register(self, request: dict) -> CallContext | None:
|
|
@@ -135,7 +142,7 @@ class RpcServer:
|
|
|
135
142
|
method = request.get("method")
|
|
136
143
|
if request_id is None or not isinstance(method, str):
|
|
137
144
|
return None
|
|
138
|
-
ctx = CallContext(self, request_id, method)
|
|
145
|
+
ctx = CallContext(self, request_id, method, request)
|
|
139
146
|
with self._active_lock:
|
|
140
147
|
self._active[request_id] = ctx
|
|
141
148
|
return ctx
|
|
@@ -147,6 +154,8 @@ class RpcServer:
|
|
|
147
154
|
if params is None:
|
|
148
155
|
params = {}
|
|
149
156
|
if not isinstance(method, str) or not isinstance(params, dict):
|
|
157
|
+
if ctx and ctx.timing:
|
|
158
|
+
ctx.timing.finish("refused")
|
|
150
159
|
if request_id is not None:
|
|
151
160
|
with self._active_lock:
|
|
152
161
|
self._active.pop(request_id, None)
|
|
@@ -160,19 +169,28 @@ class RpcServer:
|
|
|
160
169
|
self._error(request_id, METHOD_NOT_FOUND, f"unknown method {method}")
|
|
161
170
|
return
|
|
162
171
|
if ctx is None:
|
|
163
|
-
ctx = CallContext(self, request_id, method)
|
|
172
|
+
ctx = CallContext(self, request_id, method, request)
|
|
164
173
|
if request_id is not None:
|
|
165
174
|
with self._active_lock:
|
|
166
175
|
self._active[request_id] = ctx
|
|
176
|
+
outcome = "error"
|
|
177
|
+
if ctx.timing:
|
|
178
|
+
ctx.timing.end("rpc_wait")
|
|
179
|
+
ctx.timing.observe("rpc_start")
|
|
167
180
|
try:
|
|
168
181
|
result = handler(ctx, params)
|
|
182
|
+
status = result.get("status") if isinstance(result, dict) else None
|
|
183
|
+
failed = isinstance(result, dict) and bool(result.get("failed") or result.get("partial") or result.get("error"))
|
|
184
|
+
outcome = "cancelled" if ctx.cancelled or status == "cancelled" else "error" if status == "error" or failed else "ok"
|
|
169
185
|
if request_id is not None:
|
|
170
186
|
self._result(request_id, result if result is not None else {})
|
|
171
187
|
except RpcError as exc:
|
|
188
|
+
outcome = outcome_for(exc)
|
|
172
189
|
if request_id is not None:
|
|
173
190
|
error = exc.to_json()
|
|
174
191
|
self._error(request_id, error["code"], error["message"], error.get("data"))
|
|
175
192
|
except TypeError as exc:
|
|
193
|
+
outcome = "refused"
|
|
176
194
|
# Wrong keyword arguments reaching a wrapped Agent function.
|
|
177
195
|
log.debug("invalid params for %s", method, exc_info=True)
|
|
178
196
|
if request_id is not None:
|
|
@@ -182,6 +200,8 @@ class RpcServer:
|
|
|
182
200
|
if request_id is not None:
|
|
183
201
|
self._error(request_id, INTERNAL_ERROR, f"{type(exc).__name__}: {exc}")
|
|
184
202
|
finally:
|
|
203
|
+
if ctx.timing:
|
|
204
|
+
ctx.timing.finish(outcome)
|
|
185
205
|
if request_id is not None:
|
|
186
206
|
with self._active_lock:
|
|
187
207
|
self._active.pop(request_id, None)
|
|
@@ -237,6 +257,8 @@ class RpcServer:
|
|
|
237
257
|
self._dispatch(request)
|
|
238
258
|
continue
|
|
239
259
|
if not self._slots.acquire(blocking=False):
|
|
260
|
+
if request.get("method") == "chat.start":
|
|
261
|
+
StartupTiming(request).finish("refused")
|
|
240
262
|
self._error(request.get("id"), APPLICATION_ERROR, "sidecar is at its concurrent call limit", {"condition": "sidecar_busy"})
|
|
241
263
|
continue
|
|
242
264
|
ctx = self._register(request)
|
|
@@ -270,6 +270,7 @@ class AgentRuntime:
|
|
|
270
270
|
self._stale = False
|
|
271
271
|
self._source_changed = False
|
|
272
272
|
self._stale_stamp: tuple | None = None
|
|
273
|
+
self._receipt_discovery: dict = {}
|
|
273
274
|
self.agent_dir = Path(agent_dir).resolve() if agent_dir else None
|
|
274
275
|
self.pin = read_pin()
|
|
275
276
|
self.loaded = False
|
|
@@ -277,10 +278,14 @@ class AgentRuntime:
|
|
|
277
278
|
self.revision: str | None = None
|
|
278
279
|
self.import_error: str | None = None
|
|
279
280
|
self._lock = threading.Lock()
|
|
281
|
+
self._handoff = None
|
|
282
|
+
self._retired = False
|
|
280
283
|
|
|
281
284
|
# ── loading ───────────────────────────────────────────────────────────
|
|
282
285
|
def load(self) -> None:
|
|
283
286
|
with self._lock:
|
|
287
|
+
if self._retired:
|
|
288
|
+
raise AgentRuntimeStale(None)
|
|
284
289
|
if self.loaded:
|
|
285
290
|
return
|
|
286
291
|
try:
|
|
@@ -296,7 +301,20 @@ class AgentRuntime:
|
|
|
296
301
|
# a named profile's plugin loaded later never enters that process-wide snapshot.
|
|
297
302
|
importlib.import_module("hermes_cli.auth")
|
|
298
303
|
_check_site_packages_python()
|
|
304
|
+
try:
|
|
305
|
+
handoff = importlib.import_module("hermes_cli.guest_handoff")
|
|
306
|
+
except ModuleNotFoundError as exc:
|
|
307
|
+
if exc.name != "hermes_cli.guest_handoff":
|
|
308
|
+
raise
|
|
309
|
+
else:
|
|
310
|
+
# Retain custody even when startup raises after creating its thread.
|
|
311
|
+
if not callable(handoff.start_worker) or not callable(handoff.stop_worker):
|
|
312
|
+
raise RuntimeError("Native handoff lifecycle API is incomplete")
|
|
313
|
+
self._handoff = handoff
|
|
314
|
+
if not handoff.start_worker().is_alive():
|
|
315
|
+
raise RuntimeError("Native handoff worker did not start")
|
|
299
316
|
except Exception as exc: # noqa: BLE001 - reported as a handshake condition
|
|
317
|
+
self._stop_handoff()
|
|
300
318
|
self.import_error = f"{type(exc).__name__}: {exc}"
|
|
301
319
|
raise AgentIncompatible(f"Hermes Agent could not be imported: {self.import_error}", import_error=self.import_error)
|
|
302
320
|
module_file = getattr(module, "__file__", None)
|
|
@@ -306,6 +324,21 @@ class AgentRuntime:
|
|
|
306
324
|
self.revision = read_agent_revision(self.agent_dir, self.module_path)
|
|
307
325
|
self.loaded = True
|
|
308
326
|
|
|
327
|
+
def _stop_handoff(self) -> None:
|
|
328
|
+
if self._handoff is not None:
|
|
329
|
+
# Native requests are bounded. Join fully before code/dependencies may change.
|
|
330
|
+
self._handoff.stop_worker(timeout=None)
|
|
331
|
+
self._handoff = None
|
|
332
|
+
|
|
333
|
+
def retire(self) -> None:
|
|
334
|
+
"""Release native background writes; only a fresh process may own them again."""
|
|
335
|
+
with self._lock:
|
|
336
|
+
if self._handoff is None:
|
|
337
|
+
return
|
|
338
|
+
self._retired = True
|
|
339
|
+
self.loaded = False
|
|
340
|
+
self._stop_handoff()
|
|
341
|
+
|
|
309
342
|
@property
|
|
310
343
|
def agent_version(self) -> str | None:
|
|
311
344
|
try:
|
|
@@ -348,7 +381,8 @@ class AgentRuntime:
|
|
|
348
381
|
return "absent"
|
|
349
382
|
from .agent_mutation import recovery_receipts
|
|
350
383
|
try:
|
|
351
|
-
|
|
384
|
+
with self._stale_lock:
|
|
385
|
+
receipts, _ = recovery_receipts(self, discovery_cache=self._receipt_discovery)
|
|
352
386
|
return 'present' if receipts else 'absent'
|
|
353
387
|
except (OSError, UnicodeError):
|
|
354
388
|
return 'unknown'
|
|
@@ -377,12 +411,16 @@ class AgentRuntime:
|
|
|
377
411
|
self._source_changed = fresh is not None and fresh != self.revision
|
|
378
412
|
self._stale = fresh != self.revision
|
|
379
413
|
self._stale_stamp = stamp if fresh is not None else None
|
|
380
|
-
|
|
414
|
+
stale = self._stale
|
|
415
|
+
if stale:
|
|
416
|
+
self.retire()
|
|
417
|
+
return stale
|
|
381
418
|
|
|
382
419
|
def ensure_current(self) -> None:
|
|
383
420
|
"""Refuse Agent work until source drift or a durable Web update obligation is reconciled."""
|
|
384
421
|
repair = self.web_repair_state()
|
|
385
422
|
if repair != "absent":
|
|
423
|
+
self.retire()
|
|
386
424
|
raise AgentRuntimeStale("unknown" if repair == "unknown" else self.update_transaction_state())
|
|
387
425
|
if self.is_stale():
|
|
388
426
|
raise AgentRuntimeStale(self.update_transaction_state(), source_changed=self._source_changed)
|
|
@@ -391,6 +429,7 @@ class AgentRuntime:
|
|
|
391
429
|
def describe(self) -> dict:
|
|
392
430
|
# The pin records official test coverage, not runtime capability. Each operation still checks its imports,
|
|
393
431
|
# profile isolation and loaded-revision guard at the point of use.
|
|
432
|
+
stale = self.is_stale() or self._retired
|
|
394
433
|
return {
|
|
395
434
|
"rpc_version": SIDECAR_RPC_VERSION,
|
|
396
435
|
"python": sys.executable,
|
|
@@ -402,7 +441,7 @@ class AgentRuntime:
|
|
|
402
441
|
"pinned_version": self.pin["version"],
|
|
403
442
|
"pinned_image": self.pin["image"],
|
|
404
443
|
"compatible": self.loaded,
|
|
405
|
-
"stale":
|
|
444
|
+
"stale": stale,
|
|
406
445
|
"agent_source_changed": self._source_changed,
|
|
407
446
|
"update_state": self.update_transaction_state(),
|
|
408
447
|
"import_error": self.import_error,
|
|
@@ -30,6 +30,18 @@ def supported_speed_tiers(model: str, provider: str, base_url: str) -> list[dict
|
|
|
30
30
|
tiers = []
|
|
31
31
|
for tier in ("priority", "ultrafast"):
|
|
32
32
|
override = fast_overrides(model, provider, base_url, tier)
|
|
33
|
-
if override:
|
|
33
|
+
if override and (tier != "ultrafast" or ultrafast_offered(model, provider, base_url)):
|
|
34
34
|
tiers.append({"id": "fast" if override.get("speed") == "fast" else tier, "service_tier": tier})
|
|
35
35
|
return [{"id": "standard", "service_tier": "default"}, *tiers] if tiers else []
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def ultrafast_offered(model: str, provider: str, base_url: str) -> bool:
|
|
39
|
+
"""The Agent's account check: a Codex plan without Ultrafast accepts the tier and silently serves default."""
|
|
40
|
+
try:
|
|
41
|
+
from agent import codex_service_tiers
|
|
42
|
+
except ModuleNotFoundError as error:
|
|
43
|
+
if error.name not in ("agent", "agent.codex_service_tiers"):
|
|
44
|
+
raise
|
|
45
|
+
return True
|
|
46
|
+
offered = getattr(codex_service_tiers, "ultrafast_offered", None)
|
|
47
|
+
return offered is None or bool(offered(model, provider=provider, base_url=base_url))
|