@maudecode/talaria-web 1.17.2 → 1.19.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 +20 -20
- package/dist/api/auth-raw.js.map +1 -1
- package/dist/api/automation-raw.d.ts +7 -1
- package/dist/api/automation-raw.js +74 -27
- package/dist/api/automation-raw.js.map +1 -1
- package/dist/api/automation-router.d.ts +128 -23
- package/dist/api/automation-router.js +29 -13
- package/dist/api/automation-router.js.map +1 -1
- package/dist/api/chat-router.d.ts +1845 -40
- package/dist/api/chat-router.js +196 -114
- package/dist/api/chat-router.js.map +1 -1
- package/dist/api/git-router.d.ts +37 -3
- package/dist/api/git-router.js +47 -48
- package/dist/api/git-router.js.map +1 -1
- package/dist/api/raw-routes.d.ts +9 -1
- package/dist/api/raw-routes.js +286 -73
- package/dist/api/raw-routes.js.map +1 -1
- package/dist/api/router.d.ts +16 -6
- package/dist/api/router.js +28 -26
- package/dist/api/router.js.map +1 -1
- package/dist/api/session-visibility.d.ts +4 -4
- package/dist/api/session-visibility.js +26 -16
- package/dist/api/session-visibility.js.map +1 -1
- package/dist/api/sessions-router.d.ts +3312 -131
- package/dist/api/sessions-router.js +287 -157
- package/dist/api/sessions-router.js.map +1 -1
- package/dist/api/settings-router.d.ts +457 -8
- package/dist/api/settings-router.js +54 -33
- package/dist/api/settings-router.js.map +1 -1
- package/dist/api/sse-routes.d.ts +7 -2
- package/dist/api/sse-routes.js +109 -62
- package/dist/api/sse-routes.js.map +1 -1
- package/dist/api/tools-raw.d.ts +5 -0
- package/dist/api/tools-raw.js +63 -55
- package/dist/api/tools-raw.js.map +1 -1
- package/dist/api/tools-router.d.ts +998 -85
- package/dist/api/tools-router.js +447 -61
- package/dist/api/tools-router.js.map +1 -1
- package/dist/api/transcribe-stream.d.ts +16 -0
- package/dist/api/transcribe-stream.js +172 -0
- package/dist/api/transcribe-stream.js.map +1 -0
- package/dist/app.d.ts +4 -1
- package/dist/app.js +98 -59
- package/dist/app.js.map +1 -1
- package/dist/auth/gate.js +15 -11
- 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/auth/passkeys.d.ts +15 -14
- package/dist/auth/passkeys.js +89 -91
- package/dist/auth/passkeys.js.map +1 -1
- package/dist/auth/store.d.ts +17 -7
- package/dist/auth/store.js +93 -52
- package/dist/auth/store.js.map +1 -1
- package/dist/bin/talaria-web.js +12 -81
- package/dist/bin/talaria-web.js.map +1 -1
- package/dist/cli/ctl.js +2 -1
- package/dist/cli/ctl.js.map +1 -1
- package/dist/cli/dotenv.d.ts +5 -0
- package/dist/cli/dotenv.js +15 -2
- package/dist/cli/dotenv.js.map +1 -1
- package/dist/cli/launcher.js +5 -5
- package/dist/cli/launcher.js.map +1 -1
- package/dist/cli/main.d.ts +1 -0
- package/dist/cli/main.js +85 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/supervise.d.ts +2 -0
- package/dist/cli/supervise.js +67 -4
- package/dist/cli/supervise.js.map +1 -1
- package/dist/config/agent-config.d.ts +34 -11
- package/dist/config/agent-config.js +116 -60
- package/dist/config/agent-config.js.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.js +19 -6
- package/dist/config.js.map +1 -1
- package/dist/fs/atomic.d.ts +1 -0
- package/dist/fs/atomic.js +4 -1
- package/dist/fs/atomic.js.map +1 -1
- package/dist/fs/stat.d.ts +1 -0
- package/dist/fs/stat.js +11 -0
- package/dist/fs/stat.js.map +1 -0
- package/dist/http/context.d.ts +31 -12
- package/dist/http/context.js +60 -24
- 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.d.ts +2 -2
- package/dist/onboarding.js +10 -8
- package/dist/onboarding.js.map +1 -1
- package/dist/profiles/profiles.d.ts +20 -4
- package/dist/profiles/profiles.js +115 -30
- package/dist/profiles/profiles.js.map +1 -1
- package/dist/projects.d.ts +15 -6
- package/dist/projects.js +55 -47
- package/dist/projects.js.map +1 -1
- package/dist/providers/catalog.d.ts +84 -14
- package/dist/providers/catalog.js +474 -151
- package/dist/providers/catalog.js.map +1 -1
- package/dist/providers/env-file.d.ts +10 -3
- package/dist/providers/env-file.js +24 -75
- package/dist/providers/env-file.js.map +1 -1
- package/dist/providers/runtime-env.d.ts +4 -2
- package/dist/providers/runtime-env.js +9 -6
- package/dist/providers/runtime-env.js.map +1 -1
- package/dist/providers/tables.d.ts +3 -1
- package/dist/providers/tables.js +4 -2
- package/dist/providers/tables.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.js +342 -46
- package/dist/redact.js.map +1 -1
- package/dist/release.d.ts +7 -0
- package/dist/release.js +14 -0
- package/dist/release.js.map +1 -1
- package/dist/runtime.d.ts +5 -1
- package/dist/runtime.js +305 -96
- package/dist/runtime.js.map +1 -1
- package/dist/server.js +15 -0
- package/dist/server.js.map +1 -1
- package/dist/sessions/anchor.d.ts +9 -3
- package/dist/sessions/anchor.js +28 -36
- package/dist/sessions/anchor.js.map +1 -1
- package/dist/sessions/background-events.d.ts +2 -0
- package/dist/sessions/background-events.js +10 -0
- package/dist/sessions/background-events.js.map +1 -0
- package/dist/sessions/background-tasks.d.ts +26 -27
- package/dist/sessions/background-tasks.js +89 -97
- package/dist/sessions/background-tasks.js.map +1 -1
- package/dist/sessions/background-updates.d.ts +15 -8
- package/dist/sessions/background-updates.js +101 -25
- package/dist/sessions/background-updates.js.map +1 -1
- package/dist/sessions/cli-sessions.d.ts +27 -6
- package/dist/sessions/cli-sessions.js +152 -42
- package/dist/sessions/cli-sessions.js.map +1 -1
- package/dist/sessions/completions.d.ts +77 -9
- package/dist/sessions/completions.js +482 -45
- package/dist/sessions/completions.js.map +1 -1
- package/dist/sessions/compress.d.ts +8 -0
- package/dist/sessions/compress.js +2 -2
- package/dist/sessions/compress.js.map +1 -1
- package/dist/sessions/drafts.d.ts +14 -10
- package/dist/sessions/drafts.js +38 -43
- package/dist/sessions/drafts.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-sessions.d.ts +46 -0
- package/dist/sessions/gateway-sessions.js +378 -0
- package/dist/sessions/gateway-sessions.js.map +1 -0
- 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/goals.d.ts +31 -0
- package/dist/sessions/goals.js +75 -0
- package/dist/sessions/goals.js.map +1 -0
- 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 +5 -79
- package/dist/sessions/journal.js +15 -606
- package/dist/sessions/journal.js.map +1 -1
- package/dist/sessions/list.d.ts +31 -16
- package/dist/sessions/list.js +139 -129
- package/dist/sessions/list.js.map +1 -1
- package/dist/sessions/merge.d.ts +69 -13
- package/dist/sessions/merge.js +265 -64
- package/dist/sessions/merge.js.map +1 -1
- package/dist/sessions/notices.d.ts +22 -0
- package/dist/sessions/notices.js +72 -0
- package/dist/sessions/notices.js.map +1 -0
- package/dist/sessions/pending.d.ts +10 -4
- package/dist/sessions/pending.js +83 -7
- package/dist/sessions/pending.js.map +1 -1
- package/dist/sessions/prefix-index.d.ts +82 -0
- package/dist/sessions/prefix-index.js +232 -0
- package/dist/sessions/prefix-index.js.map +1 -0
- package/dist/sessions/recovery.d.ts +19 -0
- package/dist/sessions/recovery.js +322 -0
- package/dist/sessions/recovery.js.map +1 -0
- package/dist/sessions/relay.d.ts +38 -19
- package/dist/sessions/relay.js +302 -79
- package/dist/sessions/relay.js.map +1 -1
- package/dist/sessions/service.d.ts +260 -55
- package/dist/sessions/service.js +1448 -462
- package/dist/sessions/service.js.map +1 -1
- package/dist/sessions/session.d.ts +24 -2
- package/dist/sessions/session.js +69 -7
- package/dist/sessions/session.js.map +1 -1
- package/dist/sessions/shares.d.ts +7 -6
- package/dist/sessions/shares.js +22 -45
- package/dist/sessions/shares.js.map +1 -1
- package/dist/sessions/source-kind.js +1 -0
- package/dist/sessions/source-kind.js.map +1 -1
- package/dist/sessions/state-db-identity.d.ts +18 -0
- package/dist/sessions/state-db-identity.js +67 -0
- package/dist/sessions/state-db-identity.js.map +1 -0
- package/dist/sessions/state-db-worker.d.ts +1 -0
- package/dist/sessions/state-db-worker.js +35 -0
- package/dist/sessions/state-db-worker.js.map +1 -0
- package/dist/sessions/state-db.d.ts +113 -7
- package/dist/sessions/state-db.js +861 -44
- package/dist/sessions/state-db.js.map +1 -1
- package/dist/sessions/storage/backend.d.ts +162 -0
- package/dist/sessions/storage/backend.js +19 -0
- package/dist/sessions/storage/backend.js.map +1 -0
- package/dist/sessions/storage/conformance.d.ts +20 -0
- package/dist/sessions/storage/conformance.js +237 -0
- package/dist/sessions/storage/conformance.js.map +1 -0
- package/dist/sessions/storage/document.d.ts +16 -0
- package/dist/sessions/storage/document.js +44 -0
- package/dist/sessions/storage/document.js.map +1 -0
- package/dist/sessions/storage/json-documents.d.ts +23 -0
- package/dist/sessions/storage/json-documents.js +233 -0
- package/dist/sessions/storage/json-documents.js.map +1 -0
- package/dist/sessions/storage/json-files.d.ts +12 -0
- package/dist/sessions/storage/json-files.js +124 -0
- package/dist/sessions/storage/json-files.js.map +1 -0
- package/dist/sessions/storage/json-installation.d.ts +3 -0
- package/dist/sessions/storage/json-installation.js +31 -0
- package/dist/sessions/storage/json-installation.js.map +1 -0
- package/dist/sessions/storage/json-journal.d.ts +114 -0
- package/dist/sessions/storage/json-journal.js +686 -0
- package/dist/sessions/storage/json-journal.js.map +1 -0
- package/dist/sessions/storage/json-recovery.d.ts +4 -0
- package/dist/sessions/storage/json-recovery.js +195 -0
- package/dist/sessions/storage/json-recovery.js.map +1 -0
- package/dist/sessions/storage/json.d.ts +68 -0
- package/dist/sessions/storage/json.js +258 -0
- package/dist/sessions/storage/json.js.map +1 -0
- package/dist/sessions/storage/row.d.ts +6 -0
- package/dist/sessions/storage/row.js +49 -0
- package/dist/sessions/storage/row.js.map +1 -0
- package/dist/sessions/storage/search-text.d.ts +4 -0
- package/dist/sessions/storage/search-text.js +16 -0
- package/dist/sessions/storage/search-text.js.map +1 -0
- package/dist/sessions/store.d.ts +65 -68
- package/dist/sessions/store.js +305 -602
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/streams.d.ts +4 -0
- package/dist/sessions/streams.js +9 -1
- package/dist/sessions/streams.js.map +1 -1
- package/dist/sessions/titles.d.ts +2 -0
- package/dist/sessions/titles.js +5 -1
- package/dist/sessions/titles.js.map +1 -1
- package/dist/sessions/todo.d.ts +5 -0
- package/dist/sessions/todo.js +28 -21
- package/dist/sessions/todo.js.map +1 -1
- package/dist/sessions/tool-display.d.ts +5 -4
- package/dist/sessions/tool-display.js +30 -50
- package/dist/sessions/tool-display.js.map +1 -1
- package/dist/sessions/turn-context.d.ts +11 -2
- package/dist/sessions/turn-context.js +18 -11
- package/dist/sessions/turn-context.js.map +1 -1
- package/dist/sessions/turn.d.ts +122 -17
- package/dist/sessions/turn.js +939 -358
- package/dist/sessions/turn.js.map +1 -1
- package/dist/sessions/wakeup-pause.d.ts +54 -0
- package/dist/sessions/wakeup-pause.js +163 -0
- package/dist/sessions/wakeup-pause.js.map +1 -0
- package/dist/sessions/window.js +13 -12
- package/dist/sessions/window.js.map +1 -1
- package/dist/settings.d.ts +19 -7
- package/dist/settings.js +178 -184
- package/dist/settings.js.map +1 -1
- package/dist/sidecar/client.d.ts +17 -3
- package/dist/sidecar/client.js +78 -8
- package/dist/sidecar/client.js.map +1 -1
- package/dist/sidecar/discover.d.ts +2 -1
- package/dist/sidecar/discover.js +93 -10
- package/dist/sidecar/discover.js.map +1 -1
- package/dist/sidecar/env.d.ts +4 -0
- package/dist/sidecar/env.js +3 -0
- package/dist/sidecar/env.js.map +1 -0
- package/dist/sidecar/fake.d.ts +2 -2
- package/dist/sidecar/fake.js +19 -2
- package/dist/sidecar/fake.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/env-file.d.ts +5 -0
- package/dist/test/env-file.js +88 -0
- package/dist/test/env-file.js.map +1 -0
- package/dist/test/harness.d.ts +1 -0
- package/dist/test/harness.js +1 -1
- package/dist/test/harness.js.map +1 -1
- package/dist/test/passkeys.d.ts +22 -0
- package/dist/test/passkeys.js +62 -0
- package/dist/test/passkeys.js.map +1 -0
- package/dist/test/storage.d.ts +15 -0
- package/dist/test/storage.js +26 -0
- package/dist/test/storage.js.map +1 -0
- 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/commands.d.ts +6 -1
- package/dist/tools/commands.js +8 -2
- package/dist/tools/commands.js.map +1 -1
- package/dist/tools/connectors.d.ts +33 -0
- package/dist/tools/connectors.js +121 -0
- package/dist/tools/connectors.js.map +1 -0
- package/dist/tools/crons.d.ts +38 -1
- package/dist/tools/crons.js +122 -18
- 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 +18 -5
- package/dist/tools/extensions.js +344 -266
- package/dist/tools/extensions.js.map +1 -1
- package/dist/tools/gateway-restart.d.ts +62 -0
- package/dist/tools/gateway-restart.js +142 -0
- package/dist/tools/gateway-restart.js.map +1 -0
- package/dist/tools/health.d.ts +44 -0
- package/dist/tools/health.js +201 -46
- package/dist/tools/health.js.map +1 -1
- package/dist/tools/hygiene.d.ts +4 -3
- package/dist/tools/hygiene.js +23 -9
- package/dist/tools/hygiene.js.map +1 -1
- package/dist/tools/kanban.d.ts +4 -2
- package/dist/tools/kanban.js +28 -19
- package/dist/tools/kanban.js.map +1 -1
- package/dist/tools/mcp.d.ts +13 -0
- package/dist/tools/mcp.js +88 -0
- package/dist/tools/mcp.js.map +1 -1
- package/dist/tools/memory-masks.d.ts +5 -0
- package/dist/tools/memory-masks.js +256 -0
- package/dist/tools/memory-masks.js.map +1 -0
- package/dist/tools/memory.d.ts +29 -3
- package/dist/tools/memory.js +69 -27
- package/dist/tools/memory.js.map +1 -1
- package/dist/tools/plugin-settings.d.ts +15 -0
- package/dist/tools/plugin-settings.js +90 -0
- package/dist/tools/plugin-settings.js.map +1 -0
- 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 +14 -5
- package/dist/tools/skills.js +49 -16
- package/dist/tools/skills.js.map +1 -1
- package/dist/tools/update-notifications.d.ts +34 -15
- package/dist/tools/update-notifications.js +141 -57
- package/dist/tools/update-notifications.js.map +1 -1
- package/dist/tools/update-rollback.d.ts +11 -0
- package/dist/tools/update-rollback.js +28 -0
- package/dist/tools/update-rollback.js.map +1 -0
- package/dist/tools/updates.d.ts +110 -32
- package/dist/tools/updates.js +1112 -294
- 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/util.d.ts +2 -0
- package/dist/util.js +5 -0
- package/dist/util.js.map +1 -1
- 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 +12 -0
- package/dist/workspace/fs.js +92 -23
- package/dist/workspace/fs.js.map +1 -1
- package/dist/workspace/git.d.ts +34 -1
- package/dist/workspace/git.js +328 -35
- package/dist/workspace/git.js.map +1 -1
- package/dist/workspace/media.d.ts +16 -13
- package/dist/workspace/media.js +43 -61
- package/dist/workspace/media.js.map +1 -1
- package/dist/workspace/rollback.d.ts +36 -22
- package/dist/workspace/rollback.js +178 -272
- 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 +7 -4
- package/dist/workspace/upload.js +5 -2
- package/dist/workspace/upload.js.map +1 -1
- package/dist/workspace/workspaces.d.ts +15 -19
- package/dist/workspace/workspaces.js +55 -127
- package/dist/workspace/workspaces.js.map +1 -1
- package/dist/workspace/worktrees.d.ts +2 -1
- package/dist/workspace/worktrees.js +179 -42
- package/dist/workspace/worktrees.js.map +1 -1
- package/package.json +7 -3
- package/sidecar/agent_dependency.json +4 -4
- package/sidecar/agent_support.json +26 -0
- package/sidecar/scripts/record-fixtures.py +12 -3
- package/sidecar/scripts/replay_sidecar.py +32 -0
- package/sidecar/scripts/suite_runner.py +302 -0
- package/sidecar/scripts/test.sh +12 -4
- package/sidecar/talaria_sidecar/__init__.py +6 -1
- package/sidecar/talaria_sidecar/__main__.py +4 -2
- package/sidecar/talaria_sidecar/agent_mutation.py +975 -0
- package/sidecar/talaria_sidecar/agent_services.py +1053 -0
- package/sidecar/talaria_sidecar/dependency_sync.py +85 -0
- package/sidecar/talaria_sidecar/home.py +56 -3
- package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
- package/sidecar/talaria_sidecar/methods/aux.py +166 -24
- package/sidecar/talaria_sidecar/methods/chat.py +852 -135
- package/sidecar/talaria_sidecar/methods/checkpoints.py +89 -0
- package/sidecar/talaria_sidecar/methods/commands.py +294 -4
- package/sidecar/talaria_sidecar/methods/config.py +123 -4
- package/sidecar/talaria_sidecar/methods/connectors.py +343 -0
- package/sidecar/talaria_sidecar/methods/cron.py +395 -36
- package/sidecar/talaria_sidecar/methods/cron_execution.py +284 -0
- package/sidecar/talaria_sidecar/methods/gateway.py +212 -55
- package/sidecar/talaria_sidecar/methods/gateway_sessions.py +234 -0
- package/sidecar/talaria_sidecar/methods/goals.py +81 -41
- package/sidecar/talaria_sidecar/methods/kanban.py +108 -34
- package/sidecar/talaria_sidecar/methods/mcp.py +1 -1
- package/sidecar/talaria_sidecar/methods/memory.py +84 -0
- package/sidecar/talaria_sidecar/methods/oauth.py +5 -2
- package/sidecar/talaria_sidecar/methods/process.py +218 -15
- package/sidecar/talaria_sidecar/methods/profiles.py +121 -13
- package/sidecar/talaria_sidecar/methods/providers.py +217 -28
- package/sidecar/talaria_sidecar/methods/runtime.py +69 -1
- package/sidecar/talaria_sidecar/methods/skills.py +67 -4
- package/sidecar/talaria_sidecar/methods/state_db.py +316 -75
- package/sidecar/talaria_sidecar/methods/stt.py +159 -78
- package/sidecar/talaria_sidecar/methods/text.py +14 -1
- package/sidecar/talaria_sidecar/methods/toolsets.py +49 -0
- package/sidecar/talaria_sidecar/methods/usage.py +113 -14
- package/sidecar/talaria_sidecar/methods/worktree.py +26 -19
- package/sidecar/talaria_sidecar/methods/write_approval.py +181 -0
- package/sidecar/talaria_sidecar/rpc.py +45 -4
- package/sidecar/talaria_sidecar/runtime.py +98 -13
- package/sidecar/talaria_sidecar/speed.py +35 -0
- package/static/dist/FILES.txt +126 -126
- package/static/dist/assets/AppShell-cey33v9s.js +8 -0
- package/static/dist/assets/ChatPage-i8wnugr7.js +18 -0
- package/static/dist/assets/ConnectTargets-hg19553x.js +1 -0
- package/static/dist/assets/ExtensionRoute-cly4apm5.js +1 -0
- package/static/dist/assets/Field-j8uqoigz.js +9 -0
- package/static/dist/assets/HubRoute-e4bgz41j.js +2 -0
- package/static/dist/assets/Markdown-lahuichm.js +598 -0
- package/static/dist/assets/RightPanel-lbo4i0fn.js +1 -0
- package/static/dist/assets/Select-gqatm2e0.js +1 -0
- package/static/dist/assets/SessionListPanel-mfqayfjh.js +1 -0
- package/static/dist/assets/SettingsLayout-b8980u7k.js +1 -0
- package/static/dist/assets/States-e7dkgtxf.js +1 -0
- package/static/dist/assets/Toaster-bfqqy786.js +1 -0
- package/static/dist/assets/_app-n1n6pfx1.js +1 -0
- package/static/dist/assets/{_app.ext._extensionId-opyh9y0v.js → _app.ext._extensionId-buxjxav3.js} +1 -1
- package/static/dist/assets/_app.index-jt8zwiu2.js +1 -0
- package/static/dist/assets/_app.insights-cv76ml71.js +1 -0
- package/static/dist/assets/_app.kanban-h6ts53j7.js +1 -0
- package/static/dist/assets/_app.logs-dm873z90.js +1 -0
- package/static/dist/assets/_app.memory-glk5y6m8.js +1 -0
- package/static/dist/assets/_app.profiles-ka6zpstq.js +1 -0
- package/static/dist/assets/{_app.session._sessionId-bfd4h3id.js → _app.session._sessionId-g2vzghvc.js} +1 -1
- package/static/dist/assets/_app.settings-hgjdhzcd.js +1 -0
- package/static/dist/assets/_app.settings._section-jf2kmhae.js +3 -0
- package/static/dist/assets/_app.skills-cii852yq.js +1 -0
- package/static/dist/assets/_app.tasks-fp9q7atm.js +1 -0
- package/static/dist/assets/_app.todos-dw94qzue.js +1 -0
- package/static/dist/assets/_app.workspaces-inyygzze.js +1 -0
- package/static/dist/assets/{abnfDiagram-VCTEODGH-b2x1lqot.js → abnfDiagram-VCTEODGH-gjayq3ra.js} +1 -1
- package/static/dist/assets/architecture-7GRP2DOG-lp56972r.js +1 -0
- package/static/dist/assets/{architectureDiagram-5GKGNRK7-h38o5l7b.js → architectureDiagram-5GKGNRK7-nwb3xovn.js} +1 -1
- package/static/dist/assets/archive-b1j004vn.js +1 -0
- package/static/dist/assets/back-g74gkozu.js +1 -0
- package/static/dist/assets/{blockDiagram-I7D4REHJ-bqquxv2u.js → blockDiagram-I7D4REHJ-joedghi3.js} +1 -1
- package/static/dist/assets/{c4Diagram-7LVT6UL2-f3fb8w6z.js → c4Diagram-7LVT6UL2-hyrjrohe.js} +1 -1
- package/static/dist/assets/channel-es95o4y8.js +1 -0
- package/static/dist/assets/{chunk-4HAMMTFA-bzfyyzp3.js → chunk-4HAMMTFA-koouqbut.js} +1 -1
- package/static/dist/assets/{chunk-75Z2AOVW-ly99rfx5.js → chunk-75Z2AOVW-bl4bhdnt.js} +1 -1
- package/static/dist/assets/{chunk-DU6HZSFF-bg6ecfqf.js → chunk-DU6HZSFF-gpedttsp.js} +3 -3
- package/static/dist/assets/{chunk-F27PBJKO-e8k7mmqw.js → chunk-F27PBJKO-d8xxi0zi.js} +1 -1
- package/static/dist/assets/{chunk-GMAD6QVW-cmalnoaj.js → chunk-GMAD6QVW-jro0hl73.js} +1 -1
- package/static/dist/assets/{chunk-GVQU2GXP-gmif5o01.js → chunk-GVQU2GXP-djn6gbyu.js} +1 -1
- package/static/dist/assets/{chunk-IMKFNOWR-f1nwwh6u.js → chunk-IMKFNOWR-vw4p5p7o.js} +1 -1
- package/static/dist/assets/{chunk-L3NEJ4N5-oktfh5v7.js → chunk-L3NEJ4N5-n1hj77q8.js} +1 -1
- package/static/dist/assets/{chunk-OSK3NFVY-b1sdx96z.js → chunk-OSK3NFVY-oy0gwn2n.js} +1 -1
- package/static/dist/assets/{chunk-P2QGCYS3-fhu4nzxt.js → chunk-P2QGCYS3-onf1hz6c.js} +1 -1
- package/static/dist/assets/{chunk-POPQ4Y6H-em31rnef.js → chunk-POPQ4Y6H-m8sqn7cs.js} +1 -1
- package/static/dist/assets/{chunk-PWAF6VOD-bxhhyftw.js → chunk-PWAF6VOD-ek4smc8x.js} +1 -1
- package/static/dist/assets/{chunk-SHT3W25Y-fmrvwcav.js → chunk-SHT3W25Y-g9gfvefo.js} +3 -3
- package/static/dist/assets/{chunk-SVP7TREG-lymukl2j.js → chunk-SVP7TREG-f9nfv2cu.js} +1 -1
- package/static/dist/assets/{chunk-TICWLB2K-lmza6k23.js → chunk-TICWLB2K-bnk3m1mq.js} +1 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-kmihoqxh.js +1 -0
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-kmihoqxh.js +1 -0
- package/static/dist/assets/copied-bli9tbcx.js +1 -0
- package/static/dist/assets/{copy-fw5b1pc6.js → copy-jamtd1pf.js} +1 -1
- package/static/dist/assets/{cynefin-OW5HDTMX-czlhbyhs.js → cynefin-OW5HDTMX-f8xfdd3f.js} +1 -1
- package/static/dist/assets/{cynefinDiagram-5FMLGOSQ-gq7mvswb.js → cynefinDiagram-5FMLGOSQ-n9lb99h9.js} +1 -1
- package/static/dist/assets/{dagre-GXQ25YYZ-cqdbf7dr.js → dagre-GXQ25YYZ-dgailddi.js} +4 -4
- package/static/dist/assets/{diagram-S7CK7UJ4-o6arxa58.js → diagram-S7CK7UJ4-m6aeoe7c.js} +1 -1
- package/static/dist/assets/{diagram-UQ7AKVKN-nhnd68tz.js → diagram-UQ7AKVKN-jall3j0x.js} +1 -1
- package/static/dist/assets/{diagram-VSXAHHWV-dk2sclzn.js → diagram-VSXAHHWV-hbawi7hn.js} +1 -1
- package/static/dist/assets/{diagram-VX7I27RA-n3k5nyx3.js → diagram-VX7I27RA-hendl2tt.js} +1 -1
- package/static/dist/assets/{diagram-Z3DM3KII-m6q9cwdh.js → diagram-Z3DM3KII-igwc35p3.js} +1 -1
- package/static/dist/assets/{ebnfDiagram-PWID7BFC-lsa5641p.js → ebnfDiagram-PWID7BFC-c64knz08.js} +1 -1
- package/static/dist/assets/{erDiagram-RLTQ6QDP-fo2ckbe6.js → erDiagram-RLTQ6QDP-brdu9lcm.js} +1 -1
- package/static/dist/assets/eventmodeling-NTZA5JFV-njk1j8wl.js +1 -0
- package/static/dist/assets/flowDiagram-HODETNUW-nma6f0ga.js +1 -0
- package/static/dist/assets/folder-plus-lvt9kudb.js +1 -0
- package/static/dist/assets/{ganttDiagram-EL5Y4UJY-nzqz6x9g.js → ganttDiagram-EL5Y4UJY-ma6jxj5i.js} +1 -1
- package/static/dist/assets/{gitGraph-4MIJSDKK-gukvcxe6.js → gitGraph-4MIJSDKK-naa9w6xa.js} +1 -1
- package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-lqhdp8f0.js → gitGraphDiagram-WWUBYQGX-hzltvsod.js} +1 -1
- package/static/dist/assets/{highlighted-body-KPVGNVTW-igw6cp39.js → highlighted-body-KPVGNVTW-ghoavj8d.js} +1 -1
- package/static/dist/assets/host-hzm8n85n.js +1 -0
- package/static/dist/assets/index-drdcaqeq.css +2 -0
- package/static/dist/assets/index-jzm844he.js +11 -0
- package/static/dist/assets/{info-A6RAGUB7-gvu7a93l.js → info-A6RAGUB7-mn2ut5ko.js} +1 -1
- package/static/dist/assets/{infoDiagram-27XIBGKW-m8t8g6w1.js → infoDiagram-27XIBGKW-h6kuqvsb.js} +1 -1
- package/static/dist/assets/{ishikawaDiagram-5VMMS53U-l07vkbgj.js → ishikawaDiagram-5VMMS53U-e7bnwq7h.js} +1 -1
- package/static/dist/assets/{journeyDiagram-3NMN7TZE-hybkgj8l.js → journeyDiagram-3NMN7TZE-etd1bi6p.js} +1 -1
- package/static/dist/assets/{kanban-definition-UXKFOSKX-by13uvtn.js → kanban-definition-UXKFOSKX-emb1g9dz.js} +4 -4
- package/static/dist/assets/lazyRouteComponent-o816ytzl.js +1 -0
- package/static/dist/assets/{line-osxq6fq7.js → line-h0ojzsvs.js} +1 -1
- package/static/dist/assets/link-k01ryaf9.js +1 -0
- package/static/dist/assets/login-bsae49ew.js +1 -0
- package/static/dist/assets/mermaid-HWGCJPDP-ihl34s74.js +1 -0
- package/static/dist/assets/{mermaid-parser.core-i91oxmou.js → mermaid-parser.core-bnre27u8.js} +3 -3
- package/static/dist/assets/{mindmap-definition-YA3MSWOX-m82mx8ww.js → mindmap-definition-YA3MSWOX-o1vathns.js} +1 -1
- package/static/dist/assets/onboarding-c65tysya.js +1 -0
- package/static/dist/assets/onboarding_model_label-gpn28uix.js +1 -0
- package/static/dist/assets/{packet-AYTQ26CC-nbtgge2o.js → packet-AYTQ26CC-hatq7m2e.js} +1 -1
- package/static/dist/assets/pcmTap.worklet-74EKjWAZ.js +1 -0
- package/static/dist/assets/{pegDiagram-XKGWAZYB-f1zxzga1.js → pegDiagram-XKGWAZYB-gwisz8jv.js} +1 -1
- package/static/dist/assets/{pie-WAS4IAKB-of8vuhxs.js → pie-WAS4IAKB-fpftf0mk.js} +1 -1
- package/static/dist/assets/{pieDiagram-E7YTZNPT-o7y8ftio.js → pieDiagram-E7YTZNPT-khm1o9a6.js} +1 -1
- package/static/dist/assets/{quadrantDiagram-AXDQQJYC-iqiwia1t.js → quadrantDiagram-AXDQQJYC-owqc4uqn.js} +1 -1
- package/static/dist/assets/{radar-RG4KPBEZ-delnsy2v.js → radar-RG4KPBEZ-cntfwjpq.js} +1 -1
- package/static/dist/assets/{railroad-74A4TZTK-nspnyq9u.js → railroad-74A4TZTK-a7t5eibp.js} +1 -1
- package/static/dist/assets/railroad-abnf-HS5TGJTU-ol8cdktf.js +1 -0
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-i8vzd429.js +1 -0
- package/static/dist/assets/railroad-peg-WCYAUIDC-nw3ulewz.js +1 -0
- package/static/dist/assets/{railroadDiagram-O6MQD6OU-z41tqx5z.js → railroadDiagram-O6MQD6OU-etuh0qa0.js} +1 -1
- package/static/dist/assets/{refresh-cw-nt1dtsx4.js → refresh-cw-mqbkv2a3.js} +1 -1
- package/static/dist/assets/refresh-l29ljp76.js +1 -0
- package/static/dist/assets/{requirementDiagram-BXWQKSXE-bdvif194.js → requirementDiagram-BXWQKSXE-oq2ulk22.js} +1 -1
- package/static/dist/assets/{sankeyDiagram-P5KCCOFB-h73e0rol.js → sankeyDiagram-P5KCCOFB-iqc02emv.js} +1 -1
- package/static/dist/assets/saved-ndd4t2xb.js +1 -0
- package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-iv95mb1z.js → sequenceDiagram-WJ2MYXX4-i0v116q0.js} +2 -2
- package/static/dist/assets/settings_section_extensions_title-jhfo6o8z.js +1 -0
- package/static/dist/assets/share._token-c1ri0hy1.js +2 -0
- package/static/dist/assets/sliders-horizontal-j3jjt9tv.js +1 -0
- package/static/dist/assets/{stateDiagram-D77RDMKH-k417ixmf.js → stateDiagram-D77RDMKH-dnpt1ato.js} +1 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-bxjacpk6.js +1 -0
- package/static/dist/assets/{swimlanes-42K2YHIH-esola70w.js → swimlanes-42K2YHIH-loqbdazb.js} +1 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-id62p9hz.js +8 -0
- package/static/dist/assets/{timeline-definition-24CTP7MA-getrz2y8.js → timeline-definition-24CTP7MA-ol2hnvma.js} +1 -1
- package/static/dist/assets/toast-i3h34v6o.js +64 -0
- package/static/dist/assets/{treeView-Q6P3EWNA-hc7ap1q7.js → treeView-Q6P3EWNA-idrj6iox.js} +1 -1
- package/static/dist/assets/{treemap-WGGIJYW6-b7k1syy5.js → treemap-WGGIJYW6-lzr49vv5.js} +1 -1
- package/static/dist/assets/untitled-oaoya4qj.js +1 -0
- package/static/dist/assets/useForm-nfaxgmsk.js +1 -0
- package/static/dist/assets/{useParams-lhg566ew.js → useParams-gjc70qru.js} +1 -1
- package/static/dist/assets/{useSearch-lbrh6ejn.js → useSearch-e6ae539u.js} +1 -1
- package/static/dist/assets/{vennDiagram-4TSXK5OY-n6pcy5qb.js → vennDiagram-4TSXK5OY-bvwr9o2z.js} +1 -1
- package/static/dist/assets/{wardley-WFR3VGLG-lpa18vz1.js → wardley-WFR3VGLG-31ui8tma.js} +1 -1
- package/static/dist/assets/{wardleyDiagram-VM6X3IG4-kpclwwg7.js → wardleyDiagram-VM6X3IG4-k5wqtx4b.js} +1 -1
- package/static/dist/assets/{xychartDiagram-S5SC5T6Z-paa2n8y0.js → xychartDiagram-S5SC5T6Z-aqbgvujg.js} +1 -1
- package/static/dist/index.html +1 -1
- package/static/dist/sw.js +1 -1
- package/static/dist/assets/AppShell-fb2td9zi.js +0 -1
- package/static/dist/assets/ChatPage-cj96kiy9.js +0 -25
- package/static/dist/assets/Dialog-kxcg7ard.js +0 -1
- package/static/dist/assets/ExtensionRoute-jf7h0754.js +0 -1
- package/static/dist/assets/HubRoute-gmanpd5y.js +0 -2
- package/static/dist/assets/Markdown-mdwlvj3w.js +0 -598
- package/static/dist/assets/RightPanel-ftvrjlcp.js +0 -1
- package/static/dist/assets/Select-bilaypej.js +0 -1
- package/static/dist/assets/SessionListPanel-og8n36qs.js +0 -1
- package/static/dist/assets/SettingsLayout-jonjefmj.js +0 -1
- package/static/dist/assets/States-nmejrwrm.js +0 -1
- package/static/dist/assets/Toaster-nnl8zkt9.js +0 -1
- package/static/dist/assets/_app-gdidzd94.js +0 -1
- package/static/dist/assets/_app.index-hbarzbjx.js +0 -1
- package/static/dist/assets/_app.insights-luywlarz.js +0 -1
- package/static/dist/assets/_app.kanban-kincnbr8.js +0 -1
- package/static/dist/assets/_app.logs-oi2gr3gs.js +0 -1
- package/static/dist/assets/_app.memory-b6jfivt6.js +0 -1
- package/static/dist/assets/_app.profiles-lpvixmqp.js +0 -1
- package/static/dist/assets/_app.settings-vowx3iq0.js +0 -1
- package/static/dist/assets/_app.settings._section-cnntg1tu.js +0 -3
- package/static/dist/assets/_app.skills-fb57lpau.js +0 -1
- package/static/dist/assets/_app.tasks-eszpx1q7.js +0 -2
- package/static/dist/assets/_app.todos-nr05ac6w.js +0 -1
- package/static/dist/assets/_app.workspaces-d2luomu6.js +0 -1
- package/static/dist/assets/architecture-7GRP2DOG-hd0o7bde.js +0 -1
- package/static/dist/assets/back-bemaer09.js +0 -1
- package/static/dist/assets/cancel-drd0g6d9.js +0 -1
- package/static/dist/assets/channel-cpdgf867.js +0 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-ko09sguk.js +0 -1
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-ko09sguk.js +0 -1
- package/static/dist/assets/copied-ima3pysb.js +0 -1
- package/static/dist/assets/endpoints-d33siokx.js +0 -64
- package/static/dist/assets/eventmodeling-NTZA5JFV-emctlo64.js +0 -1
- package/static/dist/assets/flowDiagram-HODETNUW-bfi3moqa.js +0 -1
- package/static/dist/assets/index-cxq58xb1.js +0 -11
- package/static/dist/assets/index-hgtx08n5.css +0 -2
- package/static/dist/assets/lazyRouteComponent-af0lvgjx.js +0 -1
- package/static/dist/assets/link-jyxicdhg.js +0 -1
- package/static/dist/assets/login-ec21t39x.js +0 -1
- package/static/dist/assets/mermaid-HWGCJPDP-gfl8z3ep.js +0 -1
- package/static/dist/assets/onboarding-btnltvyz.js +0 -1
- package/static/dist/assets/onboarding_model_label-dp7xffoh.js +0 -1
- package/static/dist/assets/railroad-abnf-HS5TGJTU-nst1qxyn.js +0 -1
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-ci37x8qy.js +0 -1
- package/static/dist/assets/railroad-peg-WCYAUIDC-aimkk07z.js +0 -1
- package/static/dist/assets/refresh-b4uams1i.js +0 -1
- package/static/dist/assets/saved-kg52csy7.js +0 -1
- package/static/dist/assets/settings_section_extensions_title-ej0iapxe.js +0 -1
- package/static/dist/assets/share._token-f97e94r0.js +0 -2
- package/static/dist/assets/sliders-horizontal-fj18it47.js +0 -1
- package/static/dist/assets/sse-fwpqtzbg.js +0 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-hwn4apct.js +0 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-d1h97oyg.js +0 -8
- package/static/dist/assets/todoStore-eginf9h4.js +0 -1
- package/static/dist/assets/tts-lxdxnmjd.js +0 -1
- package/static/dist/assets/untitled-ovpfthg4.js +0 -1
- package/static/dist/assets/useForm-bcblv1rx.js +0 -1
- package/static/dist/assets/useLocale-fi5jb8ma.js +0 -1
|
@@ -10,10 +10,14 @@ composes: ``hermes_cli.auth``, ``hermes_cli.models``, ``hermes_cli.runtime_provi
|
|
|
10
10
|
from __future__ import annotations
|
|
11
11
|
|
|
12
12
|
import dataclasses
|
|
13
|
+
import json
|
|
13
14
|
import logging
|
|
15
|
+
import sqlite3
|
|
14
16
|
import sys
|
|
15
17
|
import threading
|
|
18
|
+
from contextlib import closing
|
|
16
19
|
from pathlib import Path
|
|
20
|
+
from types import SimpleNamespace
|
|
17
21
|
from typing import Any
|
|
18
22
|
|
|
19
23
|
from ..errors import InvalidParams, RpcError
|
|
@@ -94,11 +98,57 @@ def _user_plugin_profiles() -> dict[int, tuple[Any, Path]]:
|
|
|
94
98
|
return out
|
|
95
99
|
|
|
96
100
|
|
|
101
|
+
def _hosted_plugin_profiles(roots: dict[Path, str]) -> dict[Path, list] | None:
|
|
102
|
+
"""Resolve enabled directories through the Agent's host metadata and scoped provider registry."""
|
|
103
|
+
import providers
|
|
104
|
+
|
|
105
|
+
if not hasattr(providers, "_home_layer") or not callable(getattr(providers, "provider_source", None)):
|
|
106
|
+
return None
|
|
107
|
+
try:
|
|
108
|
+
from hermes_cli.plugin_isolation import ISOLATION_HOST, isolation_mode
|
|
109
|
+
except ImportError: # per-home registries predate host isolation
|
|
110
|
+
return None
|
|
111
|
+
|
|
112
|
+
if isolation_mode() != ISOLATION_HOST:
|
|
113
|
+
return None
|
|
114
|
+
from hermes_cli.plugin_host_profiles import load_hosted_profiles
|
|
115
|
+
from hermes_constants import get_hermes_home, hermes_home_key
|
|
116
|
+
|
|
117
|
+
registered = {p.name: p for p in providers.list_providers() if providers.provider_source(p.name) == "user"}
|
|
118
|
+
home_key = hermes_home_key(get_hermes_home())
|
|
119
|
+
# Discovery also loads disabled and manifest-less category plugins. Include them when checking name collisions.
|
|
120
|
+
directories = set(roots)
|
|
121
|
+
for parent, flat in ((providers._user_plugins_dir(), False), (providers._installed_plugins_dir(), True)):
|
|
122
|
+
if parent is not None:
|
|
123
|
+
directories.update(child.resolve() for child in parent.iterdir()
|
|
124
|
+
if child.is_dir() and not child.name.startswith(("_", "."))
|
|
125
|
+
and (not flat or (child.name != "model-providers" and providers._declares_model_provider_kind(child))))
|
|
126
|
+
owners: dict[str, set[Path]] = {}
|
|
127
|
+
for root in directories:
|
|
128
|
+
try:
|
|
129
|
+
# Reuse the Agent's cached extraction; provider ids need not match manifest or directory names.
|
|
130
|
+
profiles = load_hosted_profiles(root, providers._user_module_name(root, home_key))
|
|
131
|
+
for profile in profiles:
|
|
132
|
+
owners.setdefault(profile.name, set()).add(root)
|
|
133
|
+
except Exception: # noqa: BLE001 - failed extraction keeps the manifest's not_loaded row
|
|
134
|
+
log.debug("reading hosted provider plugin %s failed", root, exc_info=True)
|
|
135
|
+
found: dict[Path, list] = {root: [] for root in roots}
|
|
136
|
+
for name, profile in registered.items():
|
|
137
|
+
origins = owners.get(name, set())
|
|
138
|
+
if len(origins) == 1:
|
|
139
|
+
root = next(iter(origins))
|
|
140
|
+
if root in found:
|
|
141
|
+
found[root].append(profile)
|
|
142
|
+
return found
|
|
143
|
+
|
|
144
|
+
|
|
97
145
|
def _load_plugin(root: Path) -> None:
|
|
98
146
|
"""Load the scoped profile's installed plugin that the process-wide discovery (run under the launch profile) skipped.
|
|
99
147
|
|
|
100
|
-
Uses the Agent's own loader, as ``hermes plugins dev`` does, once per directory.
|
|
101
|
-
that is already registered, so one profile's plugin cannot
|
|
148
|
+
Uses the Agent's own loader, as ``hermes plugins dev`` does, once per directory. On an Agent with one process-wide
|
|
149
|
+
provider registry, a plugin never displaces a provider that is already registered, so one profile's plugin cannot
|
|
150
|
+
change what another profile's provider id runs. An Agent with per-home provider layers registers it in this home's
|
|
151
|
+
layer instead, so the same id is that profile's own provider.
|
|
102
152
|
"""
|
|
103
153
|
import providers
|
|
104
154
|
|
|
@@ -121,12 +171,13 @@ def _load_plugin(root: Path) -> None:
|
|
|
121
171
|
def installed_plugin_profiles() -> list[tuple[str, Any]]:
|
|
122
172
|
"""``(manifest name, profile | None)`` for each enabled model-provider plugin installed in the scoped home.
|
|
123
173
|
|
|
124
|
-
Bundled providers are built-ins, not plugins.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
174
|
+
Bundled providers are built-ins, not plugins. Hosted profiles come from the Agent's scoped user registry and
|
|
175
|
+
directory metadata. In-process profiles belong to this home when their module lives in its plugin directories;
|
|
176
|
+
a plugin the launch discovery skipped is loaded here.
|
|
177
|
+
``None`` means the plugin could not be loaded or attributed: it failed to import, its hosted provider id is
|
|
178
|
+
ambiguous, or a registration/module name collided in an older process-wide registry.
|
|
179
|
+
shortcut: in-process ownership uses module globals, so an unbound inline profile reads as not
|
|
180
|
+
loaded; use Agent registration metadata if it becomes available.
|
|
130
181
|
"""
|
|
131
182
|
try:
|
|
132
183
|
from hermes_cli.plugins_discovery import _get_disabled_plugins, _get_enabled_plugins, collect_directory_manifests, gate_manifest
|
|
@@ -141,6 +192,10 @@ def installed_plugin_profiles() -> list[tuple[str, Any]]:
|
|
|
141
192
|
if not roots:
|
|
142
193
|
return []
|
|
143
194
|
|
|
195
|
+
hosted = _hosted_plugin_profiles(roots)
|
|
196
|
+
if hosted is not None:
|
|
197
|
+
return [(name, p) for root, name in roots.items() for p in (hosted[root] or [None])]
|
|
198
|
+
|
|
144
199
|
def owned() -> dict[Path, list]:
|
|
145
200
|
found: dict[Path, list] = {root: [] for root in roots}
|
|
146
201
|
for profile, directory in _user_plugin_profiles().values():
|
|
@@ -158,18 +213,40 @@ def installed_plugin_profiles() -> list[tuple[str, Any]]:
|
|
|
158
213
|
return [(name, p) for root, name in roots.items() for p in (found[root] or [None])]
|
|
159
214
|
|
|
160
215
|
|
|
161
|
-
def
|
|
162
|
-
"""Whether
|
|
163
|
-
|
|
216
|
+
def _unavailable_plugin(provider_id: str) -> bool:
|
|
217
|
+
"""Whether a registered plugin lacks an enabled, unambiguous owner in this home."""
|
|
218
|
+
import providers
|
|
164
219
|
|
|
165
|
-
profile = get_provider_profile(provider_id)
|
|
166
|
-
if profile is None
|
|
220
|
+
profile = providers.get_provider_profile(provider_id)
|
|
221
|
+
if profile is None:
|
|
222
|
+
return False
|
|
223
|
+
if hasattr(providers, "_home_layer") and callable(getattr(providers, "provider_source", None)):
|
|
224
|
+
if providers.provider_source(profile.name) != "user":
|
|
225
|
+
return False
|
|
226
|
+
elif id(profile) not in _user_plugin_profiles():
|
|
167
227
|
return False
|
|
168
228
|
return not any(p is profile for _name, p in installed_plugin_profiles())
|
|
169
229
|
|
|
170
230
|
|
|
231
|
+
def _agent_knows_provider(name: str) -> bool:
|
|
232
|
+
"""Whether the Agent's auth layer can resolve this provider id at all.
|
|
233
|
+
|
|
234
|
+
Agent 0.21.3 resolves providers from a ``PROVIDER_REGISTRY`` snapshot of its import-time plugin discovery, so a
|
|
235
|
+
named profile's plugin loaded here on demand is unknown to it and cannot run. Registering it there would expose it
|
|
236
|
+
to every profile, so it reads as unavailable instead. Newer Agents look providers up live (``_registry_lookup``).
|
|
237
|
+
"""
|
|
238
|
+
try:
|
|
239
|
+
import hermes_cli.auth as auth
|
|
240
|
+
except Exception: # noqa: BLE001 - auth_status reports an unavailable auth layer
|
|
241
|
+
return True
|
|
242
|
+
registry = getattr(auth, "PROVIDER_REGISTRY", None)
|
|
243
|
+
return hasattr(auth, "_registry_lookup") or not isinstance(registry, dict) or name.strip().lower() in registry
|
|
244
|
+
|
|
245
|
+
|
|
171
246
|
def _setup_state(profile: Any) -> str:
|
|
172
247
|
"""The Agent's own setup verdict for a plugin provider, without spawning its CLI or reading its credentials."""
|
|
248
|
+
if not _agent_knows_provider(str(profile.name)):
|
|
249
|
+
return "unavailable"
|
|
173
250
|
try:
|
|
174
251
|
status = auth_status(profile.name)
|
|
175
252
|
except RpcError:
|
|
@@ -178,6 +255,9 @@ def _setup_state(profile: Any) -> str:
|
|
|
178
255
|
return "unavailable"
|
|
179
256
|
if profile.auth_type == "external_process":
|
|
180
257
|
return "ready" if status.get("configured") else "missing_cli"
|
|
258
|
+
if profile.auth_type in ("oauth_external", "oauth_device_code"):
|
|
259
|
+
# The Agent's ``configured`` only means registered here; a pooled token, live or refreshable on use, means signed in.
|
|
260
|
+
return "ready" if status.get("logged_in") or status.get("needs_refresh") else "needs_setup"
|
|
181
261
|
return "ready" if status.get("logged_in") or status.get("configured") else "needs_setup"
|
|
182
262
|
|
|
183
263
|
|
|
@@ -193,47 +273,97 @@ def plugin_providers() -> list[dict]:
|
|
|
193
273
|
return rows
|
|
194
274
|
|
|
195
275
|
|
|
196
|
-
def _plugin_catalog(provider_id: str) -> list[str]:
|
|
276
|
+
def _plugin_catalog(provider_id: str) -> tuple[list[str], bool]:
|
|
197
277
|
"""Discovery for an installed plugin the Agent's catalog has no fetcher for: the profile's own listing, then its fallback.
|
|
198
278
|
|
|
199
279
|
API-key plugins already get both from ``provider_model_ids`` with their key, so only keyless auth types list here.
|
|
280
|
+
Like the Agent, the fallback list is a placeholder only when a listing was tried and declined.
|
|
200
281
|
"""
|
|
201
282
|
for _name, profile in installed_plugin_profiles():
|
|
202
283
|
if profile is None or str(profile.name).strip().lower() != provider_id.strip().lower():
|
|
203
284
|
continue
|
|
285
|
+
lists = bool(profile.supports_model_listing) and profile.auth_type != "api_key"
|
|
204
286
|
try:
|
|
205
|
-
live = profile.fetch_models(timeout=8.0) if
|
|
287
|
+
live = profile.fetch_models(timeout=8.0) if lists else None
|
|
206
288
|
except Exception: # noqa: BLE001 - a broken plugin answers with its fallback catalog
|
|
207
289
|
log.debug("fetch_models(%r) failed", provider_id, exc_info=True)
|
|
208
290
|
live = None
|
|
209
|
-
return [str(m) for m in (live or profile.fallback_models or ()) if m]
|
|
210
|
-
return []
|
|
291
|
+
return [str(m) for m in (live or profile.fallback_models or ()) if m], lists and not live
|
|
292
|
+
return [], False
|
|
211
293
|
|
|
212
294
|
|
|
213
|
-
def model_ids(provider_id: str, *, force_refresh: bool) -> list[str]:
|
|
295
|
+
def model_ids(provider_id: str, *, force_refresh: bool) -> tuple[list[str], bool]:
|
|
296
|
+
"""The Agent's catalog for a provider, and whether it is the curated placeholder for an unreachable one (TAL-799)."""
|
|
214
297
|
try:
|
|
215
|
-
from hermes_cli
|
|
298
|
+
from hermes_cli import models
|
|
216
299
|
except Exception as exc: # noqa: BLE001
|
|
217
300
|
raise RpcError(f"model catalog unavailable: {exc}", condition="providers_unavailable") from exc
|
|
218
301
|
try:
|
|
219
|
-
if
|
|
220
|
-
return []
|
|
221
|
-
except Exception: # noqa: BLE001 -
|
|
302
|
+
if _unavailable_plugin(provider_id):
|
|
303
|
+
return [], False
|
|
304
|
+
except Exception: # noqa: BLE001 - an unverified owner must not expose another plugin's models
|
|
222
305
|
log.debug("plugin ownership check for %r failed", provider_id, exc_info=True)
|
|
306
|
+
return [], False
|
|
223
307
|
try:
|
|
224
|
-
ids = provider_model_ids(provider_id, force_refresh=force_refresh)
|
|
308
|
+
ids = models.provider_model_ids(provider_id, force_refresh=force_refresh)
|
|
225
309
|
except TypeError:
|
|
226
|
-
ids = provider_model_ids(provider_id)
|
|
310
|
+
ids = models.provider_model_ids(provider_id)
|
|
227
311
|
except Exception: # noqa: BLE001
|
|
228
312
|
log.debug("provider_model_ids(%r) failed", provider_id, exc_info=True)
|
|
229
313
|
ids = []
|
|
314
|
+
# Agents before the marker never flag a fallback.
|
|
315
|
+
curated = getattr(models, "CuratedFallbackModels", None)
|
|
316
|
+
fallback = isinstance(curated, type) and isinstance(ids, curated)
|
|
230
317
|
ids = [str(m) for m in (ids or []) if m]
|
|
231
318
|
if ids:
|
|
232
|
-
return ids
|
|
319
|
+
return ids, fallback
|
|
233
320
|
try:
|
|
234
321
|
return _plugin_catalog(provider_id)
|
|
235
322
|
except RpcError:
|
|
236
|
-
return []
|
|
323
|
+
return [], False
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def _requests_local_runtime(requested: str | None) -> bool:
|
|
327
|
+
"""Whether a resolution asks for the Agent's managed llama.cpp provider, picked the way the Agent picks it: the
|
|
328
|
+
named provider, else the profile's, else ``HERMES_INFERENCE_PROVIDER``."""
|
|
329
|
+
try:
|
|
330
|
+
from hermes_cli.providers import LLAMACPP_ALIASES
|
|
331
|
+
from hermes_cli.runtime_provider import resolve_requested_provider
|
|
332
|
+
|
|
333
|
+
return resolve_requested_provider(requested) in LLAMACPP_ALIASES
|
|
334
|
+
except Exception: # noqa: BLE001 - an Agent without the local runtime
|
|
335
|
+
return False
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def runtime_failure(exc: Exception, requested: str | None, message: str | None = None) -> RpcError:
|
|
339
|
+
"""The typed error for a runtime that did not resolve. The local llama.cpp provider has no credential to add: it
|
|
340
|
+
fails because its server is off or still starting, and the Agent's message says which (TAL-798)."""
|
|
341
|
+
condition = "local_runtime_unavailable" if _requests_local_runtime(requested) else "credential_missing"
|
|
342
|
+
return RpcError(message or str(exc), condition=condition, data={"error_type": type(exc).__name__})
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
def local_models() -> dict:
|
|
346
|
+
"""The Agent's managed llama.cpp runtime (TAL-798): the downloaded GGUFs, selectable before its server runs (a turn
|
|
347
|
+
on one boots it), and the endpoint the running server recorded. An Agent without the local runtime lists none."""
|
|
348
|
+
try:
|
|
349
|
+
from hermes_cli.local_runtime.bootstrap import staged_model_ids
|
|
350
|
+
from hermes_cli.providers import LLAMACPP_PROVIDER_ID
|
|
351
|
+
except Exception: # noqa: BLE001 - predates the local runtime
|
|
352
|
+
return {"provider_id": "", "models": [], "current_endpoint": None}
|
|
353
|
+
try:
|
|
354
|
+
models = [str(m) for m in staged_model_ids() if m]
|
|
355
|
+
except Exception: # noqa: BLE001 - an unreadable models directory lists none
|
|
356
|
+
log.debug("staged_model_ids failed", exc_info=True)
|
|
357
|
+
models = []
|
|
358
|
+
endpoint = None
|
|
359
|
+
try:
|
|
360
|
+
from hermes_cli.local_runtime.endpoint import _state_endpoint
|
|
361
|
+
|
|
362
|
+
state = _state_endpoint()
|
|
363
|
+
endpoint = str(state["base_url"]) if state else None
|
|
364
|
+
except Exception: # noqa: BLE001 - no recorded server
|
|
365
|
+
log.debug("local runtime endpoint failed", exc_info=True)
|
|
366
|
+
return {"provider_id": str(LLAMACPP_PROVIDER_ID), "models": models, "current_endpoint": endpoint}
|
|
237
367
|
|
|
238
368
|
|
|
239
369
|
def resolve_runtime(*, requested: str | None, api_key: str | None, base_url: str | None, target_model: str | None) -> dict:
|
|
@@ -248,7 +378,7 @@ def resolve_runtime(*, requested: str | None, api_key: str | None, base_url: str
|
|
|
248
378
|
message = format_runtime_provider_error(exc)
|
|
249
379
|
except Exception: # noqa: BLE001
|
|
250
380
|
message = str(exc)
|
|
251
|
-
raise
|
|
381
|
+
raise runtime_failure(exc, requested, message) from exc
|
|
252
382
|
return _plain(runtime) if isinstance(runtime, dict) else {"runtime": _plain(runtime)}
|
|
253
383
|
|
|
254
384
|
|
|
@@ -346,7 +476,60 @@ def capabilities(provider: str, model: str) -> dict | None:
|
|
|
346
476
|
return row if isinstance(row, dict) else None
|
|
347
477
|
|
|
348
478
|
|
|
479
|
+
def selection_warnings(home: Path, params: dict) -> dict:
|
|
480
|
+
"""Read-only guard decision using the same route resolver as a turn; never builds or evicts an Agent."""
|
|
481
|
+
from . import chat
|
|
482
|
+
try:
|
|
483
|
+
from hermes_cli.model_selection_guards import SelectionContext, selection_context_for_agent, selection_warnings as warnings
|
|
484
|
+
except ImportError as exc:
|
|
485
|
+
raise RpcError("Model selection warnings are unavailable in this Agent", condition="unsupported") from exc
|
|
486
|
+
|
|
487
|
+
model = str(params["model"])
|
|
488
|
+
runtime = chat._resolve_runtime(params.get("provider"), model)
|
|
489
|
+
provider = str(runtime.get("provider") or params.get("provider") or "")
|
|
490
|
+
base_url = str(runtime.get("base_url") or "")
|
|
491
|
+
tokens = params.get("context_tokens")
|
|
492
|
+
if not tokens:
|
|
493
|
+
with chat._AGENT_CACHE_LOCK:
|
|
494
|
+
entry = chat._AGENT_CACHE.get(params["session_id"])
|
|
495
|
+
if entry and Path(entry[2]).resolve() == home.resolve():
|
|
496
|
+
context = selection_context_for_agent(entry[0])
|
|
497
|
+
tokens = context.context_tokens if context else None
|
|
498
|
+
if not tokens and (home / "state.db").exists():
|
|
499
|
+
from agent.usage_anchor import persisted_anchor_tokens
|
|
500
|
+
|
|
501
|
+
# SessionDB opens and migrates its database. The guard needs only this read-only accessor.
|
|
502
|
+
with closing(sqlite3.connect(f"{(home / 'state.db').resolve().as_uri()}?mode=ro", uri=True)) as db:
|
|
503
|
+
row = db.execute("SELECT model_config FROM sessions WHERE id=?", (params["session_id"],)).fetchone()
|
|
504
|
+
config = json.loads(row[0] or "{}") if row else {}
|
|
505
|
+
reader = SimpleNamespace(get_session_model_config_value=lambda sid, key, default=None: config.get(key, default))
|
|
506
|
+
tokens = persisted_anchor_tokens(reader, params["session_id"], params.get("messages", []))
|
|
507
|
+
# A same-model pick on another provider still abandons the previous route's prompt cache.
|
|
508
|
+
current = params.get("current_model") if params.get("current_provider") == params.get("provider") else None
|
|
509
|
+
context = SelectionContext(context_tokens=tokens, current_model=current)
|
|
510
|
+
result = warnings(model, provider=provider, base_url=base_url, api_key=runtime.get("api_key"), selection_context=context)
|
|
511
|
+
return {"warnings": [_plain(w) for w in result], "context_tokens": tokens or None, "provider": provider, "base_url": base_url}
|
|
512
|
+
|
|
513
|
+
|
|
349
514
|
def register(reg) -> None:
|
|
515
|
+
@reg.method("models.selection_warnings")
|
|
516
|
+
def selection(ctx: CallContext, params: dict) -> dict:
|
|
517
|
+
if not params.get("model") or not params.get("session_id"):
|
|
518
|
+
raise InvalidParams("model and session_id are required")
|
|
519
|
+
home = profile_home_param(params)
|
|
520
|
+
with scoped_home(home):
|
|
521
|
+
return selection_warnings(home, params)
|
|
522
|
+
|
|
523
|
+
@reg.method("models.speed_tiers")
|
|
524
|
+
def speed_tiers(ctx: CallContext, params: dict) -> dict:
|
|
525
|
+
from ..speed import supported_speed_tiers
|
|
526
|
+
|
|
527
|
+
routes = params.get("routes")
|
|
528
|
+
if not isinstance(routes, list) or any(not isinstance(route, dict) or not route.get("model") for route in routes):
|
|
529
|
+
raise InvalidParams("routes must contain model routes")
|
|
530
|
+
with scoped_home(profile_home_param(params)):
|
|
531
|
+
return {"tiers": [supported_speed_tiers(str(route["model"]), str(route.get("provider") or ""), str(route.get("base_url") or "")) for route in routes]}
|
|
532
|
+
|
|
350
533
|
@reg.method("providers.registry")
|
|
351
534
|
def registry_(ctx: CallContext, params: dict) -> dict:
|
|
352
535
|
with scoped_home(profile_home_param(params)):
|
|
@@ -363,7 +546,13 @@ def register(reg) -> None:
|
|
|
363
546
|
if not provider:
|
|
364
547
|
raise InvalidParams("provider is required")
|
|
365
548
|
with scoped_home(profile_home_param(params)):
|
|
366
|
-
|
|
549
|
+
ids, fallback = model_ids(provider, force_refresh=bool(params.get("force_refresh", False)))
|
|
550
|
+
return {"provider": provider, "model_ids": ids, "fallback": fallback}
|
|
551
|
+
|
|
552
|
+
@reg.method("providers.local_models")
|
|
553
|
+
def local(ctx: CallContext, params: dict) -> dict:
|
|
554
|
+
with scoped_home(profile_home_param(params)):
|
|
555
|
+
return local_models()
|
|
367
556
|
|
|
368
557
|
@reg.method("providers.resolve_runtime")
|
|
369
558
|
def runtime(ctx: CallContext, params: dict) -> dict:
|
|
@@ -2,18 +2,83 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import json
|
|
5
6
|
import os
|
|
6
7
|
import re
|
|
8
|
+
import subprocess
|
|
9
|
+
import sys
|
|
10
|
+
import tempfile
|
|
11
|
+
import time
|
|
12
|
+
from pathlib import Path
|
|
7
13
|
|
|
8
14
|
from .. import SIDECAR_RPC_VERSION
|
|
9
15
|
from ..errors import InvalidParams, RpcError
|
|
10
|
-
from ..home import edit_launch_env
|
|
16
|
+
from ..home import edit_launch_env, _frozen_launch_env
|
|
11
17
|
from ..rpc import CallContext
|
|
12
18
|
|
|
13
19
|
|
|
14
20
|
def register(registry) -> None:
|
|
15
21
|
runtime = registry.runtime
|
|
16
22
|
|
|
23
|
+
@registry.method("runtime.agent_mutation", requires_agent=False)
|
|
24
|
+
def agent_mutation(ctx: CallContext, params: dict) -> dict:
|
|
25
|
+
from ..agent_mutation import call
|
|
26
|
+
return call(runtime, ctx, params)
|
|
27
|
+
|
|
28
|
+
@registry.method("runtime.agent_recovery", requires_agent=False)
|
|
29
|
+
def agent_recovery(ctx: CallContext, params: dict) -> dict:
|
|
30
|
+
from ..agent_mutation import recover_retained
|
|
31
|
+
return recover_retained(runtime, ctx, probe=params.get('probe') is True, complete_revision=params.get('complete_revision'))
|
|
32
|
+
|
|
33
|
+
@registry.method("runtime.sync_dependencies", requires_agent=False)
|
|
34
|
+
def sync_dependencies(ctx: CallContext, params: dict) -> dict:
|
|
35
|
+
# Source has already advanced; loading it or checking the old revision would prevent repair.
|
|
36
|
+
expected = params.get("agent_dir")
|
|
37
|
+
root = runtime.agent_dir
|
|
38
|
+
if not isinstance(expected, str) or not expected or root is None or Path(expected).resolve() != root.resolve():
|
|
39
|
+
raise InvalidParams("agent_dir must match the sidecar's configured Agent checkout")
|
|
40
|
+
if not (root / "hermes_cli" / "venv_sync.py").is_file():
|
|
41
|
+
return {"ok": True, "skipped": True, "detail": ""}
|
|
42
|
+
env = _frozen_launch_env()
|
|
43
|
+
env.update(HERMES_HOME=str(runtime.hermes_home), HERMES_DISABLE_LAZY_INSTALLS="1",
|
|
44
|
+
PYTHONPATH=str(root) + (os.pathsep + env["PYTHONPATH"] if env.get("PYTHONPATH") else ""))
|
|
45
|
+
# The supervisor's stdin is a lifetime lease: closing it also covers a killed sidecar.
|
|
46
|
+
with tempfile.TemporaryFile() as stdout, tempfile.TemporaryFile() as stderr:
|
|
47
|
+
try:
|
|
48
|
+
proc = subprocess.Popen(
|
|
49
|
+
[sys.executable, str(Path(__file__).parents[1] / "dependency_sync.py"), str(root)],
|
|
50
|
+
cwd=root, env=env, stdin=subprocess.PIPE, stdout=stdout, stderr=stderr,
|
|
51
|
+
)
|
|
52
|
+
except OSError as exc:
|
|
53
|
+
return {"ok": False, "skipped": False, "detail": str(exc)}
|
|
54
|
+
deadline = time.monotonic() + 300
|
|
55
|
+
try:
|
|
56
|
+
while proc.poll() is None:
|
|
57
|
+
ctx.check_cancelled()
|
|
58
|
+
if time.monotonic() >= deadline:
|
|
59
|
+
return {"ok": False, "skipped": False, "detail": "Agent dependency sync timed out."}
|
|
60
|
+
ctx.cancel_event.wait(0.05)
|
|
61
|
+
finally:
|
|
62
|
+
proc.stdin.close()
|
|
63
|
+
proc.wait() # The supervisor terminates and reaps its writer before releasing the lock.
|
|
64
|
+
stdout.seek(0)
|
|
65
|
+
output = stdout.read(4 * 1024 * 1024 + 1)
|
|
66
|
+
stderr.seek(0, os.SEEK_END)
|
|
67
|
+
stderr.seek(max(0, stderr.tell() - 4000))
|
|
68
|
+
diagnostic = stderr.read().decode("utf-8", errors="replace")
|
|
69
|
+
if proc.returncode != 0:
|
|
70
|
+
return {"ok": False, "skipped": False, "detail": diagnostic or output[-4000:].decode("utf-8", errors="replace") or "Agent dependency sync failed."}
|
|
71
|
+
try:
|
|
72
|
+
if len(output) > 4 * 1024 * 1024:
|
|
73
|
+
raise ValueError("sync output exceeds limit")
|
|
74
|
+
response = json.loads(output)
|
|
75
|
+
if not isinstance(response, dict):
|
|
76
|
+
raise ValueError("not an object")
|
|
77
|
+
except ValueError:
|
|
78
|
+
return {"ok": False, "skipped": False, "detail": "Agent dependency sync returned an invalid result."}
|
|
79
|
+
return {"ok": response.get("ok") is True, "skipped": False,
|
|
80
|
+
"detail": str(response.get("detail") or "")[-4000:]}
|
|
81
|
+
|
|
17
82
|
@registry.method("runtime.handshake", requires_agent=False)
|
|
18
83
|
def handshake(ctx: CallContext, params: dict) -> dict:
|
|
19
84
|
requested = params.get("rpc_version")
|
|
@@ -50,6 +115,7 @@ def register(registry) -> None:
|
|
|
50
115
|
raise InvalidParams("set must map variable names to strings")
|
|
51
116
|
if not isinstance(to_unset, list) or not all(isinstance(k, str) and names.match(k) for k in to_unset):
|
|
52
117
|
raise InvalidParams("unset must list variable names")
|
|
118
|
+
to_set = {**to_set, "HERMES_DISABLE_LAZY_INSTALLS": "1"}
|
|
53
119
|
for name in to_unset:
|
|
54
120
|
os.environ.pop(name, None)
|
|
55
121
|
for name, value in to_set.items():
|
|
@@ -67,7 +133,9 @@ def register(registry) -> None:
|
|
|
67
133
|
if not isinstance(code, int):
|
|
68
134
|
raise InvalidParams("exit_code must be an integer")
|
|
69
135
|
from .chat import drain_agents
|
|
136
|
+
from ..agent_mutation import close_all
|
|
70
137
|
|
|
138
|
+
close_all()
|
|
71
139
|
drain_agents()
|
|
72
140
|
ctx.server.request_shutdown(exit_code=code)
|
|
73
141
|
return {"ok": True}
|
|
@@ -54,6 +54,25 @@ def _category(skill_md: Path, dirs: list[Path], local: Path) -> str | None:
|
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
def list_skills(profile_home: Path, category: str | None = None) -> dict:
|
|
57
|
+
try:
|
|
58
|
+
from agent.skill_utils import get_disabled_skill_names, is_disabled_entry
|
|
59
|
+
from tools.skills_tool import _skill_catalog, _sort_skills
|
|
60
|
+
except ImportError:
|
|
61
|
+
return _legacy_list_skills(profile_home, category)
|
|
62
|
+
disabled = get_disabled_skill_names("webui")
|
|
63
|
+
# Keep disabled rows manageable, but never advertise shadowed or unloadable copies.
|
|
64
|
+
out = [{"name": entry["load_name"], "load_name": entry["load_name"],
|
|
65
|
+
"declared_name": entry["name"], "status": entry["status"], "tier": entry["tier"],
|
|
66
|
+
"description": entry.get("description") or "", "category": entry.get("category"),
|
|
67
|
+
"disabled": is_disabled_entry(entry, disabled)}
|
|
68
|
+
for entry in _skill_catalog(skip_disabled=True) if entry["load_name"]]
|
|
69
|
+
if category:
|
|
70
|
+
out = [s for s in out if s.get("category") == category]
|
|
71
|
+
out = _sort_skills(out)
|
|
72
|
+
return {"success": True, "skills": out, "categories": sorted({s["category"] for s in out if s.get("category")}), "count": len(out)}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _legacy_list_skills(profile_home: Path, category: str | None = None) -> dict:
|
|
57
76
|
skills_dir = profile_home / "skills"
|
|
58
77
|
try:
|
|
59
78
|
from agent.skill_utils import iter_skill_index_files
|
|
@@ -99,6 +118,27 @@ def list_skills(profile_home: Path, category: str | None = None) -> dict:
|
|
|
99
118
|
|
|
100
119
|
|
|
101
120
|
def find_skill(name: str, dirs: list[Path]) -> tuple[Path | None, Path | None]:
|
|
121
|
+
try:
|
|
122
|
+
from agent.skill_utils import resolve_skill_catalog # noqa: F401 - capability gate for the matching lookup API
|
|
123
|
+
from tools.skills_tool import _locate_skill, _skill_lookup_path_error, _skill_search_dirs
|
|
124
|
+
except ImportError:
|
|
125
|
+
return _legacy_find_skill(name, dirs)
|
|
126
|
+
if error := _skill_lookup_path_error(name):
|
|
127
|
+
raise InvalidParams(error)
|
|
128
|
+
local_name = name.replace(":", "/", 1) if ":" in name else None
|
|
129
|
+
if local_name and (error := _skill_lookup_path_error(local_name)):
|
|
130
|
+
raise InvalidParams(error)
|
|
131
|
+
roots, _ = _skill_search_dirs()
|
|
132
|
+
error, skill_dir, skill_md = _locate_skill(name, local_name, roots)
|
|
133
|
+
if error:
|
|
134
|
+
result = json.loads(error)
|
|
135
|
+
if result.get("matches"):
|
|
136
|
+
raise InvalidParams(result["error"])
|
|
137
|
+
return None, None
|
|
138
|
+
return skill_dir, skill_md
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _legacy_find_skill(name: str, dirs: list[Path]) -> tuple[Path | None, Path | None]:
|
|
102
142
|
from agent.skill_utils import iter_skill_index_files
|
|
103
143
|
from tools.skills_tool import _EXCLUDED_SKILL_DIRS, _parse_frontmatter
|
|
104
144
|
|
|
@@ -208,9 +248,15 @@ def view_from_file(skill_dir: Path | None, skill_md: Path) -> dict:
|
|
|
208
248
|
def view_skill(profile_home: Path, name: str) -> dict:
|
|
209
249
|
skills_dir = profile_home / "skills"
|
|
210
250
|
dirs = search_dirs(skills_dir)
|
|
211
|
-
|
|
251
|
+
try:
|
|
252
|
+
skill_dir, skill_md = find_skill(name, dirs)
|
|
253
|
+
except InvalidParams as exc:
|
|
254
|
+
return {"success": False, "error": str(exc)}
|
|
212
255
|
if skill_md:
|
|
213
|
-
|
|
256
|
+
result = view_from_file(skill_dir, skill_md)
|
|
257
|
+
if result.get("success"):
|
|
258
|
+
result["editable"] = skill_md.name == "SKILL.md" and _within(skills_dir, skill_md)
|
|
259
|
+
return result
|
|
214
260
|
if ":" in str(name or ""):
|
|
215
261
|
try:
|
|
216
262
|
from agent.skill_utils import is_valid_namespace, parse_qualified_name
|
|
@@ -223,7 +269,10 @@ def view_skill(profile_home: Path, name: str) -> dict:
|
|
|
223
269
|
pm = get_plugin_manager()
|
|
224
270
|
if pm.find_plugin_skill(name) is not None or pm.list_plugin_skills(namespace):
|
|
225
271
|
raw = skill_view(name)
|
|
226
|
-
|
|
272
|
+
result = json.loads(raw) if isinstance(raw, str) else raw
|
|
273
|
+
if result.get("success"):
|
|
274
|
+
result["editable"] = False
|
|
275
|
+
return result
|
|
227
276
|
except Exception: # noqa: BLE001
|
|
228
277
|
pass
|
|
229
278
|
names = [s["name"] for s in list_skills(profile_home).get("skills", [])]
|
|
@@ -259,4 +308,18 @@ def register(registry) -> None:
|
|
|
259
308
|
raise InvalidParams("name is required")
|
|
260
309
|
with scoped_home(home):
|
|
261
310
|
skill_dir, skill_md = find_skill(name, search_dirs(home / "skills"))
|
|
262
|
-
|
|
311
|
+
identity = {}
|
|
312
|
+
if skill_md:
|
|
313
|
+
try:
|
|
314
|
+
from tools.skills_tool import _skill_catalog
|
|
315
|
+
except ImportError:
|
|
316
|
+
pass
|
|
317
|
+
else:
|
|
318
|
+
catalog = _skill_catalog(skip_disabled=True, include_hidden=True)
|
|
319
|
+
entry = next((e for e in catalog if e["path"] == skill_md), None)
|
|
320
|
+
if entry is not None:
|
|
321
|
+
if not entry["load_name"]:
|
|
322
|
+
raise InvalidParams("Skill has no unambiguous catalog identity")
|
|
323
|
+
identity = {"load_name": entry["load_name"], "declared_name": entry["name"],
|
|
324
|
+
"sibling_load_names": [e["load_name"] for e in catalog if e["name"] == entry["name"] and e["load_name"]]}
|
|
325
|
+
return {"found": skill_md is not None, "skill_dir": str(skill_dir) if skill_dir else None, "skill_md": str(skill_md) if skill_md else None, **identity}
|