@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
package/dist/api/chat-router.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
/** Chat turn admission, control, approvals, clarify, goals, background tasks, and side questions. */
|
|
2
2
|
import { GATEWAY_APPROVAL_RELAY_UNAVAILABLE, isGenericContinuationIntent } from '../sessions/turn.js';
|
|
3
3
|
import { implement } from '@orpc/server';
|
|
4
|
-
import { chatContract, MAX_CHAT_ATTACHMENTS } from '@maudecode/talaria-web-contracts';
|
|
4
|
+
import { chatContract, MAX_CHAT_ATTACHMENTS, RPC_ERROR_CODES } from '@maudecode/talaria-web-contracts';
|
|
5
5
|
import { randomUUID } from 'node:crypto';
|
|
6
6
|
import { HttpError } from './router.js';
|
|
7
7
|
import { requestSessionIdGuard, streamOwnerSessionId, streamVisibleToRequest } from './session-visibility.js';
|
|
8
8
|
import { ensureAgentRuntimeCurrent, HttpFailure } from '../sessions/service.js';
|
|
9
9
|
import { SessionNotFound } from '../sessions/store.js';
|
|
10
|
-
import { isSafeSessionId } from '../sessions/session.js';
|
|
10
|
+
import { compressionRecoveryPayload, isSafeSessionId } from '../sessions/session.js';
|
|
11
|
+
import { messageText } from '../sessions/merge.js';
|
|
11
12
|
import { str } from '../util.js';
|
|
13
|
+
import { activeProfileName } from '../auth/gate.js';
|
|
14
|
+
import { SidecarError } from '../sidecar/client.js';
|
|
15
|
+
import { unsupportedPromptMessage } from '../tools/commands.js';
|
|
12
16
|
const os = implement(chatContract).$context().use(requestSessionIdGuard);
|
|
13
17
|
const STEER_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
|
|
14
18
|
const PROFILE_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
@@ -26,14 +30,14 @@ async function run(fn) {
|
|
|
26
30
|
}
|
|
27
31
|
}
|
|
28
32
|
/** A session this request's profile may see (TAL-372 background work never crosses owners). */
|
|
29
|
-
function visibleSession(ctx, sid) {
|
|
30
|
-
if (!ctx.deps.sessions.sessionIdVisible(sid))
|
|
33
|
+
async function visibleSession(ctx, sid) {
|
|
34
|
+
if (!(await ctx.deps.sessions.sessionIdVisible(sid)))
|
|
31
35
|
throw new HttpError(404, 'Session not found');
|
|
32
|
-
return getSession(ctx, sid, true);
|
|
36
|
+
return (await getSession(ctx, sid, true));
|
|
33
37
|
}
|
|
34
|
-
function getSession(ctx, sid, metadataOnly = false) {
|
|
38
|
+
async function getSession(ctx, sid, metadataOnly = false) {
|
|
35
39
|
try {
|
|
36
|
-
return ctx.deps.sessionStore.get(sid, { metadataOnly });
|
|
40
|
+
return (await ctx.deps.sessionStore.get(sid, { metadataOnly }));
|
|
37
41
|
}
|
|
38
42
|
catch {
|
|
39
43
|
throw new HttpError(404, 'Session not found');
|
|
@@ -87,38 +91,42 @@ function visibleOrRetag(ctx, s, requestedProfile) {
|
|
|
87
91
|
}
|
|
88
92
|
throw new HttpError(404, 'Session not found');
|
|
89
93
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
94
|
+
/**
|
|
95
|
+
* TAL-817: what the model gets for a typed Agent prompt built-in (`/plan`, `/initiate-setup`, …): the Agent's own expansion
|
|
96
|
+
* of it for this session's profile, workspace and toolsets, while the transcript keeps the typed text; null when `msg` is
|
|
97
|
+
* not one. One the Agent cannot expand is
|
|
98
|
+
* refused with the catalog's message instead of reaching the model raw. Without a sidecar the turn reports that itself.
|
|
99
|
+
*/
|
|
100
|
+
async function expandPromptBuiltin(ctx, s, msg, workspace) {
|
|
101
|
+
const sidecar = ctx.deps.sidecar();
|
|
102
|
+
if (!msg.startsWith('/') || !sidecar)
|
|
103
|
+
return null;
|
|
104
|
+
// Only `/init` reads the workspace, and the sidecar refuses it without one; the turn reports a bad workspace itself.
|
|
105
|
+
let cwd = '';
|
|
106
|
+
try {
|
|
107
|
+
cwd = (await ctx.deps.sessions.turnWorkspace(s, workspace));
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
cwd = '';
|
|
99
111
|
}
|
|
112
|
+
let expanded;
|
|
100
113
|
try {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return workspace;
|
|
114
|
+
expanded = await sidecar.call('commands.expand_prompt', {
|
|
115
|
+
profile_home: ctx.deps.profileHome(s.profile ?? activeProfileName(ctx)), command: msg, workspace: cwd, enabled_toolsets: s.enabled_toolsets,
|
|
116
|
+
}, { timeoutMs: 120_000 });
|
|
105
117
|
}
|
|
106
118
|
catch (error) {
|
|
107
|
-
|
|
119
|
+
if (!(error instanceof SidecarError))
|
|
120
|
+
throw error;
|
|
121
|
+
const invalid = error.condition === 'invalid_params' || error.code === RPC_ERROR_CODES.invalidParams;
|
|
122
|
+
throw new HttpError(invalid ? 400 : error.condition === 'sidecar_unavailable' ? 503 : 502, error.message);
|
|
108
123
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const requestedModel = str(body.model) || s.model;
|
|
113
|
-
const requestedProvider = 'model_provider' in body ? body.model_provider : s.model_provider;
|
|
114
|
-
const [model, provider] = ctx.deps.sessions.deps.modelStateFromRequest(requestedModel, requestedProvider, s.model_provider);
|
|
115
|
-
if (model !== requestedModel || !model || body.explicit_model_pick === true)
|
|
116
|
-
return [model, provider, model !== requestedModel];
|
|
117
|
-
const repaired = ctx.deps.sessions.deps.repairSessionModel?.(s.profile ?? null, model, provider);
|
|
118
|
-
return repaired ? [repaired[0], repaired[1], true] : [model, provider, false];
|
|
124
|
+
if (expanded.name !== null && expanded.message === null)
|
|
125
|
+
throw new HttpError(400, unsupportedPromptMessage(expanded.name));
|
|
126
|
+
return expanded.message;
|
|
119
127
|
}
|
|
120
128
|
/** `chat.start`; a `chat.steer` sent while a background turn runs starts the user's turn through it too (TAL-460). */
|
|
121
|
-
async function startChat(ctx, body) {
|
|
129
|
+
async function startChat(ctx, body, settle = {}) {
|
|
122
130
|
requireField(body, 'session_id');
|
|
123
131
|
if (str(body.message).trim() === '[SILENT]')
|
|
124
132
|
return { status: 'suppressed', reason: 'silent_control_message' };
|
|
@@ -128,26 +136,31 @@ async function startChat(ctx, body) {
|
|
|
128
136
|
// Python `_agent_runtime_barrier_response`: a stale local Agent checkout is refused with a typed 409 before any
|
|
129
137
|
// session state is materialised, claimed, or mutated.
|
|
130
138
|
await ensureAgentRuntimeCurrent(ctx.deps.sidecar());
|
|
139
|
+
if (ctx.deps.sessions.owner?.isOwned(sid)) {
|
|
140
|
+
if (!(await ctx.deps.sessions.sessionIdVisible(sid)))
|
|
141
|
+
throw new HttpError(404, 'Session not found');
|
|
142
|
+
return (await ctx.deps.sessions.owner.submit(sid, body));
|
|
143
|
+
}
|
|
131
144
|
// TAL-542: the stale-model check reads this catalog; it is built before the session is read so no await follows that read.
|
|
132
145
|
await ctx.deps.sessions.deps.warmSessionModelRepair?.();
|
|
133
146
|
let s;
|
|
134
147
|
try {
|
|
135
|
-
s = ctx.deps.sessionStore.get(sid);
|
|
148
|
+
s = (await ctx.deps.sessionStore.get(sid));
|
|
136
149
|
}
|
|
137
150
|
catch {
|
|
138
151
|
// Python `_claim_or_synthesize_cli_session` on the POST path: a claimable foreign (CLI/TUI/Desktop) session is
|
|
139
152
|
// materialised as a WebUI sidecar before its first turn; an owned foreign store answers 403, nothing → 404.
|
|
140
|
-
const synth = ctx.deps.sessions.claimOrSynthesizeCliSession(sid);
|
|
153
|
+
const synth = (await ctx.deps.sessions.claimOrSynthesizeCliSession(sid));
|
|
141
154
|
if (!synth.session)
|
|
142
155
|
throw new HttpError(404, 'Session not found');
|
|
143
156
|
if (synth.reason === 'not_claimable')
|
|
144
157
|
throw new HttpError(403, 'session is read-only in its foreign store; cannot be claimed writeable in WebUI');
|
|
145
|
-
ctx.deps.sessionStore.save(synth.session);
|
|
146
|
-
s = ctx.deps.sessionStore.get(sid);
|
|
158
|
+
await ctx.deps.sessionStore.save(synth.session);
|
|
159
|
+
s = (await ctx.deps.sessionStore.get(sid));
|
|
147
160
|
}
|
|
148
161
|
// Python `_get_or_materialize_session` raised PermissionError for both: a read-only import and a delegated
|
|
149
162
|
// subagent child (by sidecar tag or state.db row), which chat start answered with the same 403.
|
|
150
|
-
if (ctx.deps.sessions.isReadOnly(s) || s.branchSourceReadonly || ctx.deps.sessions.isSubagentViewOnly(sid))
|
|
163
|
+
if ((await ctx.deps.sessions.isReadOnly(s)) || s.branchSourceReadonly || (await ctx.deps.sessions.isSubagentViewOnly(sid)))
|
|
151
164
|
throw new HttpError(403, 'Read-only imported sessions cannot be continued from WebUI');
|
|
152
165
|
const requestedProfile = str(body.profile).trim();
|
|
153
166
|
if (requestedProfile && requestedProfile !== 'default' && !PROFILE_ID_RE.test(requestedProfile))
|
|
@@ -158,29 +171,84 @@ async function startChat(ctx, body) {
|
|
|
158
171
|
// TAL-276: an attached file alone makes a turn; one with neither text nor a file path is refused.
|
|
159
172
|
if (!msg && !attachments.some((att) => str(att.path)))
|
|
160
173
|
throw new HttpError(400, 'message is required');
|
|
174
|
+
const prompt = await expandPromptBuiltin(ctx, s, msg, body.workspace);
|
|
161
175
|
// TAL-460: the user's message never joins a background turn; that turn stops quietly and this one takes its place.
|
|
162
|
-
|
|
176
|
+
const yielded = await ctx.deps.turns.yieldBackgroundTurn(sid);
|
|
177
|
+
if (prompt !== null || yielded) {
|
|
163
178
|
await ctx.deps.sessions.deps.warmSessionModelRepair?.();
|
|
164
|
-
s = ctx.deps.sessionStore.get(sid);
|
|
179
|
+
s = (await ctx.deps.sessionStore.get(sid));
|
|
180
|
+
visibleOrRetag(ctx, s, requestedProfile);
|
|
165
181
|
}
|
|
166
182
|
// Python `compression_recovery_payload_for_session` + `is_generic_continuation_intent`.
|
|
167
|
-
|
|
168
|
-
const recoveryLive = recovery.terminal_state === 'compression_exhausted' && str(recovery.recommended_action || s.recommended_recovery_action) === 'start_focused_continuation';
|
|
169
|
-
if (recoveryLive && !attachments.length && isGenericContinuationIntent(msg)) {
|
|
183
|
+
if (compressionRecoveryPayload(s) && !attachments.length && isGenericContinuationIntent(msg)) {
|
|
170
184
|
throw new HttpError(409, 'This session exhausted context compression. Start a focused continuation, then describe the next narrow task.', { type: 'compression_recovery_required', compression_recovery: s.compression_recovery, session_id: s.session_id });
|
|
171
185
|
}
|
|
172
|
-
const workspace =
|
|
173
|
-
const [model, provider, normalized] =
|
|
186
|
+
const workspace = (await ctx.deps.sessions.turnWorkspace(s, body.workspace));
|
|
187
|
+
const [model, provider, normalized] = ctx.deps.sessions.turnModel(s, body);
|
|
174
188
|
if (body.moa_config)
|
|
175
189
|
throw new HttpError(503, 'MoA overrides need the Agent command registry (checkpoint 7).');
|
|
176
|
-
const response = ctx.deps.turns.start(s, { msg, attachments, workspace, model, modelProvider: provider, normalizedModel: normalized, source: 'webui' });
|
|
190
|
+
const response = (await ctx.deps.turns.start(s, { msg, ...(prompt === null ? {} : { prompt }), attachments, workspace, model, modelProvider: provider, normalizedModel: normalized, source: 'webui', voiceTurn: body.voice_turn === true, connectCard: body.connect_card === true, skillSecret: body.skill_secret === true, ...settle }));
|
|
177
191
|
if (response._status !== undefined && response._status >= 400)
|
|
178
192
|
throw new HttpError(response._status, response.error ?? 'chat start failed', response.active_stream_id ? { active_stream_id: response.active_stream_id } : {});
|
|
179
193
|
return startPayload(response);
|
|
180
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* Legacy `POST /api/chat`: the `chat.start` admission, then the turn awaited to its end. A turn that was cancelled, or
|
|
197
|
+
* failed after streaming text, answers `partial` with that text; any other failure answers with its error frame.
|
|
198
|
+
*/
|
|
199
|
+
async function syncChat(ctx, body) {
|
|
200
|
+
if (ctx.deps.sessions.owner?.isOwned(str(body.session_id)))
|
|
201
|
+
throw new HttpError(409, 'This owner requires the asynchronous chat stream', { code: 'owner_requires_streaming' });
|
|
202
|
+
if ((await ctx.deps.sessions.isSubagentViewOnly(str(body.session_id))))
|
|
203
|
+
throw new HttpError(400, 'Subagent sessions are view-only and cannot be written from WebUI');
|
|
204
|
+
if (!str(body.message).trim())
|
|
205
|
+
throw new HttpError(400, 'empty message');
|
|
206
|
+
let outcome = null;
|
|
207
|
+
const started = await startChat(ctx, { session_id: body.session_id, message: body.message, workspace: body.workspace, model: body.model, ...('model_provider' in body ? { model_provider: body.model_provider } : {}) }, {
|
|
208
|
+
onDone: (answer) => { outcome = { answer }; },
|
|
209
|
+
onFailed: (failure) => { outcome = failure; },
|
|
210
|
+
});
|
|
211
|
+
const streamId = str(started.stream_id);
|
|
212
|
+
if (streamId)
|
|
213
|
+
await ctx.deps.turns.finished(streamId);
|
|
214
|
+
const s = (await getSession(ctx, str(body.session_id)));
|
|
215
|
+
const session = (await ctx.deps.turns.publicTerminalSession(s));
|
|
216
|
+
const ended = outcome;
|
|
217
|
+
// A `[SILENT]` control message starts no turn.
|
|
218
|
+
if (!streamId || (ended && 'answer' in ended)) {
|
|
219
|
+
const answer = ended && 'answer' in ended ? ended.answer : '';
|
|
220
|
+
return { answer, status: 'done', session, result: { final_response: answer, completed: true, interrupted: false } };
|
|
221
|
+
}
|
|
222
|
+
const partial = s.messages.filter((m) => m._turn_id === streamId && m._partial).map((m) => messageText(m.content)).join('').trim();
|
|
223
|
+
const cancelled = ended?.cancelled ?? false;
|
|
224
|
+
if (cancelled || (ended?.apperror && partial))
|
|
225
|
+
return { answer: partial, status: 'partial', session, result: { final_response: partial, completed: false, interrupted: cancelled } };
|
|
226
|
+
if (ended?.apperror) {
|
|
227
|
+
const { message, ...rest } = ended.apperror;
|
|
228
|
+
const type = str(rest.type);
|
|
229
|
+
throw new HttpError(type === 'agent_runtime_stale' ? 409 : type === 'sidecar_unavailable' ? 503 : 500, str(message) || 'chat failed', rest);
|
|
230
|
+
}
|
|
231
|
+
// Python `_chat_writeback_timeout_response`: the turn ended but another stream owned the session at writeback.
|
|
232
|
+
throw new HttpError(503, 'response persistence is uncertain', { code: 'chat_writeback_timeout', message: 'The response finished but could not be persisted because this session remained busy. Do not retry automatically; refresh the session first.', retryable: false, outcome_unknown: true });
|
|
233
|
+
}
|
|
181
234
|
export const chatRouter = os.router({
|
|
182
235
|
chat: {
|
|
183
|
-
|
|
236
|
+
ownerAction: os.chat.ownerAction.handler(({ input, context: { ctx } }) => run(async () => {
|
|
237
|
+
if (!(await ctx.deps.sessions.sessionIdVisible(input.session_id)))
|
|
238
|
+
throw new HttpError(404, 'Session not found');
|
|
239
|
+
const owner = ctx.deps.sessions.owner;
|
|
240
|
+
if (!owner)
|
|
241
|
+
throw new HttpError(503, 'Native session controls are unavailable');
|
|
242
|
+
let draft;
|
|
243
|
+
if (input.action === 'retry') {
|
|
244
|
+
draft = await owner.retry(input.session_id, input.admission_id, input.execution_generation);
|
|
245
|
+
}
|
|
246
|
+
else
|
|
247
|
+
await owner.action(input.session_id, input);
|
|
248
|
+
return { ok: true, session: await ctx.deps.sessions.detail(input.session_id, {}), ...(draft === undefined ? {} : { draft }) };
|
|
249
|
+
})),
|
|
250
|
+
sync: os.chat.sync.handler(({ input, context: { ctx } }) => run(async () => (await syncChat(ctx, input)))),
|
|
251
|
+
start: os.chat.start.handler(({ input, context: { ctx } }) => run(async () => (await startChat(ctx, input)))),
|
|
184
252
|
steer: os.chat.steer.handler(({ input, context: { ctx } }) => run(async () => {
|
|
185
253
|
const sid = str(input.session_id).trim();
|
|
186
254
|
const text = str(input.text).trim();
|
|
@@ -194,43 +262,52 @@ export const chatRouter = os.router({
|
|
|
194
262
|
throw new HttpError(400, 'steer_id must be 1-128 URL-safe characters');
|
|
195
263
|
if (!steerId)
|
|
196
264
|
steerId = `steer-${randomUUID()}`;
|
|
197
|
-
if (!ctx.deps.sessions.sessionIdVisible(sid))
|
|
265
|
+
if (!(await ctx.deps.sessions.sessionIdVisible(sid)))
|
|
198
266
|
throw new HttpError(404, 'Session not found');
|
|
199
267
|
const active = ctx.deps.registry.activeRunStreamForSession(sid);
|
|
200
268
|
if (active && ctx.deps.registry.activeRuns.get(active)?.origin === 'background') {
|
|
201
269
|
const started = await startChat(ctx, { session_id: sid, message: text });
|
|
202
270
|
return { accepted: true, fallback: null, stream_id: started.stream_id ? str(started.stream_id) : null, steer_id: steerId, started_turn: started };
|
|
203
271
|
}
|
|
204
|
-
|
|
272
|
+
// TAL-817: a prompt built-in steers with its expansion; the steer still shows as typed. A missing session is the steer's to report.
|
|
273
|
+
let target = null;
|
|
274
|
+
try {
|
|
275
|
+
target = (await ctx.deps.sessionStore.get(sid, { metadataOnly: true }));
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
target = null;
|
|
279
|
+
}
|
|
280
|
+
const prompt = target ? await expandPromptBuiltin(ctx, target, text, undefined) : null;
|
|
281
|
+
return (await ctx.deps.turns.steer(sid, prompt ?? text, display || (prompt === null ? '' : text), steerId));
|
|
205
282
|
})),
|
|
206
283
|
// TAL-424: Edit, Cancel and Send now on a pending steer; unknown or already-taken steers answer false.
|
|
207
284
|
steerWithdraw: os.chat.steerWithdraw.handler(({ input, context: { ctx } }) => run(async () => {
|
|
208
|
-
if (!ctx.deps.sessions.sessionIdVisible(input.session_id))
|
|
285
|
+
if (!(await ctx.deps.sessions.sessionIdVisible(input.session_id)))
|
|
209
286
|
throw new HttpError(404, 'Session not found');
|
|
210
|
-
return ctx.deps.turns.withdrawSteer(input.session_id, input.steer_id, input.reason);
|
|
287
|
+
return (await ctx.deps.turns.withdrawSteer(input.session_id, input.steer_id, input.reason));
|
|
211
288
|
})),
|
|
212
289
|
steerSendNow: os.chat.steerSendNow.handler(({ input, context: { ctx } }) => run(async () => {
|
|
213
|
-
if (!ctx.deps.sessions.sessionIdVisible(input.session_id))
|
|
290
|
+
if (!(await ctx.deps.sessions.sessionIdVisible(input.session_id)))
|
|
214
291
|
throw new HttpError(404, 'Session not found');
|
|
215
|
-
return ctx.deps.turns.sendSteerNow(input.session_id, input.steer_id);
|
|
292
|
+
return (await ctx.deps.turns.sendSteerNow(input.session_id, input.steer_id));
|
|
216
293
|
})),
|
|
217
294
|
cancel: os.chat.cancel.handler(({ input, context: { ctx } }) => run(async () => {
|
|
218
295
|
const streamId = str(input.stream_id);
|
|
219
296
|
if (!streamId)
|
|
220
297
|
throw new HttpError(400, 'stream_id required');
|
|
221
|
-
if (!streamVisibleToRequest(ctx, streamId))
|
|
298
|
+
if (!(await streamVisibleToRequest(ctx, streamId)))
|
|
222
299
|
throw new HttpError(404, 'Session not found');
|
|
223
300
|
const { cancelled, withdrawn } = await ctx.deps.turns.cancel(streamId);
|
|
224
301
|
return { ok: true, cancelled, stream_id: streamId, withdrawn_steers: withdrawn };
|
|
225
302
|
})),
|
|
226
|
-
streamStatus: os.chat.streamStatus.handler(({ input, context: { ctx } }) => run(() => {
|
|
303
|
+
streamStatus: os.chat.streamStatus.handler(({ input, context: { ctx } }) => run(async () => {
|
|
227
304
|
const streamId = str(input.stream_id);
|
|
228
|
-
if (!streamVisibleToRequest(ctx, streamId))
|
|
305
|
+
if (!(await streamVisibleToRequest(ctx, streamId)))
|
|
229
306
|
throw new HttpError(404, 'Session not found');
|
|
230
307
|
const active = ctx.deps.registry.liveIds.has(streamId);
|
|
231
|
-
const owner = streamOwnerSessionId(ctx, streamId);
|
|
232
|
-
const payload = { active, stream_id: streamId, replay_available: false, blocking_stream_id: owner ? ctx.deps.sessions.activeRunBlocking(owner) : null };
|
|
233
|
-
const summary = streamId ? ctx.deps.journal.findRunSummary(streamId) : null;
|
|
308
|
+
const owner = (await streamOwnerSessionId(ctx, streamId));
|
|
309
|
+
const payload = { active, stream_id: streamId, replay_available: false, blocking_stream_id: owner ? (await ctx.deps.sessions.activeRunBlocking(owner)) : null };
|
|
310
|
+
const summary = streamId ? (await ctx.deps.journal.findRunSummary(streamId)) : null;
|
|
234
311
|
if (summary) {
|
|
235
312
|
payload.replay_available = true;
|
|
236
313
|
const terminal = summary.terminal;
|
|
@@ -240,7 +317,7 @@ export const chatRouter = os.router({
|
|
|
240
317
|
})),
|
|
241
318
|
},
|
|
242
319
|
approval: {
|
|
243
|
-
pending: os.approval.pending.handler(({ input, context: { ctx } }) => run(() => ctx.deps.pending.approvalPending(str(input.session_id)))),
|
|
320
|
+
pending: os.approval.pending.handler(({ input, context: { ctx } }) => run(() => ctx.deps.sessions.owner?.isOwned(str(input.session_id)) ? ctx.deps.sessions.owner.pending(str(input.session_id), 'approval') : ctx.deps.pending.approvalPending(str(input.session_id)))),
|
|
244
321
|
respond: os.approval.respond.handler(({ input, context: { ctx } }) => run(async () => {
|
|
245
322
|
const sid = str(input.session_id);
|
|
246
323
|
if (!sid)
|
|
@@ -261,14 +338,15 @@ export const chatRouter = os.router({
|
|
|
261
338
|
})),
|
|
262
339
|
},
|
|
263
340
|
clarify: {
|
|
264
|
-
pending: os.clarify.pending.handler(({ input, context: { ctx } }) => run(() => ctx.deps.pending.clarifyPending(str(input.session_id)))),
|
|
341
|
+
pending: os.clarify.pending.handler(({ input, context: { ctx } }) => run(() => ctx.deps.sessions.owner?.isOwned(str(input.session_id)) ? ctx.deps.sessions.owner.pending(str(input.session_id), 'clarify') : ctx.deps.pending.clarifyPending(str(input.session_id)))),
|
|
265
342
|
respond: os.clarify.respond.handler(({ input, context: { ctx } }) => run(async () => {
|
|
266
343
|
const sid = str(input.session_id);
|
|
267
344
|
if (!sid)
|
|
268
345
|
throw new HttpError(400, 'session_id is required');
|
|
269
|
-
//
|
|
270
|
-
|
|
271
|
-
|
|
346
|
+
// Both keyed answers and older clients' raw replies are shaped against the pending prompt; only a vault prompt
|
|
347
|
+
// takes a decline (TAL-887).
|
|
348
|
+
const reply = input.decline === true ? null : input.answers ?? str(input.response ?? input.answer ?? input.choice).trim();
|
|
349
|
+
if (reply === '')
|
|
272
350
|
throw new HttpError(400, 'response is required');
|
|
273
351
|
const result = await ctx.deps.turns.respondClarify(sid, str(input.clarify_id), reply);
|
|
274
352
|
if (result.stale)
|
|
@@ -277,7 +355,8 @@ export const chatRouter = os.router({
|
|
|
277
355
|
throw new HttpError(400, 'answers must answer every question of the pending clarification', { ok: false });
|
|
278
356
|
if (!result.ok)
|
|
279
357
|
throw new HttpError(503, result.error ?? 'clarify relay failed', { ok: false });
|
|
280
|
-
|
|
358
|
+
// A vault answer is never echoed back.
|
|
359
|
+
return result.response === undefined ? { ok: true } : { ok: true, response: result.response };
|
|
281
360
|
})),
|
|
282
361
|
},
|
|
283
362
|
goal: os.goal.handler(({ input, context: { ctx } }) => run(async () => {
|
|
@@ -288,10 +367,10 @@ export const chatRouter = os.router({
|
|
|
288
367
|
return { status: 'suppressed', reason: 'silent_control_message' };
|
|
289
368
|
const sid = str(body.session_id);
|
|
290
369
|
// Python: a delegated subagent child is view-only; its goal state is never mutated and no turn starts on it.
|
|
291
|
-
if (ctx.deps.sessions.isSubagentViewOnly(sid))
|
|
370
|
+
if ((await ctx.deps.sessions.isSubagentViewOnly(sid)))
|
|
292
371
|
throw new HttpError(400, 'Subagent sessions are view-only and cannot run /goal from WebUI');
|
|
293
|
-
const s = getSession(ctx, sid);
|
|
294
|
-
if (ctx.deps.sessions.isReadOnly(s) || s.branchSourceReadonly)
|
|
372
|
+
const s = (await getSession(ctx, sid));
|
|
373
|
+
if ((await ctx.deps.sessions.isReadOnly(s)) || s.branchSourceReadonly)
|
|
295
374
|
throw new HttpError(403, 'Read-only imported sessions cannot be continued from WebUI');
|
|
296
375
|
const requestedProfile = str(body.profile).trim();
|
|
297
376
|
if (requestedProfile && requestedProfile !== 'default' && !PROFILE_ID_RE.test(requestedProfile))
|
|
@@ -302,7 +381,7 @@ export const chatRouter = os.router({
|
|
|
302
381
|
if (s.active_stream_id) {
|
|
303
382
|
streamRunning = ctx.deps.registry.liveIds.has(s.active_stream_id);
|
|
304
383
|
if (!streamRunning)
|
|
305
|
-
ctx.deps.sessions.clearStaleStreamState(s);
|
|
384
|
+
(await ctx.deps.sessions.clearStaleStreamState(s));
|
|
306
385
|
}
|
|
307
386
|
const sidecar = ctx.deps.sidecar();
|
|
308
387
|
if (!sidecar)
|
|
@@ -322,21 +401,29 @@ export const chatRouter = os.router({
|
|
|
322
401
|
defaultMaxTurns = 20;
|
|
323
402
|
}
|
|
324
403
|
const snapshot = await sidecar.call('goals.snapshot', { session_id: sid, profile_home: profileHome, default_max_turns: defaultMaxTurns });
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
404
|
+
ctx.deps.sessions.assertWritable(s);
|
|
405
|
+
const payload = await sidecar.call('goals.command', { session_id: sid, profile_home: profileHome, args, stream_running: streamRunning, default_max_turns: defaultMaxTurns, workspace: str(s.workspace) || undefined });
|
|
406
|
+
// TAL-808: the session `goal` follows the command before the client reloads the session.
|
|
407
|
+
await ctx.deps.turns.refreshGoal(s);
|
|
408
|
+
if (payload.ok === false) {
|
|
409
|
+
// Clients show the body's `error`, so the Agent's reason replaces the sidecar's code there.
|
|
410
|
+
const reason = str(payload.message || payload.error || 'goal command failed');
|
|
411
|
+
throw new HttpError(payload.error === 'agent_running' ? 409 : 400, reason, { ...payload, error: reason });
|
|
412
|
+
}
|
|
328
413
|
const kickoff = str(payload.kickoff_prompt).trim();
|
|
329
414
|
if (kickoff) {
|
|
330
415
|
// TAL-542: after the goal RPCs, so the stale-model check reads a catalog for the profile the session now runs under.
|
|
331
416
|
await ctx.deps.sessions.deps.warmSessionModelRepair?.(s.profile);
|
|
332
|
-
const workspace =
|
|
333
|
-
const [model, provider, normalized] =
|
|
334
|
-
const started = ctx.deps.turns.start(s, { msg: kickoff, attachments: [], workspace, model, modelProvider: provider, normalizedModel: normalized, source: 'webui', goalRelated: true });
|
|
417
|
+
const workspace = (await ctx.deps.sessions.turnWorkspace(s, body.workspace));
|
|
418
|
+
const [model, provider, normalized] = ctx.deps.sessions.turnModel(s, body);
|
|
419
|
+
const started = (await ctx.deps.turns.start(s, { msg: kickoff, attachments: [], workspace, model, modelProvider: provider, normalizedModel: normalized, source: 'webui', goalRelated: true }));
|
|
335
420
|
if (started._status !== undefined && started._status >= 400) {
|
|
336
421
|
try {
|
|
422
|
+
(ctx.deps.sessions.assertWritable(s));
|
|
337
423
|
await sidecar.call('goals.restore', { session_id: sid, profile_home: profileHome, snapshot: snapshot.snapshot });
|
|
338
424
|
}
|
|
339
425
|
catch { /* best effort */ }
|
|
426
|
+
await ctx.deps.turns.refreshGoal(s);
|
|
340
427
|
throw new HttpError(started._status, started.error ?? 'goal kickoff failed', { ...payload, ok: false });
|
|
341
428
|
}
|
|
342
429
|
Object.assign(payload, startPayload(started));
|
|
@@ -348,74 +435,69 @@ export const chatRouter = os.router({
|
|
|
348
435
|
const body = input;
|
|
349
436
|
requireField(body, 'session_id', 'prompt');
|
|
350
437
|
// A subagent child's profile/workspace/context must never seed a runnable background session.
|
|
351
|
-
if (ctx.deps.sessions.isSubagentViewOnly(str(body.session_id)))
|
|
438
|
+
if ((await ctx.deps.sessions.isSubagentViewOnly(str(body.session_id))))
|
|
352
439
|
throw new HttpError(400, 'Subagent sessions are view-only and cannot run background tasks from WebUI');
|
|
353
440
|
// TAL-542: the background turn starts on the parent's repaired pair; the catalog is built before the parent is read.
|
|
354
441
|
await ctx.deps.sessions.deps.warmSessionModelRepair?.();
|
|
355
|
-
const parent = getSession(ctx, str(body.session_id));
|
|
356
|
-
if (ctx.deps.sessions.isReadOnly(parent) || parent.branchSourceReadonly)
|
|
442
|
+
const parent = (await getSession(ctx, str(body.session_id)));
|
|
443
|
+
if ((await ctx.deps.sessions.isReadOnly(parent)) || parent.branchSourceReadonly)
|
|
357
444
|
throw new HttpError(403, 'Read-only imported sessions cannot be continued from WebUI');
|
|
358
445
|
const prompt = str(body.prompt).trim();
|
|
359
446
|
if (!prompt)
|
|
360
447
|
throw new HttpError(400, 'prompt is required');
|
|
361
|
-
const [model, modelProvider] =
|
|
362
|
-
const bg = ctx.deps.sessionStore.newSession({ workspace: parent.workspace, model, modelProvider, profile: parent.profile });
|
|
448
|
+
const [model, modelProvider] = ctx.deps.sessions.turnModel(parent, {});
|
|
449
|
+
const bg = (await ctx.deps.sessionStore.newSession({ workspace: parent.workspace, model, modelProvider, profile: parent.profile }));
|
|
363
450
|
bg.title = `bg: ${prompt.slice(0, 60)}`;
|
|
364
|
-
ctx.deps.sessionStore.save(bg);
|
|
365
|
-
// Python: `uuid.uuid4().hex[:8]`; a failed run still completes the task so `/api/background/
|
|
451
|
+
await ctx.deps.sessionStore.save(bg);
|
|
452
|
+
// Python: `uuid.uuid4().hex[:8]`; a failed run still completes the task so `/api/background/tasks` reports it,
|
|
366
453
|
// and the hidden bg session file is removed afterwards.
|
|
367
454
|
const taskId = randomUUID().replace(/-/g, '').slice(0, 8);
|
|
368
455
|
// TAL-372: the parent session keeps the task's record and result, so every client and a restart see it.
|
|
369
|
-
ctx.deps.background.trackCommand(parent.session_id, taskId, prompt);
|
|
370
|
-
const cleanup = () => { try {
|
|
371
|
-
ctx.deps.sessionStore.
|
|
456
|
+
await ctx.deps.background.trackCommand(parent.session_id, taskId, prompt);
|
|
457
|
+
const cleanup = async () => { try {
|
|
458
|
+
(await ctx.deps.sessionStore.delete(bg.session_id, { tombstone: false }));
|
|
372
459
|
}
|
|
373
460
|
catch { /* best effort */ } };
|
|
374
|
-
const started = ctx.deps.turns.start(bg, {
|
|
461
|
+
const started = (await ctx.deps.turns.start(bg, {
|
|
375
462
|
msg: prompt, attachments: [], workspace: parent.workspace, model, modelProvider, source: 'webui',
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
463
|
+
// Python: the last non-error assistant reply with content, else "(no answer produced)".
|
|
464
|
+
onDone: async (answer) => { (await ctx.deps.background.settleCommand(parent.session_id, taskId, 'completed', answer || '(no answer produced)')); (await cleanup()); },
|
|
465
|
+
onFailed: async () => { (await ctx.deps.background.settleCommand(parent.session_id, taskId, 'failed', '(background task failed)')); (await cleanup()); },
|
|
466
|
+
}));
|
|
379
467
|
if (started._status !== undefined && started._status >= 400) {
|
|
380
468
|
// Admission refused (profile deleting, session busy…): nothing runs, so the tracked task and hidden
|
|
381
469
|
// session must not linger as "running".
|
|
382
|
-
ctx.deps.background.forgetCommand(parent.session_id, taskId);
|
|
383
|
-
cleanup();
|
|
470
|
+
await ctx.deps.background.forgetCommand(parent.session_id, taskId);
|
|
471
|
+
await cleanup();
|
|
384
472
|
throw new HttpError(started._status, started.error ?? 'background start failed');
|
|
385
473
|
}
|
|
386
|
-
ctx.deps.background.setCommandStream(parent.session_id, taskId, str(started.stream_id));
|
|
474
|
+
await ctx.deps.background.setCommandStream(parent.session_id, taskId, str(started.stream_id));
|
|
387
475
|
return { ok: true, task_id: taskId, stream_id: str(started.stream_id), session_id: bg.session_id };
|
|
388
476
|
})),
|
|
389
|
-
status: os.background.status.handler(({ input, context: { ctx } }) => run(() => {
|
|
390
|
-
const sid = str(input.session_id);
|
|
391
|
-
if (!sid)
|
|
392
|
-
throw new HttpError(400, 'Missing session_id');
|
|
393
|
-
return { results: ctx.deps.background.legacyResults(sid) };
|
|
394
|
-
})),
|
|
395
477
|
tasks: os.background.tasks.handler(({ input, context: { ctx } }) => run(async () => {
|
|
396
|
-
const s = visibleSession(ctx, input.session_id);
|
|
478
|
+
const s = (await visibleSession(ctx, input.session_id));
|
|
397
479
|
const snapshot = await ctx.deps.background.snapshot(s.session_id, s.profile);
|
|
398
480
|
return { session_id: s.session_id, ...snapshot, tasks: input.kind ? snapshot.tasks.filter((t) => t.kind === input.kind) : snapshot.tasks };
|
|
399
481
|
})),
|
|
400
482
|
result: os.background.result.handler(({ input, context: { ctx } }) => run(async () => {
|
|
401
|
-
const s = visibleSession(ctx, input.session_id);
|
|
483
|
+
const s = (await visibleSession(ctx, input.session_id));
|
|
402
484
|
const text = await ctx.deps.background.result(s.session_id, s.profile, input.task_id);
|
|
403
485
|
if (text === null)
|
|
404
486
|
throw new HttpError(404, 'No result for this background task');
|
|
405
487
|
return { task_id: input.task_id, text };
|
|
406
488
|
})),
|
|
407
|
-
dismiss: os.background.dismiss.handler(({ input, context: { ctx } }) => run(() => {
|
|
408
|
-
const s = visibleSession(ctx, input.session_id);
|
|
409
|
-
const task = ctx.deps.background.dismiss(s.session_id, input.task_id);
|
|
489
|
+
dismiss: os.background.dismiss.handler(({ input, context: { ctx } }) => run(async () => {
|
|
490
|
+
const s = (await visibleSession(ctx, input.session_id));
|
|
491
|
+
const task = (await ctx.deps.background.dismiss(s.session_id, input.task_id));
|
|
410
492
|
if (!task)
|
|
411
493
|
throw new HttpError(404, 'Background task not found');
|
|
412
494
|
return { ok: true, task };
|
|
413
495
|
})),
|
|
414
|
-
ack: os.background.ack.handler(({ input, context: { ctx } }) => run(() => {
|
|
496
|
+
ack: os.background.ack.handler(({ input, context: { ctx } }) => run(async () => {
|
|
415
497
|
const body = input;
|
|
416
498
|
requireField(body, 'session_id');
|
|
417
499
|
const sid = str(body.session_id).trim();
|
|
418
|
-
const s = getSession(ctx, sid, true);
|
|
500
|
+
const s = (await getSession(ctx, sid, true));
|
|
419
501
|
const pid = str(body.task_id || body.process_id).trim();
|
|
420
502
|
if (str(body.process_id).trim())
|
|
421
503
|
ctx.extraResponseHeaders = { deprecation: 'true' };
|
|
@@ -429,31 +511,31 @@ export const chatRouter = os.router({
|
|
|
429
511
|
if (!isSafeSessionId(sid))
|
|
430
512
|
throw new HttpError(404, 'Session not found');
|
|
431
513
|
// Python: a subagent child's context must not be cloned into a runnable ephemeral session.
|
|
432
|
-
if (ctx.deps.sessions.isSubagentViewOnly(sid))
|
|
514
|
+
if ((await ctx.deps.sessions.isSubagentViewOnly(sid)))
|
|
433
515
|
throw new HttpError(400, 'Subagent sessions are view-only and cannot be used for /btw from WebUI');
|
|
434
516
|
// TAL-542: the side question starts on the chat's repaired pair; the catalog is built before the chat is read.
|
|
435
517
|
await ctx.deps.sessions.deps.warmSessionModelRepair?.();
|
|
436
|
-
const s = getSession(ctx, sid);
|
|
437
|
-
if (ctx.deps.sessions.isReadOnly(s) || s.branchSourceReadonly)
|
|
518
|
+
const s = (await getSession(ctx, sid));
|
|
519
|
+
if ((await ctx.deps.sessions.isReadOnly(s)) || s.branchSourceReadonly)
|
|
438
520
|
throw new HttpError(403, 'Read-only imported sessions cannot be continued from WebUI');
|
|
439
521
|
const question = str(body.question).trim();
|
|
440
522
|
if (!question)
|
|
441
523
|
throw new HttpError(400, 'question is required');
|
|
442
524
|
// TAL-518: a side question runs in its own hidden session, so the chat's running turn does not block it.
|
|
443
|
-
const [model, modelProvider] =
|
|
444
|
-
const ephemeral = ctx.deps.sessionStore.newSession({ workspace: s.workspace, model, modelProvider, profile: s.profile });
|
|
525
|
+
const [model, modelProvider] = ctx.deps.sessions.turnModel(s, {});
|
|
526
|
+
const ephemeral = (await ctx.deps.sessionStore.newSession({ workspace: s.workspace, model, modelProvider, profile: s.profile }));
|
|
445
527
|
ephemeral.messages = structuredClone(s.messages);
|
|
446
528
|
ephemeral.context_messages = ctx.deps.sessions.sideQuestionContext(s);
|
|
447
529
|
ephemeral.title = `btw: ${question.slice(0, 60)}`;
|
|
448
|
-
ctx.deps.sessionStore.save(ephemeral);
|
|
530
|
+
await ctx.deps.sessionStore.save(ephemeral);
|
|
449
531
|
// TAL-512: a failed or refused btw turn must not leave its copy of the parent conversation behind.
|
|
450
|
-
const cleanup = () => { try {
|
|
451
|
-
ctx.deps.sessionStore.
|
|
532
|
+
const cleanup = async () => { try {
|
|
533
|
+
(await ctx.deps.sessionStore.delete(ephemeral.session_id, { tombstone: false }));
|
|
452
534
|
}
|
|
453
535
|
catch { /* best effort */ } };
|
|
454
|
-
const started = ctx.deps.turns.start(ephemeral, { msg: question, attachments: [], workspace: s.workspace, model, modelProvider, source: 'webui', ephemeral: true, onFailed: cleanup });
|
|
536
|
+
const started = (await ctx.deps.turns.start(ephemeral, { msg: question, attachments: [], workspace: s.workspace, model, modelProvider, source: 'webui', ephemeral: true, onFailed: cleanup }));
|
|
455
537
|
if (started._status !== undefined && started._status >= 400) {
|
|
456
|
-
cleanup();
|
|
538
|
+
await cleanup();
|
|
457
539
|
throw new HttpError(started._status, started.error ?? 'btw start failed');
|
|
458
540
|
}
|
|
459
541
|
return { stream_id: str(started.stream_id), session_id: ephemeral.session_id, parent_session_id: sid };
|