@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
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"""``write_approval.*``: the Agent's staged skill and memory writes (TAL-819).
|
|
2
|
+
|
|
3
|
+
With ``skills.write_approval`` or ``memory.write_approval`` on, the Agent stages writes under
|
|
4
|
+
``<home>/pending/<kind>/<id>.json`` instead of committing them. These methods list them with
|
|
5
|
+
the diff an approval would apply, and approve or reject them through the Agent's own
|
|
6
|
+
``/skills`` and ``/memory`` review handlers.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import contextlib
|
|
12
|
+
import difflib
|
|
13
|
+
import hashlib
|
|
14
|
+
import re
|
|
15
|
+
import tempfile
|
|
16
|
+
import threading
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
from ..errors import InvalidParams, RpcError
|
|
20
|
+
from ..home import profile_home_param, scoped_home
|
|
21
|
+
from ..rpc import CallContext
|
|
22
|
+
|
|
23
|
+
KINDS = ("skills", "memory")
|
|
24
|
+
# The Agent names records ``uuid4().hex[:8]`` and builds their path from the id; anything else could leave the pending dir.
|
|
25
|
+
_ID = re.compile(r"[A-Za-z0-9_-]{1,64}")
|
|
26
|
+
# One review at a time in this process, so two approvals of one record cannot both replay it.
|
|
27
|
+
_LOCK = threading.Lock()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _agent():
|
|
31
|
+
try:
|
|
32
|
+
from hermes_cli import write_approval_commands
|
|
33
|
+
from tools import write_approval
|
|
34
|
+
except ImportError as exc:
|
|
35
|
+
raise RpcError("This Hermes Agent cannot review staged writes", condition="write_approval_unavailable") from exc
|
|
36
|
+
return write_approval, write_approval_commands
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _kind(params: dict) -> str:
|
|
40
|
+
kind = str(params.get("kind") or "")
|
|
41
|
+
if kind not in KINDS:
|
|
42
|
+
raise InvalidParams("kind must be skills or memory")
|
|
43
|
+
return kind
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _memory_diff(payload: dict) -> str:
|
|
47
|
+
"""Replay the record on a scratch copy of its file through the Agent's approve path; the diff is what approval commits."""
|
|
48
|
+
from tools.memory_tool import ENTRY_DELIMITER, apply_memory_pending, load_on_disk_store
|
|
49
|
+
|
|
50
|
+
store = load_on_disk_store()
|
|
51
|
+
target = "user" if payload.get("target") == "user" else "memory"
|
|
52
|
+
real = store._path_for(target)
|
|
53
|
+
before = list(store._entries_for(target))
|
|
54
|
+
with tempfile.TemporaryDirectory(prefix="talaria-pending-") as scratch:
|
|
55
|
+
copy = Path(scratch) / real.name
|
|
56
|
+
if real.is_file():
|
|
57
|
+
copy.write_bytes(real.read_bytes())
|
|
58
|
+
# The store resolves every read, lock and write through ``self._path_for``.
|
|
59
|
+
store._path_for = lambda t: Path(scratch) / ("USER.md" if t == "user" else "MEMORY.md")
|
|
60
|
+
result = apply_memory_pending(payload, store)
|
|
61
|
+
after = list(store._entries_for(target))
|
|
62
|
+
if not result.get("success"):
|
|
63
|
+
raise _Unapprovable(f"(approve would fail: {result.get('error') or 'unknown error'})")
|
|
64
|
+
lines = lambda entries: ENTRY_DELIMITER.join(entries).splitlines(keepends=True) # noqa: E731
|
|
65
|
+
diff = difflib.unified_diff(lines(before), lines(after), fromfile=f"a/{real.name}", tofile=f"b/{real.name}")
|
|
66
|
+
return "".join(diff) or "(no textual change)"
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class _Unapprovable(Exception):
|
|
70
|
+
"""A write with no diff the user could review: its message replaces the diff and approval is refused."""
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _skill_names(payload: dict) -> list[str]:
|
|
74
|
+
ops = payload.get("operations") or [] if payload.get("action") == "batch" else [payload]
|
|
75
|
+
return list(dict.fromkeys(str(op.get("name")) for op in ops if isinstance(op, dict) and op.get("name")))
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _item(wa, kind: str, record: dict) -> dict:
|
|
79
|
+
payload = record.get("payload") if isinstance(record.get("payload"), dict) else {}
|
|
80
|
+
if kind == "memory":
|
|
81
|
+
target = "user" if payload.get("target") == "user" else "memory"
|
|
82
|
+
else:
|
|
83
|
+
target = ", ".join(_skill_names(payload))
|
|
84
|
+
diff, approvable = _diff(wa, kind, record)
|
|
85
|
+
return {
|
|
86
|
+
"id": str(record.get("id") or ""), "kind": kind, "target": target, "op": str(payload.get("action") or record.get("action") or ""),
|
|
87
|
+
"summary": str(record.get("summary") or ""), "origin": str(record.get("origin") or "foreground"),
|
|
88
|
+
"created_at": float(record.get("created_at") or 0), "diff": diff,
|
|
89
|
+
"approvable": approvable, "revision": _revision(diff) if approvable else "",
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _diff(wa, kind: str, record: dict) -> tuple[str, bool]:
|
|
94
|
+
"""The diff approving ``record`` applies and whether it may be approved; a diff that cannot be built is never approvable."""
|
|
95
|
+
payload = record.get("payload") if isinstance(record.get("payload"), dict) else {}
|
|
96
|
+
try:
|
|
97
|
+
return (_memory_diff(payload) if kind == "memory" else wa.skill_pending_diff(record)), True
|
|
98
|
+
except _Unapprovable as exc:
|
|
99
|
+
return str(exc), False
|
|
100
|
+
except Exception as exc: # noqa: BLE001 - one unreadable record must not hide the rest
|
|
101
|
+
return f"(diff unavailable: {exc})", False
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _apply_lock(kind: str, record: dict):
|
|
105
|
+
"""Hold the Agent's own per-skill locks across the revision check and the apply (they are re-entrant in this thread, so
|
|
106
|
+
the Agent's apply takes them again). Memory needs none: the Agent applies a staged remove/patch only to the exact entry
|
|
107
|
+
it pinned at staging and an add only appends, so a concurrent write can never be dropped by an approval."""
|
|
108
|
+
if kind != "skills":
|
|
109
|
+
return contextlib.nullcontext()
|
|
110
|
+
from tools.skill_manager_tool import _skill_mutation_locks
|
|
111
|
+
|
|
112
|
+
return _skill_mutation_locks(_skill_names(record.get("payload") if isinstance(record.get("payload"), dict) else {}))
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _revision(diff: str) -> str:
|
|
116
|
+
"""What the reviewer saw: the diff changes whenever the record or the file it applies to does."""
|
|
117
|
+
return hashlib.sha256(diff.encode("utf-8")).hexdigest()
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def pending(kind: str) -> dict:
|
|
121
|
+
try:
|
|
122
|
+
wa, _ = _agent()
|
|
123
|
+
except RpcError:
|
|
124
|
+
return {"supported": False, "enabled": False, "items": []}
|
|
125
|
+
items = [_item(wa, kind, record) for record in wa.list_pending(kind) if _ID.fullmatch(str(record.get("id") or ""))]
|
|
126
|
+
return {"supported": True, "enabled": wa.write_approval_enabled(kind), "items": items}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def review(kind: str, verb: str, writes: list[dict]) -> dict:
|
|
130
|
+
"""``approve`` or ``reject`` each write through the Agent's handler; a record that is gone afterwards was applied or dropped.
|
|
131
|
+
|
|
132
|
+
An approval applies only while the write's diff still has the ``revision`` the reviewer saw; a changed file or record
|
|
133
|
+
is refused, so nothing lands that the user did not review.
|
|
134
|
+
"""
|
|
135
|
+
wa, commands = _agent()
|
|
136
|
+
if not writes or any(not (isinstance(w, dict) and _ID.fullmatch(str(w.get("id") or "")) and isinstance(w.get("revision"), str)) for w in writes):
|
|
137
|
+
raise InvalidParams("writes must be pending write ids with the revision reviewed")
|
|
138
|
+
results = []
|
|
139
|
+
with _LOCK:
|
|
140
|
+
for write in writes:
|
|
141
|
+
pending_id = write["id"]
|
|
142
|
+
record = wa.get_pending(kind, pending_id)
|
|
143
|
+
if record is None:
|
|
144
|
+
results.append({"id": pending_id, "done": False, "message": f"No pending {kind} write with id '{pending_id}'."})
|
|
145
|
+
continue
|
|
146
|
+
if verb == "reject":
|
|
147
|
+
message = commands.handle_pending_subcommand(kind, [verb, pending_id]) or ""
|
|
148
|
+
else:
|
|
149
|
+
with _apply_lock(kind, record):
|
|
150
|
+
diff, approvable = _diff(wa, kind, record)
|
|
151
|
+
if not approvable:
|
|
152
|
+
results.append({"id": pending_id, "done": False, "message": f"This write cannot be approved: {diff}"})
|
|
153
|
+
continue
|
|
154
|
+
if _revision(diff) != write["revision"]:
|
|
155
|
+
results.append({"id": pending_id, "done": False, "message": "This write's diff changed after you reviewed it. Review the new diff, then approve again."})
|
|
156
|
+
continue
|
|
157
|
+
store = None
|
|
158
|
+
if kind == "memory":
|
|
159
|
+
from tools.memory_tool import load_on_disk_store
|
|
160
|
+
|
|
161
|
+
store = load_on_disk_store()
|
|
162
|
+
message = commands.handle_pending_subcommand(kind, [verb, pending_id], memory_store=store) or ""
|
|
163
|
+
results.append({"id": pending_id, "done": wa.get_pending(kind, pending_id) is None, "message": message})
|
|
164
|
+
return {"results": results}
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def register(registry) -> None:
|
|
168
|
+
@registry.method("write_approval.pending")
|
|
169
|
+
def pending_(ctx: CallContext, params: dict) -> dict:
|
|
170
|
+
kind = _kind(params)
|
|
171
|
+
with scoped_home(profile_home_param(params)):
|
|
172
|
+
return pending(kind)
|
|
173
|
+
|
|
174
|
+
for verb in ("approve", "reject"):
|
|
175
|
+
def handler(ctx: CallContext, params: dict, verb: str = verb) -> dict:
|
|
176
|
+
kind = _kind(params)
|
|
177
|
+
writes = list(params.get("writes") or [])
|
|
178
|
+
with scoped_home(profile_home_param(params)):
|
|
179
|
+
return review(kind, verb, writes)
|
|
180
|
+
|
|
181
|
+
registry.method(f"write_approval.{verb}")(handler)
|
|
@@ -13,6 +13,9 @@ from __future__ import annotations
|
|
|
13
13
|
|
|
14
14
|
import json
|
|
15
15
|
import logging
|
|
16
|
+
import os
|
|
17
|
+
import queue
|
|
18
|
+
import time
|
|
16
19
|
import sys
|
|
17
20
|
import threading
|
|
18
21
|
import traceback
|
|
@@ -121,6 +124,9 @@ class RpcServer:
|
|
|
121
124
|
def request_shutdown(self, exit_code: int = 0) -> None:
|
|
122
125
|
self.exit_code = exit_code
|
|
123
126
|
self._closed.set()
|
|
127
|
+
with self._active_lock:
|
|
128
|
+
for ctx in self._active.values():
|
|
129
|
+
ctx.cancel_event.set()
|
|
124
130
|
|
|
125
131
|
# ── dispatch ──────────────────────────────────────────────────────────
|
|
126
132
|
def _register(self, request: dict) -> CallContext | None:
|
|
@@ -182,12 +188,38 @@ class RpcServer:
|
|
|
182
188
|
|
|
183
189
|
def serve_forever(self) -> int:
|
|
184
190
|
"""Read requests until stdin closes or shutdown is requested."""
|
|
185
|
-
|
|
191
|
+
incoming = queue.Queue(maxsize=1)
|
|
192
|
+
def read_input():
|
|
186
193
|
try:
|
|
187
|
-
|
|
194
|
+
try:
|
|
195
|
+
fd = self._in.fileno()
|
|
196
|
+
except (AttributeError, OSError, ValueError):
|
|
197
|
+
fd = None
|
|
198
|
+
if fd is None:
|
|
199
|
+
while raw := self._in.readline():
|
|
200
|
+
incoming.put(raw)
|
|
201
|
+
else:
|
|
202
|
+
# An unbuffered OS read cannot hold sys.stdin's Python buffer lock at interpreter exit.
|
|
203
|
+
pending = []
|
|
204
|
+
while chunk := os.read(fd, 65536):
|
|
205
|
+
lines = chunk.split(b"\n")
|
|
206
|
+
pending.append(lines[0])
|
|
207
|
+
for line in lines[1:]:
|
|
208
|
+
incoming.put(b"".join(pending))
|
|
209
|
+
pending = [line]
|
|
210
|
+
if pending:
|
|
211
|
+
incoming.put(b"".join(pending))
|
|
188
212
|
except (OSError, ValueError):
|
|
189
|
-
|
|
190
|
-
|
|
213
|
+
pass
|
|
214
|
+
finally:
|
|
215
|
+
incoming.put(None)
|
|
216
|
+
threading.Thread(target=read_input, name="rpc-input", daemon=True).start()
|
|
217
|
+
while not self._closed.is_set():
|
|
218
|
+
try:
|
|
219
|
+
raw = incoming.get(timeout=.1)
|
|
220
|
+
except queue.Empty:
|
|
221
|
+
continue
|
|
222
|
+
if raw is None or self._closed.is_set():
|
|
191
223
|
break
|
|
192
224
|
raw = raw.strip()
|
|
193
225
|
if not raw:
|
|
@@ -209,6 +241,15 @@ class RpcServer:
|
|
|
209
241
|
continue
|
|
210
242
|
ctx = self._register(request)
|
|
211
243
|
threading.Thread(target=self._dispatch_slot, args=(request, ctx), name=f"rpc-{request.get('method')}", daemon=True).start()
|
|
244
|
+
if self._closed.is_set():
|
|
245
|
+
# Let the terminal reply reach stdout before the process returns its final exit code.
|
|
246
|
+
deadline = time.monotonic() + 5
|
|
247
|
+
while time.monotonic() < deadline:
|
|
248
|
+
with self._active_lock:
|
|
249
|
+
terminal_reply = any(ctx.method in {"runtime.shutdown", "runtime.handshake"} for ctx in self._active.values())
|
|
250
|
+
if not terminal_reply:
|
|
251
|
+
break
|
|
252
|
+
threading.Event().wait(.01)
|
|
212
253
|
return self.exit_code
|
|
213
254
|
|
|
214
255
|
def _dispatch_slot(self, request: dict, ctx: CallContext | None) -> None:
|
|
@@ -10,12 +10,15 @@ from __future__ import annotations
|
|
|
10
10
|
|
|
11
11
|
import errno
|
|
12
12
|
import importlib
|
|
13
|
+
import hashlib
|
|
13
14
|
import json
|
|
14
15
|
import math
|
|
15
16
|
import os
|
|
17
|
+
import re
|
|
16
18
|
import stat
|
|
17
19
|
import subprocess
|
|
18
20
|
import sys
|
|
21
|
+
import sysconfig
|
|
19
22
|
import threading
|
|
20
23
|
import time
|
|
21
24
|
from pathlib import Path
|
|
@@ -24,11 +27,8 @@ from . import SIDECAR_RPC_VERSION
|
|
|
24
27
|
from .errors import RpcError
|
|
25
28
|
|
|
26
29
|
PIN_PATH = Path(__file__).resolve().parent.parent / "agent_dependency.json"
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"Talaria Web cannot verify that the Agent update completed safely. "
|
|
30
|
-
"Check the Agent update outcome and environment first. "
|
|
31
|
-
"Restart Talaria Web manually before retrying this action."
|
|
30
|
+
_RUNTIME_UNAVAILABLE_MESSAGE = (
|
|
31
|
+
"Agent runtime is unavailable. Check the Agent update outcome before retrying this action."
|
|
32
32
|
)
|
|
33
33
|
_AGENT_UPDATE_MARKER = ".hermes-update-in-progress"
|
|
34
34
|
_AGENT_RECOVERY_MARKERS = (".update-incomplete", ".lazy-refresh-incomplete")
|
|
@@ -40,11 +40,16 @@ _MARKER_SAFE_OPEN_AVAILABLE = bool(_O_NOFOLLOW) and bool(_O_NONBLOCK)
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
class AgentRuntimeStale(RpcError):
|
|
43
|
-
def __init__(self, update_state: str | None):
|
|
44
|
-
data = {"retryable": True, "restart_scheduled": False}
|
|
43
|
+
def __init__(self, update_state: str | None, message: str | None = None, *, source_changed: bool = False):
|
|
44
|
+
data = {"retryable": True, "restart_scheduled": False, "agent_source_changed": source_changed}
|
|
45
45
|
if update_state is not None:
|
|
46
46
|
data["agent_update_state"] = update_state
|
|
47
|
-
|
|
47
|
+
if message is None:
|
|
48
|
+
message = {
|
|
49
|
+
"active": "Agent update is in progress. Wait for it to finish before starting new work.",
|
|
50
|
+
"incomplete": "Agent update recovery is incomplete. Finish the Agent update before starting new work.",
|
|
51
|
+
}.get(update_state, _RUNTIME_UNAVAILABLE_MESSAGE)
|
|
52
|
+
super().__init__(message, condition="agent_runtime_stale", data=data)
|
|
48
53
|
|
|
49
54
|
|
|
50
55
|
class AgentIncompatible(RpcError):
|
|
@@ -205,6 +210,57 @@ def _marker_presence(marker: Path) -> str:
|
|
|
205
210
|
return "present"
|
|
206
211
|
|
|
207
212
|
|
|
213
|
+
def installed_agent_version() -> str | None:
|
|
214
|
+
"""Agents since v0.21.6 resolve their identity from the install stamp, else the checkout's release tag; their
|
|
215
|
+
``__version__`` reads only the stamp, which a source checkout does not have."""
|
|
216
|
+
try:
|
|
217
|
+
from hermes_cli.version_info import get_version_info
|
|
218
|
+
except ModuleNotFoundError as error:
|
|
219
|
+
if error.name != "hermes_cli.version_info":
|
|
220
|
+
raise
|
|
221
|
+
return getattr(importlib.import_module("hermes_cli"), "__version__", None)
|
|
222
|
+
return get_version_info().base_version
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def _python_abi(major: int | str, minor: int | str, free_threaded: bool) -> str:
|
|
226
|
+
"""``3.14`` or ``3.14t``: regular and free-threaded builds of one version load different native extensions."""
|
|
227
|
+
return f"{major}.{minor}{'t' if free_threaded else ''}"
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def _site_packages_python(entry: str) -> tuple[str, Path] | None:
|
|
231
|
+
"""The Python ABI a ``sys.path`` site-packages directory was built for, and that venv's interpreter."""
|
|
232
|
+
path = Path(entry)
|
|
233
|
+
if path.name != "site-packages" or not path.is_dir():
|
|
234
|
+
return None
|
|
235
|
+
match = re.fullmatch(r"python(\d+)\.(\d+)(t?)", path.parent.name)
|
|
236
|
+
if match and path.parent.parent.name in {"lib", "lib64"}:
|
|
237
|
+
return _python_abi(match[1], match[2], bool(match[3])), path.parent.parent.parent / "bin" / "python"
|
|
238
|
+
if path.parent.name.lower() == "lib":
|
|
239
|
+
venv = path.parent.parent
|
|
240
|
+
try:
|
|
241
|
+
config = (venv / "pyvenv.cfg").read_text(encoding="utf-8")
|
|
242
|
+
except OSError:
|
|
243
|
+
return None
|
|
244
|
+
found = re.search(r"^\s*version(?:_info)?\s*=\s*(\d+)\.(\d+)", config, re.MULTILINE)
|
|
245
|
+
if found:
|
|
246
|
+
free_threaded = re.search(r"^\s*executable\s*=.*python\d+\.\d+t(?:\.exe)?\s*$", config, re.MULTILINE | re.IGNORECASE)
|
|
247
|
+
return _python_abi(found[1], found[2], bool(free_threaded)), venv / "Scripts" / "python.exe"
|
|
248
|
+
return None
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def _check_site_packages_python() -> None:
|
|
252
|
+
"""Compiled Agent dependencies load lazily on the first chat; fail the handshake when ``sys.path`` holds
|
|
253
|
+
site-packages built for another Python (a stale ``HERMES_WEBUI_PYTHON`` after a PM environment update)."""
|
|
254
|
+
running = _python_abi(sys.version_info[0], sys.version_info[1], bool(sysconfig.get_config_var("Py_GIL_DISABLED")))
|
|
255
|
+
for entry in sys.path:
|
|
256
|
+
built = _site_packages_python(entry)
|
|
257
|
+
if built is not None and built[0] != running:
|
|
258
|
+
raise ImportError(
|
|
259
|
+
f"interpreter Python {running} cannot load Agent packages built for Python {built[0]} ({entry}); "
|
|
260
|
+
f"unset HERMES_WEBUI_PYTHON or point it at {built[1]}"
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
|
|
208
264
|
class AgentRuntime:
|
|
209
265
|
"""Loads the Agent once and guards against a changed checkout."""
|
|
210
266
|
|
|
@@ -212,6 +268,7 @@ class AgentRuntime:
|
|
|
212
268
|
self.hermes_home = Path(hermes_home)
|
|
213
269
|
self._stale_lock = threading.Lock()
|
|
214
270
|
self._stale = False
|
|
271
|
+
self._source_changed = False
|
|
215
272
|
self._stale_stamp: tuple | None = None
|
|
216
273
|
self.agent_dir = Path(agent_dir).resolve() if agent_dir else None
|
|
217
274
|
self.pin = read_pin()
|
|
@@ -227,8 +284,18 @@ class AgentRuntime:
|
|
|
227
284
|
if self.loaded:
|
|
228
285
|
return
|
|
229
286
|
try:
|
|
287
|
+
# Direct Agent imports skip CLI startup's PM tool PATH activation.
|
|
288
|
+
if self.agent_dir is not None and (self.agent_dir / "pm").is_dir():
|
|
289
|
+
compose_path = getattr(importlib.import_module("pm"), "store_first_path", None)
|
|
290
|
+
if compose_path is not None:
|
|
291
|
+
os.environ["PATH"] = compose_path(os.environ.get("PATH", ""))
|
|
230
292
|
module = importlib.import_module("run_agent")
|
|
231
293
|
getattr(module, "AIAgent")
|
|
294
|
+
# Agent 0.21.3 snapshots its auth provider registry, discovered plugins included, when hermes_cli.auth
|
|
295
|
+
# first imports. Take it here, under the launch profile and before any profile-scoped method runs, so
|
|
296
|
+
# a named profile's plugin loaded later never enters that process-wide snapshot.
|
|
297
|
+
importlib.import_module("hermes_cli.auth")
|
|
298
|
+
_check_site_packages_python()
|
|
232
299
|
except Exception as exc: # noqa: BLE001 - reported as a handshake condition
|
|
233
300
|
self.import_error = f"{type(exc).__name__}: {exc}"
|
|
234
301
|
raise AgentIncompatible(f"Hermes Agent could not be imported: {self.import_error}", import_error=self.import_error)
|
|
@@ -242,7 +309,7 @@ class AgentRuntime:
|
|
|
242
309
|
@property
|
|
243
310
|
def agent_version(self) -> str | None:
|
|
244
311
|
try:
|
|
245
|
-
return
|
|
312
|
+
return installed_agent_version()
|
|
246
313
|
except Exception: # noqa: BLE001
|
|
247
314
|
return None
|
|
248
315
|
|
|
@@ -260,9 +327,12 @@ class AgentRuntime:
|
|
|
260
327
|
|
|
261
328
|
def update_transaction_state(self) -> str:
|
|
262
329
|
live = _read_live_agent_update(self.hermes_home / _AGENT_UPDATE_MARKER)
|
|
263
|
-
if live
|
|
330
|
+
if live in {"unknown", "active"}:
|
|
331
|
+
return live
|
|
332
|
+
repair = self.web_repair_state()
|
|
333
|
+
if repair == "unknown":
|
|
264
334
|
return "unknown"
|
|
265
|
-
recovery =
|
|
335
|
+
recovery = repair == "present"
|
|
266
336
|
for root in self._install_roots():
|
|
267
337
|
for name in _AGENT_RECOVERY_MARKERS:
|
|
268
338
|
presence = _marker_presence(root / name)
|
|
@@ -273,6 +343,16 @@ class AgentRuntime:
|
|
|
273
343
|
return "incomplete"
|
|
274
344
|
return "unverified" if live == "absent" else live
|
|
275
345
|
|
|
346
|
+
def web_repair_state(self) -> str:
|
|
347
|
+
if self.agent_dir is None:
|
|
348
|
+
return "absent"
|
|
349
|
+
from .agent_mutation import recovery_receipts
|
|
350
|
+
try:
|
|
351
|
+
receipts, _ = recovery_receipts(self)
|
|
352
|
+
return 'present' if receipts else 'absent'
|
|
353
|
+
except (OSError, UnicodeError):
|
|
354
|
+
return 'unknown'
|
|
355
|
+
|
|
276
356
|
def is_stale(self) -> bool:
|
|
277
357
|
"""True when the checkout revision no longer matches the loaded module.
|
|
278
358
|
|
|
@@ -294,14 +374,18 @@ class AgentRuntime:
|
|
|
294
374
|
fresh = None
|
|
295
375
|
if fresh is not None:
|
|
296
376
|
break
|
|
377
|
+
self._source_changed = fresh is not None and fresh != self.revision
|
|
297
378
|
self._stale = fresh != self.revision
|
|
298
379
|
self._stale_stamp = stamp if fresh is not None else None
|
|
299
380
|
return self._stale
|
|
300
381
|
|
|
301
382
|
def ensure_current(self) -> None:
|
|
302
|
-
"""
|
|
383
|
+
"""Refuse Agent work until source drift or a durable Web update obligation is reconciled."""
|
|
384
|
+
repair = self.web_repair_state()
|
|
385
|
+
if repair != "absent":
|
|
386
|
+
raise AgentRuntimeStale("unknown" if repair == "unknown" else self.update_transaction_state())
|
|
303
387
|
if self.is_stale():
|
|
304
|
-
raise AgentRuntimeStale(self.update_transaction_state())
|
|
388
|
+
raise AgentRuntimeStale(self.update_transaction_state(), source_changed=self._source_changed)
|
|
305
389
|
|
|
306
390
|
# ── handshake ─────────────────────────────────────────────────────────
|
|
307
391
|
def describe(self) -> dict:
|
|
@@ -319,6 +403,7 @@ class AgentRuntime:
|
|
|
319
403
|
"pinned_image": self.pin["image"],
|
|
320
404
|
"compatible": self.loaded,
|
|
321
405
|
"stale": self.is_stale(),
|
|
406
|
+
"agent_source_changed": self._source_changed,
|
|
322
407
|
"update_state": self.update_transaction_state(),
|
|
323
408
|
"import_error": self.import_error,
|
|
324
409
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""One route-aware speed gate for the model catalog and chat request overrides."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import inspect
|
|
6
|
+
import re
|
|
7
|
+
from urllib.parse import urlparse
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def fast_overrides(model: str, provider: str, base_url: str, tier: str) -> dict | None:
|
|
11
|
+
if tier not in ("priority", "ultrafast"):
|
|
12
|
+
return None
|
|
13
|
+
from hermes_cli import models
|
|
14
|
+
|
|
15
|
+
resolver = getattr(models, "resolve_fast_mode_overrides", None)
|
|
16
|
+
if resolver is not None:
|
|
17
|
+
if "tier" in inspect.signature(resolver).parameters:
|
|
18
|
+
return resolver(model, provider=provider, base_url=base_url, tier=tier)
|
|
19
|
+
return resolver(model, provider=provider, base_url=base_url) if tier == "priority" else None
|
|
20
|
+
# Older Agents have no resolver. Keep the former GPT-5/o-series gate, restricted to first-party routes.
|
|
21
|
+
hosts = {"openai": "api.openai.com", "openai-api": "api.openai.com", "openai-codex": "chatgpt.com"}
|
|
22
|
+
model = model.strip().lower().removeprefix("openai/")
|
|
23
|
+
host = urlparse(base_url).hostname if base_url else None
|
|
24
|
+
if tier == "priority" and provider in hosts and (not host or host == hosts[provider]) and (model.startswith("gpt-5") or re.match(r"o[0-9]", model)):
|
|
25
|
+
return {"service_tier": "priority"}
|
|
26
|
+
return None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def supported_speed_tiers(model: str, provider: str, base_url: str) -> list[dict]:
|
|
30
|
+
tiers = []
|
|
31
|
+
for tier in ("priority", "ultrafast"):
|
|
32
|
+
override = fast_overrides(model, provider, base_url, tier)
|
|
33
|
+
if override:
|
|
34
|
+
tiers.append({"id": "fast" if override.get("speed") == "fast" else tier, "service_tier": tier})
|
|
35
|
+
return [{"id": "standard", "service_tier": "default"}, *tiers] if tiers else []
|