@rudderhq/server 0.4.6-canary.8 → 0.5.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/dist/agent-runtimes/http/execute.d.ts.map +1 -1
- package/dist/agent-runtimes/http/execute.js +8 -2
- package/dist/agent-runtimes/http/execute.js.map +1 -1
- package/dist/agent-runtimes/process/execute.d.ts.map +1 -1
- package/dist/agent-runtimes/process/execute.js +3 -1
- package/dist/agent-runtimes/process/execute.js.map +1 -1
- package/dist/agent-runtimes/utils.d.ts +6 -1
- package/dist/agent-runtimes/utils.d.ts.map +1 -1
- package/dist/agent-runtimes/utils.js +1 -1
- package/dist/agent-runtimes/utils.js.map +1 -1
- package/dist/app.d.ts +3 -3
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +17 -8
- package/dist/app.js.map +1 -1
- package/dist/bootstrap/create-http-app.d.ts +6 -1
- package/dist/bootstrap/create-http-app.d.ts.map +1 -1
- package/dist/bootstrap/create-http-app.js +122 -46
- package/dist/bootstrap/create-http-app.js.map +1 -1
- package/dist/bootstrap/plugin-host-runtime.d.ts.map +1 -1
- package/dist/bootstrap/plugin-host-runtime.js +89 -31
- package/dist/bootstrap/plugin-host-runtime.js.map +1 -1
- package/dist/bootstrap/register-api-routes.d.ts +3 -1
- package/dist/bootstrap/register-api-routes.d.ts.map +1 -1
- package/dist/bootstrap/register-api-routes.js +3 -3
- package/dist/bootstrap/register-api-routes.js.map +1 -1
- package/dist/bootstrap/types.d.ts +1 -0
- package/dist/bootstrap/types.d.ts.map +1 -1
- package/dist/bundled-plugins/plugin-linear/dist/worker.js +351 -174
- package/dist/bundled-plugins/plugin-linear/dist/worker.js.map +3 -3
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +23 -0
- package/dist/config.js.map +1 -1
- package/dist/home-paths.d.ts.map +1 -1
- package/dist/home-paths.js +79 -7
- package/dist/home-paths.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +112 -119
- package/dist/index.js.map +1 -1
- package/dist/realtime/live-events-ws.d.ts +4 -20
- package/dist/realtime/live-events-ws.d.ts.map +1 -1
- package/dist/realtime/live-events-ws.js +68 -8
- package/dist/realtime/live-events-ws.js.map +1 -1
- package/dist/routes/access-onboarding.helpers.js +3 -3
- package/dist/routes/access-onboarding.helpers.js.map +1 -1
- package/dist/routes/access.helpers.d.ts.map +1 -1
- package/dist/routes/access.helpers.js +3 -2
- package/dist/routes/access.helpers.js.map +1 -1
- package/dist/routes/access.js +1 -1
- package/dist/routes/access.js.map +1 -1
- package/dist/routes/activity.d.ts.map +1 -1
- package/dist/routes/activity.js +5 -1
- package/dist/routes/activity.js.map +1 -1
- package/dist/routes/agents.management-routes.d.ts.map +1 -1
- package/dist/routes/agents.management-routes.js +15 -15
- package/dist/routes/agents.management-routes.js.map +1 -1
- package/dist/routes/assets.d.ts.map +1 -1
- package/dist/routes/assets.js +9 -2
- package/dist/routes/assets.js.map +1 -1
- package/dist/routes/chat-background-runtime.d.ts +19 -0
- package/dist/routes/chat-background-runtime.d.ts.map +1 -0
- package/dist/routes/chat-background-runtime.js +129 -0
- package/dist/routes/chat-background-runtime.js.map +1 -0
- package/dist/routes/chats.d.ts +2 -1
- package/dist/routes/chats.d.ts.map +1 -1
- package/dist/routes/chats.js +944 -24
- package/dist/routes/chats.js.map +1 -1
- package/dist/routes/chats.stream-routes.d.ts.map +1 -1
- package/dist/routes/chats.stream-routes.js +552 -76
- package/dist/routes/chats.stream-routes.js.map +1 -1
- package/dist/routes/issues.comments-attachments.d.ts.map +1 -1
- package/dist/routes/issues.comments-attachments.js +14 -31
- package/dist/routes/issues.comments-attachments.js.map +1 -1
- package/dist/routes/onboarding.js +1 -1
- package/dist/routes/onboarding.js.map +1 -1
- package/dist/routes/orgs.d.ts +2 -1
- package/dist/routes/orgs.d.ts.map +1 -1
- package/dist/routes/orgs.js +32 -3
- package/dist/routes/orgs.js.map +1 -1
- package/dist/routes/run-intelligence.d.ts.map +1 -1
- package/dist/routes/run-intelligence.js +109 -25
- package/dist/routes/run-intelligence.js.map +1 -1
- package/dist/runtime/runtime-supervisor.d.ts +21 -0
- package/dist/runtime/runtime-supervisor.d.ts.map +1 -0
- package/dist/runtime/runtime-supervisor.js +66 -0
- package/dist/runtime/runtime-supervisor.js.map +1 -0
- package/dist/services/activity-log.d.ts +4 -1
- package/dist/services/activity-log.d.ts.map +1 -1
- package/dist/services/activity-log.js +12 -4
- package/dist/services/activity-log.js.map +1 -1
- package/dist/services/activity.d.ts +11 -394
- package/dist/services/activity.d.ts.map +1 -1
- package/dist/services/activity.js +24 -18
- package/dist/services/activity.js.map +1 -1
- package/dist/services/agents.d.ts +799 -137
- package/dist/services/agents.d.ts.map +1 -1
- package/dist/services/approvals.d.ts +3 -3
- package/dist/services/automation-chat-output.d.ts.map +1 -1
- package/dist/services/automation-chat-output.js +115 -94
- package/dist/services/automation-chat-output.js.map +1 -1
- package/dist/services/budgets.d.ts.map +1 -1
- package/dist/services/budgets.js +38 -36
- package/dist/services/budgets.js.map +1 -1
- package/dist/services/chat-agent-runs.d.ts +3 -1
- package/dist/services/chat-agent-runs.d.ts.map +1 -1
- package/dist/services/chat-agent-runs.js +97 -34
- package/dist/services/chat-agent-runs.js.map +1 -1
- package/dist/services/chat-assistant.d.ts.map +1 -1
- package/dist/services/chat-assistant.helpers.d.ts +27 -4
- package/dist/services/chat-assistant.helpers.d.ts.map +1 -1
- package/dist/services/chat-assistant.helpers.js +66 -2
- package/dist/services/chat-assistant.helpers.js.map +1 -1
- package/dist/services/chat-assistant.inline-visuals.test.d.ts +2 -0
- package/dist/services/chat-assistant.inline-visuals.test.d.ts.map +1 -0
- package/dist/services/chat-assistant.inline-visuals.test.js +86 -0
- package/dist/services/chat-assistant.inline-visuals.test.js.map +1 -0
- package/dist/services/chat-assistant.js +115 -22
- package/dist/services/chat-assistant.js.map +1 -1
- package/dist/services/chat-generation-locks.d.ts +85 -0
- package/dist/services/chat-generation-locks.d.ts.map +1 -1
- package/dist/services/chat-generation-locks.js +371 -9
- package/dist/services/chat-generation-locks.js.map +1 -1
- package/dist/services/chat-generation-locks.test.d.ts +2 -0
- package/dist/services/chat-generation-locks.test.d.ts.map +1 -0
- package/dist/services/chat-generation-locks.test.js +324 -0
- package/dist/services/chat-generation-locks.test.js.map +1 -0
- package/dist/services/chat-generation-protocol.d.ts +674 -0
- package/dist/services/chat-generation-protocol.d.ts.map +1 -0
- package/dist/services/chat-generation-protocol.js +1571 -0
- package/dist/services/chat-generation-protocol.js.map +1 -0
- package/dist/services/chat-generation-protocol.test.d.ts +2 -0
- package/dist/services/chat-generation-protocol.test.d.ts.map +1 -0
- package/dist/services/chat-generation-protocol.test.js +1156 -0
- package/dist/services/chat-generation-protocol.test.js.map +1 -0
- package/dist/services/chat-title-generation.d.ts +0 -3
- package/dist/services/chat-title-generation.d.ts.map +1 -1
- package/dist/services/chat-title-generation.js +2 -32
- package/dist/services/chat-title-generation.js.map +1 -1
- package/dist/services/chat-work-manifest.d.ts.map +1 -1
- package/dist/services/chat-work-manifest.js +5 -1
- package/dist/services/chat-work-manifest.js.map +1 -1
- package/dist/services/chats.d.ts +1451 -272
- package/dist/services/chats.d.ts.map +1 -1
- package/dist/services/chats.js +1372 -35
- package/dist/services/chats.js.map +1 -1
- package/dist/services/costs.d.ts +34 -7
- package/dist/services/costs.d.ts.map +1 -1
- package/dist/services/costs.js +129 -61
- package/dist/services/costs.js.map +1 -1
- package/dist/services/finance.d.ts +3 -3
- package/dist/services/goals.d.ts +2 -2
- package/dist/services/heartbeat-run-summary.d.ts.map +1 -1
- package/dist/services/heartbeat-run-summary.js +16 -1
- package/dist/services/heartbeat-run-summary.js.map +1 -1
- package/dist/services/heartbeat.d.ts +1 -1
- package/dist/services/heartbeat.d.ts.map +1 -1
- package/dist/services/heartbeat.js +1 -1
- package/dist/services/heartbeat.js.map +1 -1
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +1 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/integrations/agent-integrations.d.ts +1 -1
- package/dist/services/integrations/custom-integrations.d.ts +1 -1
- package/dist/services/integrations/feishu/runtime.d.ts.map +1 -1
- package/dist/services/integrations/feishu/runtime.js +16 -0
- package/dist/services/integrations/feishu/runtime.js.map +1 -1
- package/dist/services/issues.comments-attachments.d.ts +111 -0
- package/dist/services/issues.comments-attachments.d.ts.map +1 -1
- package/dist/services/issues.comments-attachments.js +138 -66
- package/dist/services/issues.comments-attachments.js.map +1 -1
- package/dist/services/issues.d.ts +56 -0
- package/dist/services/issues.d.ts.map +1 -1
- package/dist/services/issues.helpers.d.ts.map +1 -1
- package/dist/services/issues.helpers.js +2 -2
- package/dist/services/issues.helpers.js.map +1 -1
- package/dist/services/issues.js +5 -2
- package/dist/services/issues.js.map +1 -1
- package/dist/services/knowledge-portability/organization-skills.catalog.d.ts.map +1 -1
- package/dist/services/knowledge-portability/organization-skills.catalog.js +7 -1
- package/dist/services/knowledge-portability/organization-skills.catalog.js.map +1 -1
- package/dist/services/messenger.d.ts.map +1 -1
- package/dist/services/messenger.js +11 -9
- package/dist/services/messenger.js.map +1 -1
- package/dist/services/organization-workspace-browser.d.ts +1 -1
- package/dist/services/organization-workspace-browser.d.ts.map +1 -1
- package/dist/services/organization-workspace-browser.js +49 -5
- package/dist/services/organization-workspace-browser.js.map +1 -1
- package/dist/services/orgs.d.ts.map +1 -1
- package/dist/services/orgs.js +36 -12
- package/dist/services/orgs.js.map +1 -1
- package/dist/services/plugin-dev-watcher.d.ts +19 -2
- package/dist/services/plugin-dev-watcher.d.ts.map +1 -1
- package/dist/services/plugin-dev-watcher.js +45 -11
- package/dist/services/plugin-dev-watcher.js.map +1 -1
- package/dist/services/plugin-registry.d.ts +28 -28
- package/dist/services/projects.d.ts +1 -1
- package/dist/services/run-events.d.ts +20 -0
- package/dist/services/run-events.d.ts.map +1 -0
- package/dist/services/run-events.js +34 -0
- package/dist/services/run-events.js.map +1 -0
- package/dist/services/run-intelligence.d.ts +66 -4
- package/dist/services/run-intelligence.d.ts.map +1 -1
- package/dist/services/run-intelligence.js +391 -42
- package/dist/services/run-intelligence.js.map +1 -1
- package/dist/services/run-log-store.d.ts.map +1 -1
- package/dist/services/run-log-store.js +26 -3
- package/dist/services/run-log-store.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.core.d.ts +24 -1
- package/dist/services/runtime-kernel/heartbeat.core.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.core.js +2 -1
- package/dist/services/runtime-kernel/heartbeat.core.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.d.ts +98 -37
- package/dist/services/runtime-kernel/heartbeat.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.execute.d.ts +3 -1
- package/dist/services/runtime-kernel/heartbeat.execute.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.execute.js +394 -219
- package/dist/services/runtime-kernel/heartbeat.execute.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.js +603 -205
- package/dist/services/runtime-kernel/heartbeat.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.misc.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.misc.js +34 -24
- package/dist/services/runtime-kernel/heartbeat.misc.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.recovery.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.recovery.js +56 -6
- package/dist/services/runtime-kernel/heartbeat.recovery.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.release.d.ts +3 -1
- package/dist/services/runtime-kernel/heartbeat.release.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.release.js +276 -44
- package/dist/services/runtime-kernel/heartbeat.release.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.sessions.d.ts +42 -1
- package/dist/services/runtime-kernel/heartbeat.sessions.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.sessions.js +110 -8
- package/dist/services/runtime-kernel/heartbeat.sessions.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.terminal.d.ts +575 -0
- package/dist/services/runtime-kernel/heartbeat.terminal.d.ts.map +1 -0
- package/dist/services/runtime-kernel/heartbeat.terminal.js +589 -0
- package/dist/services/runtime-kernel/heartbeat.terminal.js.map +1 -0
- package/dist/services/runtime-kernel/heartbeat.wakeup.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.wakeup.js +238 -92
- package/dist/services/runtime-kernel/heartbeat.wakeup.js.map +1 -1
- package/dist/services/runtime-kernel/model-fallback.d.ts.map +1 -1
- package/dist/services/runtime-kernel/model-fallback.js +11 -0
- package/dist/services/runtime-kernel/model-fallback.js.map +1 -1
- package/dist/services/side-chats.d.ts +212 -0
- package/dist/services/side-chats.d.ts.map +1 -0
- package/dist/services/side-chats.js +379 -0
- package/dist/services/side-chats.js.map +1 -0
- package/dist/services/workspace-runtime.services.d.ts +1 -1
- package/dist/services/workspace-web-preview.d.ts +36 -0
- package/dist/services/workspace-web-preview.d.ts.map +1 -0
- package/dist/services/workspace-web-preview.js +566 -0
- package/dist/services/workspace-web-preview.js.map +1 -0
- package/package.json +13 -13
- package/resources/bundled-skills/rudder-docs/SKILL.md +161 -0
- package/resources/bundled-skills/rudder-docs/evals/trigger-evals.json +82 -0
- package/{skills/rudder → resources/bundled-skills/rudder-docs}/references/api-reference.md +17 -1
- package/{skills/rudder → resources/bundled-skills/rudder-docs}/references/cli-reference.md +52 -97
- package/resources/bundled-skills/rudder-docs/references/control-plane-practices.md +231 -0
- package/{skills/rudder → resources/bundled-skills/rudder-docs}/references/organization-skills.md +15 -1
- package/resources/bundled-skills/rudder-docs/references/source-map.md +138 -0
- package/resources/bundled-skills/visualize/SKILL.md +132 -0
- package/resources/bundled-skills/visualize/agents/openai.yaml +7 -0
- package/resources/bundled-skills/visualize/assets/example-chart.html +89 -0
- package/resources/bundled-skills/visualize/references/runtime-contract.md +114 -0
- package/skills/rudder-docs/SKILL.md +161 -0
- package/skills/rudder-docs/evals/trigger-evals.json +82 -0
- package/{resources/bundled-skills/rudder → skills/rudder-docs}/references/api-reference.md +17 -1
- package/{resources/bundled-skills/rudder → skills/rudder-docs}/references/cli-reference.md +52 -97
- package/skills/rudder-docs/references/control-plane-practices.md +231 -0
- package/{resources/bundled-skills/rudder → skills/rudder-docs}/references/organization-skills.md +15 -1
- package/skills/rudder-docs/references/source-map.md +138 -0
- package/skills/visualize/SKILL.md +132 -0
- package/skills/visualize/agents/openai.yaml +7 -0
- package/skills/visualize/assets/example-chart.html +89 -0
- package/skills/visualize/references/runtime-contract.md +114 -0
- package/ui-dist/assets/{abnfDiagram-VRR7QNED-C4e_AuJm.js → abnfDiagram-VRR7QNED-Dpnx79fp.js} +1 -1
- package/ui-dist/assets/{arc-3OG5_qjR.js → arc-Cpvh_rCf.js} +1 -1
- package/ui-dist/assets/{architectureDiagram-ZJ3FMSHR-CJz3inSs.js → architectureDiagram-ZJ3FMSHR-sDD_mBAI.js} +1 -1
- package/ui-dist/assets/{blockDiagram-677ZJIJ3-CpBIok39.js → blockDiagram-677ZJIJ3-4O4wWti1.js} +1 -1
- package/ui-dist/assets/{c4Diagram-LMCZKHZV-BbQrD6Fx.js → c4Diagram-LMCZKHZV-BkGODE4P.js} +1 -1
- package/ui-dist/assets/channel-CM4Myg_6.js +1 -0
- package/ui-dist/assets/{chunk-2Q5K7J3B-BkoT6fZL.js → chunk-2Q5K7J3B-DsDQQpID.js} +1 -1
- package/ui-dist/assets/{chunk-32BRIVSS-DecBtqTH.js → chunk-32BRIVSS-Bzx_VnIw.js} +1 -1
- package/ui-dist/assets/{chunk-5VM5RSS4-SFFAgh5q.js → chunk-5VM5RSS4-D4LoPCni.js} +1 -1
- package/ui-dist/assets/{chunk-EX3LRPZG-CxUndf0S.js → chunk-EX3LRPZG-BO0R-mS4.js} +3 -3
- package/ui-dist/assets/{chunk-JWPE2WC7-BbEXuDLm.js → chunk-JWPE2WC7-B4Nr8KRL.js} +1 -1
- package/ui-dist/assets/{chunk-MOJQB5TN-MOCGQpRH.js → chunk-MOJQB5TN--uaDDrYM.js} +1 -1
- package/ui-dist/assets/{chunk-RYQCIY6F-CUuwDB4L.js → chunk-RYQCIY6F-CyBY2w_j.js} +1 -1
- package/ui-dist/assets/{chunk-V7JOEXUC-D5H80ZpL.js → chunk-V7JOEXUC-BMid_x8S.js} +3 -3
- package/ui-dist/assets/{chunk-VR4S4FIN-Cg5d82yb.js → chunk-VR4S4FIN-DVqdPKuG.js} +1 -1
- package/ui-dist/assets/{chunk-XXDRQBXY-Bu7DXS_3.js → chunk-XXDRQBXY-vy03lLSS.js} +1 -1
- package/ui-dist/assets/classDiagram-OUVF2IWQ-CtlIEzTt.js +1 -0
- package/ui-dist/assets/classDiagram-v2-EOCWNBFH-CtlIEzTt.js +1 -0
- package/ui-dist/assets/{cose-bilkent-JH36ORCC-LCobsJkA.js → cose-bilkent-JH36ORCC-jQDZmrG3.js} +1 -1
- package/ui-dist/assets/{cynefin-VYW2F7L2-CxDfvhGJ.js → cynefin-VYW2F7L2-BxBj6aea.js} +1 -1
- package/ui-dist/assets/{cynefinDiagram-TSTJHNR4-BbebJ96a.js → cynefinDiagram-TSTJHNR4-BuUubF5I.js} +1 -1
- package/ui-dist/assets/{dagre-VKFMJZFB-BNQ0fvpl.js → dagre-VKFMJZFB-B8HipJ3a.js} +1 -1
- package/ui-dist/assets/{diagram-FQU43EPY-B9vCEyLD.js → diagram-FQU43EPY-r7gkbKSt.js} +2 -2
- package/ui-dist/assets/{diagram-G47NLZAW-Z7Hg_sXF.js → diagram-G47NLZAW-CxClRsxD.js} +1 -1
- package/ui-dist/assets/{diagram-NH7WQ7WH-B_TZ5-gD.js → diagram-NH7WQ7WH-C8HYTLlq.js} +1 -1
- package/ui-dist/assets/{diagram-OA4YK3LP-qe-twEnv.js → diagram-OA4YK3LP-CjwqqLKz.js} +1 -1
- package/ui-dist/assets/{diagram-WEI45ONY-D8ufoJVE.js → diagram-WEI45ONY-2IWfCqZb.js} +1 -1
- package/ui-dist/assets/{ebnfDiagram-CCIWWBDH-BXXAFqU6.js → ebnfDiagram-CCIWWBDH-DVGZkgjy.js} +1 -1
- package/ui-dist/assets/{erDiagram-Q63AITRT-uXmIG2c_.js → erDiagram-Q63AITRT-C_-u3Gmw.js} +1 -1
- package/ui-dist/assets/{flowDiagram-23GEKE2U-3eiT6gWx.js → flowDiagram-23GEKE2U-BvGg0NCq.js} +4 -4
- package/ui-dist/assets/{ganttDiagram-NO4QXBWP-CiVmqV02.js → ganttDiagram-NO4QXBWP-U3CZUUUR.js} +1 -1
- package/ui-dist/assets/{gitGraphDiagram-IHSO6WYX-DmIrlFHc.js → gitGraphDiagram-IHSO6WYX-CIWuEBIo.js} +1 -1
- package/ui-dist/assets/{graph-BpS6eOIF.js → graph-D3P5q-7m.js} +1 -1
- package/ui-dist/assets/index-B1rLBtZ1.js +1875 -0
- package/ui-dist/assets/{index-Dlx6uy7_.js → index-BAMXpiI5.js} +1 -1
- package/ui-dist/assets/{index-CUHGsSRd.js → index-BAgtKYR1.js} +1 -1
- package/ui-dist/assets/{index--YRaLrzl.js → index-CBOr9F6w.js} +1 -1
- package/ui-dist/assets/{index-cHC60zXl.js → index-CbHqnWUe.js} +1 -1
- package/ui-dist/assets/{index-DeWKDYpk.js → index-CjztBLJi.js} +1 -1
- package/ui-dist/assets/{index-T2PpfhXU.js → index-Cu1iMhjl.js} +1 -1
- package/ui-dist/assets/{index-Dgj1-Gzi.js → index-D7ycf1qU.js} +1 -1
- package/ui-dist/assets/{index-Dpvu2aoc.js → index-DAYlwxsg.js} +1 -1
- package/ui-dist/assets/{index-BAU4CU-l.js → index-DCFf9dps.js} +4 -4
- package/ui-dist/assets/{index-CWaZ_rS8.js → index-DOPIV8vd.js} +1 -1
- package/ui-dist/assets/{index-C-TZf854.js → index-DRxLJD40.js} +1 -1
- package/ui-dist/assets/{index-CUI9Uyvz.js → index-DYMtCDKT.js} +1 -1
- package/ui-dist/assets/index-DekHKOsL.css +1 -0
- package/ui-dist/assets/{index-BncN7e-4.js → index-DidCCw78.js} +1 -1
- package/ui-dist/assets/{index-Cl27pPic.js → index-Ds_qma4-.js} +1 -1
- package/ui-dist/assets/{index-CF3Fjm4r.js → index-HkQRx1D6.js} +1 -1
- package/ui-dist/assets/{index-Cp12taja.js → index-ikpL--zj.js} +1 -1
- package/ui-dist/assets/{index-BzDB5XYN.js → index-mnl55Stn.js} +1 -1
- package/ui-dist/assets/{infoDiagram-FWYZ7A6U-B_e34a6A.js → infoDiagram-FWYZ7A6U-Cx8Fa-I4.js} +1 -1
- package/ui-dist/assets/{ishikawaDiagram-FXEZZL3T-C_h8nqRS.js → ishikawaDiagram-FXEZZL3T-Cmuz1QUN.js} +1 -1
- package/ui-dist/assets/{journeyDiagram-5HDEW3XC-CrxAvEMf.js → journeyDiagram-5HDEW3XC-CJgkiVXG.js} +1 -1
- package/ui-dist/assets/{kanban-definition-HUTT4EX6-Zp6LAKss.js → kanban-definition-HUTT4EX6-RAWpefOB.js} +1 -1
- package/ui-dist/assets/layout-DyWQv0Rr.js +1 -0
- package/ui-dist/assets/{linear-_N4Odhfh.js → linear-D5pdgIf9.js} +1 -1
- package/ui-dist/assets/{map-CYGuJtD3.js → map-bVSzNLl2.js} +1 -1
- package/ui-dist/assets/mermaid.core-CeaXGD6B.js +312 -0
- package/ui-dist/assets/{mindmap-definition-LN4V7U3C-C-J9N_o_.js → mindmap-definition-LN4V7U3C-B8B8AX5C.js} +1 -1
- package/ui-dist/assets/{pegDiagram-2B236MQR-B9Mlsk91.js → pegDiagram-2B236MQR-C4Sv-ua6.js} +1 -1
- package/ui-dist/assets/{pieDiagram-ENE6RG2P-BY7DU2f8.js → pieDiagram-ENE6RG2P-CLARlOHx.js} +1 -1
- package/ui-dist/assets/{quadrantDiagram-ABIIQ3AL-CdCl_yc0.js → quadrantDiagram-ABIIQ3AL-DPCXQmeT.js} +1 -1
- package/ui-dist/assets/{railroadDiagram-RFXS5EU6-C5w2LKAD.js → railroadDiagram-RFXS5EU6-BpqRuKUQ.js} +1 -1
- package/ui-dist/assets/{requirementDiagram-TGXJPOKE-fRb_n-yH.js → requirementDiagram-TGXJPOKE-Dd-h62HZ.js} +1 -1
- package/ui-dist/assets/{sankeyDiagram-HTMAVEWB-CYjb1HUH.js → sankeyDiagram-HTMAVEWB-DylT_pqq.js} +1 -1
- package/ui-dist/assets/{sequenceDiagram-DBY2YBRQ-CS95ySsI.js → sequenceDiagram-DBY2YBRQ-RiCF1REj.js} +1 -1
- package/ui-dist/assets/{sizeCapture-X5ZJPWSS-DPXTC0TI.js → sizeCapture-X5ZJPWSS-DXW4JQz2.js} +1 -1
- package/ui-dist/assets/{stateDiagram-2N3HPSRC-C4VFIMBR.js → stateDiagram-2N3HPSRC-6U3ESIGT.js} +1 -1
- package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-KQTrcZvp.js +1 -0
- package/ui-dist/assets/{swimlanes-5IMT3BWC-UvxkQ8RD.js → swimlanes-5IMT3BWC-CeNHVNCi.js} +2 -2
- package/ui-dist/assets/swimlanesDiagram-G3AALYLV-CcxS1c6r.js +8 -0
- package/ui-dist/assets/{timeline-definition-FHXFAJF6-BKotSwXW.js → timeline-definition-FHXFAJF6-Vlwoe_1b.js} +1 -1
- package/ui-dist/assets/{vennDiagram-L72KCM5P-TmXc-aFs.js → vennDiagram-L72KCM5P-DBP7D3HE.js} +6 -6
- package/ui-dist/assets/{wardleyDiagram-EHGQE667-aTINQKt9.js → wardleyDiagram-EHGQE667-DG-wzqpy.js} +1 -1
- package/ui-dist/assets/{xychartDiagram-FW5EYKEG-CZ86hWNQ.js → xychartDiagram-FW5EYKEG-BAq3mbha.js} +1 -1
- package/ui-dist/index.html +2 -2
- package/resources/bundled-skills/rudder/SKILL.md +0 -314
- package/skills/rudder/SKILL.md +0 -314
- package/ui-dist/assets/channel-roHkdL27.js +0 -1
- package/ui-dist/assets/classDiagram-OUVF2IWQ-CKZLREY1.js +0 -1
- package/ui-dist/assets/classDiagram-v2-EOCWNBFH-CKZLREY1.js +0 -1
- package/ui-dist/assets/index-BTW19O7e.js +0 -1808
- package/ui-dist/assets/index-DOlmbVZk.css +0 -1
- package/ui-dist/assets/layout-DlHAdVX4.js +0 -1
- package/ui-dist/assets/mermaid.core-B8dXcSSK.js +0 -314
- package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-CF5IY4p0.js +0 -1
- package/ui-dist/assets/swimlanesDiagram-G3AALYLV-BVLEg2fG.js +0 -8
|
@@ -1,17 +1,45 @@
|
|
|
1
|
-
import { addChatMessageSchema, convertChatToIssueSchema, createChatAttachmentMetadataSchema, createChatContextLinkSchema, resolveChatOperationProposalSchema, setChatProjectContextSchema, updateChatConversationUserStateSchema } from "@rudderhq/shared";
|
|
1
|
+
import { addChatMessageSchema, chatClientCheckpointSchema, convertChatToIssueSchema, createChatAttachmentMetadataSchema, createChatContextLinkSchema, resolveChatOperationProposalSchema, setChatProjectContextSchema, stopChatGenerationSchema, updateChatConversationUserStateSchema } from "@rudderhq/shared";
|
|
2
2
|
import multer from "multer";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { isAllowedContentType, MAX_ATTACHMENT_BYTES } from "../attachment-types.js";
|
|
5
|
+
import { conflict } from "../errors.js";
|
|
5
6
|
import { logger } from "../middleware/logger.js";
|
|
6
7
|
import { validate } from "../middleware/validate.js";
|
|
8
|
+
import { createAssistantTextAccumulator } from "../services/chat-assistant.helpers.js";
|
|
7
9
|
import { CHAT_ASSISTANT_USER_ERROR_MESSAGE, ChatAssistantStreamError, userVisiblePartialBodyFromError } from "../services/chat-assistant.js";
|
|
8
|
-
import { cancelActiveChatGeneration, claimChatGeneration, getActiveChatGeneration, setActiveChatGenerationId, } from "../services/chat-generation-locks.js";
|
|
10
|
+
import { cancelActiveChatGeneration, claimChatGeneration, createChatRuntimeControlCoordinator, getActiveChatGeneration, setActiveChatGenerationId, } from "../services/chat-generation-locks.js";
|
|
11
|
+
import { hashChatGenerationBody } from "../services/chat-generation-protocol.js";
|
|
9
12
|
import { logActivity } from "../services/index.js";
|
|
10
13
|
import { assertCompanyAccess, getActorInfo } from "./authz.js";
|
|
11
14
|
import { wakeIssueAssigneeAfterChatConversion } from "./chat-issue-assignment-wakeup.js";
|
|
15
|
+
const startingChatGenerationGates = new Map();
|
|
16
|
+
function createStartingChatGenerationGate() {
|
|
17
|
+
let resolveGeneration;
|
|
18
|
+
let resolveStopApplied;
|
|
19
|
+
return {
|
|
20
|
+
generationReady: new Promise((resolve) => {
|
|
21
|
+
resolveGeneration = resolve;
|
|
22
|
+
}),
|
|
23
|
+
stopApplied: new Promise((resolve) => {
|
|
24
|
+
resolveStopApplied = resolve;
|
|
25
|
+
}),
|
|
26
|
+
stopRequested: false,
|
|
27
|
+
resolveGeneration,
|
|
28
|
+
resolveStopApplied,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function outputAdmissionClosed(error) {
|
|
32
|
+
return Boolean(error
|
|
33
|
+
&& typeof error === "object"
|
|
34
|
+
&& "status" in error
|
|
35
|
+
&& Number(error.status) === 409
|
|
36
|
+
&& "message" in error
|
|
37
|
+
&& error.message === "Chat-visible output admission is closed for this generation");
|
|
38
|
+
}
|
|
12
39
|
export function registerChatStreamRoutes(ctx) {
|
|
13
40
|
const CHAT_ASSISTANT_RECOVERABLE_FAILURE_FALLBACK_MESSAGE = "The assistant reply could not be completed. Rudder saved this attempt for diagnostics; retry when ready.";
|
|
14
|
-
const
|
|
41
|
+
const CHAT_ASSISTANT_STOPPED_FALLBACK_MESSAGE = "Chat run stopped before a final reply. Continue the conversation to resume from the preserved context.";
|
|
42
|
+
const { router, db, storage, svc, assistantSvc, agentsSvc, issuesSvc, projectsSvc, goalsSvc, access, operatorProfiles, heartbeat, assertConversationAccess, assertChatLocalMutationAllowed, assertSideChatMutationAllowed, touchSideChat, boardUserId, assertCanAssignTasks, runSingleFileUpload, runMessageFileUpload, isMultipartRequest, uploadedMessageFiles, validateUploadedMessageFiles, logChatMessagesAdded, assertContextLinksBelongToCompany, turnContextFromUserMessage, addUserMessage, startChatTitleGeneration, attachFilesToUserMessage, loadAssistantInput, chatReplyingAgentId, assertCanConvertIssueProposal, persistAssistantReply, linkChatRunMessages, attachGeneratedFilesToPartialMessage, persistPartialAssistantMessage, recoverableFailurePayload, recoverableFailureBody, writeStreamEvent, queueRequestActor, wakeServerQueue, wakeTerminalProjector, } = ctx;
|
|
15
43
|
router.post("/chats/:id/messages/stream", async (req, res) => {
|
|
16
44
|
if (isMultipartRequest(req)) {
|
|
17
45
|
try {
|
|
@@ -46,6 +74,7 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
46
74
|
return;
|
|
47
75
|
}
|
|
48
76
|
assertChatLocalMutationAllowed(conversation);
|
|
77
|
+
await assertSideChatMutationAllowed(req, conversation);
|
|
49
78
|
const actor = getActorInfo(req);
|
|
50
79
|
if (actor.actorType === "agent") {
|
|
51
80
|
if (parsedBody.data.editUserMessageId) {
|
|
@@ -77,6 +106,7 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
77
106
|
conversationId: conversation.id,
|
|
78
107
|
clientMutationId: `stream:${randomUUID()}`,
|
|
79
108
|
expectedGenerationId: getActiveChatGeneration(conversation.id)?.generationId ?? null,
|
|
109
|
+
requestActor: queueRequestActor(req),
|
|
80
110
|
payload: {
|
|
81
111
|
body: parsedBody.data.body,
|
|
82
112
|
attachmentIds: [],
|
|
@@ -98,6 +128,8 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
98
128
|
res.end();
|
|
99
129
|
return;
|
|
100
130
|
}
|
|
131
|
+
const startupGate = createStartingChatGenerationGate();
|
|
132
|
+
startingChatGenerationGates.set(conversation.id, startupGate);
|
|
101
133
|
if (queuedMessageId) {
|
|
102
134
|
try {
|
|
103
135
|
await svc.assertQueuedMessageClaimedForDelivery({
|
|
@@ -107,6 +139,8 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
107
139
|
});
|
|
108
140
|
}
|
|
109
141
|
catch (error) {
|
|
142
|
+
startupGate.resolveGeneration(null);
|
|
143
|
+
startingChatGenerationGates.delete(conversation.id);
|
|
110
144
|
releaseGeneration();
|
|
111
145
|
throw error;
|
|
112
146
|
}
|
|
@@ -116,52 +150,116 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
116
150
|
const createdGeneration = await svc.createGeneration(conversation.orgId, conversation.id);
|
|
117
151
|
generation = createdGeneration;
|
|
118
152
|
setActiveChatGenerationId(conversation.id, createdGeneration.id);
|
|
153
|
+
startupGate.resolveGeneration(createdGeneration.id);
|
|
119
154
|
}
|
|
120
155
|
catch (error) {
|
|
156
|
+
startupGate.resolveGeneration(null);
|
|
157
|
+
startingChatGenerationGates.delete(conversation.id);
|
|
121
158
|
releaseGeneration();
|
|
122
159
|
throw error;
|
|
123
160
|
}
|
|
161
|
+
if (abortController.signal.aborted && startupGate.stopRequested) {
|
|
162
|
+
await startupGate.stopApplied;
|
|
163
|
+
}
|
|
124
164
|
let assistantConversationForPartial = null;
|
|
125
165
|
let turnContextForPartial = null;
|
|
126
166
|
const transcript = [];
|
|
127
|
-
let assistantProgressMessage = null;
|
|
128
167
|
let assistantProgressMessageId = null;
|
|
129
168
|
let activeChatRunId = null;
|
|
130
169
|
let generationTerminalStatus = "failed";
|
|
131
|
-
let
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
170
|
+
let admittedAssistantBody = "";
|
|
171
|
+
let stopCutoff = null;
|
|
172
|
+
let outputAdmissionTail = Promise.resolve();
|
|
173
|
+
const serializeOutputAdmission = (operation) => {
|
|
174
|
+
const result = outputAdmissionTail.then(operation, operation);
|
|
175
|
+
outputAdmissionTail = result.then(() => undefined, () => undefined);
|
|
176
|
+
return result;
|
|
177
|
+
};
|
|
178
|
+
const freezeStopCutoff = () => {
|
|
179
|
+
if (stopCutoff)
|
|
180
|
+
return;
|
|
181
|
+
stopCutoff = {
|
|
182
|
+
body: admittedAssistantBody,
|
|
183
|
+
transcript: [...transcript],
|
|
142
184
|
};
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
185
|
+
};
|
|
186
|
+
abortController.signal.addEventListener("abort", freezeStopCutoff, { once: true });
|
|
187
|
+
const stoppedState = (fallbackBody) => {
|
|
188
|
+
if (!stopCutoff) {
|
|
189
|
+
return {
|
|
190
|
+
body: admittedAssistantBody.trim() ? admittedAssistantBody : fallbackBody,
|
|
191
|
+
transcript: [...transcript],
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
const accumulator = createAssistantTextAccumulator();
|
|
195
|
+
for (const entry of stopCutoff.transcript) {
|
|
196
|
+
if (entry.kind === "assistant") {
|
|
197
|
+
accumulator.push(entry.text, entry.delta === true);
|
|
149
198
|
}
|
|
150
199
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
200
|
+
return {
|
|
201
|
+
body: stopCutoff.body.trim() ? stopCutoff.body : accumulator.fullText,
|
|
202
|
+
transcript: stopCutoff.transcript,
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
let stoppedPersistencePromise = null;
|
|
206
|
+
const persistStoppedAssistant = (stoppedConversation, replyingAgentId, fallbackBody) => {
|
|
207
|
+
if (stoppedPersistencePromise)
|
|
208
|
+
return stoppedPersistencePromise;
|
|
209
|
+
generationTerminalStatus = "stopped";
|
|
210
|
+
stoppedPersistencePromise = (async () => {
|
|
211
|
+
await outputAdmissionTail;
|
|
212
|
+
let frozen = stoppedState(fallbackBody);
|
|
213
|
+
if (generation) {
|
|
214
|
+
const durableFrozen = await svc.generationProtocol.getFrozenVisibleProjection({
|
|
215
|
+
orgId: conversation.orgId,
|
|
216
|
+
conversationId: conversation.id,
|
|
217
|
+
generationId: generation.id,
|
|
218
|
+
}).catch(() => null);
|
|
219
|
+
if (durableFrozen && durableFrozen.generation.acceptedThroughSeq !== null) {
|
|
220
|
+
frozen = {
|
|
221
|
+
body: durableFrozen.projection.body,
|
|
222
|
+
transcript: durableFrozen.projection.transcript,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
const stoppedBody = frozen.body.trim()
|
|
227
|
+
? frozen.body
|
|
228
|
+
: (assistantProgressMessageId ? CHAT_ASSISTANT_STOPPED_FALLBACK_MESSAGE : "");
|
|
229
|
+
let stoppedMessage = null;
|
|
230
|
+
let lastProjectionError;
|
|
231
|
+
for (let attempt = 1; attempt <= 3; attempt += 1) {
|
|
232
|
+
try {
|
|
233
|
+
stoppedMessage = await persistPartialAssistantMessage(stoppedConversation, stoppedBody, "stopped", turnContextForPartial, frozen.transcript, replyingAgentId, assistantProgressMessageId, activeChatRunId);
|
|
234
|
+
lastProjectionError = undefined;
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
lastProjectionError = error;
|
|
239
|
+
logger.warn({ err: error, conversationId: stoppedConversation.id, attempt }, "failed to project stopped chat assistant message");
|
|
240
|
+
await Promise.resolve();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (lastProjectionError)
|
|
244
|
+
throw lastProjectionError;
|
|
245
|
+
await linkChatRunMessages(stoppedConversation, activeChatRunId, stoppedMessage ? [stoppedMessage] : []);
|
|
246
|
+
if (stoppedMessage) {
|
|
247
|
+
await logChatMessagesAdded(stoppedConversation, [stoppedMessage], {
|
|
248
|
+
actorType: "system",
|
|
249
|
+
actorId: "chat-assistant",
|
|
250
|
+
agentId: replyingAgentId,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
if (!clientClosed) {
|
|
254
|
+
writeStreamEvent(res, {
|
|
255
|
+
type: "final",
|
|
256
|
+
messages: stoppedMessage ? [stoppedMessage] : [],
|
|
257
|
+
});
|
|
258
|
+
res.end();
|
|
259
|
+
}
|
|
260
|
+
return stoppedMessage;
|
|
261
|
+
})();
|
|
262
|
+
return stoppedPersistencePromise;
|
|
165
263
|
};
|
|
166
264
|
let clientClosed = false;
|
|
167
265
|
const handleClosed = () => {
|
|
@@ -178,6 +276,7 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
178
276
|
res.flushHeaders();
|
|
179
277
|
try {
|
|
180
278
|
const userMessage = await addUserMessage(conversation, parsedBody.data.body, actor, parsedBody.data.editUserMessageId ?? null);
|
|
279
|
+
await touchSideChat(req, conversation);
|
|
181
280
|
if (queuedMessageId) {
|
|
182
281
|
await svc.markQueuedMessageRunning({
|
|
183
282
|
conversationId: conversation.id,
|
|
@@ -205,7 +304,19 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
205
304
|
writeStreamEvent(res, {
|
|
206
305
|
type: "ack",
|
|
207
306
|
userMessage: hydratedUserMessage,
|
|
307
|
+
generationId: generation.id,
|
|
308
|
+
attemptEpoch: generation.attemptEpoch ?? 1,
|
|
309
|
+
generationSeq: 0,
|
|
310
|
+
bodyHash: hashChatGenerationBody(""),
|
|
208
311
|
});
|
|
312
|
+
if (abortController.signal.aborted) {
|
|
313
|
+
generationTerminalStatus = "stopped";
|
|
314
|
+
if (!clientClosed) {
|
|
315
|
+
writeStreamEvent(res, { type: "final", messages: [] });
|
|
316
|
+
res.end();
|
|
317
|
+
}
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
209
320
|
{
|
|
210
321
|
const assistantInput = await loadAssistantInput(conversation, actor);
|
|
211
322
|
assistantConversationForPartial = assistantInput.conversation;
|
|
@@ -220,54 +331,181 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
220
331
|
activeChatRunId = runId;
|
|
221
332
|
},
|
|
222
333
|
abortSignal: abortController.signal,
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
334
|
+
controlCoordinator: createChatRuntimeControlCoordinator(conversation.id, generation.id, {
|
|
335
|
+
onAttemptStarted: async ({ generationId, attemptEpoch, ownerToken, attempt }) => {
|
|
336
|
+
await svc.beginGenerationControlAttempt({
|
|
337
|
+
orgId: conversation.orgId,
|
|
338
|
+
conversationId: conversation.id,
|
|
339
|
+
generationId,
|
|
340
|
+
attemptEpoch,
|
|
341
|
+
ownerToken,
|
|
342
|
+
runtimeType: attempt.runtimeType,
|
|
343
|
+
});
|
|
344
|
+
},
|
|
345
|
+
onHandleRegistered: async ({ generationId, attemptEpoch, ownerToken, handle }) => {
|
|
346
|
+
await svc.markGenerationControlReady({
|
|
347
|
+
generationId,
|
|
348
|
+
attemptEpoch,
|
|
349
|
+
ownerToken,
|
|
350
|
+
runtimeType: handle.runtimeType,
|
|
351
|
+
providerThreadId: handle.providerThreadId ?? null,
|
|
352
|
+
providerTurnId: handle.providerTurnId ?? null,
|
|
353
|
+
});
|
|
354
|
+
},
|
|
355
|
+
onAttemptLeaseRenewed: async ({ generationId, attemptEpoch, ownerToken }) => {
|
|
356
|
+
await svc.renewGenerationControlLease({ generationId, attemptEpoch, ownerToken });
|
|
357
|
+
},
|
|
358
|
+
onAttemptCompleted: async ({ generationId, attemptEpoch, ownerToken }) => {
|
|
359
|
+
await svc.markGenerationControlAttemptCompleted({
|
|
360
|
+
generationId,
|
|
361
|
+
attemptEpoch,
|
|
362
|
+
ownerToken,
|
|
363
|
+
});
|
|
364
|
+
},
|
|
365
|
+
}),
|
|
366
|
+
onAssistantDelta: (delta) => serializeOutputAdmission(async () => {
|
|
367
|
+
if (abortController.signal.aborted)
|
|
368
|
+
return;
|
|
369
|
+
const activeControl = getActiveChatGeneration(conversation.id);
|
|
370
|
+
const attemptEpoch = Math.max(1, activeControl?.attemptEpoch ?? generation?.attemptEpoch ?? 1);
|
|
371
|
+
const projectedBody = `${admittedAssistantBody}${delta}`;
|
|
372
|
+
let committed;
|
|
373
|
+
try {
|
|
374
|
+
committed = await svc.generationProtocol.appendVisibleEventAndProject({
|
|
375
|
+
orgId: conversation.orgId,
|
|
376
|
+
conversationId: conversation.id,
|
|
377
|
+
generationId: generation.id,
|
|
378
|
+
expectedAttemptEpoch: attemptEpoch,
|
|
379
|
+
eventKind: "assistant_delta",
|
|
380
|
+
payload: { delta },
|
|
381
|
+
bodyOffset: admittedAssistantBody.length,
|
|
382
|
+
bodyLength: delta.length,
|
|
383
|
+
messageId: assistantProgressMessageId,
|
|
384
|
+
runId: activeChatRunId,
|
|
385
|
+
bodyHash: hashChatGenerationBody(projectedBody),
|
|
386
|
+
body: projectedBody,
|
|
387
|
+
transcript: [...transcript],
|
|
388
|
+
replyingAgentId: chatReplyingAgentId(assistantInput.conversation),
|
|
389
|
+
chatTurnId: turnContextForPartial.chatTurnId,
|
|
390
|
+
turnVariant: turnContextForPartial.turnVariant,
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
catch (error) {
|
|
394
|
+
if (outputAdmissionClosed(error))
|
|
395
|
+
return;
|
|
396
|
+
throw error;
|
|
397
|
+
}
|
|
398
|
+
assistantProgressMessageId = committed.message.id;
|
|
399
|
+
admittedAssistantBody = projectedBody;
|
|
400
|
+
if (abortController.signal.aborted || clientClosed)
|
|
227
401
|
return;
|
|
228
402
|
writeStreamEvent(res, {
|
|
229
403
|
type: "assistant_delta",
|
|
230
404
|
delta,
|
|
405
|
+
generationId: generation.id,
|
|
406
|
+
attemptEpoch,
|
|
407
|
+
generationSeq: committed.event.generationSeq,
|
|
408
|
+
bodyHash: committed.event.payload.bodyHash,
|
|
231
409
|
});
|
|
232
|
-
},
|
|
233
|
-
onAssistantState: async (
|
|
234
|
-
|
|
410
|
+
}),
|
|
411
|
+
onAssistantState: (state) => serializeOutputAdmission(async () => {
|
|
412
|
+
if (abortController.signal.aborted)
|
|
413
|
+
return;
|
|
235
414
|
if (clientClosed)
|
|
236
415
|
return;
|
|
237
416
|
writeStreamEvent(res, {
|
|
238
417
|
type: "assistant_state",
|
|
239
418
|
state,
|
|
240
419
|
});
|
|
241
|
-
},
|
|
242
|
-
onTranscriptEntry: async (
|
|
420
|
+
}),
|
|
421
|
+
onTranscriptEntry: (entry) => serializeOutputAdmission(async () => {
|
|
422
|
+
if (abortController.signal.aborted)
|
|
423
|
+
return;
|
|
424
|
+
const activeControl = getActiveChatGeneration(conversation.id);
|
|
425
|
+
const attemptEpoch = Math.max(1, activeControl?.attemptEpoch ?? generation?.attemptEpoch ?? 1);
|
|
426
|
+
const projectedTranscript = [...transcript, entry];
|
|
427
|
+
let committed;
|
|
428
|
+
try {
|
|
429
|
+
committed = await svc.generationProtocol.appendVisibleEventAndProject({
|
|
430
|
+
orgId: conversation.orgId,
|
|
431
|
+
conversationId: conversation.id,
|
|
432
|
+
generationId: generation.id,
|
|
433
|
+
expectedAttemptEpoch: attemptEpoch,
|
|
434
|
+
eventKind: "transcript",
|
|
435
|
+
payload: { entry },
|
|
436
|
+
messageId: assistantProgressMessageId,
|
|
437
|
+
runId: activeChatRunId,
|
|
438
|
+
bodyHash: hashChatGenerationBody(admittedAssistantBody),
|
|
439
|
+
body: admittedAssistantBody,
|
|
440
|
+
transcript: projectedTranscript,
|
|
441
|
+
replyingAgentId: chatReplyingAgentId(assistantInput.conversation),
|
|
442
|
+
chatTurnId: turnContextForPartial.chatTurnId,
|
|
443
|
+
turnVariant: turnContextForPartial.turnVariant,
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
catch (error) {
|
|
447
|
+
if (outputAdmissionClosed(error))
|
|
448
|
+
return;
|
|
449
|
+
throw error;
|
|
450
|
+
}
|
|
451
|
+
assistantProgressMessageId = committed.message.id;
|
|
243
452
|
transcript.push(entry);
|
|
244
|
-
|
|
245
|
-
if (clientClosed)
|
|
453
|
+
if (abortController.signal.aborted || clientClosed)
|
|
246
454
|
return;
|
|
247
455
|
writeStreamEvent(res, {
|
|
248
456
|
type: "transcript_entry",
|
|
249
457
|
entry,
|
|
458
|
+
generationId: generation.id,
|
|
459
|
+
attemptEpoch,
|
|
460
|
+
generationSeq: committed.event.generationSeq,
|
|
461
|
+
bodyHash: committed.event.payload.bodyHash,
|
|
250
462
|
});
|
|
251
|
-
},
|
|
463
|
+
}),
|
|
252
464
|
});
|
|
253
|
-
if (streamed.outcome === "stopped") {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
465
|
+
if (abortController.signal.aborted || streamed.outcome === "stopped") {
|
|
466
|
+
await persistStoppedAssistant(assistantInput.conversation, streamed.replyingAgentId, streamed.partialBody);
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
const resultAdmission = await serializeOutputAdmission(async () => {
|
|
470
|
+
if (abortController.signal.aborted)
|
|
471
|
+
return null;
|
|
472
|
+
const activeControl = getActiveChatGeneration(conversation.id);
|
|
473
|
+
const attemptEpoch = Math.max(1, activeControl?.attemptEpoch ?? generation?.attemptEpoch ?? 1);
|
|
474
|
+
try {
|
|
475
|
+
const committed = await svc.generationProtocol.appendVisibleEventAndProject({
|
|
476
|
+
orgId: conversation.orgId,
|
|
477
|
+
conversationId: conversation.id,
|
|
478
|
+
generationId: generation.id,
|
|
479
|
+
expectedAttemptEpoch: attemptEpoch,
|
|
480
|
+
eventKind: "runtime_output",
|
|
481
|
+
payload: {
|
|
482
|
+
resultKind: streamed.reply.kind,
|
|
483
|
+
body: streamed.reply.body,
|
|
484
|
+
},
|
|
485
|
+
bodyOffset: 0,
|
|
486
|
+
bodyLength: streamed.reply.body.length,
|
|
487
|
+
messageId: assistantProgressMessageId,
|
|
488
|
+
runId: activeChatRunId,
|
|
489
|
+
bodyHash: hashChatGenerationBody(streamed.reply.body),
|
|
490
|
+
body: streamed.reply.body,
|
|
491
|
+
transcript: [...transcript],
|
|
492
|
+
replyingAgentId: streamed.replyingAgentId,
|
|
493
|
+
chatTurnId: turnContextForPartial.chatTurnId,
|
|
494
|
+
turnVariant: turnContextForPartial.turnVariant,
|
|
262
495
|
});
|
|
496
|
+
assistantProgressMessageId = committed.message.id;
|
|
497
|
+
admittedAssistantBody = streamed.reply.body;
|
|
498
|
+
return committed;
|
|
263
499
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
});
|
|
269
|
-
res.end();
|
|
500
|
+
catch (error) {
|
|
501
|
+
if (outputAdmissionClosed(error))
|
|
502
|
+
return null;
|
|
503
|
+
throw error;
|
|
270
504
|
}
|
|
505
|
+
});
|
|
506
|
+
if (!resultAdmission) {
|
|
507
|
+
freezeStopCutoff();
|
|
508
|
+
await persistStoppedAssistant(assistantInput.conversation, streamed.replyingAgentId, streamed.partialBody);
|
|
271
509
|
return;
|
|
272
510
|
}
|
|
273
511
|
const createdMessages = await persistAssistantReply(req, assistantInput.conversation, actor, streamed.reply, turnContextForPartial, transcript, streamed.replyingAgentId, assistantProgressMessageId, activeChatRunId);
|
|
@@ -287,12 +525,30 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
287
525
|
}
|
|
288
526
|
}
|
|
289
527
|
catch (error) {
|
|
290
|
-
|
|
528
|
+
if (!abortController.signal.aborted) {
|
|
529
|
+
generationTerminalStatus = "failed";
|
|
530
|
+
}
|
|
291
531
|
throw error;
|
|
292
532
|
}
|
|
293
533
|
}
|
|
294
534
|
}
|
|
295
535
|
catch (err) {
|
|
536
|
+
if (abortController.signal.aborted) {
|
|
537
|
+
try {
|
|
538
|
+
if (stoppedPersistencePromise) {
|
|
539
|
+
await stoppedPersistencePromise;
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
await persistStoppedAssistant(assistantConversationForPartial ?? conversation, chatReplyingAgentId(assistantConversationForPartial ?? conversation), "");
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
catch (stopPersistenceError) {
|
|
546
|
+
logger.warn({ err: stopPersistenceError, conversationId: conversation.id }, "failed to persist stopped chat assistant message");
|
|
547
|
+
if (!clientClosed && !res.writableEnded)
|
|
548
|
+
res.end();
|
|
549
|
+
}
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
296
552
|
const failurePayload = recoverableFailurePayload(err, activeChatRunId);
|
|
297
553
|
const partialBody = userVisiblePartialBodyFromError(err)
|
|
298
554
|
|| recoverableFailureBody(failurePayload)
|
|
@@ -323,11 +579,32 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
323
579
|
}
|
|
324
580
|
}
|
|
325
581
|
finally {
|
|
582
|
+
abortController.signal.removeEventListener("abort", freezeStopCutoff);
|
|
326
583
|
req.off("aborted", handleClosed);
|
|
327
584
|
res.off("close", handleClosed);
|
|
328
585
|
if (generation) {
|
|
329
|
-
await
|
|
330
|
-
|
|
586
|
+
await (async () => {
|
|
587
|
+
const latestGeneration = await svc.getLatestGeneration(conversation.id);
|
|
588
|
+
const expectedAttemptEpoch = latestGeneration?.attemptEpoch
|
|
589
|
+
?? generation?.attemptEpoch
|
|
590
|
+
?? 1;
|
|
591
|
+
await svc.generationProtocol.recordRuntimeTerminal({
|
|
592
|
+
orgId: conversation.orgId,
|
|
593
|
+
conversationId: conversation.id,
|
|
594
|
+
generationId: generation.id,
|
|
595
|
+
expectedAttemptEpoch,
|
|
596
|
+
finalStatus: generationTerminalStatus,
|
|
597
|
+
terminalReason: generationTerminalStatus === "stopped"
|
|
598
|
+
? "operator_stop"
|
|
599
|
+
: generationTerminalStatus,
|
|
600
|
+
payload: {
|
|
601
|
+
assistantMessageId: assistantProgressMessageId,
|
|
602
|
+
runId: activeChatRunId,
|
|
603
|
+
},
|
|
604
|
+
});
|
|
605
|
+
wakeTerminalProjector();
|
|
606
|
+
})().catch((error) => {
|
|
607
|
+
logger.warn({ err: error, generationId: generation?.id }, "failed to record chat generation terminal evidence");
|
|
331
608
|
});
|
|
332
609
|
}
|
|
333
610
|
if (queuedMessageId) {
|
|
@@ -339,32 +616,225 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
339
616
|
logger.warn({ err: error, queuedMessageId }, "failed to mark queued chat message terminal");
|
|
340
617
|
});
|
|
341
618
|
}
|
|
619
|
+
if (startingChatGenerationGates.get(conversation.id) === startupGate) {
|
|
620
|
+
startingChatGenerationGates.delete(conversation.id);
|
|
621
|
+
}
|
|
342
622
|
releaseGeneration();
|
|
623
|
+
wakeServerQueue();
|
|
343
624
|
}
|
|
344
625
|
});
|
|
626
|
+
router.post("/chats/:id/messages/stream/checkpoint", validate(chatClientCheckpointSchema), async (req, res) => {
|
|
627
|
+
const conversation = await assertConversationAccess(req, req.params.id);
|
|
628
|
+
if (!conversation) {
|
|
629
|
+
res.status(404).json({ error: "Chat conversation not found" });
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
assertChatLocalMutationAllowed(conversation);
|
|
633
|
+
await assertSideChatMutationAllowed(req, conversation);
|
|
634
|
+
const checkpoint = await svc.generationProtocol.recordClientCheckpoint({
|
|
635
|
+
orgId: conversation.orgId,
|
|
636
|
+
conversationId: conversation.id,
|
|
637
|
+
generationId: req.body.generationId,
|
|
638
|
+
expectedAttemptEpoch: req.body.attemptEpoch,
|
|
639
|
+
generationSeq: req.body.generationSeq,
|
|
640
|
+
renderedBodyHash: req.body.renderedBodyHash,
|
|
641
|
+
});
|
|
642
|
+
res.json({
|
|
643
|
+
generationId: checkpoint.generation.id,
|
|
644
|
+
generationSeq: checkpoint.generation.lastClientCheckpointSeq,
|
|
645
|
+
advanced: checkpoint.advanced,
|
|
646
|
+
});
|
|
647
|
+
});
|
|
345
648
|
router.post("/chats/:id/messages/stream/stop", async (req, res) => {
|
|
649
|
+
const parsed = stopChatGenerationSchema.safeParse(req.body ?? {});
|
|
650
|
+
if (!parsed.success) {
|
|
651
|
+
res.status(400).json({ error: "Invalid chat Stop request", details: parsed.error.issues });
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
346
654
|
const conversation = await assertConversationAccess(req, req.params.id);
|
|
347
655
|
if (!conversation) {
|
|
348
656
|
res.status(404).json({ error: "Chat conversation not found" });
|
|
349
657
|
return;
|
|
350
658
|
}
|
|
351
659
|
assertChatLocalMutationAllowed(conversation);
|
|
352
|
-
|
|
353
|
-
const
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
660
|
+
await assertSideChatMutationAllowed(req, conversation);
|
|
661
|
+
const controlActionId = parsed.data.controlActionId ?? randomUUID();
|
|
662
|
+
const startupGate = startingChatGenerationGates.get(conversation.id) ?? null;
|
|
663
|
+
let startupStopRequested = false;
|
|
664
|
+
let startupInterruptRequested = false;
|
|
665
|
+
try {
|
|
666
|
+
let active = getActiveChatGeneration(conversation.id);
|
|
667
|
+
if (active && !active.generationId && startupGate) {
|
|
668
|
+
startupStopRequested = true;
|
|
669
|
+
startupGate.stopRequested = true;
|
|
670
|
+
startupInterruptRequested = cancelActiveChatGeneration(conversation.id);
|
|
671
|
+
const startupGenerationId = await startupGate.generationReady;
|
|
672
|
+
active = startupGenerationId ? getActiveChatGeneration(conversation.id) : null;
|
|
673
|
+
if (!startupGenerationId) {
|
|
674
|
+
res.json({
|
|
675
|
+
stopped: startupInterruptRequested,
|
|
676
|
+
controlActionId,
|
|
677
|
+
generationId: null,
|
|
678
|
+
disposition: startupInterruptRequested ? "startup_cancelled" : "interrupted_unverified",
|
|
679
|
+
});
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
const latestActiveGeneration = active?.generationId
|
|
684
|
+
? null
|
|
685
|
+
: await svc.getLatestActiveGeneration(conversation.id);
|
|
686
|
+
const generationId = parsed.data.expectedGenerationId
|
|
687
|
+
?? active?.generationId
|
|
688
|
+
?? latestActiveGeneration?.id
|
|
689
|
+
?? null;
|
|
690
|
+
if (!generationId) {
|
|
691
|
+
res.json({
|
|
692
|
+
stopped: false,
|
|
693
|
+
controlActionId,
|
|
694
|
+
generationId: null,
|
|
695
|
+
disposition: "no_active_generation",
|
|
696
|
+
});
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
let durableCheckpoint = await svc.generationProtocol.getLatestVisibleCheckpoint({
|
|
700
|
+
orgId: conversation.orgId,
|
|
701
|
+
conversationId: conversation.id,
|
|
702
|
+
generationId,
|
|
703
|
+
});
|
|
704
|
+
if (durableCheckpoint.generation.runtimeTerminalAt && !parsed.data.controlActionId) {
|
|
705
|
+
wakeTerminalProjector();
|
|
706
|
+
res.json({
|
|
707
|
+
stopped: false,
|
|
708
|
+
controlActionId,
|
|
709
|
+
generationId,
|
|
710
|
+
disposition: "no_active_generation",
|
|
711
|
+
});
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
const expectedAttemptEpoch = parsed.data.expectedAttemptEpoch
|
|
715
|
+
?? durableCheckpoint.generation.attemptEpoch;
|
|
716
|
+
const requestedRenderSeq = parsed.data.lastCommittedRenderSeq
|
|
717
|
+
?? durableCheckpoint.generationSeq;
|
|
718
|
+
const requestedBodyHash = parsed.data.renderedBodyHash
|
|
719
|
+
?? durableCheckpoint.bodyHash;
|
|
720
|
+
let stop = null;
|
|
721
|
+
for (let attempt = 0; attempt < 2 && !stop; attempt += 1) {
|
|
722
|
+
try {
|
|
723
|
+
stop = await svc.generationProtocol.beginStopAction({
|
|
724
|
+
orgId: conversation.orgId,
|
|
725
|
+
conversationId: conversation.id,
|
|
726
|
+
controlActionId,
|
|
727
|
+
expectedGenerationId: generationId,
|
|
728
|
+
expectedAttemptEpoch,
|
|
729
|
+
expectedControlVersion: parsed.data.expectedControlVersion
|
|
730
|
+
?? durableCheckpoint.generation.controlVersion,
|
|
731
|
+
requestedRenderSeq,
|
|
732
|
+
requestedBodyHash,
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
catch (error) {
|
|
736
|
+
const status = error && typeof error === "object" && "status" in error
|
|
737
|
+
? Number(error.status)
|
|
738
|
+
: null;
|
|
739
|
+
if (attempt > 0 || status !== 409)
|
|
740
|
+
throw error;
|
|
741
|
+
durableCheckpoint = await svc.generationProtocol.getLatestVisibleCheckpoint({
|
|
742
|
+
orgId: conversation.orgId,
|
|
743
|
+
conversationId: conversation.id,
|
|
744
|
+
generationId,
|
|
745
|
+
});
|
|
746
|
+
if (durableCheckpoint.generation.runtimeTerminalAt && !parsed.data.controlActionId) {
|
|
747
|
+
wakeTerminalProjector();
|
|
748
|
+
res.json({
|
|
749
|
+
stopped: false,
|
|
750
|
+
controlActionId,
|
|
751
|
+
generationId,
|
|
752
|
+
disposition: "no_active_generation",
|
|
753
|
+
});
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
if (durableCheckpoint.generation.attemptEpoch !== expectedAttemptEpoch)
|
|
757
|
+
throw error;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
if (!stop)
|
|
761
|
+
throw new Error("Failed to establish the chat Stop cutoff");
|
|
762
|
+
if (stop.idempotent
|
|
763
|
+
&& parsed.data.expectedControlVersion !== undefined
|
|
764
|
+
&& stop.action.expectedControlVersion !== parsed.data.expectedControlVersion) {
|
|
765
|
+
throw conflict("Control action id was already used for a different Stop request");
|
|
766
|
+
}
|
|
767
|
+
if (stop.outcome === "completion_committed") {
|
|
768
|
+
res.json({
|
|
769
|
+
stopped: false,
|
|
770
|
+
controlActionId,
|
|
771
|
+
generationId,
|
|
772
|
+
disposition: "completion_committed",
|
|
773
|
+
});
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
if (stop.idempotent && stop.generation.runtimeTerminalAt) {
|
|
777
|
+
const terminalDisposition = stop.generation.status === "stopped"
|
|
778
|
+
|| stop.action.localDisposition === "stopped"
|
|
779
|
+
? "stopped"
|
|
780
|
+
: "stopping";
|
|
781
|
+
wakeTerminalProjector();
|
|
782
|
+
res.json({
|
|
783
|
+
stopped: true,
|
|
784
|
+
controlActionId,
|
|
785
|
+
generationId,
|
|
786
|
+
disposition: terminalDisposition,
|
|
787
|
+
acceptedThroughSeq: stop.action.acceptedThroughSeq,
|
|
788
|
+
frozenBodyHash: stop.action.frozenBodyHash,
|
|
789
|
+
});
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
const localInterruptRequested = startupInterruptRequested || cancelActiveChatGeneration(conversation.id);
|
|
793
|
+
let disposition = "stopping";
|
|
794
|
+
if (startupStopRequested) {
|
|
795
|
+
await svc.generationProtocol.recordRuntimeTerminal({
|
|
796
|
+
orgId: conversation.orgId,
|
|
797
|
+
conversationId: conversation.id,
|
|
798
|
+
generationId,
|
|
799
|
+
expectedAttemptEpoch: stop.generation.attemptEpoch,
|
|
800
|
+
finalStatus: "stopped",
|
|
801
|
+
terminalReason: "operator_stop",
|
|
802
|
+
controlActionId,
|
|
803
|
+
});
|
|
804
|
+
wakeTerminalProjector();
|
|
805
|
+
}
|
|
806
|
+
else if (!localInterruptRequested) {
|
|
807
|
+
disposition = "interrupted_unverified";
|
|
808
|
+
await svc.generationProtocol.recordRuntimeTerminal({
|
|
809
|
+
orgId: conversation.orgId,
|
|
810
|
+
conversationId: conversation.id,
|
|
811
|
+
generationId,
|
|
812
|
+
expectedAttemptEpoch: stop.generation.attemptEpoch,
|
|
813
|
+
finalStatus: "interrupted_unverified",
|
|
814
|
+
terminalReason: "stop_without_local_runtime_owner",
|
|
815
|
+
controlActionId,
|
|
816
|
+
});
|
|
817
|
+
wakeTerminalProjector();
|
|
818
|
+
}
|
|
819
|
+
res.json({
|
|
820
|
+
stopped: Boolean(localInterruptRequested),
|
|
821
|
+
controlActionId,
|
|
822
|
+
generationId,
|
|
823
|
+
disposition,
|
|
824
|
+
acceptedThroughSeq: stop.action.acceptedThroughSeq,
|
|
825
|
+
frozenBodyHash: stop.action.frozenBodyHash,
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
finally {
|
|
829
|
+
if (startupStopRequested)
|
|
830
|
+
startupGate?.resolveStopApplied();
|
|
831
|
+
}
|
|
362
832
|
});
|
|
363
833
|
router.post("/orgs/:orgId/chats/:chatId/attachments", async (req, res) => {
|
|
364
834
|
const orgId = req.params.orgId;
|
|
365
835
|
const chatId = req.params.chatId;
|
|
366
836
|
assertCompanyAccess(req, orgId);
|
|
367
|
-
const conversation = await
|
|
837
|
+
const conversation = await assertConversationAccess(req, chatId);
|
|
368
838
|
if (!conversation) {
|
|
369
839
|
res.status(404).json({ error: "Chat conversation not found" });
|
|
370
840
|
return;
|
|
@@ -374,6 +844,7 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
374
844
|
return;
|
|
375
845
|
}
|
|
376
846
|
assertChatLocalMutationAllowed(conversation);
|
|
847
|
+
await assertSideChatMutationAllowed(req, conversation);
|
|
377
848
|
try {
|
|
378
849
|
await runSingleFileUpload(req, res);
|
|
379
850
|
}
|
|
@@ -453,6 +924,7 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
453
924
|
return;
|
|
454
925
|
}
|
|
455
926
|
assertChatLocalMutationAllowed(conversation);
|
|
927
|
+
await assertSideChatMutationAllowed(req, conversation);
|
|
456
928
|
await assertContextLinksBelongToCompany(conversation.orgId, [req.body]);
|
|
457
929
|
const linked = await svc.addContextLink(conversation.id, conversation.orgId, req.body);
|
|
458
930
|
const actor = getActorInfo(req);
|
|
@@ -476,6 +948,7 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
476
948
|
return;
|
|
477
949
|
}
|
|
478
950
|
assertChatLocalMutationAllowed(conversation);
|
|
951
|
+
await assertSideChatMutationAllowed(req, conversation);
|
|
479
952
|
const projectId = req.body.projectId ?? null;
|
|
480
953
|
if (projectId) {
|
|
481
954
|
await assertContextLinksBelongToCompany(conversation.orgId, [{
|
|
@@ -514,6 +987,7 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
514
987
|
return;
|
|
515
988
|
}
|
|
516
989
|
assertChatLocalMutationAllowed(conversation);
|
|
990
|
+
await assertSideChatMutationAllowed(req, conversation);
|
|
517
991
|
const actor = getActorInfo(req);
|
|
518
992
|
if (req.body.proposal?.goalId) {
|
|
519
993
|
const goal = await goalsSvc.getById(req.body.proposal.goalId);
|
|
@@ -577,6 +1051,7 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
577
1051
|
return;
|
|
578
1052
|
}
|
|
579
1053
|
assertChatLocalMutationAllowed(conversation);
|
|
1054
|
+
await assertSideChatMutationAllowed(req, conversation);
|
|
580
1055
|
const actor = getActorInfo(req);
|
|
581
1056
|
const messageId = req.params.messageId;
|
|
582
1057
|
const resolved = await svc.resolveOperationProposal(conversation.id, messageId, {
|
|
@@ -593,6 +1068,7 @@ export function registerChatStreamRoutes(ctx) {
|
|
|
593
1068
|
return;
|
|
594
1069
|
}
|
|
595
1070
|
assertChatLocalMutationAllowed(conversation);
|
|
1071
|
+
await assertSideChatMutationAllowed(req, conversation);
|
|
596
1072
|
const resolved = await svc.resolve(conversation.id);
|
|
597
1073
|
const actor = getActorInfo(req);
|
|
598
1074
|
await logActivity(db, {
|