@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
|
@@ -228,6 +228,18 @@ def _unavailable_plugin(provider_id: str) -> bool:
|
|
|
228
228
|
return not any(p is profile for _name, p in installed_plugin_profiles())
|
|
229
229
|
|
|
230
230
|
|
|
231
|
+
def require_runtime_ownership(requested: str | None) -> None:
|
|
232
|
+
"""A process-wide Agent registry must not lend another home's plugin to this runtime."""
|
|
233
|
+
if not requested:
|
|
234
|
+
return
|
|
235
|
+
try:
|
|
236
|
+
if not _unavailable_plugin(requested.strip().lower()):
|
|
237
|
+
return
|
|
238
|
+
except Exception: # noqa: BLE001 - an unverified plugin owner cannot authorize execution
|
|
239
|
+
log.debug("runtime plugin ownership check failed", exc_info=True)
|
|
240
|
+
raise RpcError("Requested provider is unavailable in this profile", condition="credential_missing")
|
|
241
|
+
|
|
242
|
+
|
|
231
243
|
def _agent_knows_provider(name: str) -> bool:
|
|
232
244
|
"""Whether the Agent's auth layer can resolve this provider id at all.
|
|
233
245
|
|
|
@@ -323,6 +335,35 @@ def model_ids(provider_id: str, *, force_refresh: bool) -> tuple[list[str], bool
|
|
|
323
335
|
return [], False
|
|
324
336
|
|
|
325
337
|
|
|
338
|
+
def model_allowance_snapshot(provider_id: str, *, force_refresh: bool) -> dict:
|
|
339
|
+
"""Native picker metadata in this call's scoped home; no billing write or second usage poll."""
|
|
340
|
+
if provider_id != "nous":
|
|
341
|
+
return {}
|
|
342
|
+
try:
|
|
343
|
+
from hermes_cli.inventory import build_model_options_payload, load_picker_context
|
|
344
|
+
from hermes_cli.model_picker_usage import nous_picker_usage
|
|
345
|
+
except ImportError:
|
|
346
|
+
return {"metadata_status": "unsupported"}
|
|
347
|
+
try:
|
|
348
|
+
payload = build_model_options_payload(load_picker_context(), refresh=force_refresh)
|
|
349
|
+
row = next((r for r in payload.get("providers", []) if r.get("slug") == provider_id), {})
|
|
350
|
+
pending = row.get("pricing_pending") is True or row.get("free_tier_pending") is True
|
|
351
|
+
plan = row.get("plan_usage")
|
|
352
|
+
fresh = nous_picker_usage() if isinstance(plan, dict) else None
|
|
353
|
+
return {
|
|
354
|
+
"metadata_status": "pending" if pending else "stale" if plan and fresh is None else "current",
|
|
355
|
+
"plan_usage": plan if isinstance(plan, dict) else None,
|
|
356
|
+
"usage_levels": {mid: level for mid, level in (row.get("usage_levels") or {}).items()
|
|
357
|
+
if isinstance(mid, str) and level in ("free", "low", "medium", "top_tier")},
|
|
358
|
+
"unavailable_model_ids": [mid for mid in row.get("unavailable_models", []) if isinstance(mid, str)] if not pending else [],
|
|
359
|
+
"allowance_pending": pending,
|
|
360
|
+
"free_tier": row.get("free_tier") if isinstance(row.get("free_tier"), bool) else None,
|
|
361
|
+
}
|
|
362
|
+
except Exception: # noqa: BLE001 - unknown entitlement is not unavailability
|
|
363
|
+
log.debug("native picker allowance unavailable", exc_info=True)
|
|
364
|
+
return {"metadata_status": "error"}
|
|
365
|
+
|
|
366
|
+
|
|
326
367
|
def _requests_local_runtime(requested: str | None) -> bool:
|
|
327
368
|
"""Whether a resolution asks for the Agent's managed llama.cpp provider, picked the way the Agent picks it: the
|
|
328
369
|
named provider, else the profile's, else ``HERMES_INFERENCE_PROVIDER``."""
|
|
@@ -367,6 +408,7 @@ def local_models() -> dict:
|
|
|
367
408
|
|
|
368
409
|
|
|
369
410
|
def resolve_runtime(*, requested: str | None, api_key: str | None, base_url: str | None, target_model: str | None) -> dict:
|
|
411
|
+
require_runtime_ownership(requested)
|
|
370
412
|
try:
|
|
371
413
|
from hermes_cli.runtime_provider import format_runtime_provider_error, resolve_runtime_provider
|
|
372
414
|
except Exception as exc: # noqa: BLE001
|
|
@@ -535,6 +577,13 @@ def register(reg) -> None:
|
|
|
535
577
|
with scoped_home(profile_home_param(params)):
|
|
536
578
|
return {"providers": registry()}
|
|
537
579
|
|
|
580
|
+
@reg.method("providers.nous_account")
|
|
581
|
+
def nous_account_(ctx: CallContext, params: dict) -> dict:
|
|
582
|
+
from . import nous_account
|
|
583
|
+
home = profile_home_param(params)
|
|
584
|
+
with scoped_home(home):
|
|
585
|
+
return {"nous_account": nous_account.read(home)}
|
|
586
|
+
|
|
538
587
|
@reg.method("providers.auth_status")
|
|
539
588
|
def auth(ctx: CallContext, params: dict) -> dict:
|
|
540
589
|
with scoped_home(profile_home_param(params)):
|
|
@@ -547,7 +596,8 @@ def register(reg) -> None:
|
|
|
547
596
|
raise InvalidParams("provider is required")
|
|
548
597
|
with scoped_home(profile_home_param(params)):
|
|
549
598
|
ids, fallback = model_ids(provider, force_refresh=bool(params.get("force_refresh", False)))
|
|
550
|
-
return {"provider": provider, "model_ids": ids, "fallback": fallback
|
|
599
|
+
return {"provider": provider, "model_ids": ids, "fallback": fallback,
|
|
600
|
+
**model_allowance_snapshot(provider, force_refresh=bool(params.get("force_refresh", False)))}
|
|
551
601
|
|
|
552
602
|
@reg.method("providers.local_models")
|
|
553
603
|
def local(ctx: CallContext, params: dict) -> dict:
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"""Read the reviewed Hermetic store without executing its API or migrating legacy data."""
|
|
2
|
+
from contextlib import contextmanager
|
|
3
|
+
from datetime import datetime, timezone
|
|
4
|
+
import difflib
|
|
5
|
+
import hashlib
|
|
6
|
+
import itertools
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
import re
|
|
11
|
+
import stat
|
|
12
|
+
|
|
13
|
+
from ..errors import InvalidParams
|
|
14
|
+
from . import dashboard_plugins
|
|
15
|
+
|
|
16
|
+
_PIN = 'f7026c949d8831b26910f2ebd3434e8c58cdff89'
|
|
17
|
+
_SOURCES = {
|
|
18
|
+
'__init__.py': '9dfb815be185965bf06c7c5a0fec401f6f376569d1a6830497502898fffcf01d',
|
|
19
|
+
'plugin.yaml': 'b4fbd03f70f50d2cc391e530b3e4079ecbe249ab6e5c2e4702d475911327b50e',
|
|
20
|
+
'dashboard/manifest.json': '466cada1eb3345f6fa7e12a5eaef44f8a19bb02546b9456fa0576d81ff89b6c1',
|
|
21
|
+
'dashboard/plugin_api.py': '23f1c612559f0086ff5c7da6d3cc8fe0c596a05c6f6eaa89db94c8c4d8c99d1d',
|
|
22
|
+
}
|
|
23
|
+
_NAME = re.compile(r'[A-Za-z0-9][A-Za-z0-9._ -]{0,127}')
|
|
24
|
+
_FILE = re.compile(r'([a-f0-9]{16})-SKILL[.]md')
|
|
25
|
+
_MAX_TEXT = 32 * 1024
|
|
26
|
+
_MAX_REVISIONS = 64
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@contextmanager
|
|
30
|
+
def _directory(anchor, parts=()):
|
|
31
|
+
"""Hold every traversal no-follow, including the profile's ancestors, through the read."""
|
|
32
|
+
anchor = Path(anchor).absolute()
|
|
33
|
+
components = (*anchor.parts[1:], *parts)
|
|
34
|
+
if any(p in ('', '.', '..') or '/' in p or '\\' in p for p in components):
|
|
35
|
+
raise ValueError('Invalid history path')
|
|
36
|
+
fd = os.open(anchor.anchor, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW)
|
|
37
|
+
try:
|
|
38
|
+
for part in components:
|
|
39
|
+
child = os.open(part, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW, dir_fd=fd)
|
|
40
|
+
os.close(fd)
|
|
41
|
+
fd = child
|
|
42
|
+
yield fd
|
|
43
|
+
finally:
|
|
44
|
+
os.close(fd)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _read(fd, name, limit):
|
|
48
|
+
child = os.open(name, os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK, dir_fd=fd)
|
|
49
|
+
with os.fdopen(child, 'rb') as file:
|
|
50
|
+
info = os.fstat(file.fileno())
|
|
51
|
+
if not stat.S_ISREG(info.st_mode) or info.st_size > limit:
|
|
52
|
+
raise ValueError('History file is too large or not regular')
|
|
53
|
+
data = file.read(limit + 1)
|
|
54
|
+
if len(data) > limit:
|
|
55
|
+
raise ValueError('History file is too large')
|
|
56
|
+
return data, info.st_mtime
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _timestamp(value):
|
|
60
|
+
try:
|
|
61
|
+
date = datetime.fromtimestamp(value, timezone.utc) if type(value) in (int, float) else datetime.fromisoformat(value.replace('Z', '+00:00'))
|
|
62
|
+
return date.astimezone(timezone.utc).isoformat() if date.tzinfo else None
|
|
63
|
+
except (TypeError, ValueError, OverflowError, OSError, AttributeError):
|
|
64
|
+
return None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _result(state, reason=None, **fields):
|
|
68
|
+
return dict(state=state, reason=reason, backend_revision=None, revisions=[], selected=None,
|
|
69
|
+
comparison=None, replay_available=False) | fields
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _identity(catalog, name):
|
|
73
|
+
entries = catalog(skip_disabled=True, include_hidden=True)
|
|
74
|
+
matches = [entry for entry in entries if entry.get('load_name') == name]
|
|
75
|
+
if len(matches) != 1:
|
|
76
|
+
return None
|
|
77
|
+
selected = matches[0]
|
|
78
|
+
declared = selected.get('name')
|
|
79
|
+
# Hermetic keys storage by declared name; two catalog copies cannot be attributed safely.
|
|
80
|
+
if not isinstance(declared, str) or not _NAME.fullmatch(declared) or '..' in declared:
|
|
81
|
+
return None
|
|
82
|
+
return selected if len([entry for entry in entries if entry.get('name') == declared]) == 1 else None
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def inspect_revisions(home, name, revision=None, compare_to=None):
|
|
86
|
+
from .skills import _skill_helper
|
|
87
|
+
|
|
88
|
+
if not isinstance(name, str) or not 0 < len(name) <= 256:
|
|
89
|
+
raise InvalidParams('Invalid skill identity')
|
|
90
|
+
if any(v is not None and (not isinstance(v, str) or not re.fullmatch('[a-f0-9]{64}', v)) for v in (revision, compare_to)):
|
|
91
|
+
raise InvalidParams('Invalid revision identity')
|
|
92
|
+
if not getattr(os, 'O_NOFOLLOW', 0) or not dashboard_plugins.reviewed_producer(home, 'hermetic', _PIN, _SOURCES):
|
|
93
|
+
return _result('unavailable', 'backend_unavailable')
|
|
94
|
+
try:
|
|
95
|
+
catalog = _skill_helper('skill_catalog')
|
|
96
|
+
selected = _identity(catalog, name) if catalog else None
|
|
97
|
+
if selected is None:
|
|
98
|
+
return _result('unavailable', 'identity_unavailable')
|
|
99
|
+
declared = selected['name']
|
|
100
|
+
local = Path(selected['path']).relative_to(home / 'skills')
|
|
101
|
+
if local.name != 'SKILL.md':
|
|
102
|
+
raise ValueError('Not a local skill')
|
|
103
|
+
with _directory(home, ('skills', *local.parts[:-1])) as fd:
|
|
104
|
+
current, _ = _read(fd, 'SKILL.md', _MAX_TEXT)
|
|
105
|
+
provenance = {}
|
|
106
|
+
with _directory(home, ('skills',)) as fd:
|
|
107
|
+
try:
|
|
108
|
+
ledger, _ = _read(fd, '.curator_ledger.jsonl', 256 * 1024)
|
|
109
|
+
except FileNotFoundError:
|
|
110
|
+
ledger = b''
|
|
111
|
+
for line in ledger.decode('utf-8').splitlines():
|
|
112
|
+
row = json.loads(line)
|
|
113
|
+
if not isinstance(row, dict):
|
|
114
|
+
raise ValueError('Invalid ledger')
|
|
115
|
+
if row.get('skill') == declared:
|
|
116
|
+
after = row.get('after') or []
|
|
117
|
+
if not isinstance(after, list):
|
|
118
|
+
raise ValueError('Invalid ledger provenance')
|
|
119
|
+
for item in after:
|
|
120
|
+
if isinstance(item, dict) and isinstance(item.get('sha256'), str):
|
|
121
|
+
actor = row.get('actor')
|
|
122
|
+
actor = actor if isinstance(actor, str) and len(actor) <= 80 and not any(ord(c) < 32 for c in actor) else None
|
|
123
|
+
provenance[item['sha256']] = (_timestamp(row.get('ts')), actor)
|
|
124
|
+
try:
|
|
125
|
+
with _directory(home, ('hermetic', 'skill-versions', declared)) as fd:
|
|
126
|
+
with os.scandir(fd) as iterator:
|
|
127
|
+
files = list(itertools.islice(iterator, _MAX_REVISIONS + 1))
|
|
128
|
+
if len(files) > _MAX_REVISIONS:
|
|
129
|
+
raise ValueError('Too many revisions')
|
|
130
|
+
rows = []
|
|
131
|
+
for file in files:
|
|
132
|
+
match = _FILE.fullmatch(file.name)
|
|
133
|
+
if not match:
|
|
134
|
+
continue
|
|
135
|
+
data, modified = _read(fd, file.name, _MAX_TEXT)
|
|
136
|
+
sha = hashlib.sha256(data).hexdigest()
|
|
137
|
+
if not sha.startswith(match[1]):
|
|
138
|
+
raise ValueError('Revision hash does not match saved bytes')
|
|
139
|
+
text = data.decode('utf-8')
|
|
140
|
+
if len(text.splitlines()) > 512:
|
|
141
|
+
raise ValueError('Too many revision lines')
|
|
142
|
+
saved_at, actor = provenance.get(sha, (_timestamp(modified), None))
|
|
143
|
+
identity = hashlib.sha256(json.dumps([str(home), name, sha]).encode()).hexdigest()
|
|
144
|
+
rows.append(dict(id=identity, sha256=sha, label=sha[:12], saved_at=saved_at, actor=actor,
|
|
145
|
+
current=sha == hashlib.sha256(current).hexdigest(), content=text))
|
|
146
|
+
except FileNotFoundError:
|
|
147
|
+
rows = []
|
|
148
|
+
if not rows:
|
|
149
|
+
if revision or compare_to:
|
|
150
|
+
raise InvalidParams('Revision no longer exists; reload history')
|
|
151
|
+
return _result('missing', 'history_unavailable', backend_revision=_PIN)
|
|
152
|
+
rows.sort(key=lambda row: (row['saved_at'] or '', row['sha256']), reverse=True)
|
|
153
|
+
by_id = {row['id']: row for row in rows}
|
|
154
|
+
target = by_id.get(revision) if revision else rows[0]
|
|
155
|
+
if target is None:
|
|
156
|
+
raise InvalidParams('Revision no longer exists; reload history')
|
|
157
|
+
source = by_id.get(compare_to) if compare_to else next((r for r in rows if r['id'] != target['id']), None)
|
|
158
|
+
if compare_to and source is None:
|
|
159
|
+
raise InvalidParams('Revision no longer exists; reload history')
|
|
160
|
+
comparison = None
|
|
161
|
+
if source:
|
|
162
|
+
lines = difflib.unified_diff(source['content'].splitlines(keepends=True), target['content'].splitlines(keepends=True),
|
|
163
|
+
fromfile=source['label'], tofile=target['label'])
|
|
164
|
+
diff = ''.join(line if line.endswith('\n') else line + '\n\\n' for line in lines)
|
|
165
|
+
comparison = dict(from_revision=source['id'], to_revision=target['id'], diff=diff)
|
|
166
|
+
# Native admission can be revoked while filesystem reads are in progress.
|
|
167
|
+
if not dashboard_plugins.reviewed_producer(home, 'hermetic', _PIN, _SOURCES):
|
|
168
|
+
return _result('unavailable', 'backend_unavailable')
|
|
169
|
+
if _identity(catalog, name) != selected:
|
|
170
|
+
return _result('unavailable', 'identity_unavailable')
|
|
171
|
+
return dict(state='available', reason=None, backend_revision=_PIN,
|
|
172
|
+
revisions=[{k: v for k, v in row.items() if k != 'content'} for row in rows],
|
|
173
|
+
selected=dict(revision=target['id'], content=target['content']), comparison=comparison, replay_available=False)
|
|
174
|
+
except InvalidParams:
|
|
175
|
+
raise
|
|
176
|
+
except (ImportError, AttributeError, OSError, ValueError, TypeError, KeyError):
|
|
177
|
+
return _result('unavailable', 'invalid_history')
|
|
@@ -300,6 +300,16 @@ def view_skill(profile_home: Path, name: str) -> dict:
|
|
|
300
300
|
|
|
301
301
|
|
|
302
302
|
def register(registry) -> None:
|
|
303
|
+
@registry.method("skills.revisions")
|
|
304
|
+
def revisions(ctx: CallContext, params: dict) -> dict:
|
|
305
|
+
from .skill_revisions import inspect_revisions
|
|
306
|
+
home = profile_home_param(params)
|
|
307
|
+
ctx.check_cancelled()
|
|
308
|
+
with scoped_home(home, load_plugins=False, recover_processes=False):
|
|
309
|
+
result = inspect_revisions(home, params.get('name'), params.get('revision'), params.get('compare_to'))
|
|
310
|
+
ctx.check_cancelled()
|
|
311
|
+
return result
|
|
312
|
+
|
|
303
313
|
@registry.method("skills.list")
|
|
304
314
|
def list_(ctx: CallContext, params: dict) -> dict:
|
|
305
315
|
home = profile_home_param(params)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""``tts.synthesize``: bounded audio through the Agent's own speech providers."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import base64
|
|
5
|
+
import json
|
|
6
|
+
import math
|
|
7
|
+
import tempfile
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from ..errors import InvalidParams, RpcError
|
|
11
|
+
from ..home import profile_home_param, scoped_home
|
|
12
|
+
from ..rpc import CallContext
|
|
13
|
+
|
|
14
|
+
MAX_AUDIO_BYTES = 8 * 1024 * 1024
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def synthesize(text: str, provider: str, speed: float | None = None) -> dict:
|
|
18
|
+
from tools import tts_tool
|
|
19
|
+
|
|
20
|
+
if (provider != 'edge' and provider not in tts_tool._BUILTIN_DISPATCH
|
|
21
|
+
and tts_tool._resolve_command_provider_config(provider, tts_tool._load_tts_config()) is None):
|
|
22
|
+
raise InvalidParams(f'unknown TTS provider {provider}')
|
|
23
|
+
try:
|
|
24
|
+
with tempfile.TemporaryDirectory(prefix='talaria-tts-') as directory:
|
|
25
|
+
root = Path(directory).resolve()
|
|
26
|
+
result = json.loads(tts_tool.text_to_speech_tool(
|
|
27
|
+
text, output_path=str(root / 'speech.mp3'), speed=speed, provider=provider))
|
|
28
|
+
if not isinstance(result, dict) or result.get('success') is not True:
|
|
29
|
+
message = result.get('error') if isinstance(result, dict) else None
|
|
30
|
+
raise ValueError(str(message or 'Agent speech generation failed'))
|
|
31
|
+
paths = result.get('file_paths')
|
|
32
|
+
if not isinstance(paths, list) or not paths:
|
|
33
|
+
raise ValueError('Agent returned no audio files')
|
|
34
|
+
audio = bytearray()
|
|
35
|
+
audio_format = ''
|
|
36
|
+
for raw_path in paths:
|
|
37
|
+
path = Path(raw_path).resolve()
|
|
38
|
+
if not path.is_relative_to(root):
|
|
39
|
+
raise ValueError('Agent audio escaped the temporary directory')
|
|
40
|
+
suffix = path.suffix.lower().lstrip('.')
|
|
41
|
+
if suffix not in ('mp3', 'wav', 'flac') or (len(paths) > 1 and suffix != 'mp3'):
|
|
42
|
+
raise ValueError('Agent returned unsupported audio parts')
|
|
43
|
+
audio_format = suffix
|
|
44
|
+
with path.open('rb') as source:
|
|
45
|
+
part = source.read(MAX_AUDIO_BYTES - len(audio) + 1)
|
|
46
|
+
if not part or len(audio) + len(part) > MAX_AUDIO_BYTES:
|
|
47
|
+
raise ValueError('Agent audio is empty or exceeds 8 MiB')
|
|
48
|
+
audio.extend(part)
|
|
49
|
+
return {'provider': str(result.get('provider') or provider), 'format': audio_format,
|
|
50
|
+
'audio_b64': base64.b64encode(audio).decode('ascii')}
|
|
51
|
+
except Exception as error:
|
|
52
|
+
raise RpcError(str(error), condition='tts_failed') from error
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def register(registry) -> None:
|
|
56
|
+
@registry.method('tts.synthesize')
|
|
57
|
+
def synthesize_(ctx: CallContext, params: dict) -> dict:
|
|
58
|
+
text, provider, speed = params.get('text'), params.get('provider'), params.get('speed')
|
|
59
|
+
if not isinstance(text, str) or not text.strip() or len(text) > 5000:
|
|
60
|
+
raise InvalidParams('text must contain 1 to 5000 characters')
|
|
61
|
+
if not isinstance(provider, str) or not provider.strip():
|
|
62
|
+
raise InvalidParams('provider is required')
|
|
63
|
+
if speed is not None and (isinstance(speed, bool) or not isinstance(speed, (int, float))
|
|
64
|
+
or not math.isfinite(speed) or not 0.5 <= speed <= 2):
|
|
65
|
+
raise InvalidParams('speed must be a number from 0.5 to 2')
|
|
66
|
+
with scoped_home(profile_home_param(params)):
|
|
67
|
+
return synthesize(text, provider, speed)
|
|
@@ -74,7 +74,10 @@ class CallContext:
|
|
|
74
74
|
class RpcServer:
|
|
75
75
|
def __init__(self, methods: dict[str, Handler], *, stdin=None, stdout=None, max_calls: int = DEFAULT_MAX_CALLS):
|
|
76
76
|
self.methods = dict(methods)
|
|
77
|
-
|
|
77
|
+
call_limit = max(1, int(max_calls))
|
|
78
|
+
self._slots = threading.BoundedSemaphore(call_limit)
|
|
79
|
+
# A parked command must leave room for its answer and unrelated Agent work.
|
|
80
|
+
self._command_slots = threading.BoundedSemaphore(min(8, call_limit - 1))
|
|
78
81
|
self.methods.setdefault("rpc.cancel", self._cancel)
|
|
79
82
|
self.methods.setdefault("rpc.methods", lambda ctx, params: {"methods": sorted(self.methods)})
|
|
80
83
|
self._in = stdin or sys.stdin.buffer
|
|
@@ -256,7 +259,11 @@ class RpcServer:
|
|
|
256
259
|
# Cancellation must not queue behind the call it targets.
|
|
257
260
|
self._dispatch(request)
|
|
258
261
|
continue
|
|
259
|
-
|
|
262
|
+
command = request.get("method") == "commands.exec"
|
|
263
|
+
command_admitted = not command or self._command_slots.acquire(blocking=False)
|
|
264
|
+
if not command_admitted or not self._slots.acquire(blocking=False):
|
|
265
|
+
if command and command_admitted:
|
|
266
|
+
self._command_slots.release()
|
|
260
267
|
if request.get("method") == "chat.start":
|
|
261
268
|
StartupTiming(request).finish("refused")
|
|
262
269
|
self._error(request.get("id"), APPLICATION_ERROR, "sidecar is at its concurrent call limit", {"condition": "sidecar_busy"})
|
|
@@ -279,3 +286,5 @@ class RpcServer:
|
|
|
279
286
|
self._dispatch(request, ctx)
|
|
280
287
|
finally:
|
|
281
288
|
self._slots.release()
|
|
289
|
+
if request.get("method") == "commands.exec":
|
|
290
|
+
self._command_slots.release()
|