@maudecode/talaria-web 1.16.1 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_release.json +8 -8
- package/dist/api/auth-raw.d.ts +1 -1
- package/dist/api/auth-raw.js +4 -4
- package/dist/api/auth-raw.js.map +1 -1
- package/dist/api/automation-raw.d.ts +6 -0
- package/dist/api/automation-raw.js +59 -9
- package/dist/api/automation-raw.js.map +1 -1
- package/dist/api/automation-router.d.ts +163 -10
- package/dist/api/automation-router.js +25 -8
- package/dist/api/automation-router.js.map +1 -1
- package/dist/api/chat-router.d.ts +700 -15
- package/dist/api/chat-router.js +74 -55
- package/dist/api/chat-router.js.map +1 -1
- package/dist/api/git-router.d.ts +47 -2
- package/dist/api/git-router.js +31 -22
- package/dist/api/git-router.js.map +1 -1
- package/dist/api/raw-routes.d.ts +14 -0
- package/dist/api/raw-routes.js +277 -36
- package/dist/api/raw-routes.js.map +1 -1
- package/dist/api/router.d.ts +10 -0
- package/dist/api/router.js +10 -8
- package/dist/api/router.js.map +1 -1
- package/dist/api/sessions-router.d.ts +1710 -73
- package/dist/api/sessions-router.js +164 -10
- package/dist/api/sessions-router.js.map +1 -1
- package/dist/api/settings-router.d.ts +132 -2
- package/dist/api/settings-router.js +15 -5
- package/dist/api/settings-router.js.map +1 -1
- package/dist/api/sse-routes.d.ts +16 -3
- package/dist/api/sse-routes.js +194 -67
- package/dist/api/sse-routes.js.map +1 -1
- package/dist/api/tools-raw.js +12 -25
- package/dist/api/tools-raw.js.map +1 -1
- package/dist/api/tools-router.d.ts +425 -19
- package/dist/api/tools-router.js +157 -26
- package/dist/api/tools-router.js.map +1 -1
- package/dist/app.d.ts +0 -9377
- package/dist/app.js +42 -17
- package/dist/app.js.map +1 -1
- package/dist/auth/gate.js +8 -2
- package/dist/auth/gate.js.map +1 -1
- package/dist/auth/oidc.d.ts +5 -2
- package/dist/auth/oidc.js +8 -7
- package/dist/auth/oidc.js.map +1 -1
- package/dist/bin/talaria-web.js +1 -1
- package/dist/bin/talaria-web.js.map +1 -1
- package/dist/cli/dotenv.js +1 -0
- package/dist/cli/dotenv.js.map +1 -1
- package/dist/config/agent-config.d.ts +2 -0
- package/dist/config/agent-config.js +12 -2
- package/dist/config/agent-config.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.js +5 -1
- package/dist/config.js.map +1 -1
- package/dist/http/context.d.ts +20 -3
- package/dist/http/context.js +41 -8
- package/dist/http/context.js.map +1 -1
- package/dist/http/csp.d.ts +2 -1
- package/dist/http/csp.js +3 -2
- package/dist/http/csp.js.map +1 -1
- package/dist/onboarding.js +4 -0
- package/dist/onboarding.js.map +1 -1
- package/dist/profiles/profiles.d.ts +10 -0
- package/dist/profiles/profiles.js +40 -2
- package/dist/profiles/profiles.js.map +1 -1
- package/dist/providers/catalog.d.ts +101 -8
- package/dist/providers/catalog.js +463 -123
- package/dist/providers/catalog.js.map +1 -1
- package/dist/raster-image.d.ts +7 -0
- package/dist/raster-image.js +267 -0
- package/dist/raster-image.js.map +1 -0
- package/dist/redact.d.ts +1 -0
- package/dist/redact.js +354 -44
- package/dist/redact.js.map +1 -1
- package/dist/runtime.js +111 -27
- package/dist/runtime.js.map +1 -1
- package/dist/server.js +5 -0
- package/dist/server.js.map +1 -1
- package/dist/sessions/anchor.d.ts +2 -0
- package/dist/sessions/anchor.js +8 -3
- package/dist/sessions/anchor.js.map +1 -1
- package/dist/sessions/background-tasks.d.ts +2 -9
- package/dist/sessions/background-tasks.js +2 -12
- package/dist/sessions/background-tasks.js.map +1 -1
- package/dist/sessions/claude-code.d.ts +19 -0
- package/dist/sessions/claude-code.js +250 -0
- package/dist/sessions/claude-code.js.map +1 -0
- package/dist/sessions/cli-sessions.d.ts +15 -4
- package/dist/sessions/cli-sessions.js +120 -29
- package/dist/sessions/cli-sessions.js.map +1 -1
- package/dist/sessions/completions.d.ts +61 -9
- package/dist/sessions/completions.js +282 -34
- package/dist/sessions/completions.js.map +1 -1
- package/dist/sessions/compress.d.ts +14 -1
- package/dist/sessions/compress.js +52 -11
- package/dist/sessions/compress.js.map +1 -1
- package/dist/sessions/export.d.ts +5 -0
- package/dist/sessions/export.js +30 -0
- package/dist/sessions/export.js.map +1 -1
- package/dist/sessions/gateway-watcher.d.ts +7 -3
- package/dist/sessions/gateway-watcher.js +31 -19
- package/dist/sessions/gateway-watcher.js.map +1 -1
- package/dist/sessions/handoff.d.ts +32 -0
- package/dist/sessions/handoff.js +114 -0
- package/dist/sessions/handoff.js.map +1 -0
- package/dist/sessions/journal.d.ts +8 -0
- package/dist/sessions/journal.js +44 -10
- package/dist/sessions/journal.js.map +1 -1
- package/dist/sessions/list.d.ts +13 -3
- package/dist/sessions/list.js +46 -15
- package/dist/sessions/list.js.map +1 -1
- package/dist/sessions/merge.d.ts +53 -5
- package/dist/sessions/merge.js +219 -23
- package/dist/sessions/merge.js.map +1 -1
- package/dist/sessions/recovery.d.ts +22 -0
- package/dist/sessions/recovery.js +506 -0
- package/dist/sessions/recovery.js.map +1 -0
- package/dist/sessions/relay.d.ts +21 -2
- package/dist/sessions/relay.js +156 -11
- package/dist/sessions/relay.js.map +1 -1
- package/dist/sessions/service.d.ts +152 -8
- package/dist/sessions/service.js +640 -72
- package/dist/sessions/service.js.map +1 -1
- package/dist/sessions/session.d.ts +17 -1
- package/dist/sessions/session.js +63 -4
- package/dist/sessions/session.js.map +1 -1
- package/dist/sessions/state-db-worker.d.ts +1 -0
- package/dist/sessions/state-db-worker.js +33 -0
- package/dist/sessions/state-db-worker.js.map +1 -0
- package/dist/sessions/state-db.d.ts +87 -4
- package/dist/sessions/state-db.js +417 -8
- package/dist/sessions/state-db.js.map +1 -1
- package/dist/sessions/store.d.ts +7 -0
- package/dist/sessions/store.js +36 -22
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/streams.d.ts +10 -0
- package/dist/sessions/streams.js +14 -3
- package/dist/sessions/streams.js.map +1 -1
- package/dist/sessions/titles.d.ts +2 -0
- package/dist/sessions/titles.js +4 -0
- package/dist/sessions/titles.js.map +1 -1
- package/dist/sessions/todo.d.ts +6 -1
- package/dist/sessions/todo.js +11 -4
- package/dist/sessions/todo.js.map +1 -1
- package/dist/sessions/tool-display.d.ts +12 -1
- package/dist/sessions/tool-display.js +50 -1
- package/dist/sessions/tool-display.js.map +1 -1
- package/dist/sessions/turn-context.d.ts +1 -1
- package/dist/sessions/turn-context.js +11 -7
- package/dist/sessions/turn-context.js.map +1 -1
- package/dist/sessions/turn.d.ts +67 -11
- package/dist/sessions/turn.js +413 -111
- package/dist/sessions/turn.js.map +1 -1
- package/dist/sessions/wakeup-pause.d.ts +59 -0
- package/dist/sessions/wakeup-pause.js +181 -0
- package/dist/sessions/wakeup-pause.js.map +1 -0
- package/dist/settings.d.ts +20 -2
- package/dist/settings.js +45 -9
- package/dist/settings.js.map +1 -1
- package/dist/sidecar/fake.d.ts +4 -4
- package/dist/sidecar/fake.js +5 -2
- package/dist/sidecar/fake.js.map +1 -1
- package/dist/spa.js +2 -1
- package/dist/spa.js.map +1 -1
- package/dist/startup.d.ts +13 -5
- package/dist/startup.js +48 -0
- package/dist/startup.js.map +1 -1
- package/dist/test/harness.js +2 -0
- package/dist/test/harness.js.map +1 -1
- package/dist/test/ts-worker-hooks.d.ts +1 -0
- package/dist/test/ts-worker-hooks.js +24 -0
- package/dist/test/ts-worker-hooks.js.map +1 -0
- package/dist/text/diff.d.ts +9 -14
- package/dist/text/diff.js +74 -108
- package/dist/text/diff.js.map +1 -1
- package/dist/tools/crons.js +45 -8
- package/dist/tools/crons.js.map +1 -1
- package/dist/tools/dashboard-plugins.d.ts +53 -0
- package/dist/tools/dashboard-plugins.js +188 -0
- package/dist/tools/dashboard-plugins.js.map +1 -0
- package/dist/tools/extensions.d.ts +13 -1
- package/dist/tools/extensions.js +132 -60
- package/dist/tools/extensions.js.map +1 -1
- package/dist/tools/health.d.ts +32 -0
- package/dist/tools/health.js +111 -19
- package/dist/tools/health.js.map +1 -1
- package/dist/tools/insights.d.ts +8 -2
- package/dist/tools/insights.js +18 -2
- package/dist/tools/insights.js.map +1 -1
- package/dist/tools/kanban.d.ts +41 -1
- package/dist/tools/kanban.js +113 -2
- package/dist/tools/kanban.js.map +1 -1
- package/dist/tools/mcp.d.ts +15 -1
- package/dist/tools/mcp.js +99 -5
- package/dist/tools/mcp.js.map +1 -1
- package/dist/tools/project-os.d.ts +11 -0
- package/dist/tools/project-os.js +267 -0
- package/dist/tools/project-os.js.map +1 -0
- package/dist/tools/skills.d.ts +5 -1
- package/dist/tools/skills.js +5 -3
- package/dist/tools/skills.js.map +1 -1
- package/dist/tools/terminal.d.ts +1 -0
- package/dist/tools/terminal.js +1 -1
- package/dist/tools/terminal.js.map +1 -1
- package/dist/tools/updates.d.ts +33 -8
- package/dist/tools/updates.js +236 -57
- package/dist/tools/updates.js.map +1 -1
- package/dist/tools/wiki.d.ts +68 -0
- package/dist/tools/wiki.js +413 -0
- package/dist/tools/wiki.js.map +1 -0
- package/dist/workspace/escape.d.ts +61 -0
- package/dist/workspace/escape.js +149 -0
- package/dist/workspace/escape.js.map +1 -0
- package/dist/workspace/extract.d.ts +22 -0
- package/dist/workspace/extract.js +308 -0
- package/dist/workspace/extract.js.map +1 -0
- package/dist/workspace/fs.d.ts +19 -3
- package/dist/workspace/fs.js +96 -23
- package/dist/workspace/fs.js.map +1 -1
- package/dist/workspace/git.d.ts +18 -0
- package/dist/workspace/git.js +38 -25
- package/dist/workspace/git.js.map +1 -1
- package/dist/workspace/media.d.ts +4 -4
- package/dist/workspace/media.js +18 -45
- package/dist/workspace/media.js.map +1 -1
- package/dist/workspace/preview.d.ts +28 -0
- package/dist/workspace/preview.js +110 -0
- package/dist/workspace/preview.js.map +1 -0
- package/dist/workspace/rollback.d.ts +36 -21
- package/dist/workspace/rollback.js +179 -270
- package/dist/workspace/rollback.js.map +1 -1
- package/dist/workspace/unzip.js +4 -1
- package/dist/workspace/unzip.js.map +1 -1
- package/dist/workspace/upload.d.ts +9 -4
- package/dist/workspace/upload.js +9 -3
- package/dist/workspace/upload.js.map +1 -1
- package/dist/workspace/worktrees.d.ts +2 -1
- package/dist/workspace/worktrees.js +14 -15
- package/dist/workspace/worktrees.js.map +1 -1
- package/package.json +4 -2
- package/sidecar/agent_dependency.json +4 -4
- package/sidecar/scripts/replay_sidecar.py +25 -1
- package/sidecar/talaria_sidecar/__init__.py +1 -1
- package/sidecar/talaria_sidecar/__main__.py +7 -1
- package/sidecar/talaria_sidecar/home.py +52 -2
- package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
- package/sidecar/talaria_sidecar/methods/aux.py +39 -5
- package/sidecar/talaria_sidecar/methods/chat.py +431 -43
- package/sidecar/talaria_sidecar/methods/checkpoints.py +89 -0
- package/sidecar/talaria_sidecar/methods/commands.py +96 -2
- package/sidecar/talaria_sidecar/methods/cron.py +39 -8
- package/sidecar/talaria_sidecar/methods/gateway.py +32 -15
- package/sidecar/talaria_sidecar/methods/kanban.py +140 -19
- package/sidecar/talaria_sidecar/methods/mcp.py +1 -1
- package/sidecar/talaria_sidecar/methods/process.py +115 -2
- package/sidecar/talaria_sidecar/methods/profiles.py +84 -8
- package/sidecar/talaria_sidecar/methods/providers.py +27 -8
- package/sidecar/talaria_sidecar/methods/runtime.py +3 -0
- package/sidecar/talaria_sidecar/methods/state_db.py +39 -5
- package/sidecar/talaria_sidecar/methods/text.py +17 -1
- package/sidecar/talaria_sidecar/methods/usage.py +257 -4
- package/sidecar/talaria_sidecar/runtime.py +17 -1
- package/static/dist/FILES.txt +127 -125
- package/static/dist/assets/AppShell-g3bkgnvt.js +1 -0
- package/static/dist/assets/ChatPage-oo7bdan6.js +25 -0
- package/static/dist/assets/Dialog-g355qxhp.js +1 -0
- package/static/dist/assets/ExtensionRoute-i2y9fvjm.js +1 -0
- package/static/dist/assets/HubRoute-lmkrbw47.js +2 -0
- package/static/dist/assets/{Markdown-jqrx5es0.js → Markdown-j4kut4j2.js} +125 -125
- package/static/dist/assets/RightPanel-ohlsdzfl.js +1 -0
- package/static/dist/assets/Select-kddq75qc.js +1 -0
- package/static/dist/assets/SessionListPanel-lu3oy0hw.js +1 -0
- package/static/dist/assets/SettingsLayout-o9bv4mgb.js +1 -0
- package/static/dist/assets/States-eq6fe29m.js +1 -0
- package/static/dist/assets/Toaster-pc247u9f.js +1 -0
- package/static/dist/assets/_app-f8n1i0m1.js +1 -0
- package/static/dist/assets/_app.ext._extensionId-gfbzpoou.js +1 -0
- package/static/dist/assets/_app.index-bzzv80hk.js +1 -0
- package/static/dist/assets/_app.insights-dzixbryi.js +1 -0
- package/static/dist/assets/_app.kanban-c6hep2us.js +1 -0
- package/static/dist/assets/_app.logs-i69qds98.js +1 -0
- package/static/dist/assets/_app.memory-kl4vf0gd.js +1 -0
- package/static/dist/assets/_app.profiles-b8zinmyp.js +1 -0
- package/static/dist/assets/{_app.session._sessionId-hh27wwu2.js → _app.session._sessionId-fn1bhde6.js} +1 -1
- package/static/dist/assets/_app.settings-cg8plwmf.js +1 -0
- package/static/dist/assets/_app.settings._section-bkwbi9zn.js +3 -0
- package/static/dist/assets/_app.skills-cs47sbvs.js +1 -0
- package/static/dist/assets/_app.tasks-dwvk64tc.js +1 -0
- package/static/dist/assets/_app.todos-c8xjm8p3.js +1 -0
- package/static/dist/assets/_app.workspaces-ehvd1gds.js +1 -0
- package/static/dist/assets/{abnfDiagram-VCTEODGH-oity9y4o.js → abnfDiagram-VCTEODGH-c8kdixke.js} +1 -1
- package/static/dist/assets/architecture-7GRP2DOG-6crvnylg.js +1 -0
- package/static/dist/assets/{architectureDiagram-5GKGNRK7-ceaepnyr.js → architectureDiagram-5GKGNRK7-cku06x1p.js} +1 -1
- package/static/dist/assets/{back-eu64w89w.js → back-h7aun7ew.js} +1 -1
- package/static/dist/assets/{blockDiagram-I7D4REHJ-n79st4pj.js → blockDiagram-I7D4REHJ-jzthp1wa.js} +1 -1
- package/static/dist/assets/{c4Diagram-7LVT6UL2-mi73akzk.js → c4Diagram-7LVT6UL2-mwr67mt8.js} +1 -1
- package/static/dist/assets/{cancel-mzvkdjg8.js → cancel-fhi0vcnu.js} +1 -1
- package/static/dist/assets/channel-b2zo73z1.js +1 -0
- package/static/dist/assets/{chunk-4HAMMTFA-laat0g1q.js → chunk-4HAMMTFA-gpq1y228.js} +1 -1
- package/static/dist/assets/{chunk-75Z2AOVW-0psy1tr2.js → chunk-75Z2AOVW-ktje58c4.js} +1 -1
- package/static/dist/assets/{chunk-DU6HZSFF-lw8uox8x.js → chunk-DU6HZSFF-ofajdixh.js} +3 -3
- package/static/dist/assets/{chunk-F27PBJKO-erassib3.js → chunk-F27PBJKO-cmev85ti.js} +1 -1
- package/static/dist/assets/{chunk-GMAD6QVW-fz7rx619.js → chunk-GMAD6QVW-htjgt22y.js} +1 -1
- package/static/dist/assets/{chunk-GVQU2GXP-gdb0epb2.js → chunk-GVQU2GXP-qndvoxl7.js} +1 -1
- package/static/dist/assets/{chunk-IMKFNOWR-ea8t26qw.js → chunk-IMKFNOWR-e5bkd5q6.js} +1 -1
- package/static/dist/assets/{chunk-L3NEJ4N5-mb1gu9kz.js → chunk-L3NEJ4N5-mj1155r6.js} +1 -1
- package/static/dist/assets/{chunk-OSK3NFVY-eovmccvy.js → chunk-OSK3NFVY-e7gkikcw.js} +1 -1
- package/static/dist/assets/{chunk-P2QGCYS3-bo55zjo5.js → chunk-P2QGCYS3-f7t54xfm.js} +1 -1
- package/static/dist/assets/{chunk-POPQ4Y6H-ja7ohe4h.js → chunk-POPQ4Y6H-i927v9oa.js} +1 -1
- package/static/dist/assets/{chunk-PWAF6VOD-e30g9nus.js → chunk-PWAF6VOD-m84lmnyt.js} +1 -1
- package/static/dist/assets/{chunk-SHT3W25Y-gbb798f7.js → chunk-SHT3W25Y-mi0tlcu9.js} +1 -1
- package/static/dist/assets/{chunk-SVP7TREG-h2iw8urm.js → chunk-SVP7TREG-dnau702j.js} +1 -1
- package/static/dist/assets/{chunk-TICWLB2K-fd2cottz.js → chunk-TICWLB2K-edem1gkg.js} +1 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-oe99st8x.js +1 -0
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-oe99st8x.js +1 -0
- package/static/dist/assets/{copied-h65fc3cx.js → copied-hcplv46p.js} +1 -1
- package/static/dist/assets/copy-magtofyp.js +1 -0
- package/static/dist/assets/{cynefin-OW5HDTMX-lbltyl5j.js → cynefin-OW5HDTMX-siqlulkl.js} +1 -1
- package/static/dist/assets/{cynefinDiagram-5FMLGOSQ-lxhsqq4a.js → cynefinDiagram-5FMLGOSQ-i648tah9.js} +1 -1
- package/static/dist/assets/{dagre-GXQ25YYZ-gn4nnaln.js → dagre-GXQ25YYZ-mwn6uc17.js} +1 -1
- package/static/dist/assets/{diagram-S7CK7UJ4-pa3ij6q7.js → diagram-S7CK7UJ4-l8abxaes.js} +1 -1
- package/static/dist/assets/{diagram-UQ7AKVKN-zbipyz57.js → diagram-UQ7AKVKN-mekq7zgq.js} +1 -1
- package/static/dist/assets/{diagram-VSXAHHWV-d1kbpzgf.js → diagram-VSXAHHWV-fnky6lvc.js} +1 -1
- package/static/dist/assets/{diagram-VX7I27RA-i3ty14xl.js → diagram-VX7I27RA-xe6r5qfw.js} +1 -1
- package/static/dist/assets/{diagram-Z3DM3KII-m8xefqa7.js → diagram-Z3DM3KII-nq07dg7k.js} +1 -1
- package/static/dist/assets/{ebnfDiagram-PWID7BFC-nz7wj05l.js → ebnfDiagram-PWID7BFC-c62ipm3g.js} +1 -1
- package/static/dist/assets/endpoints-klbxod4t.js +64 -0
- package/static/dist/assets/{erDiagram-RLTQ6QDP-fa41ib83.js → erDiagram-RLTQ6QDP-h39kmnzy.js} +1 -1
- package/static/dist/assets/eventmodeling-NTZA5JFV-obfede4u.js +1 -0
- package/static/dist/assets/flowDiagram-HODETNUW-kdpsp1je.js +1 -0
- package/static/dist/assets/{ganttDiagram-EL5Y4UJY-n7zq01qu.js → ganttDiagram-EL5Y4UJY-ngbsyp37.js} +1 -1
- package/static/dist/assets/{gitGraph-4MIJSDKK-c89emb07.js → gitGraph-4MIJSDKK-fr2i7caa.js} +1 -1
- package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-cz7cgr6w.js → gitGraphDiagram-WWUBYQGX-eravdti4.js} +1 -1
- package/static/dist/assets/{highlighted-body-KPVGNVTW-d9bapmni.js → highlighted-body-KPVGNVTW-jwpop9p8.js} +1 -1
- package/static/dist/assets/host-i828xuo7.js +1 -0
- package/static/dist/assets/index-eh8zilnv.css +2 -0
- package/static/dist/assets/index-r648f4o1.js +11 -0
- package/static/dist/assets/{info-A6RAGUB7-ndddhhhh.js → info-A6RAGUB7-h11x0dxo.js} +1 -1
- package/static/dist/assets/{infoDiagram-27XIBGKW-ccxigcpf.js → infoDiagram-27XIBGKW-dfh47dw9.js} +1 -1
- package/static/dist/assets/{ishikawaDiagram-5VMMS53U-le0z9vtc.js → ishikawaDiagram-5VMMS53U-i6ypq351.js} +1 -1
- package/static/dist/assets/{journeyDiagram-3NMN7TZE-ivsmb26o.js → journeyDiagram-3NMN7TZE-lduf1z95.js} +1 -1
- package/static/dist/assets/{kanban-definition-UXKFOSKX-h6n2awt0.js → kanban-definition-UXKFOSKX-e18bu4pg.js} +1 -1
- package/static/dist/assets/lazyRouteComponent-e1y4t2i9.js +1 -0
- package/static/dist/assets/{line-dmzlfe0u.js → line-meizqsvn.js} +1 -1
- package/static/dist/assets/link-oot2yn73.js +1 -0
- package/static/dist/assets/login-gu28l9ou.js +1 -0
- package/static/dist/assets/mermaid-HWGCJPDP-mtwrj8fn.js +1 -0
- package/static/dist/assets/{mermaid-parser.core-gwyd5bnq.js → mermaid-parser.core-ntne45i9.js} +3 -3
- package/static/dist/assets/{mindmap-definition-YA3MSWOX-l68gg5h7.js → mindmap-definition-YA3MSWOX-27b26eok.js} +1 -1
- package/static/dist/assets/onboarding-lkphzu1s.js +1 -0
- package/static/dist/assets/onboarding_model_label-ftpjdwqk.js +1 -0
- package/static/dist/assets/{packet-AYTQ26CC-gpv06065.js → packet-AYTQ26CC-l6jdka8p.js} +1 -1
- package/static/dist/assets/{pegDiagram-XKGWAZYB-e52vs23u.js → pegDiagram-XKGWAZYB-g1er3bxj.js} +1 -1
- package/static/dist/assets/{pie-WAS4IAKB-l6m7nz5s.js → pie-WAS4IAKB-i0ylcrt9.js} +1 -1
- package/static/dist/assets/{pieDiagram-E7YTZNPT-b4is36bq.js → pieDiagram-E7YTZNPT-fbz1e55z.js} +1 -1
- package/static/dist/assets/{quadrantDiagram-AXDQQJYC-m8vt2788.js → quadrantDiagram-AXDQQJYC-hhue7d8o.js} +1 -1
- package/static/dist/assets/{radar-RG4KPBEZ-nxbrhiov.js → radar-RG4KPBEZ-f9b70aa4.js} +1 -1
- package/static/dist/assets/{railroad-74A4TZTK-222mu9hi.js → railroad-74A4TZTK-lgsuoeda.js} +1 -1
- package/static/dist/assets/railroad-abnf-HS5TGJTU-nf9d6pdx.js +1 -0
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-f7ummkt5.js +1 -0
- package/static/dist/assets/railroad-peg-WCYAUIDC-oczq5tqs.js +1 -0
- package/static/dist/assets/{railroadDiagram-O6MQD6OU-o8lldfzv.js → railroadDiagram-O6MQD6OU-eqpy9fnz.js} +1 -1
- package/static/dist/assets/refresh-abtu93ke.js +1 -0
- package/static/dist/assets/refresh-cw-hlwb02qv.js +1 -0
- package/static/dist/assets/{requirementDiagram-BXWQKSXE-ovyq38kv.js → requirementDiagram-BXWQKSXE-ogf6puhi.js} +1 -1
- package/static/dist/assets/{sankeyDiagram-P5KCCOFB-ou7lznor.js → sankeyDiagram-P5KCCOFB-fqb8xcjf.js} +1 -1
- package/static/dist/assets/{saved-bazmcup9.js → saved-girnabkf.js} +1 -1
- package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-ovckdzf2.js → sequenceDiagram-WJ2MYXX4-dlcz6qjz.js} +1 -1
- package/static/dist/assets/{settings_section_extensions_title-ertwwhlx.js → settings_section_extensions_title-h14cwk6f.js} +1 -1
- package/static/dist/assets/share._token-kl0r7ido.js +2 -0
- package/static/dist/assets/sliders-horizontal-n1zm34qq.js +1 -0
- package/static/dist/assets/sse-iwku0sjo.js +1 -0
- package/static/dist/assets/{stateDiagram-D77RDMKH-fcrexkkv.js → stateDiagram-D77RDMKH-fyoznpcs.js} +1 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-ixhx8r46.js +1 -0
- package/static/dist/assets/{swimlanes-42K2YHIH-f7usu8fw.js → swimlanes-42K2YHIH-oefldhfy.js} +1 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-h9ersk2e.js +8 -0
- package/static/dist/assets/{timeline-definition-24CTP7MA-gp1hvz9f.js → timeline-definition-24CTP7MA-b1vl2zil.js} +1 -1
- package/static/dist/assets/todoStore-jjr5yr78.js +1 -0
- package/static/dist/assets/{treeView-Q6P3EWNA-gb9gf11u.js → treeView-Q6P3EWNA-f7hcci5o.js} +1 -1
- package/static/dist/assets/{treemap-WGGIJYW6-nuvfnvvi.js → treemap-WGGIJYW6-nl85071a.js} +1 -1
- package/static/dist/assets/units-kgxzxfhi.js +1 -0
- package/static/dist/assets/{untitled-htelhc68.js → untitled-cikfjntn.js} +1 -1
- package/static/dist/assets/{useForm-h2t0u14e.js → useForm-kqoqg0k9.js} +1 -1
- package/static/dist/assets/useLocale-o59tbiea.js +1 -0
- package/static/dist/assets/{useParams-dqd64jv7.js → useParams-b4dq6n4q.js} +1 -1
- package/static/dist/assets/{useSearch-j30pvsy7.js → useSearch-ipfmv3he.js} +1 -1
- package/static/dist/assets/{vennDiagram-4TSXK5OY-fzchbzaj.js → vennDiagram-4TSXK5OY-h5hzbk0n.js} +1 -1
- package/static/dist/assets/{wardley-WFR3VGLG-m47mhfbh.js → wardley-WFR3VGLG-jftvpm3e.js} +1 -1
- package/static/dist/assets/{wardleyDiagram-VM6X3IG4-odg6ct1z.js → wardleyDiagram-VM6X3IG4-hedh85ge.js} +1 -1
- package/static/dist/assets/{xychartDiagram-S5SC5T6Z-mrhms5um.js → xychartDiagram-S5SC5T6Z-e49523ab.js} +1 -1
- package/static/dist/index.html +1 -1
- package/static/dist/sw.js +2 -2
- package/static/dist/assets/AppShell-ef3bhu32.js +0 -1
- package/static/dist/assets/Button-nx37f4u1.js +0 -1
- package/static/dist/assets/ChatPage-cdcpykcg.js +0 -25
- package/static/dist/assets/Dialog-mec42hvb.js +0 -1
- package/static/dist/assets/HubRoute-ecb65zpr.js +0 -2
- package/static/dist/assets/RightPanel-d1lgvk4s.js +0 -1
- package/static/dist/assets/Select-h4ivl9qf.js +0 -1
- package/static/dist/assets/SessionListPanel-ewib046b.js +0 -1
- package/static/dist/assets/SettingsLayout-lx654cup.js +0 -1
- package/static/dist/assets/States-ehsb6lzo.js +0 -1
- package/static/dist/assets/Toaster-mch1pa3t.js +0 -1
- package/static/dist/assets/_app-m8d961ef.js +0 -1
- package/static/dist/assets/_app.ext._extensionId-mp33hbzi.js +0 -1
- package/static/dist/assets/_app.index-dk6zp7e0.js +0 -1
- package/static/dist/assets/_app.insights-jt2fk4i1.js +0 -1
- package/static/dist/assets/_app.kanban-if4pubeu.js +0 -1
- package/static/dist/assets/_app.logs-mfaw9m6g.js +0 -1
- package/static/dist/assets/_app.memory-h3eaarb6.js +0 -1
- package/static/dist/assets/_app.profiles-ienktovs.js +0 -1
- package/static/dist/assets/_app.settings-dpoe0bzf.js +0 -1
- package/static/dist/assets/_app.settings._section-l468ynag.js +0 -3
- package/static/dist/assets/_app.skills-kcbncc8i.js +0 -1
- package/static/dist/assets/_app.tasks-occdrqhw.js +0 -2
- package/static/dist/assets/_app.todos-nnke2rcc.js +0 -1
- package/static/dist/assets/_app.workspaces-cdlatvwj.js +0 -1
- package/static/dist/assets/architecture-7GRP2DOG-hj11333z.js +0 -1
- package/static/dist/assets/channel-mbvmf2vv.js +0 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-o8r05k0n.js +0 -1
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-o8r05k0n.js +0 -1
- package/static/dist/assets/copy-e6977uwq.js +0 -1
- package/static/dist/assets/endpoints-k7yf25m0.js +0 -64
- package/static/dist/assets/eventmodeling-NTZA5JFV-kpbq09bx.js +0 -1
- package/static/dist/assets/flowDiagram-HODETNUW-lcz0kx14.js +0 -1
- package/static/dist/assets/index-h00usru2.js +0 -11
- package/static/dist/assets/index-n73ijkv2.css +0 -2
- package/static/dist/assets/lazyRouteComponent-m1rtyk4t.js +0 -1
- package/static/dist/assets/link-budeg5t9.js +0 -1
- package/static/dist/assets/login-kjhasvp8.js +0 -1
- package/static/dist/assets/matchContext-f8oy3lo7.js +0 -1
- package/static/dist/assets/mermaid-HWGCJPDP-jb5d211j.js +0 -1
- package/static/dist/assets/onboarding-cdfrk0pj.js +0 -1
- package/static/dist/assets/railroad-abnf-HS5TGJTU-kdvgl6x8.js +0 -1
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-itiqslby.js +0 -1
- package/static/dist/assets/railroad-peg-WCYAUIDC-go7kov78.js +0 -1
- package/static/dist/assets/refresh-cw-kbcje1uy.js +0 -1
- package/static/dist/assets/search-jen74z4u.js +0 -1
- package/static/dist/assets/share._token-dan9hgvj.js +0 -2
- package/static/dist/assets/sliders-horizontal-f9cb3lh3.js +0 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-lcfraua2.js +0 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-ogmanni0.js +0 -8
- package/static/dist/assets/todoStore-eqtid4r4.js +0 -1
- package/static/dist/assets/useLocale-hcsb84pj.js +0 -1
- package/static/dist/assets/useNavigate-nwy70ztj.js +0 -1
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
"""``usage.*``: provider account usage through ``agent.account_usage
|
|
1
|
+
"""``usage.*``: provider account usage through ``agent.account_usage``, the credential pool's local per-entry
|
|
2
|
+
state, and the key-based balance endpoints (TAL-548). Pool keys never leave the sidecar."""
|
|
2
3
|
|
|
3
4
|
from __future__ import annotations
|
|
4
5
|
|
|
5
6
|
import dataclasses
|
|
7
|
+
import json
|
|
6
8
|
import logging
|
|
9
|
+
import math
|
|
10
|
+
import time
|
|
11
|
+
import urllib.error
|
|
12
|
+
import urllib.request
|
|
7
13
|
from datetime import date, datetime, timezone
|
|
8
14
|
from typing import Any
|
|
9
15
|
|
|
@@ -32,13 +38,237 @@ def _plain(value: Any) -> Any:
|
|
|
32
38
|
return str(value)
|
|
33
39
|
|
|
34
40
|
|
|
35
|
-
def
|
|
41
|
+
def _iso(epoch: float | None) -> str | None:
|
|
42
|
+
return None if epoch is None else datetime.fromtimestamp(epoch, tz=timezone.utc).isoformat().replace("+00:00", "Z")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# Python `_is_ambient_gh_cli_entry`: a seeded `gh` CLI or GitHub env token is not an account the user added.
|
|
46
|
+
_AMBIENT_GH_SOURCES = frozenset({"gh_cli", "gh auth token", "env:github_token", "env:gh_token"})
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _is_ambient(entry) -> bool:
|
|
50
|
+
return any(str((entry.get(k) if isinstance(entry, dict) else getattr(entry, k, "")) or "").strip().lower() in _AMBIENT_GH_SOURCES for k in ("source", "label", "key_source"))
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def pool_providers() -> list[str]:
|
|
54
|
+
"""Providers whose persisted credential pool holds an account the user added; a read of ``auth.json`` with no seeding."""
|
|
55
|
+
try:
|
|
56
|
+
from hermes_cli.auth import read_credential_pool
|
|
57
|
+
except Exception as exc: # noqa: BLE001
|
|
58
|
+
raise RpcError(f"credential pool unavailable: {exc}", condition="usage_unavailable") from exc
|
|
59
|
+
try:
|
|
60
|
+
pools = read_credential_pool()
|
|
61
|
+
except Exception: # noqa: BLE001
|
|
62
|
+
log.debug("read_credential_pool() failed", exc_info=True)
|
|
63
|
+
return []
|
|
64
|
+
return sorted(str(pid) for pid, entries in (pools or {}).items()
|
|
65
|
+
if isinstance(entries, list) and any(isinstance(e, dict) and str(e.get("id") or "").strip() and not _is_ambient(e) for e in entries))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _pool(provider: str) -> tuple[Any, list]:
|
|
69
|
+
"""The Agent's credential pool for the scoped profile and its non-ambient entries; ``(None, [])`` when unreadable."""
|
|
70
|
+
try:
|
|
71
|
+
from agent.credential_pool import load_pool
|
|
72
|
+
except Exception as exc: # noqa: BLE001
|
|
73
|
+
raise RpcError(f"credential pool unavailable: {exc}", condition="usage_unavailable") from exc
|
|
74
|
+
try:
|
|
75
|
+
pool = load_pool(provider)
|
|
76
|
+
entries = list(pool.entries()) if pool is not None else []
|
|
77
|
+
except Exception: # noqa: BLE001
|
|
78
|
+
log.debug("load_pool(%r) failed", provider, exc_info=True)
|
|
79
|
+
return None, []
|
|
80
|
+
return pool, [e for e in entries if not _is_ambient(e)]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _entry(provider: str, credential_id: str):
|
|
84
|
+
return next((e for e in _pool(provider)[1] if str(getattr(e, "id", "") or "").strip() == credential_id), None)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _entry_key(entry) -> str:
|
|
88
|
+
"""Python `_get_provider_api_key(provider, credential_id)`: the entry's runtime key."""
|
|
89
|
+
for name in ("runtime_api_key", "agent_key", "access_token"):
|
|
90
|
+
try:
|
|
91
|
+
value = str(getattr(entry, name, "") or "").strip()
|
|
92
|
+
except Exception: # noqa: BLE001 - a runtime key property that cannot resolve
|
|
93
|
+
value = ""
|
|
94
|
+
if value:
|
|
95
|
+
return value
|
|
96
|
+
return ""
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _label(entry, index: int) -> str:
|
|
100
|
+
"""Python `_safe_entry_label`."""
|
|
101
|
+
label = " ".join(str(getattr(entry, "label", "") or getattr(entry, "source", "") or f"Credential {index}").split())
|
|
102
|
+
return label[:61].rstrip() + "..." if len(label) > 64 else label
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def pool(provider: str, *, api_key: str | None = None) -> list[dict]:
|
|
106
|
+
"""Python `_local_pool_snapshot` rows: one per pool entry with an id, its local status, whether it holds the
|
|
107
|
+
server-resolved ``api_key``, and no secrets."""
|
|
108
|
+
agent_pool, entries = _pool(provider)
|
|
109
|
+
configured = str(api_key or "").strip()
|
|
110
|
+
try:
|
|
111
|
+
from agent.credential_pool import _exhausted_until
|
|
112
|
+
except Exception: # noqa: BLE001 - an Agent without it cannot date an exhausted mark, so the entry reads as available
|
|
113
|
+
def _exhausted_until(entry, *, sole_credential=False):
|
|
114
|
+
return None
|
|
115
|
+
sole_fn = getattr(agent_pool, "_is_sole_credential", None)
|
|
116
|
+
sole = bool(sole_fn()) if callable(sole_fn) else len(entries) == 1
|
|
117
|
+
rows = []
|
|
118
|
+
for index, entry in enumerate(entries, start=1):
|
|
119
|
+
credential_id = str(getattr(entry, "id", "") or "").strip()
|
|
120
|
+
if not credential_id:
|
|
121
|
+
continue
|
|
122
|
+
row = {"credential_id": credential_id, "label": _label(entry, index), "status": "available", "unavailable_reason": None, "retry_after": None,
|
|
123
|
+
"matches_api_key": bool(configured) and _entry_key(entry) == configured}
|
|
124
|
+
status = str(getattr(entry, "last_status", "") or "").strip().lower()
|
|
125
|
+
until = _exhausted_until(entry, sole_credential=sole) if status == "exhausted" else None
|
|
126
|
+
if status == "dead":
|
|
127
|
+
row.update(status="dead", unavailable_reason="Credential permanently revoked or invalid.")
|
|
128
|
+
elif until is not None and time.time() < until:
|
|
129
|
+
retry_after = _iso(until)
|
|
130
|
+
code = getattr(entry, "last_error_code", None)
|
|
131
|
+
reason = "Credential pool marked this credential exhausted" + (f" after provider status {code}" if code else "") + (f"; retry after {retry_after}" if retry_after else "")
|
|
132
|
+
row.update(status="exhausted", unavailable_reason=reason + ".", retry_after=retry_after)
|
|
133
|
+
rows.append(row)
|
|
134
|
+
return rows
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
_BALANCE_URLS = {
|
|
138
|
+
"openrouter": "https://openrouter.ai/api/v1/key",
|
|
139
|
+
"deepseek": "https://api.deepseek.com/user/balance",
|
|
140
|
+
"opencode-go": "https://opencode.ai/zen/go/v1/usage",
|
|
141
|
+
}
|
|
142
|
+
_BALANCE_TIMEOUT_SECONDS = 15.0
|
|
143
|
+
_BALANCE_MAX_BYTES = 256 * 1024
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def _number(value: Any) -> int | float | None:
|
|
147
|
+
"""Python `_quota_number`, finite only: a NaN or infinity is not JSON."""
|
|
148
|
+
if isinstance(value, bool) or value is None:
|
|
149
|
+
return None
|
|
150
|
+
if isinstance(value, int):
|
|
151
|
+
return value
|
|
152
|
+
try:
|
|
153
|
+
number = float(value if isinstance(value, float) else str(value).strip())
|
|
154
|
+
except (TypeError, ValueError):
|
|
155
|
+
return None
|
|
156
|
+
if not math.isfinite(number):
|
|
157
|
+
return None
|
|
158
|
+
return int(number) if number.is_integer() and not isinstance(value, float) else number
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def _openrouter(payload: Any) -> dict | None:
|
|
162
|
+
data = payload.get("data") if isinstance(payload, dict) and isinstance(payload.get("data"), dict) else payload
|
|
163
|
+
data = data if isinstance(data, dict) else {}
|
|
164
|
+
return {"quota": {k: _number(data.get(k)) for k in ("limit_remaining", "usage", "limit")}, "label": str(data.get("label") or "").strip() or None}
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _deepseek(payload: Any) -> dict | None:
|
|
168
|
+
"""Python `_sanitize_deepseek_balances`: CNY/USD rows with a total, plus the account's `is_available`."""
|
|
169
|
+
if not isinstance(payload, dict) or not isinstance(payload.get("is_available"), bool):
|
|
170
|
+
return None
|
|
171
|
+
balances = []
|
|
172
|
+
for row in payload.get("balance_infos") or []:
|
|
173
|
+
if not isinstance(row, dict):
|
|
174
|
+
continue
|
|
175
|
+
currency = str(row.get("currency") or "").strip().upper()
|
|
176
|
+
total = _number(row.get("total_balance"))
|
|
177
|
+
if currency in {"CNY", "USD"} and total is not None:
|
|
178
|
+
balances.append({"currency": currency, "total": total, "granted": _number(row.get("granted_balance")), "topped_up": _number(row.get("topped_up_balance"))})
|
|
179
|
+
return {"balances": balances, "is_available": payload["is_available"]} if balances else None
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def _opencode_go(payload: Any) -> dict | None:
|
|
183
|
+
"""Python `_sanitize_opencode_go_account_limits`: all three windows, each well-formed, or nothing."""
|
|
184
|
+
usage = payload.get("usage") if isinstance(payload, dict) else None
|
|
185
|
+
if not isinstance(usage, dict):
|
|
186
|
+
return None
|
|
187
|
+
windows = []
|
|
188
|
+
for key in ("rolling", "weekly", "monthly"):
|
|
189
|
+
window = usage.get(key)
|
|
190
|
+
if not isinstance(window, dict) or window.get("status") not in {"ok", "rate-limited"}:
|
|
191
|
+
return None
|
|
192
|
+
used = _number(window.get("percent"))
|
|
193
|
+
try:
|
|
194
|
+
reset_at = datetime.fromisoformat(str(window.get("resetsAt") or "").strip().replace("Z", "+00:00"))
|
|
195
|
+
except ValueError:
|
|
196
|
+
return None
|
|
197
|
+
if used is None or not 0 <= used <= 100:
|
|
198
|
+
return None
|
|
199
|
+
reset_at = reset_at if reset_at.tzinfo else reset_at.replace(tzinfo=timezone.utc)
|
|
200
|
+
windows.append({"key": key, "used_percent": used, "reset_at": _iso(reset_at.timestamp()), "rate_limited": window["status"] == "rate-limited"})
|
|
201
|
+
return {"windows": windows}
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
_BALANCE_PARSERS = {"openrouter": _openrouter, "deepseek": _deepseek, "opencode-go": _opencode_go}
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def balance(provider: str, *, credential_id: str | None, api_key: str | None) -> dict:
|
|
208
|
+
"""One key-based balance read. A pool credential's key resolves here; otherwise the server passes the configured key."""
|
|
209
|
+
result = {"status": "unavailable", "http_status": None, "quota": None, "label": None, "is_available": None, "balances": [], "windows": []}
|
|
210
|
+
key = str(api_key or "").strip()
|
|
211
|
+
if credential_id:
|
|
212
|
+
entry = _entry(provider, credential_id)
|
|
213
|
+
key = _entry_key(entry) if entry is not None else ""
|
|
214
|
+
if not key:
|
|
215
|
+
return {**result, "status": "no_key"}
|
|
216
|
+
request = urllib.request.Request(_BALANCE_URLS[provider], headers={"Authorization": f"Bearer {key}", "Accept": "application/json", "User-Agent": "Talaria-Web/1.0"})
|
|
217
|
+
try:
|
|
218
|
+
with urllib.request.urlopen(request, timeout=_BALANCE_TIMEOUT_SECONDS) as response:
|
|
219
|
+
raw = response.read(_BALANCE_MAX_BYTES + 1)
|
|
220
|
+
if len(raw) > _BALANCE_MAX_BYTES:
|
|
221
|
+
raise ValueError("oversized balance response")
|
|
222
|
+
parsed = _BALANCE_PARSERS[provider](json.loads(raw.decode("utf-8")))
|
|
223
|
+
except urllib.error.HTTPError as exc:
|
|
224
|
+
return {**result, "status": "http_error", "http_status": exc.code}
|
|
225
|
+
except (OSError, ValueError): # URLError and timeouts are OSErrors; malformed JSON or UTF-8 are ValueErrors
|
|
226
|
+
log.debug("%s balance read failed", provider, exc_info=True)
|
|
227
|
+
return result
|
|
228
|
+
return {**result, **parsed, "status": "ok"} if parsed is not None else result
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
_ANTHROPIC_WINDOWS = (("five_hour", "Current session"), ("seven_day", "Current week"), ("seven_day_opus", "Opus week"), ("seven_day_sonnet", "Sonnet week"))
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def _anthropic_usage(token: str):
|
|
235
|
+
"""The Agent's Anthropic account-usage read for one given token. The Agent's fetcher reads only the ambient token, so a
|
|
236
|
+
pool account would otherwise report the active account's limits."""
|
|
237
|
+
# ponytail: mirrors agent.account_usage._fetch_anthropic_account_usage on the Agent's own helpers; drop it once that
|
|
238
|
+
# fetcher honours its api_key argument.
|
|
239
|
+
from agent import account_usage as agent_usage
|
|
240
|
+
|
|
241
|
+
if not agent_usage._is_oauth_token(token):
|
|
242
|
+
return agent_usage._snapshot("anthropic", "oauth_usage_api", [], [], unavailable_reason="Anthropic account limits are only available for OAuth-backed Claude accounts.")
|
|
243
|
+
headers = {"Authorization": f"Bearer {token}", "Accept": "application/json", "Content-Type": "application/json",
|
|
244
|
+
"anthropic-beta": "oauth-2025-04-20", "User-Agent": "claude-code/2.1.0"}
|
|
245
|
+
payload = agent_usage._get_json("https://api.anthropic.com/api/oauth/usage", headers, timeout=15.0)
|
|
246
|
+
windows = agent_usage._usage_windows(payload, _ANTHROPIC_WINDOWS, "utilization", "resets_at", fraction=True)
|
|
247
|
+
extra = payload.get("extra_usage") or {}
|
|
248
|
+
used, limit = extra.get("used_credits"), extra.get("monthly_limit")
|
|
249
|
+
details = [f"Extra usage: {used:.2f} / {limit:.2f} {extra.get('currency') or 'USD'}"] if extra.get("is_enabled") and agent_usage._is_num(used) and agent_usage._is_num(limit) else []
|
|
250
|
+
return agent_usage._snapshot("anthropic", "oauth_usage_api", windows, details)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def account(provider: str, *, base_url: str | None, api_key: str | None, credential_id: str | None = None) -> dict | None:
|
|
254
|
+
if credential_id:
|
|
255
|
+
# One pool account's usage, read with that account's own key.
|
|
256
|
+
entry = _entry(provider, credential_id)
|
|
257
|
+
if entry is None:
|
|
258
|
+
return None
|
|
259
|
+
api_key = _entry_key(entry)
|
|
260
|
+
if not api_key:
|
|
261
|
+
return {"provider": provider, "available": False, "unavailable_reason": "No runtime token available.", "windows": [], "details": []}
|
|
262
|
+
base_url = str(getattr(entry, "runtime_base_url", None) or getattr(entry, "base_url", None) or "").strip() or base_url
|
|
36
263
|
try:
|
|
37
264
|
from agent.account_usage import fetch_account_usage
|
|
38
265
|
except Exception as exc: # noqa: BLE001
|
|
39
266
|
raise RpcError(f"account usage unavailable: {exc}", condition="usage_unavailable") from exc
|
|
40
267
|
try:
|
|
41
|
-
|
|
268
|
+
if credential_id and provider == "anthropic":
|
|
269
|
+
snapshot = _anthropic_usage(api_key)
|
|
270
|
+
else:
|
|
271
|
+
snapshot = fetch_account_usage(provider, base_url=base_url, api_key=api_key)
|
|
42
272
|
except Exception as exc: # noqa: BLE001
|
|
43
273
|
log.debug("fetch_account_usage(%r) failed", provider, exc_info=True)
|
|
44
274
|
return {"provider": provider, "available": False, "unavailable_reason": f"{type(exc).__name__}: {exc}", "windows": [], "details": []}
|
|
@@ -61,5 +291,28 @@ def register(registry) -> None:
|
|
|
61
291
|
provider = str(params.get("provider") or "").strip()
|
|
62
292
|
if not provider:
|
|
63
293
|
raise InvalidParams("provider is required")
|
|
294
|
+
credential_id = str(params.get("credential_id") or "").strip() or None
|
|
295
|
+
with scoped_home(profile_home_param(params)):
|
|
296
|
+
return {"snapshot": account(provider, base_url=params.get("base_url"), api_key=params.get("api_key"), credential_id=credential_id)}
|
|
297
|
+
|
|
298
|
+
@registry.method("usage.pool")
|
|
299
|
+
def pool_(ctx: CallContext, params: dict) -> dict:
|
|
300
|
+
provider = str(params.get("provider") or "").strip()
|
|
301
|
+
if not provider:
|
|
302
|
+
raise InvalidParams("provider is required")
|
|
303
|
+
with scoped_home(profile_home_param(params)):
|
|
304
|
+
return {"entries": pool(provider, api_key=params.get("api_key"))}
|
|
305
|
+
|
|
306
|
+
@registry.method("usage.pool_providers")
|
|
307
|
+
def pool_providers_(ctx: CallContext, params: dict) -> dict:
|
|
308
|
+
with scoped_home(profile_home_param(params)):
|
|
309
|
+
return {"providers": pool_providers()}
|
|
310
|
+
|
|
311
|
+
@registry.method("usage.balance")
|
|
312
|
+
def balance_(ctx: CallContext, params: dict) -> dict:
|
|
313
|
+
provider = str(params.get("provider") or "").strip()
|
|
314
|
+
if provider not in _BALANCE_URLS:
|
|
315
|
+
raise InvalidParams(f"provider must be one of {sorted(_BALANCE_URLS)}")
|
|
316
|
+
credential_id = str(params.get("credential_id") or "").strip() or None
|
|
64
317
|
with scoped_home(profile_home_param(params)):
|
|
65
|
-
return
|
|
318
|
+
return balance(provider, credential_id=credential_id, api_key=params.get("api_key"))
|
|
@@ -205,6 +205,18 @@ def _marker_presence(marker: Path) -> str:
|
|
|
205
205
|
return "present"
|
|
206
206
|
|
|
207
207
|
|
|
208
|
+
def installed_agent_version() -> str | None:
|
|
209
|
+
"""Agents since v0.21.6 resolve their identity from the install stamp, else the checkout's release tag; their
|
|
210
|
+
``__version__`` reads only the stamp, which a source checkout does not have."""
|
|
211
|
+
try:
|
|
212
|
+
from hermes_cli.version_info import get_version_info
|
|
213
|
+
except ModuleNotFoundError as error:
|
|
214
|
+
if error.name != "hermes_cli.version_info":
|
|
215
|
+
raise
|
|
216
|
+
return getattr(importlib.import_module("hermes_cli"), "__version__", None)
|
|
217
|
+
return get_version_info().base_version
|
|
218
|
+
|
|
219
|
+
|
|
208
220
|
class AgentRuntime:
|
|
209
221
|
"""Loads the Agent once and guards against a changed checkout."""
|
|
210
222
|
|
|
@@ -229,6 +241,10 @@ class AgentRuntime:
|
|
|
229
241
|
try:
|
|
230
242
|
module = importlib.import_module("run_agent")
|
|
231
243
|
getattr(module, "AIAgent")
|
|
244
|
+
# Agent 0.21.3 snapshots its auth provider registry, discovered plugins included, when hermes_cli.auth
|
|
245
|
+
# first imports. Take it here, under the launch profile and before any profile-scoped method runs, so
|
|
246
|
+
# a named profile's plugin loaded later never enters that process-wide snapshot.
|
|
247
|
+
importlib.import_module("hermes_cli.auth")
|
|
232
248
|
except Exception as exc: # noqa: BLE001 - reported as a handshake condition
|
|
233
249
|
self.import_error = f"{type(exc).__name__}: {exc}"
|
|
234
250
|
raise AgentIncompatible(f"Hermes Agent could not be imported: {self.import_error}", import_error=self.import_error)
|
|
@@ -242,7 +258,7 @@ class AgentRuntime:
|
|
|
242
258
|
@property
|
|
243
259
|
def agent_version(self) -> str | None:
|
|
244
260
|
try:
|
|
245
|
-
return
|
|
261
|
+
return installed_agent_version()
|
|
246
262
|
except Exception: # noqa: BLE001
|
|
247
263
|
return None
|
|
248
264
|
|