@maudecode/talaria-web 1.18.0 → 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.js +16 -16
- package/dist/api/auth-raw.js.map +1 -1
- package/dist/api/automation-raw.d.ts +2 -2
- package/dist/api/automation-raw.js +32 -32
- package/dist/api/automation-raw.js.map +1 -1
- package/dist/api/automation-router.d.ts +102 -22
- package/dist/api/automation-router.js +15 -13
- package/dist/api/automation-router.js.map +1 -1
- package/dist/api/chat-router.d.ts +1205 -34
- package/dist/api/chat-router.js +158 -78
- package/dist/api/chat-router.js.map +1 -1
- package/dist/api/git-router.d.ts +2 -2
- package/dist/api/git-router.js +29 -29
- package/dist/api/git-router.js.map +1 -1
- package/dist/api/raw-routes.d.ts +3 -3
- package/dist/api/raw-routes.js +63 -61
- package/dist/api/raw-routes.js.map +1 -1
- package/dist/api/router.d.ts +6 -6
- package/dist/api/router.js +22 -22
- 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 +1928 -124
- package/dist/api/sessions-router.js +177 -173
- package/dist/api/sessions-router.js.map +1 -1
- package/dist/api/settings-router.d.ts +427 -9
- package/dist/api/settings-router.js +48 -32
- package/dist/api/settings-router.js.map +1 -1
- package/dist/api/sse-routes.d.ts +2 -2
- package/dist/api/sse-routes.js +63 -63
- package/dist/api/sse-routes.js.map +1 -1
- package/dist/api/tools-raw.d.ts +5 -0
- package/dist/api/tools-raw.js +58 -33
- package/dist/api/tools-raw.js.map +1 -1
- package/dist/api/tools-router.d.ts +663 -91
- package/dist/api/tools-router.js +309 -52
- 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 +66 -47
- package/dist/app.js.map +1 -1
- package/dist/auth/gate.js +10 -9
- package/dist/auth/gate.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 +14 -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 +113 -58
- package/dist/config/agent-config.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.js +14 -5
- 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 +14 -9
- package/dist/http/context.js +29 -20
- package/dist/http/context.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 +10 -4
- package/dist/profiles/profiles.js +77 -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 +78 -12
- package/dist/providers/catalog.js +445 -141
- 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/redact.js +18 -9
- 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 +233 -90
- package/dist/runtime.js.map +1 -1
- package/dist/server.js +10 -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 -20
- package/dist/sessions/background-tasks.js +88 -86
- 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 +15 -5
- package/dist/sessions/cli-sessions.js +62 -43
- package/dist/sessions/cli-sessions.js.map +1 -1
- package/dist/sessions/completions.d.ts +30 -2
- package/dist/sessions/completions.js +294 -53
- 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/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/goals.d.ts +31 -0
- package/dist/sessions/goals.js +75 -0
- package/dist/sessions/goals.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 +27 -18
- package/dist/sessions/list.js +133 -131
- package/dist/sessions/list.js.map +1 -1
- package/dist/sessions/merge.d.ts +68 -10
- package/dist/sessions/merge.js +259 -51
- 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 +4 -7
- package/dist/sessions/recovery.js +97 -281
- package/dist/sessions/recovery.js.map +1 -1
- package/dist/sessions/relay.d.ts +20 -20
- package/dist/sessions/relay.js +205 -127
- package/dist/sessions/relay.js.map +1 -1
- package/dist/sessions/service.d.ts +162 -59
- package/dist/sessions/service.js +1133 -521
- package/dist/sessions/service.js.map +1 -1
- package/dist/sessions/session.d.ts +18 -2
- package/dist/sessions/session.js +29 -5
- 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.js +3 -1
- package/dist/sessions/state-db-worker.js.map +1 -1
- package/dist/sessions/state-db.d.ts +53 -8
- package/dist/sessions/state-db.js +576 -50
- 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 +63 -73
- package/dist/sessions/store.js +305 -611
- 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.js +1 -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 +22 -16
- package/dist/sessions/tool-display.js.map +1 -1
- package/dist/sessions/turn-context.d.ts +10 -1
- package/dist/sessions/turn-context.js +7 -4
- package/dist/sessions/turn-context.js.map +1 -1
- package/dist/sessions/turn.d.ts +87 -17
- package/dist/sessions/turn.js +795 -347
- package/dist/sessions/turn.js.map +1 -1
- package/dist/sessions/wakeup-pause.d.ts +8 -13
- package/dist/sessions/wakeup-pause.js +31 -49
- package/dist/sessions/wakeup-pause.js.map +1 -1
- 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 +179 -183
- 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.js +19 -2
- package/dist/sidecar/fake.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/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 +82 -15
- package/dist/tools/crons.js.map +1 -1
- package/dist/tools/dashboard-plugins.d.ts +5 -5
- package/dist/tools/dashboard-plugins.js +14 -14
- package/dist/tools/dashboard-plugins.js.map +1 -1
- package/dist/tools/extensions.d.ts +5 -4
- package/dist/tools/extensions.js +213 -207
- 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 +15 -3
- package/dist/tools/health.js +97 -34
- 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/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/skills.d.ts +9 -4
- package/dist/tools/skills.js +44 -13
- 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 +93 -33
- package/dist/tools/updates.js +1051 -345
- package/dist/tools/updates.js.map +1 -1
- package/dist/util.d.ts +2 -0
- package/dist/util.js +5 -0
- package/dist/util.js.map +1 -1
- package/dist/workspace/git.d.ts +16 -1
- package/dist/workspace/git.js +291 -11
- package/dist/workspace/git.js.map +1 -1
- package/dist/workspace/media.d.ts +12 -9
- package/dist/workspace/media.js +31 -20
- package/dist/workspace/media.js.map +1 -1
- package/dist/workspace/rollback.d.ts +2 -2
- package/dist/workspace/rollback.js +5 -5
- package/dist/workspace/rollback.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.js +170 -32
- package/dist/workspace/worktrees.js.map +1 -1
- package/package.json +5 -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 +8 -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 +43 -1
- package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
- package/sidecar/talaria_sidecar/methods/aux.py +139 -31
- package/sidecar/talaria_sidecar/methods/chat.py +847 -134
- package/sidecar/talaria_sidecar/methods/commands.py +213 -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 +366 -34
- package/sidecar/talaria_sidecar/methods/cron_execution.py +284 -0
- package/sidecar/talaria_sidecar/methods/gateway.py +194 -54
- 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 +80 -27
- 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 +160 -11
- package/sidecar/talaria_sidecar/methods/profiles.py +44 -6
- package/sidecar/talaria_sidecar/methods/providers.py +196 -26
- 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 +277 -70
- 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 +81 -12
- package/sidecar/talaria_sidecar/speed.py +35 -0
- package/static/dist/FILES.txt +126 -127
- 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-gfbzpoou.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-fn1bhde6.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-c8kdixke.js → abnfDiagram-VCTEODGH-gjayq3ra.js} +1 -1
- package/static/dist/assets/architecture-7GRP2DOG-lp56972r.js +1 -0
- package/static/dist/assets/{architectureDiagram-5GKGNRK7-cku06x1p.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-jzthp1wa.js → blockDiagram-I7D4REHJ-joedghi3.js} +1 -1
- package/static/dist/assets/{c4Diagram-7LVT6UL2-mwr67mt8.js → c4Diagram-7LVT6UL2-hyrjrohe.js} +1 -1
- package/static/dist/assets/channel-es95o4y8.js +1 -0
- package/static/dist/assets/{chunk-4HAMMTFA-gpq1y228.js → chunk-4HAMMTFA-koouqbut.js} +1 -1
- package/static/dist/assets/{chunk-75Z2AOVW-ktje58c4.js → chunk-75Z2AOVW-bl4bhdnt.js} +1 -1
- package/static/dist/assets/{chunk-DU6HZSFF-ofajdixh.js → chunk-DU6HZSFF-gpedttsp.js} +3 -3
- package/static/dist/assets/{chunk-F27PBJKO-cmev85ti.js → chunk-F27PBJKO-d8xxi0zi.js} +1 -1
- package/static/dist/assets/{chunk-GMAD6QVW-htjgt22y.js → chunk-GMAD6QVW-jro0hl73.js} +1 -1
- package/static/dist/assets/{chunk-GVQU2GXP-qndvoxl7.js → chunk-GVQU2GXP-djn6gbyu.js} +1 -1
- package/static/dist/assets/{chunk-IMKFNOWR-e5bkd5q6.js → chunk-IMKFNOWR-vw4p5p7o.js} +1 -1
- package/static/dist/assets/{chunk-L3NEJ4N5-mj1155r6.js → chunk-L3NEJ4N5-n1hj77q8.js} +1 -1
- package/static/dist/assets/{chunk-OSK3NFVY-e7gkikcw.js → chunk-OSK3NFVY-oy0gwn2n.js} +1 -1
- package/static/dist/assets/{chunk-P2QGCYS3-f7t54xfm.js → chunk-P2QGCYS3-onf1hz6c.js} +1 -1
- package/static/dist/assets/{chunk-POPQ4Y6H-i927v9oa.js → chunk-POPQ4Y6H-m8sqn7cs.js} +1 -1
- package/static/dist/assets/{chunk-PWAF6VOD-m84lmnyt.js → chunk-PWAF6VOD-ek4smc8x.js} +1 -1
- package/static/dist/assets/{chunk-SHT3W25Y-mi0tlcu9.js → chunk-SHT3W25Y-g9gfvefo.js} +3 -3
- package/static/dist/assets/{chunk-SVP7TREG-dnau702j.js → chunk-SVP7TREG-f9nfv2cu.js} +1 -1
- package/static/dist/assets/{chunk-TICWLB2K-edem1gkg.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-magtofyp.js → copy-jamtd1pf.js} +1 -1
- package/static/dist/assets/{cynefin-OW5HDTMX-siqlulkl.js → cynefin-OW5HDTMX-f8xfdd3f.js} +1 -1
- package/static/dist/assets/{cynefinDiagram-5FMLGOSQ-i648tah9.js → cynefinDiagram-5FMLGOSQ-n9lb99h9.js} +1 -1
- package/static/dist/assets/{dagre-GXQ25YYZ-mwn6uc17.js → dagre-GXQ25YYZ-dgailddi.js} +4 -4
- package/static/dist/assets/{diagram-S7CK7UJ4-l8abxaes.js → diagram-S7CK7UJ4-m6aeoe7c.js} +1 -1
- package/static/dist/assets/{diagram-UQ7AKVKN-mekq7zgq.js → diagram-UQ7AKVKN-jall3j0x.js} +1 -1
- package/static/dist/assets/{diagram-VSXAHHWV-fnky6lvc.js → diagram-VSXAHHWV-hbawi7hn.js} +1 -1
- package/static/dist/assets/{diagram-VX7I27RA-xe6r5qfw.js → diagram-VX7I27RA-hendl2tt.js} +1 -1
- package/static/dist/assets/{diagram-Z3DM3KII-nq07dg7k.js → diagram-Z3DM3KII-igwc35p3.js} +1 -1
- package/static/dist/assets/{ebnfDiagram-PWID7BFC-c62ipm3g.js → ebnfDiagram-PWID7BFC-c64knz08.js} +1 -1
- package/static/dist/assets/{erDiagram-RLTQ6QDP-h39kmnzy.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-ngbsyp37.js → ganttDiagram-EL5Y4UJY-ma6jxj5i.js} +1 -1
- package/static/dist/assets/{gitGraph-4MIJSDKK-fr2i7caa.js → gitGraph-4MIJSDKK-naa9w6xa.js} +1 -1
- package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-eravdti4.js → gitGraphDiagram-WWUBYQGX-hzltvsod.js} +1 -1
- package/static/dist/assets/{highlighted-body-KPVGNVTW-jwpop9p8.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-h11x0dxo.js → info-A6RAGUB7-mn2ut5ko.js} +1 -1
- package/static/dist/assets/{infoDiagram-27XIBGKW-dfh47dw9.js → infoDiagram-27XIBGKW-h6kuqvsb.js} +1 -1
- package/static/dist/assets/{ishikawaDiagram-5VMMS53U-i6ypq351.js → ishikawaDiagram-5VMMS53U-e7bnwq7h.js} +1 -1
- package/static/dist/assets/{journeyDiagram-3NMN7TZE-lduf1z95.js → journeyDiagram-3NMN7TZE-etd1bi6p.js} +1 -1
- package/static/dist/assets/{kanban-definition-UXKFOSKX-e18bu4pg.js → kanban-definition-UXKFOSKX-emb1g9dz.js} +4 -4
- package/static/dist/assets/lazyRouteComponent-o816ytzl.js +1 -0
- package/static/dist/assets/{line-meizqsvn.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-ntne45i9.js → mermaid-parser.core-bnre27u8.js} +3 -3
- package/static/dist/assets/{mindmap-definition-YA3MSWOX-27b26eok.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-l6jdka8p.js → packet-AYTQ26CC-hatq7m2e.js} +1 -1
- package/static/dist/assets/pcmTap.worklet-74EKjWAZ.js +1 -0
- package/static/dist/assets/{pegDiagram-XKGWAZYB-g1er3bxj.js → pegDiagram-XKGWAZYB-gwisz8jv.js} +1 -1
- package/static/dist/assets/{pie-WAS4IAKB-i0ylcrt9.js → pie-WAS4IAKB-fpftf0mk.js} +1 -1
- package/static/dist/assets/{pieDiagram-E7YTZNPT-fbz1e55z.js → pieDiagram-E7YTZNPT-khm1o9a6.js} +1 -1
- package/static/dist/assets/{quadrantDiagram-AXDQQJYC-hhue7d8o.js → quadrantDiagram-AXDQQJYC-owqc4uqn.js} +1 -1
- package/static/dist/assets/{radar-RG4KPBEZ-f9b70aa4.js → radar-RG4KPBEZ-cntfwjpq.js} +1 -1
- package/static/dist/assets/{railroad-74A4TZTK-lgsuoeda.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-eqpy9fnz.js → railroadDiagram-O6MQD6OU-etuh0qa0.js} +1 -1
- package/static/dist/assets/{refresh-cw-hlwb02qv.js → refresh-cw-mqbkv2a3.js} +1 -1
- package/static/dist/assets/refresh-l29ljp76.js +1 -0
- package/static/dist/assets/{requirementDiagram-BXWQKSXE-ogf6puhi.js → requirementDiagram-BXWQKSXE-oq2ulk22.js} +1 -1
- package/static/dist/assets/{sankeyDiagram-P5KCCOFB-fqb8xcjf.js → sankeyDiagram-P5KCCOFB-iqc02emv.js} +1 -1
- package/static/dist/assets/saved-ndd4t2xb.js +1 -0
- package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-dlcz6qjz.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-fyoznpcs.js → stateDiagram-D77RDMKH-dnpt1ato.js} +1 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-bxjacpk6.js +1 -0
- package/static/dist/assets/{swimlanes-42K2YHIH-oefldhfy.js → swimlanes-42K2YHIH-loqbdazb.js} +1 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-id62p9hz.js +8 -0
- package/static/dist/assets/{timeline-definition-24CTP7MA-b1vl2zil.js → timeline-definition-24CTP7MA-ol2hnvma.js} +1 -1
- package/static/dist/assets/toast-i3h34v6o.js +64 -0
- package/static/dist/assets/{treeView-Q6P3EWNA-f7hcci5o.js → treeView-Q6P3EWNA-idrj6iox.js} +1 -1
- package/static/dist/assets/{treemap-WGGIJYW6-nl85071a.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-b4dq6n4q.js → useParams-gjc70qru.js} +1 -1
- package/static/dist/assets/{useSearch-ipfmv3he.js → useSearch-e6ae539u.js} +1 -1
- package/static/dist/assets/{vennDiagram-4TSXK5OY-h5hzbk0n.js → vennDiagram-4TSXK5OY-bvwr9o2z.js} +1 -1
- package/static/dist/assets/{wardley-WFR3VGLG-jftvpm3e.js → wardley-WFR3VGLG-31ui8tma.js} +1 -1
- package/static/dist/assets/{wardleyDiagram-VM6X3IG4-hedh85ge.js → wardleyDiagram-VM6X3IG4-k5wqtx4b.js} +1 -1
- package/static/dist/assets/{xychartDiagram-S5SC5T6Z-e49523ab.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-g3bkgnvt.js +0 -1
- package/static/dist/assets/ChatPage-oo7bdan6.js +0 -25
- package/static/dist/assets/Dialog-g355qxhp.js +0 -1
- package/static/dist/assets/ExtensionRoute-i2y9fvjm.js +0 -1
- package/static/dist/assets/HubRoute-lmkrbw47.js +0 -2
- package/static/dist/assets/Markdown-j4kut4j2.js +0 -598
- package/static/dist/assets/RightPanel-ohlsdzfl.js +0 -1
- package/static/dist/assets/Select-kddq75qc.js +0 -1
- package/static/dist/assets/SessionListPanel-lu3oy0hw.js +0 -1
- package/static/dist/assets/SettingsLayout-o9bv4mgb.js +0 -1
- package/static/dist/assets/States-eq6fe29m.js +0 -1
- package/static/dist/assets/Toaster-pc247u9f.js +0 -1
- package/static/dist/assets/_app-f8n1i0m1.js +0 -1
- package/static/dist/assets/_app.index-bzzv80hk.js +0 -1
- package/static/dist/assets/_app.insights-dzixbryi.js +0 -1
- package/static/dist/assets/_app.kanban-c6hep2us.js +0 -1
- package/static/dist/assets/_app.logs-i69qds98.js +0 -1
- package/static/dist/assets/_app.memory-kl4vf0gd.js +0 -1
- package/static/dist/assets/_app.profiles-b8zinmyp.js +0 -1
- package/static/dist/assets/_app.settings-cg8plwmf.js +0 -1
- package/static/dist/assets/_app.settings._section-bkwbi9zn.js +0 -3
- package/static/dist/assets/_app.skills-cs47sbvs.js +0 -1
- package/static/dist/assets/_app.tasks-dwvk64tc.js +0 -1
- package/static/dist/assets/_app.todos-c8xjm8p3.js +0 -1
- package/static/dist/assets/_app.workspaces-ehvd1gds.js +0 -1
- package/static/dist/assets/architecture-7GRP2DOG-6crvnylg.js +0 -1
- package/static/dist/assets/back-h7aun7ew.js +0 -1
- package/static/dist/assets/cancel-fhi0vcnu.js +0 -1
- package/static/dist/assets/channel-b2zo73z1.js +0 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-oe99st8x.js +0 -1
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-oe99st8x.js +0 -1
- package/static/dist/assets/copied-hcplv46p.js +0 -1
- package/static/dist/assets/endpoints-klbxod4t.js +0 -64
- package/static/dist/assets/eventmodeling-NTZA5JFV-obfede4u.js +0 -1
- package/static/dist/assets/flowDiagram-HODETNUW-kdpsp1je.js +0 -1
- package/static/dist/assets/host-i828xuo7.js +0 -1
- package/static/dist/assets/index-eh8zilnv.css +0 -2
- package/static/dist/assets/index-r648f4o1.js +0 -11
- package/static/dist/assets/lazyRouteComponent-e1y4t2i9.js +0 -1
- package/static/dist/assets/link-oot2yn73.js +0 -1
- package/static/dist/assets/login-gu28l9ou.js +0 -1
- package/static/dist/assets/mermaid-HWGCJPDP-mtwrj8fn.js +0 -1
- package/static/dist/assets/onboarding-lkphzu1s.js +0 -1
- package/static/dist/assets/onboarding_model_label-ftpjdwqk.js +0 -1
- package/static/dist/assets/railroad-abnf-HS5TGJTU-nf9d6pdx.js +0 -1
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-f7ummkt5.js +0 -1
- package/static/dist/assets/railroad-peg-WCYAUIDC-oczq5tqs.js +0 -1
- package/static/dist/assets/refresh-abtu93ke.js +0 -1
- package/static/dist/assets/saved-girnabkf.js +0 -1
- package/static/dist/assets/settings_section_extensions_title-h14cwk6f.js +0 -1
- package/static/dist/assets/share._token-kl0r7ido.js +0 -2
- package/static/dist/assets/sliders-horizontal-n1zm34qq.js +0 -1
- package/static/dist/assets/sse-iwku0sjo.js +0 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-ixhx8r46.js +0 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-h9ersk2e.js +0 -8
- package/static/dist/assets/todoStore-jjr5yr78.js +0 -1
- package/static/dist/assets/units-kgxzxfhi.js +0 -1
- package/static/dist/assets/untitled-cikfjntn.js +0 -1
- package/static/dist/assets/useForm-kqoqg0k9.js +0 -1
- package/static/dist/assets/useLocale-o59tbiea.js +0 -1
package/dist/api/chat-router.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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';
|
|
@@ -10,6 +10,9 @@ import { SessionNotFound } from '../sessions/store.js';
|
|
|
10
10
|
import { compressionRecoveryPayload, isSafeSessionId } from '../sessions/session.js';
|
|
11
11
|
import { messageText } from '../sessions/merge.js';
|
|
12
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';
|
|
13
16
|
const os = implement(chatContract).$context().use(requestSessionIdGuard);
|
|
14
17
|
const STEER_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
|
|
15
18
|
const PROFILE_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
@@ -27,14 +30,14 @@ async function run(fn) {
|
|
|
27
30
|
}
|
|
28
31
|
}
|
|
29
32
|
/** A session this request's profile may see (TAL-372 background work never crosses owners). */
|
|
30
|
-
function visibleSession(ctx, sid) {
|
|
31
|
-
if (!ctx.deps.sessions.sessionIdVisible(sid))
|
|
33
|
+
async function visibleSession(ctx, sid) {
|
|
34
|
+
if (!(await ctx.deps.sessions.sessionIdVisible(sid)))
|
|
32
35
|
throw new HttpError(404, 'Session not found');
|
|
33
|
-
return getSession(ctx, sid, true);
|
|
36
|
+
return (await getSession(ctx, sid, true));
|
|
34
37
|
}
|
|
35
|
-
function getSession(ctx, sid, metadataOnly = false) {
|
|
38
|
+
async function getSession(ctx, sid, metadataOnly = false) {
|
|
36
39
|
try {
|
|
37
|
-
return ctx.deps.sessionStore.get(sid, { metadataOnly });
|
|
40
|
+
return (await ctx.deps.sessionStore.get(sid, { metadataOnly }));
|
|
38
41
|
}
|
|
39
42
|
catch {
|
|
40
43
|
throw new HttpError(404, 'Session not found');
|
|
@@ -88,6 +91,40 @@ function visibleOrRetag(ctx, s, requestedProfile) {
|
|
|
88
91
|
}
|
|
89
92
|
throw new HttpError(404, 'Session not found');
|
|
90
93
|
}
|
|
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 = '';
|
|
111
|
+
}
|
|
112
|
+
let expanded;
|
|
113
|
+
try {
|
|
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 });
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
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);
|
|
123
|
+
}
|
|
124
|
+
if (expanded.name !== null && expanded.message === null)
|
|
125
|
+
throw new HttpError(400, unsupportedPromptMessage(expanded.name));
|
|
126
|
+
return expanded.message;
|
|
127
|
+
}
|
|
91
128
|
/** `chat.start`; a `chat.steer` sent while a background turn runs starts the user's turn through it too (TAL-460). */
|
|
92
129
|
async function startChat(ctx, body, settle = {}) {
|
|
93
130
|
requireField(body, 'session_id');
|
|
@@ -99,26 +136,31 @@ async function startChat(ctx, body, settle = {}) {
|
|
|
99
136
|
// Python `_agent_runtime_barrier_response`: a stale local Agent checkout is refused with a typed 409 before any
|
|
100
137
|
// session state is materialised, claimed, or mutated.
|
|
101
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
|
+
}
|
|
102
144
|
// TAL-542: the stale-model check reads this catalog; it is built before the session is read so no await follows that read.
|
|
103
145
|
await ctx.deps.sessions.deps.warmSessionModelRepair?.();
|
|
104
146
|
let s;
|
|
105
147
|
try {
|
|
106
|
-
s = ctx.deps.sessionStore.get(sid);
|
|
148
|
+
s = (await ctx.deps.sessionStore.get(sid));
|
|
107
149
|
}
|
|
108
150
|
catch {
|
|
109
151
|
// Python `_claim_or_synthesize_cli_session` on the POST path: a claimable foreign (CLI/TUI/Desktop) session is
|
|
110
152
|
// materialised as a WebUI sidecar before its first turn; an owned foreign store answers 403, nothing → 404.
|
|
111
|
-
const synth = ctx.deps.sessions.claimOrSynthesizeCliSession(sid);
|
|
153
|
+
const synth = (await ctx.deps.sessions.claimOrSynthesizeCliSession(sid));
|
|
112
154
|
if (!synth.session)
|
|
113
155
|
throw new HttpError(404, 'Session not found');
|
|
114
156
|
if (synth.reason === 'not_claimable')
|
|
115
157
|
throw new HttpError(403, 'session is read-only in its foreign store; cannot be claimed writeable in WebUI');
|
|
116
|
-
ctx.deps.sessionStore.save(synth.session);
|
|
117
|
-
s = ctx.deps.sessionStore.get(sid);
|
|
158
|
+
await ctx.deps.sessionStore.save(synth.session);
|
|
159
|
+
s = (await ctx.deps.sessionStore.get(sid));
|
|
118
160
|
}
|
|
119
161
|
// Python `_get_or_materialize_session` raised PermissionError for both: a read-only import and a delegated
|
|
120
162
|
// subagent child (by sidecar tag or state.db row), which chat start answered with the same 403.
|
|
121
|
-
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)))
|
|
122
164
|
throw new HttpError(403, 'Read-only imported sessions cannot be continued from WebUI');
|
|
123
165
|
const requestedProfile = str(body.profile).trim();
|
|
124
166
|
if (requestedProfile && requestedProfile !== 'default' && !PROFILE_ID_RE.test(requestedProfile))
|
|
@@ -129,20 +171,23 @@ async function startChat(ctx, body, settle = {}) {
|
|
|
129
171
|
// TAL-276: an attached file alone makes a turn; one with neither text nor a file path is refused.
|
|
130
172
|
if (!msg && !attachments.some((att) => str(att.path)))
|
|
131
173
|
throw new HttpError(400, 'message is required');
|
|
174
|
+
const prompt = await expandPromptBuiltin(ctx, s, msg, body.workspace);
|
|
132
175
|
// TAL-460: the user's message never joins a background turn; that turn stops quietly and this one takes its place.
|
|
133
|
-
|
|
176
|
+
const yielded = await ctx.deps.turns.yieldBackgroundTurn(sid);
|
|
177
|
+
if (prompt !== null || yielded) {
|
|
134
178
|
await ctx.deps.sessions.deps.warmSessionModelRepair?.();
|
|
135
|
-
s = ctx.deps.sessionStore.get(sid);
|
|
179
|
+
s = (await ctx.deps.sessionStore.get(sid));
|
|
180
|
+
visibleOrRetag(ctx, s, requestedProfile);
|
|
136
181
|
}
|
|
137
182
|
// Python `compression_recovery_payload_for_session` + `is_generic_continuation_intent`.
|
|
138
183
|
if (compressionRecoveryPayload(s) && !attachments.length && isGenericContinuationIntent(msg)) {
|
|
139
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 });
|
|
140
185
|
}
|
|
141
|
-
const workspace = ctx.deps.sessions.turnWorkspace(s, body.workspace);
|
|
186
|
+
const workspace = (await ctx.deps.sessions.turnWorkspace(s, body.workspace));
|
|
142
187
|
const [model, provider, normalized] = ctx.deps.sessions.turnModel(s, body);
|
|
143
188
|
if (body.moa_config)
|
|
144
189
|
throw new HttpError(503, 'MoA overrides need the Agent command registry (checkpoint 7).');
|
|
145
|
-
const response = ctx.deps.turns.start(s, { msg, attachments, workspace, model, modelProvider: provider, normalizedModel: normalized, source: 'webui', ...settle });
|
|
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 }));
|
|
146
191
|
if (response._status !== undefined && response._status >= 400)
|
|
147
192
|
throw new HttpError(response._status, response.error ?? 'chat start failed', response.active_stream_id ? { active_stream_id: response.active_stream_id } : {});
|
|
148
193
|
return startPayload(response);
|
|
@@ -152,7 +197,9 @@ async function startChat(ctx, body, settle = {}) {
|
|
|
152
197
|
* failed after streaming text, answers `partial` with that text; any other failure answers with its error frame.
|
|
153
198
|
*/
|
|
154
199
|
async function syncChat(ctx, body) {
|
|
155
|
-
if (ctx.deps.sessions.
|
|
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))))
|
|
156
203
|
throw new HttpError(400, 'Subagent sessions are view-only and cannot be written from WebUI');
|
|
157
204
|
if (!str(body.message).trim())
|
|
158
205
|
throw new HttpError(400, 'empty message');
|
|
@@ -164,8 +211,8 @@ async function syncChat(ctx, body) {
|
|
|
164
211
|
const streamId = str(started.stream_id);
|
|
165
212
|
if (streamId)
|
|
166
213
|
await ctx.deps.turns.finished(streamId);
|
|
167
|
-
const s = getSession(ctx, str(body.session_id));
|
|
168
|
-
const session = ctx.deps.turns.publicTerminalSession(s);
|
|
214
|
+
const s = (await getSession(ctx, str(body.session_id)));
|
|
215
|
+
const session = (await ctx.deps.turns.publicTerminalSession(s));
|
|
169
216
|
const ended = outcome;
|
|
170
217
|
// A `[SILENT]` control message starts no turn.
|
|
171
218
|
if (!streamId || (ended && 'answer' in ended)) {
|
|
@@ -186,8 +233,22 @@ async function syncChat(ctx, body) {
|
|
|
186
233
|
}
|
|
187
234
|
export const chatRouter = os.router({
|
|
188
235
|
chat: {
|
|
189
|
-
|
|
190
|
-
|
|
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)))),
|
|
191
252
|
steer: os.chat.steer.handler(({ input, context: { ctx } }) => run(async () => {
|
|
192
253
|
const sid = str(input.session_id).trim();
|
|
193
254
|
const text = str(input.text).trim();
|
|
@@ -201,43 +262,52 @@ export const chatRouter = os.router({
|
|
|
201
262
|
throw new HttpError(400, 'steer_id must be 1-128 URL-safe characters');
|
|
202
263
|
if (!steerId)
|
|
203
264
|
steerId = `steer-${randomUUID()}`;
|
|
204
|
-
if (!ctx.deps.sessions.sessionIdVisible(sid))
|
|
265
|
+
if (!(await ctx.deps.sessions.sessionIdVisible(sid)))
|
|
205
266
|
throw new HttpError(404, 'Session not found');
|
|
206
267
|
const active = ctx.deps.registry.activeRunStreamForSession(sid);
|
|
207
268
|
if (active && ctx.deps.registry.activeRuns.get(active)?.origin === 'background') {
|
|
208
269
|
const started = await startChat(ctx, { session_id: sid, message: text });
|
|
209
270
|
return { accepted: true, fallback: null, stream_id: started.stream_id ? str(started.stream_id) : null, steer_id: steerId, started_turn: started };
|
|
210
271
|
}
|
|
211
|
-
|
|
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));
|
|
212
282
|
})),
|
|
213
283
|
// TAL-424: Edit, Cancel and Send now on a pending steer; unknown or already-taken steers answer false.
|
|
214
284
|
steerWithdraw: os.chat.steerWithdraw.handler(({ input, context: { ctx } }) => run(async () => {
|
|
215
|
-
if (!ctx.deps.sessions.sessionIdVisible(input.session_id))
|
|
285
|
+
if (!(await ctx.deps.sessions.sessionIdVisible(input.session_id)))
|
|
216
286
|
throw new HttpError(404, 'Session not found');
|
|
217
|
-
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));
|
|
218
288
|
})),
|
|
219
289
|
steerSendNow: os.chat.steerSendNow.handler(({ input, context: { ctx } }) => run(async () => {
|
|
220
|
-
if (!ctx.deps.sessions.sessionIdVisible(input.session_id))
|
|
290
|
+
if (!(await ctx.deps.sessions.sessionIdVisible(input.session_id)))
|
|
221
291
|
throw new HttpError(404, 'Session not found');
|
|
222
|
-
return ctx.deps.turns.sendSteerNow(input.session_id, input.steer_id);
|
|
292
|
+
return (await ctx.deps.turns.sendSteerNow(input.session_id, input.steer_id));
|
|
223
293
|
})),
|
|
224
294
|
cancel: os.chat.cancel.handler(({ input, context: { ctx } }) => run(async () => {
|
|
225
295
|
const streamId = str(input.stream_id);
|
|
226
296
|
if (!streamId)
|
|
227
297
|
throw new HttpError(400, 'stream_id required');
|
|
228
|
-
if (!streamVisibleToRequest(ctx, streamId))
|
|
298
|
+
if (!(await streamVisibleToRequest(ctx, streamId)))
|
|
229
299
|
throw new HttpError(404, 'Session not found');
|
|
230
300
|
const { cancelled, withdrawn } = await ctx.deps.turns.cancel(streamId);
|
|
231
301
|
return { ok: true, cancelled, stream_id: streamId, withdrawn_steers: withdrawn };
|
|
232
302
|
})),
|
|
233
|
-
streamStatus: os.chat.streamStatus.handler(({ input, context: { ctx } }) => run(() => {
|
|
303
|
+
streamStatus: os.chat.streamStatus.handler(({ input, context: { ctx } }) => run(async () => {
|
|
234
304
|
const streamId = str(input.stream_id);
|
|
235
|
-
if (!streamVisibleToRequest(ctx, streamId))
|
|
305
|
+
if (!(await streamVisibleToRequest(ctx, streamId)))
|
|
236
306
|
throw new HttpError(404, 'Session not found');
|
|
237
307
|
const active = ctx.deps.registry.liveIds.has(streamId);
|
|
238
|
-
const owner = streamOwnerSessionId(ctx, streamId);
|
|
239
|
-
const payload = { active, stream_id: streamId, replay_available: false, blocking_stream_id: owner ? ctx.deps.sessions.activeRunBlocking(owner) : null };
|
|
240
|
-
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;
|
|
241
311
|
if (summary) {
|
|
242
312
|
payload.replay_available = true;
|
|
243
313
|
const terminal = summary.terminal;
|
|
@@ -247,7 +317,7 @@ export const chatRouter = os.router({
|
|
|
247
317
|
})),
|
|
248
318
|
},
|
|
249
319
|
approval: {
|
|
250
|
-
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)))),
|
|
251
321
|
respond: os.approval.respond.handler(({ input, context: { ctx } }) => run(async () => {
|
|
252
322
|
const sid = str(input.session_id);
|
|
253
323
|
if (!sid)
|
|
@@ -268,14 +338,15 @@ export const chatRouter = os.router({
|
|
|
268
338
|
})),
|
|
269
339
|
},
|
|
270
340
|
clarify: {
|
|
271
|
-
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)))),
|
|
272
342
|
respond: os.clarify.respond.handler(({ input, context: { ctx } }) => run(async () => {
|
|
273
343
|
const sid = str(input.session_id);
|
|
274
344
|
if (!sid)
|
|
275
345
|
throw new HttpError(400, 'session_id is required');
|
|
276
|
-
//
|
|
277
|
-
|
|
278
|
-
|
|
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 === '')
|
|
279
350
|
throw new HttpError(400, 'response is required');
|
|
280
351
|
const result = await ctx.deps.turns.respondClarify(sid, str(input.clarify_id), reply);
|
|
281
352
|
if (result.stale)
|
|
@@ -284,7 +355,8 @@ export const chatRouter = os.router({
|
|
|
284
355
|
throw new HttpError(400, 'answers must answer every question of the pending clarification', { ok: false });
|
|
285
356
|
if (!result.ok)
|
|
286
357
|
throw new HttpError(503, result.error ?? 'clarify relay failed', { ok: false });
|
|
287
|
-
|
|
358
|
+
// A vault answer is never echoed back.
|
|
359
|
+
return result.response === undefined ? { ok: true } : { ok: true, response: result.response };
|
|
288
360
|
})),
|
|
289
361
|
},
|
|
290
362
|
goal: os.goal.handler(({ input, context: { ctx } }) => run(async () => {
|
|
@@ -295,10 +367,10 @@ export const chatRouter = os.router({
|
|
|
295
367
|
return { status: 'suppressed', reason: 'silent_control_message' };
|
|
296
368
|
const sid = str(body.session_id);
|
|
297
369
|
// Python: a delegated subagent child is view-only; its goal state is never mutated and no turn starts on it.
|
|
298
|
-
if (ctx.deps.sessions.isSubagentViewOnly(sid))
|
|
370
|
+
if ((await ctx.deps.sessions.isSubagentViewOnly(sid)))
|
|
299
371
|
throw new HttpError(400, 'Subagent sessions are view-only and cannot run /goal from WebUI');
|
|
300
|
-
const s = getSession(ctx, sid);
|
|
301
|
-
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)
|
|
302
374
|
throw new HttpError(403, 'Read-only imported sessions cannot be continued from WebUI');
|
|
303
375
|
const requestedProfile = str(body.profile).trim();
|
|
304
376
|
if (requestedProfile && requestedProfile !== 'default' && !PROFILE_ID_RE.test(requestedProfile))
|
|
@@ -309,7 +381,7 @@ export const chatRouter = os.router({
|
|
|
309
381
|
if (s.active_stream_id) {
|
|
310
382
|
streamRunning = ctx.deps.registry.liveIds.has(s.active_stream_id);
|
|
311
383
|
if (!streamRunning)
|
|
312
|
-
ctx.deps.sessions.clearStaleStreamState(s);
|
|
384
|
+
(await ctx.deps.sessions.clearStaleStreamState(s));
|
|
313
385
|
}
|
|
314
386
|
const sidecar = ctx.deps.sidecar();
|
|
315
387
|
if (!sidecar)
|
|
@@ -329,21 +401,29 @@ export const chatRouter = os.router({
|
|
|
329
401
|
defaultMaxTurns = 20;
|
|
330
402
|
}
|
|
331
403
|
const snapshot = await sidecar.call('goals.snapshot', { session_id: sid, profile_home: profileHome, default_max_turns: defaultMaxTurns });
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
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
|
+
}
|
|
335
413
|
const kickoff = str(payload.kickoff_prompt).trim();
|
|
336
414
|
if (kickoff) {
|
|
337
415
|
// TAL-542: after the goal RPCs, so the stale-model check reads a catalog for the profile the session now runs under.
|
|
338
416
|
await ctx.deps.sessions.deps.warmSessionModelRepair?.(s.profile);
|
|
339
|
-
const workspace = ctx.deps.sessions.turnWorkspace(s, body.workspace);
|
|
417
|
+
const workspace = (await ctx.deps.sessions.turnWorkspace(s, body.workspace));
|
|
340
418
|
const [model, provider, normalized] = ctx.deps.sessions.turnModel(s, body);
|
|
341
|
-
const started = ctx.deps.turns.start(s, { msg: kickoff, attachments: [], workspace, model, modelProvider: provider, normalizedModel: normalized, source: 'webui', goalRelated: true });
|
|
419
|
+
const started = (await ctx.deps.turns.start(s, { msg: kickoff, attachments: [], workspace, model, modelProvider: provider, normalizedModel: normalized, source: 'webui', goalRelated: true }));
|
|
342
420
|
if (started._status !== undefined && started._status >= 400) {
|
|
343
421
|
try {
|
|
422
|
+
(ctx.deps.sessions.assertWritable(s));
|
|
344
423
|
await sidecar.call('goals.restore', { session_id: sid, profile_home: profileHome, snapshot: snapshot.snapshot });
|
|
345
424
|
}
|
|
346
425
|
catch { /* best effort */ }
|
|
426
|
+
await ctx.deps.turns.refreshGoal(s);
|
|
347
427
|
throw new HttpError(started._status, started.error ?? 'goal kickoff failed', { ...payload, ok: false });
|
|
348
428
|
}
|
|
349
429
|
Object.assign(payload, startPayload(started));
|
|
@@ -355,69 +435,69 @@ export const chatRouter = os.router({
|
|
|
355
435
|
const body = input;
|
|
356
436
|
requireField(body, 'session_id', 'prompt');
|
|
357
437
|
// A subagent child's profile/workspace/context must never seed a runnable background session.
|
|
358
|
-
if (ctx.deps.sessions.isSubagentViewOnly(str(body.session_id)))
|
|
438
|
+
if ((await ctx.deps.sessions.isSubagentViewOnly(str(body.session_id))))
|
|
359
439
|
throw new HttpError(400, 'Subagent sessions are view-only and cannot run background tasks from WebUI');
|
|
360
440
|
// TAL-542: the background turn starts on the parent's repaired pair; the catalog is built before the parent is read.
|
|
361
441
|
await ctx.deps.sessions.deps.warmSessionModelRepair?.();
|
|
362
|
-
const parent = getSession(ctx, str(body.session_id));
|
|
363
|
-
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)
|
|
364
444
|
throw new HttpError(403, 'Read-only imported sessions cannot be continued from WebUI');
|
|
365
445
|
const prompt = str(body.prompt).trim();
|
|
366
446
|
if (!prompt)
|
|
367
447
|
throw new HttpError(400, 'prompt is required');
|
|
368
448
|
const [model, modelProvider] = ctx.deps.sessions.turnModel(parent, {});
|
|
369
|
-
const bg = ctx.deps.sessionStore.newSession({ workspace: parent.workspace, model, modelProvider, profile: parent.profile });
|
|
449
|
+
const bg = (await ctx.deps.sessionStore.newSession({ workspace: parent.workspace, model, modelProvider, profile: parent.profile }));
|
|
370
450
|
bg.title = `bg: ${prompt.slice(0, 60)}`;
|
|
371
|
-
ctx.deps.sessionStore.save(bg);
|
|
451
|
+
await ctx.deps.sessionStore.save(bg);
|
|
372
452
|
// Python: `uuid.uuid4().hex[:8]`; a failed run still completes the task so `/api/background/tasks` reports it,
|
|
373
453
|
// and the hidden bg session file is removed afterwards.
|
|
374
454
|
const taskId = randomUUID().replace(/-/g, '').slice(0, 8);
|
|
375
455
|
// TAL-372: the parent session keeps the task's record and result, so every client and a restart see it.
|
|
376
|
-
ctx.deps.background.trackCommand(parent.session_id, taskId, prompt);
|
|
377
|
-
const cleanup = () => { try {
|
|
378
|
-
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 }));
|
|
379
459
|
}
|
|
380
460
|
catch { /* best effort */ } };
|
|
381
|
-
const started = ctx.deps.turns.start(bg, {
|
|
461
|
+
const started = (await ctx.deps.turns.start(bg, {
|
|
382
462
|
msg: prompt, attachments: [], workspace: parent.workspace, model, modelProvider, source: 'webui',
|
|
383
463
|
// Python: the last non-error assistant reply with content, else "(no answer produced)".
|
|
384
|
-
onDone: (answer) => { ctx.deps.background.settleCommand(parent.session_id, taskId, 'completed', answer || '(no answer produced)'); cleanup(); },
|
|
385
|
-
onFailed: () => { ctx.deps.background.settleCommand(parent.session_id, taskId, 'failed', '(background task failed)'); cleanup(); },
|
|
386
|
-
});
|
|
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
|
+
}));
|
|
387
467
|
if (started._status !== undefined && started._status >= 400) {
|
|
388
468
|
// Admission refused (profile deleting, session busy…): nothing runs, so the tracked task and hidden
|
|
389
469
|
// session must not linger as "running".
|
|
390
|
-
ctx.deps.background.forgetCommand(parent.session_id, taskId);
|
|
391
|
-
cleanup();
|
|
470
|
+
await ctx.deps.background.forgetCommand(parent.session_id, taskId);
|
|
471
|
+
await cleanup();
|
|
392
472
|
throw new HttpError(started._status, started.error ?? 'background start failed');
|
|
393
473
|
}
|
|
394
|
-
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));
|
|
395
475
|
return { ok: true, task_id: taskId, stream_id: str(started.stream_id), session_id: bg.session_id };
|
|
396
476
|
})),
|
|
397
477
|
tasks: os.background.tasks.handler(({ input, context: { ctx } }) => run(async () => {
|
|
398
|
-
const s = visibleSession(ctx, input.session_id);
|
|
478
|
+
const s = (await visibleSession(ctx, input.session_id));
|
|
399
479
|
const snapshot = await ctx.deps.background.snapshot(s.session_id, s.profile);
|
|
400
480
|
return { session_id: s.session_id, ...snapshot, tasks: input.kind ? snapshot.tasks.filter((t) => t.kind === input.kind) : snapshot.tasks };
|
|
401
481
|
})),
|
|
402
482
|
result: os.background.result.handler(({ input, context: { ctx } }) => run(async () => {
|
|
403
|
-
const s = visibleSession(ctx, input.session_id);
|
|
483
|
+
const s = (await visibleSession(ctx, input.session_id));
|
|
404
484
|
const text = await ctx.deps.background.result(s.session_id, s.profile, input.task_id);
|
|
405
485
|
if (text === null)
|
|
406
486
|
throw new HttpError(404, 'No result for this background task');
|
|
407
487
|
return { task_id: input.task_id, text };
|
|
408
488
|
})),
|
|
409
|
-
dismiss: os.background.dismiss.handler(({ input, context: { ctx } }) => run(() => {
|
|
410
|
-
const s = visibleSession(ctx, input.session_id);
|
|
411
|
-
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));
|
|
412
492
|
if (!task)
|
|
413
493
|
throw new HttpError(404, 'Background task not found');
|
|
414
494
|
return { ok: true, task };
|
|
415
495
|
})),
|
|
416
|
-
ack: os.background.ack.handler(({ input, context: { ctx } }) => run(() => {
|
|
496
|
+
ack: os.background.ack.handler(({ input, context: { ctx } }) => run(async () => {
|
|
417
497
|
const body = input;
|
|
418
498
|
requireField(body, 'session_id');
|
|
419
499
|
const sid = str(body.session_id).trim();
|
|
420
|
-
const s = getSession(ctx, sid, true);
|
|
500
|
+
const s = (await getSession(ctx, sid, true));
|
|
421
501
|
const pid = str(body.task_id || body.process_id).trim();
|
|
422
502
|
if (str(body.process_id).trim())
|
|
423
503
|
ctx.extraResponseHeaders = { deprecation: 'true' };
|
|
@@ -431,31 +511,31 @@ export const chatRouter = os.router({
|
|
|
431
511
|
if (!isSafeSessionId(sid))
|
|
432
512
|
throw new HttpError(404, 'Session not found');
|
|
433
513
|
// Python: a subagent child's context must not be cloned into a runnable ephemeral session.
|
|
434
|
-
if (ctx.deps.sessions.isSubagentViewOnly(sid))
|
|
514
|
+
if ((await ctx.deps.sessions.isSubagentViewOnly(sid)))
|
|
435
515
|
throw new HttpError(400, 'Subagent sessions are view-only and cannot be used for /btw from WebUI');
|
|
436
516
|
// TAL-542: the side question starts on the chat's repaired pair; the catalog is built before the chat is read.
|
|
437
517
|
await ctx.deps.sessions.deps.warmSessionModelRepair?.();
|
|
438
|
-
const s = getSession(ctx, sid);
|
|
439
|
-
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)
|
|
440
520
|
throw new HttpError(403, 'Read-only imported sessions cannot be continued from WebUI');
|
|
441
521
|
const question = str(body.question).trim();
|
|
442
522
|
if (!question)
|
|
443
523
|
throw new HttpError(400, 'question is required');
|
|
444
524
|
// TAL-518: a side question runs in its own hidden session, so the chat's running turn does not block it.
|
|
445
525
|
const [model, modelProvider] = ctx.deps.sessions.turnModel(s, {});
|
|
446
|
-
const ephemeral = ctx.deps.sessionStore.newSession({ workspace: s.workspace, model, modelProvider, profile: s.profile });
|
|
526
|
+
const ephemeral = (await ctx.deps.sessionStore.newSession({ workspace: s.workspace, model, modelProvider, profile: s.profile }));
|
|
447
527
|
ephemeral.messages = structuredClone(s.messages);
|
|
448
528
|
ephemeral.context_messages = ctx.deps.sessions.sideQuestionContext(s);
|
|
449
529
|
ephemeral.title = `btw: ${question.slice(0, 60)}`;
|
|
450
|
-
ctx.deps.sessionStore.save(ephemeral);
|
|
530
|
+
await ctx.deps.sessionStore.save(ephemeral);
|
|
451
531
|
// TAL-512: a failed or refused btw turn must not leave its copy of the parent conversation behind.
|
|
452
|
-
const cleanup = () => { try {
|
|
453
|
-
ctx.deps.sessionStore.
|
|
532
|
+
const cleanup = async () => { try {
|
|
533
|
+
(await ctx.deps.sessionStore.delete(ephemeral.session_id, { tombstone: false }));
|
|
454
534
|
}
|
|
455
535
|
catch { /* best effort */ } };
|
|
456
|
-
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 }));
|
|
457
537
|
if (started._status !== undefined && started._status >= 400) {
|
|
458
|
-
cleanup();
|
|
538
|
+
await cleanup();
|
|
459
539
|
throw new HttpError(started._status, started.error ?? 'btw start failed');
|
|
460
540
|
}
|
|
461
541
|
return { stream_id: str(started.stream_id), session_id: ephemeral.session_id, parent_session_id: sid };
|