@rudderhq/server 0.5.0 → 0.5.1
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 +56 -1
- package/dist/agent-runtimes/http/execute.js.map +1 -1
- package/dist/agent-runtimes/http/index.d.ts.map +1 -1
- package/dist/agent-runtimes/http/index.js +10 -0
- package/dist/agent-runtimes/http/index.js.map +1 -1
- package/dist/agent-runtimes/process/execute.d.ts.map +1 -1
- package/dist/agent-runtimes/process/execute.js +9 -1
- package/dist/agent-runtimes/process/execute.js.map +1 -1
- package/dist/agent-runtimes/process/index.d.ts.map +1 -1
- package/dist/agent-runtimes/process/index.js +7 -0
- package/dist/agent-runtimes/process/index.js.map +1 -1
- package/dist/agent-runtimes/registry.d.ts.map +1 -1
- package/dist/agent-runtimes/registry.js +21 -1
- package/dist/agent-runtimes/registry.js.map +1 -1
- package/dist/agent-runtimes/utils.d.ts +1 -0
- package/dist/agent-runtimes/utils.d.ts.map +1 -1
- package/dist/agent-runtimes/utils.js.map +1 -1
- package/dist/bundled-plugins/plugin-linear/dist/worker.js +183 -10
- package/dist/bundled-plugins/plugin-linear/dist/worker.js.map +3 -3
- package/dist/home-paths.d.ts +7 -0
- package/dist/home-paths.d.ts.map +1 -1
- package/dist/home-paths.js +46 -2
- package/dist/home-paths.js.map +1 -1
- package/dist/index.js +23 -4
- package/dist/index.js.map +1 -1
- package/dist/routes/access.d.ts.map +1 -1
- package/dist/routes/access.helpers.d.ts +1 -1
- package/dist/routes/access.helpers.d.ts.map +1 -1
- package/dist/routes/access.helpers.js +0 -3
- package/dist/routes/access.helpers.js.map +1 -1
- package/dist/routes/access.js +0 -4
- package/dist/routes/access.js.map +1 -1
- package/dist/routes/agents.js +2 -2
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/chats.d.ts.map +1 -1
- package/dist/routes/chats.generated-attachments.d.ts +16 -0
- package/dist/routes/chats.generated-attachments.d.ts.map +1 -0
- package/dist/routes/chats.generated-attachments.js +157 -0
- package/dist/routes/chats.generated-attachments.js.map +1 -0
- package/dist/routes/chats.helpers.d.ts +27 -0
- package/dist/routes/chats.helpers.d.ts.map +1 -0
- package/dist/routes/chats.helpers.js +52 -0
- package/dist/routes/chats.helpers.js.map +1 -0
- package/dist/routes/chats.js +126 -188
- 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 +185 -16
- package/dist/routes/chats.stream-routes.js.map +1 -1
- package/dist/routes/llms.js +3 -3
- package/dist/routes/llms.js.map +1 -1
- package/dist/routes/messenger.d.ts.map +1 -1
- package/dist/routes/messenger.js +48 -6
- package/dist/routes/messenger.js.map +1 -1
- package/dist/services/activity.d.ts.map +1 -1
- package/dist/services/activity.js +7 -2
- package/dist/services/activity.js.map +1 -1
- package/dist/services/agents.d.ts +65 -65
- package/dist/services/agents.d.ts.map +1 -1
- package/dist/services/agents.js +5 -4
- package/dist/services/agents.js.map +1 -1
- package/dist/services/approvals.d.ts +1 -1
- package/dist/services/assets.d.ts +2 -2
- package/dist/services/automation-chat-output.d.ts +1 -1
- package/dist/services/automation-chat-output.d.ts.map +1 -1
- package/dist/services/automation-chat-output.js +38 -23
- package/dist/services/automation-chat-output.js.map +1 -1
- package/dist/services/automations.d.ts.map +1 -1
- package/dist/services/automations.js +39 -41
- package/dist/services/automations.js.map +1 -1
- package/dist/services/budgets.d.ts +1 -1
- package/dist/services/chat-assistant.d.ts +23 -1
- package/dist/services/chat-assistant.d.ts.map +1 -1
- package/dist/services/chat-assistant.helpers.d.ts +21 -0
- package/dist/services/chat-assistant.helpers.d.ts.map +1 -1
- package/dist/services/chat-assistant.helpers.js +29 -10
- package/dist/services/chat-assistant.helpers.js.map +1 -1
- package/dist/services/chat-assistant.inline-visuals.d.ts +23 -0
- package/dist/services/chat-assistant.inline-visuals.d.ts.map +1 -0
- package/dist/services/chat-assistant.inline-visuals.js +129 -0
- package/dist/services/chat-assistant.inline-visuals.js.map +1 -0
- package/dist/services/chat-assistant.inline-visuals.test.js +85 -1
- package/dist/services/chat-assistant.inline-visuals.test.js.map +1 -1
- package/dist/services/chat-assistant.js +262 -38
- package/dist/services/chat-assistant.js.map +1 -1
- package/dist/services/chat-family-groups.d.ts +14 -0
- package/dist/services/chat-family-groups.d.ts.map +1 -0
- package/dist/services/chat-family-groups.js +96 -0
- package/dist/services/chat-family-groups.js.map +1 -0
- package/dist/services/chat-generation-protocol.d.ts +17 -31
- package/dist/services/chat-generation-protocol.d.ts.map +1 -1
- package/dist/services/chat-generation-protocol.helpers.d.ts +36 -0
- package/dist/services/chat-generation-protocol.helpers.d.ts.map +1 -0
- package/dist/services/chat-generation-protocol.helpers.js +53 -0
- package/dist/services/chat-generation-protocol.helpers.js.map +1 -0
- package/dist/services/chat-generation-protocol.js +86 -55
- package/dist/services/chat-generation-protocol.js.map +1 -1
- package/dist/services/chat-generation-protocol.test.js +31 -3
- package/dist/services/chat-generation-protocol.test.js.map +1 -1
- package/dist/services/chat-steer-messages.d.ts +117 -0
- package/dist/services/chat-steer-messages.d.ts.map +1 -0
- package/dist/services/chat-steer-messages.js +410 -0
- package/dist/services/chat-steer-messages.js.map +1 -0
- package/dist/services/chat-title-generation.d.ts +1 -0
- package/dist/services/chat-title-generation.d.ts.map +1 -1
- package/dist/services/chat-title-generation.js +12 -9
- 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 +39 -2
- package/dist/services/chat-work-manifest.js.map +1 -1
- package/dist/services/chats.constants.d.ts +5 -0
- package/dist/services/chats.constants.d.ts.map +1 -0
- package/dist/services/chats.constants.js +13 -0
- package/dist/services/chats.constants.js.map +1 -0
- package/dist/services/chats.create.d.ts +75 -0
- package/dist/services/chats.create.d.ts.map +1 -0
- package/dist/services/chats.create.js +159 -0
- package/dist/services/chats.create.js.map +1 -0
- package/dist/services/chats.d.ts +85 -76
- package/dist/services/chats.d.ts.map +1 -1
- package/dist/services/chats.fork-helpers.d.ts +8 -0
- package/dist/services/chats.fork-helpers.d.ts.map +1 -0
- package/dist/services/chats.fork-helpers.js +45 -0
- package/dist/services/chats.fork-helpers.js.map +1 -0
- package/dist/services/chats.inline-visual-persistence.d.ts +30 -0
- package/dist/services/chats.inline-visual-persistence.d.ts.map +1 -0
- package/dist/services/chats.inline-visual-persistence.js +209 -0
- package/dist/services/chats.inline-visual-persistence.js.map +1 -0
- package/dist/services/chats.js +288 -273
- package/dist/services/chats.js.map +1 -1
- package/dist/services/chats.types.d.ts +31 -0
- package/dist/services/chats.types.d.ts.map +1 -0
- package/dist/services/chats.types.js +2 -0
- package/dist/services/chats.types.js.map +1 -0
- package/dist/services/integrations/feishu/inbound-dispatcher-db.d.ts.map +1 -1
- package/dist/services/integrations/feishu/inbound-dispatcher-db.js +81 -53
- package/dist/services/integrations/feishu/inbound-dispatcher-db.js.map +1 -1
- package/dist/services/integrations/feishu/inbound-dispatcher.d.ts +1 -0
- package/dist/services/integrations/feishu/inbound-dispatcher.d.ts.map +1 -1
- package/dist/services/integrations/feishu/inbound-dispatcher.js.map +1 -1
- package/dist/services/issues.comments-attachments.d.ts.map +1 -1
- package/dist/services/issues.comments-attachments.js +11 -2
- package/dist/services/issues.comments-attachments.js.map +1 -1
- package/dist/services/issues.d.ts.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/knowledge-portability/organization-skills.d.ts.map +1 -1
- package/dist/services/knowledge-portability/organization-skills.js +13 -1
- package/dist/services/knowledge-portability/organization-skills.js.map +1 -1
- package/dist/services/messenger-run-origin.d.ts +18 -0
- package/dist/services/messenger-run-origin.d.ts.map +1 -0
- package/dist/services/messenger-run-origin.js +248 -0
- package/dist/services/messenger-run-origin.js.map +1 -0
- package/dist/services/messenger-run-summary.d.ts +4 -0
- package/dist/services/messenger-run-summary.d.ts.map +1 -0
- package/dist/services/messenger-run-summary.js +6 -0
- package/dist/services/messenger-run-summary.js.map +1 -0
- package/dist/services/messenger-saved-views.d.ts +133 -0
- package/dist/services/messenger-saved-views.d.ts.map +1 -0
- package/dist/services/messenger-saved-views.js +275 -0
- package/dist/services/messenger-saved-views.js.map +1 -0
- package/dist/services/messenger.d.ts +17 -3
- package/dist/services/messenger.d.ts.map +1 -1
- package/dist/services/messenger.js +276 -56
- package/dist/services/messenger.js.map +1 -1
- package/dist/services/operator-event-visibility.d.ts +3 -0
- package/dist/services/operator-event-visibility.d.ts.map +1 -0
- package/dist/services/operator-event-visibility.js +5 -0
- package/dist/services/operator-event-visibility.js.map +1 -0
- package/dist/services/orgs.d.ts +5 -5
- package/dist/services/plugin-registry.d.ts +4 -4
- package/dist/services/projects.d.ts +2 -2
- package/dist/services/run-intelligence.d.ts.map +1 -1
- package/dist/services/run-intelligence.js +7 -3
- package/dist/services/run-intelligence.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.core.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.core.js +9 -8
- package/dist/services/runtime-kernel/heartbeat.core.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.d.ts +2 -2
- package/dist/services/runtime-kernel/heartbeat.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.js +3 -2
- package/dist/services/runtime-kernel/heartbeat.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.misc.js +1 -1
- package/dist/services/runtime-kernel/heartbeat.misc.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.recovery.js +1 -1
- package/dist/services/runtime-kernel/heartbeat.recovery.js.map +1 -1
- package/dist/services/side-chats.d.ts +1 -46
- package/dist/services/side-chats.d.ts.map +1 -1
- package/dist/services/side-chats.js +58 -65
- package/dist/services/side-chats.js.map +1 -1
- package/dist/services/title-generation.d.ts +3 -0
- package/dist/services/title-generation.d.ts.map +1 -1
- package/dist/services/title-generation.js +178 -6
- package/dist/services/title-generation.js.map +1 -1
- package/dist/services/workspace-backups.d.ts +19 -8
- package/dist/services/workspace-backups.d.ts.map +1 -1
- package/dist/services/workspace-backups.js +335 -127
- package/dist/services/workspace-backups.js.map +1 -1
- package/package.json +14 -13
- package/resources/bundled-skills/browser/references/tool-contract.md +2 -2
- package/resources/bundled-skills/rudder-docs/SKILL.md +20 -4
- package/resources/bundled-skills/rudder-docs/evals/retrieval-authority-evals.json +262 -0
- package/resources/bundled-skills/rudder-docs/evals/trigger-evals.json +11 -11
- package/resources/bundled-skills/rudder-docs/references/agent-creation.md +153 -0
- package/resources/bundled-skills/rudder-docs/references/api-reference.md +9 -2
- package/resources/bundled-skills/rudder-docs/references/cli-reference.md +12 -12
- package/{skills/rudder-docs/references/control-plane-practices.md → resources/bundled-skills/rudder-docs/references/operating-practices.md} +4 -4
- package/resources/bundled-skills/rudder-docs/references/organization-skills.md +3 -3
- package/resources/bundled-skills/rudder-docs/references/plugin-authoring.md +116 -0
- package/resources/bundled-skills/rudder-docs/references/source-map.md +26 -2
- package/resources/bundled-skills/visualize/SKILL.md +29 -27
- package/resources/bundled-skills/visualize/references/runtime-contract.md +18 -8
- package/skills/browser/references/tool-contract.md +2 -2
- package/skills/rudder-docs/SKILL.md +20 -4
- package/skills/rudder-docs/evals/retrieval-authority-evals.json +262 -0
- package/skills/rudder-docs/evals/trigger-evals.json +11 -11
- package/skills/rudder-docs/references/agent-creation.md +153 -0
- package/skills/rudder-docs/references/api-reference.md +9 -2
- package/skills/rudder-docs/references/cli-reference.md +12 -12
- package/{resources/bundled-skills/rudder-docs/references/control-plane-practices.md → skills/rudder-docs/references/operating-practices.md} +4 -4
- package/skills/rudder-docs/references/organization-skills.md +3 -3
- package/skills/rudder-docs/references/plugin-authoring.md +116 -0
- package/skills/rudder-docs/references/source-map.md +26 -2
- package/skills/visualize/SKILL.md +29 -27
- package/skills/visualize/references/runtime-contract.md +18 -8
- package/ui-dist/assets/{abnfDiagram-VRR7QNED-Dpnx79fp.js → abnfDiagram-VRR7QNED-CAAPm9Nj.js} +1 -1
- package/ui-dist/assets/{arc-Cpvh_rCf.js → arc-DOFoNr3M.js} +1 -1
- package/ui-dist/assets/{architectureDiagram-ZJ3FMSHR-sDD_mBAI.js → architectureDiagram-ZJ3FMSHR-DRg6yhG8.js} +1 -1
- package/ui-dist/assets/{blockDiagram-677ZJIJ3-4O4wWti1.js → blockDiagram-677ZJIJ3-e3ShzsXT.js} +1 -1
- package/ui-dist/assets/{c4Diagram-LMCZKHZV-BkGODE4P.js → c4Diagram-LMCZKHZV-Csd_18O2.js} +1 -1
- package/ui-dist/assets/channel-BFLsBJOK.js +1 -0
- package/ui-dist/assets/{chunk-2Q5K7J3B-DsDQQpID.js → chunk-2Q5K7J3B-eF77FV1C.js} +1 -1
- package/ui-dist/assets/{chunk-32BRIVSS-Bzx_VnIw.js → chunk-32BRIVSS-CpMx72B5.js} +1 -1
- package/ui-dist/assets/{chunk-5VM5RSS4-D4LoPCni.js → chunk-5VM5RSS4-Be6WylCu.js} +1 -1
- package/ui-dist/assets/{chunk-EX3LRPZG-BO0R-mS4.js → chunk-EX3LRPZG-D-A_TfL-.js} +1 -1
- package/ui-dist/assets/{chunk-JWPE2WC7-B4Nr8KRL.js → chunk-JWPE2WC7-CdBLDqvo.js} +1 -1
- package/ui-dist/assets/{chunk-MOJQB5TN--uaDDrYM.js → chunk-MOJQB5TN-DkLjRENV.js} +1 -1
- package/ui-dist/assets/{chunk-RYQCIY6F-CyBY2w_j.js → chunk-RYQCIY6F-57VqTsE9.js} +1 -1
- package/ui-dist/assets/{chunk-V7JOEXUC-BMid_x8S.js → chunk-V7JOEXUC-DI_m8pt6.js} +1 -1
- package/ui-dist/assets/{chunk-VR4S4FIN-DVqdPKuG.js → chunk-VR4S4FIN-CM_944j4.js} +1 -1
- package/ui-dist/assets/{chunk-XXDRQBXY-vy03lLSS.js → chunk-XXDRQBXY--WTAlt82.js} +1 -1
- package/ui-dist/assets/classDiagram-OUVF2IWQ-Dah6C4Dl.js +1 -0
- package/ui-dist/assets/classDiagram-v2-EOCWNBFH-Dah6C4Dl.js +1 -0
- package/ui-dist/assets/{cose-bilkent-JH36ORCC-jQDZmrG3.js → cose-bilkent-JH36ORCC-CR0qu31s.js} +1 -1
- package/ui-dist/assets/{cynefin-VYW2F7L2-BxBj6aea.js → cynefin-VYW2F7L2-f41lF5RD.js} +1 -1
- package/ui-dist/assets/{cynefinDiagram-TSTJHNR4-BuUubF5I.js → cynefinDiagram-TSTJHNR4-88wJ2LA8.js} +1 -1
- package/ui-dist/assets/{dagre-VKFMJZFB-B8HipJ3a.js → dagre-VKFMJZFB-B1yJCIRh.js} +1 -1
- package/ui-dist/assets/{diagram-FQU43EPY-r7gkbKSt.js → diagram-FQU43EPY-C0iYYFUe.js} +1 -1
- package/ui-dist/assets/{diagram-G47NLZAW-CxClRsxD.js → diagram-G47NLZAW-Cp6S0siK.js} +1 -1
- package/ui-dist/assets/{diagram-NH7WQ7WH-C8HYTLlq.js → diagram-NH7WQ7WH-CmZb5OSk.js} +1 -1
- package/ui-dist/assets/{diagram-OA4YK3LP-CjwqqLKz.js → diagram-OA4YK3LP-9rFYGY7H.js} +1 -1
- package/ui-dist/assets/{diagram-WEI45ONY-2IWfCqZb.js → diagram-WEI45ONY-Og8vyDQh.js} +1 -1
- package/ui-dist/assets/{ebnfDiagram-CCIWWBDH-DVGZkgjy.js → ebnfDiagram-CCIWWBDH--5sMape2.js} +1 -1
- package/ui-dist/assets/{erDiagram-Q63AITRT-C_-u3Gmw.js → erDiagram-Q63AITRT-DG10Bza-.js} +1 -1
- package/ui-dist/assets/{flowDiagram-23GEKE2U-BvGg0NCq.js → flowDiagram-23GEKE2U-BW-aZfEk.js} +1 -1
- package/ui-dist/assets/{ganttDiagram-NO4QXBWP-U3CZUUUR.js → ganttDiagram-NO4QXBWP-DcA7on8t.js} +1 -1
- package/ui-dist/assets/{gitGraphDiagram-IHSO6WYX-CIWuEBIo.js → gitGraphDiagram-IHSO6WYX-ygGufg32.js} +1 -1
- package/ui-dist/assets/{graph-D3P5q-7m.js → graph-BXl6uBoM.js} +1 -1
- package/ui-dist/assets/{index-DOPIV8vd.js → index-9bXlV2sq.js} +1 -1
- package/ui-dist/assets/{index-CjztBLJi.js → index-B58ems-F.js} +1 -1
- package/ui-dist/assets/{index-mnl55Stn.js → index-BM-SJNCx.js} +1 -1
- package/ui-dist/assets/index-BcdA9dZc.css +1 -0
- package/ui-dist/assets/{index-BAgtKYR1.js → index-BmTNDbzy.js} +1 -1
- package/ui-dist/assets/{index-DidCCw78.js → index-CCDynlok.js} +1 -1
- package/ui-dist/assets/{index-CbHqnWUe.js → index-CRLl2Ck7.js} +1 -1
- package/ui-dist/assets/{index-D7ycf1qU.js → index-CqmU1PxY.js} +1 -1
- package/ui-dist/assets/{index-B1rLBtZ1.js → index-CssgLJwf.js} +605 -493
- package/ui-dist/assets/{index-DRxLJD40.js → index-DOVMMhyj.js} +1 -1
- package/ui-dist/assets/{index-Ds_qma4-.js → index-DTlR8bJV.js} +1 -1
- package/ui-dist/assets/{index-DCFf9dps.js → index-Dl6nXXNc.js} +1 -1
- package/ui-dist/assets/{index-DAYlwxsg.js → index-DoiNhQrY.js} +1 -1
- package/ui-dist/assets/{index-CBOr9F6w.js → index-Dug5GX1J.js} +1 -1
- package/ui-dist/assets/{index-HkQRx1D6.js → index-DxXOCTVe.js} +1 -1
- package/ui-dist/assets/{index-BAMXpiI5.js → index-GdN-7KLt.js} +1 -1
- package/ui-dist/assets/{index-ikpL--zj.js → index-ZA8lPH2n.js} +1 -1
- package/ui-dist/assets/{index-Cu1iMhjl.js → index-fkDP349f.js} +1 -1
- package/ui-dist/assets/{index-DYMtCDKT.js → index-uKIvv9n9.js} +1 -1
- package/ui-dist/assets/{infoDiagram-FWYZ7A6U-Cx8Fa-I4.js → infoDiagram-FWYZ7A6U-27INMkBm.js} +1 -1
- package/ui-dist/assets/{ishikawaDiagram-FXEZZL3T-Cmuz1QUN.js → ishikawaDiagram-FXEZZL3T-Bp6XQ1_r.js} +1 -1
- package/ui-dist/assets/{journeyDiagram-5HDEW3XC-CJgkiVXG.js → journeyDiagram-5HDEW3XC-9vaIwdZ3.js} +1 -1
- package/ui-dist/assets/{kanban-definition-HUTT4EX6-RAWpefOB.js → kanban-definition-HUTT4EX6-DjsMaR6l.js} +1 -1
- package/ui-dist/assets/{layout-DyWQv0Rr.js → layout-C0oWcIiC.js} +1 -1
- package/ui-dist/assets/{linear-D5pdgIf9.js → linear-DNbmenmQ.js} +1 -1
- package/ui-dist/assets/{map-bVSzNLl2.js → map-B1s9kpcR.js} +1 -1
- package/ui-dist/assets/{mermaid.core-CeaXGD6B.js → mermaid.core-DsYT9DxL.js} +4 -4
- package/ui-dist/assets/{mindmap-definition-LN4V7U3C-B8B8AX5C.js → mindmap-definition-LN4V7U3C-vVHeRI83.js} +1 -1
- package/ui-dist/assets/{pegDiagram-2B236MQR-C4Sv-ua6.js → pegDiagram-2B236MQR-ohrgWLo_.js} +1 -1
- package/ui-dist/assets/{pieDiagram-ENE6RG2P-CLARlOHx.js → pieDiagram-ENE6RG2P-B0EqPrjn.js} +1 -1
- package/ui-dist/assets/{quadrantDiagram-ABIIQ3AL-DPCXQmeT.js → quadrantDiagram-ABIIQ3AL-D44iYm0o.js} +1 -1
- package/ui-dist/assets/{railroadDiagram-RFXS5EU6-BpqRuKUQ.js → railroadDiagram-RFXS5EU6-BQU5bpbU.js} +1 -1
- package/ui-dist/assets/{requirementDiagram-TGXJPOKE-Dd-h62HZ.js → requirementDiagram-TGXJPOKE-DGJciRxB.js} +1 -1
- package/ui-dist/assets/{sankeyDiagram-HTMAVEWB-DylT_pqq.js → sankeyDiagram-HTMAVEWB-NMXZW_Qb.js} +1 -1
- package/ui-dist/assets/{sequenceDiagram-DBY2YBRQ-RiCF1REj.js → sequenceDiagram-DBY2YBRQ-8uWY67Bb.js} +1 -1
- package/ui-dist/assets/{sizeCapture-X5ZJPWSS-DXW4JQz2.js → sizeCapture-X5ZJPWSS-BnUUR-On.js} +1 -1
- package/ui-dist/assets/{stateDiagram-2N3HPSRC-6U3ESIGT.js → stateDiagram-2N3HPSRC-B37bcKMy.js} +1 -1
- package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-p6H0vL7N.js +1 -0
- package/ui-dist/assets/{swimlanes-5IMT3BWC-CeNHVNCi.js → swimlanes-5IMT3BWC-Bi2ZzUMi.js} +2 -2
- package/ui-dist/assets/swimlanesDiagram-G3AALYLV-BX6FiLF9.js +8 -0
- package/ui-dist/assets/{timeline-definition-FHXFAJF6-Vlwoe_1b.js → timeline-definition-FHXFAJF6-CkWauU5D.js} +1 -1
- package/ui-dist/assets/{vennDiagram-L72KCM5P-DBP7D3HE.js → vennDiagram-L72KCM5P-BrmBXmnk.js} +1 -1
- package/ui-dist/assets/{wardleyDiagram-EHGQE667-DG-wzqpy.js → wardleyDiagram-EHGQE667-kO5cojc6.js} +1 -1
- package/ui-dist/assets/{xychartDiagram-FW5EYKEG-BAq3mbha.js → xychartDiagram-FW5EYKEG-CUBDaCDm.js} +1 -1
- package/ui-dist/index.html +5 -4
- package/resources/bundled-skills/rudder-create-agent/SKILL.md +0 -185
- package/resources/bundled-skills/rudder-create-agent/references/api-reference.md +0 -179
- package/resources/bundled-skills/rudder-create-agent/references/cli-reference.md +0 -132
- package/resources/bundled-skills/rudder-create-plugin/SKILL.md +0 -103
- package/resources/bundled-skills/skill-optimizer/CHANGELOG.md +0 -29
- package/resources/bundled-skills/skill-optimizer/SKILL.md +0 -205
- package/resources/bundled-skills/skill-optimizer/references/adapters/creative-brand-content.md +0 -30
- package/resources/bundled-skills/skill-optimizer/references/adapters/customer-support-sales.md +0 -30
- package/resources/bundled-skills/skill-optimizer/references/adapters/document-data-processing.md +0 -31
- package/resources/bundled-skills/skill-optimizer/references/adapters/education-training.md +0 -31
- package/resources/bundled-skills/skill-optimizer/references/adapters/finance-accounting.md +0 -31
- package/resources/bundled-skills/skill-optimizer/references/adapters/healthcare-operations.md +0 -30
- package/resources/bundled-skills/skill-optimizer/references/adapters/hr-people-ops.md +0 -31
- package/resources/bundled-skills/skill-optimizer/references/adapters/legal-compliance.md +0 -31
- package/resources/bundled-skills/skill-optimizer/references/adapters/operations-supply-chain.md +0 -31
- package/resources/bundled-skills/skill-optimizer/references/adapters/personal-productivity.md +0 -29
- package/resources/bundled-skills/skill-optimizer/references/adapters/research-knowledge.md +0 -31
- package/resources/bundled-skills/skill-optimizer/references/adapters/software-ai.md +0 -31
- package/resources/bundled-skills/skill-optimizer/references/domain-adapter-patterns.md +0 -66
- package/resources/bundled-skills/skill-optimizer/references/eval-method.md +0 -17
- package/resources/bundled-skills/skill-optimizer/references/universal-optimization-lens.md +0 -73
- package/skills/rudder-create-agent/SKILL.md +0 -185
- package/skills/rudder-create-agent/references/api-reference.md +0 -179
- package/skills/rudder-create-agent/references/cli-reference.md +0 -132
- package/skills/rudder-create-plugin/SKILL.md +0 -103
- package/skills/skill-optimizer/CHANGELOG.md +0 -29
- package/skills/skill-optimizer/SKILL.md +0 -205
- package/skills/skill-optimizer/references/adapters/creative-brand-content.md +0 -30
- package/skills/skill-optimizer/references/adapters/customer-support-sales.md +0 -30
- package/skills/skill-optimizer/references/adapters/document-data-processing.md +0 -31
- package/skills/skill-optimizer/references/adapters/education-training.md +0 -31
- package/skills/skill-optimizer/references/adapters/finance-accounting.md +0 -31
- package/skills/skill-optimizer/references/adapters/healthcare-operations.md +0 -30
- package/skills/skill-optimizer/references/adapters/hr-people-ops.md +0 -31
- package/skills/skill-optimizer/references/adapters/legal-compliance.md +0 -31
- package/skills/skill-optimizer/references/adapters/operations-supply-chain.md +0 -31
- package/skills/skill-optimizer/references/adapters/personal-productivity.md +0 -29
- package/skills/skill-optimizer/references/adapters/research-knowledge.md +0 -31
- package/skills/skill-optimizer/references/adapters/software-ai.md +0 -31
- package/skills/skill-optimizer/references/domain-adapter-patterns.md +0 -66
- package/skills/skill-optimizer/references/eval-method.md +0 -17
- package/skills/skill-optimizer/references/universal-optimization-lens.md +0 -73
- package/ui-dist/assets/channel-CM4Myg_6.js +0 -1
- package/ui-dist/assets/classDiagram-OUVF2IWQ-CtlIEzTt.js +0 -1
- package/ui-dist/assets/classDiagram-v2-EOCWNBFH-CtlIEzTt.js +0 -1
- package/ui-dist/assets/index-DekHKOsL.css +0 -1
- package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-KQTrcZvp.js +0 -1
- package/ui-dist/assets/swimlanesDiagram-G3AALYLV-CcxS1c6r.js +0 -8
package/dist/services/chats.js
CHANGED
|
@@ -1,75 +1,24 @@
|
|
|
1
|
-
import { agentIntegrationChatBindings, agentIntegrations, approvals, assets, chatAttachments, chatContextLinks, chatControlActions, chatConversations, chatConversationUserStates, chatGenerationEvents, chatGenerations, chatMessages, chatQueuedMessages
|
|
2
|
-
import {
|
|
3
|
-
import { and, asc, desc, eq, gt, gte, inArray, isNull, lt, or, sql } from "drizzle-orm";
|
|
1
|
+
import { agentIntegrationChatBindings, agentIntegrations, approvals, assets, chatAttachments, chatContextLinks, chatControlActions, chatConversations, chatConversationUserStates, chatGenerationEvents, chatGenerations, chatMessages, chatQueuedMessages } from "@rudderhq/db";
|
|
2
|
+
import { sanitizeChatStructuredPayload } from "@rudderhq/shared";
|
|
3
|
+
import { and, asc, desc, eq, gt, gte, inArray, isNotNull, isNull, lt, or, sql } from "drizzle-orm";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { conflict, notFound, unprocessable } from "../errors.js";
|
|
6
6
|
import { logActivity } from "./activity-log.js";
|
|
7
7
|
import { agentService } from "./agents.js";
|
|
8
8
|
import { approvalService } from "./approvals.js";
|
|
9
|
+
import { ensureChatFamilyGroup } from "./chat-family-groups.js";
|
|
9
10
|
import { chatGenerationProtocolService } from "./chat-generation-protocol.js";
|
|
11
|
+
import { ACTIVE_CHAT_GENERATION_STATUSES, CHAT_GENERATION_CONTROL_LEASE_MS, NATIVE_STEER_GENERATION_STATUSES, SERVER_QUEUE_RUNNING_STATUSES, } from "./chats.constants.js";
|
|
12
|
+
import { createChatConversation, createChatWithInitialMessage } from "./chats.create.js";
|
|
13
|
+
import { conversationMutability, nextForkTitle } from "./chats.fork-helpers.js";
|
|
14
|
+
import { buildSearchSnippet, CHAT_TRANSCRIPT_KEY, chatTranscriptFromPayload, chatTranscriptSummaryFromEntries, contentPath, escapeLikePattern, incomingMessagePreviewSql, issueProposalFromPayload, isVisibleIncomingChatMessage, listContextLinksForConversationIds, listPrimaryIssues, operationProposalDecisionStatusFromPayload, operationProposalFromPayload, resolveContextEntities, safeTrim, stripChatMetadataFromPayload, textContains, truncatePreview, visibleIncomingMessageSql, withOperationProposalDecisionState, withPersistedTranscript, } from "./chats.helpers.js";
|
|
15
|
+
import { copyForkInlineVisualMessages, listRecentUserChatMessages, updateTrustedInlineVisualMappings, } from "./chats.inline-visual-persistence.js";
|
|
10
16
|
import { issueApprovalService } from "./issue-approvals.js";
|
|
11
17
|
import { issueService } from "./issues.js";
|
|
12
18
|
import { normalizeLocalLibraryPathMarkdown } from "./library-path-markdown.js";
|
|
13
19
|
import { organizationService } from "./orgs.js";
|
|
14
20
|
import { isPostgresError } from "./postgres-errors.js";
|
|
15
21
|
const CHAT_TITLE_MAX_LENGTH = 200;
|
|
16
|
-
const FORK_TITLE_SUFFIX_PATTERN = / \(([1-9]\d*)\)$/;
|
|
17
|
-
const ACTIVE_CHAT_GENERATION_STATUSES = [
|
|
18
|
-
"starting",
|
|
19
|
-
"active",
|
|
20
|
-
"running",
|
|
21
|
-
"tool_busy",
|
|
22
|
-
"closing",
|
|
23
|
-
"stop_requested",
|
|
24
|
-
"stopping",
|
|
25
|
-
];
|
|
26
|
-
const NATIVE_STEER_GENERATION_STATUSES = ["starting", "active", "running", "tool_busy"];
|
|
27
|
-
const SERVER_QUEUE_RUNNING_STATUSES = ["dequeue_claimed", "running_next"];
|
|
28
|
-
const CHAT_GENERATION_CONTROL_LEASE_MS = 30_000;
|
|
29
|
-
function baseForkTitle(title, sourceIsFork, familyTitles) {
|
|
30
|
-
const trimmed = title.trim() || "Forked conversation";
|
|
31
|
-
if (!sourceIsFork)
|
|
32
|
-
return trimmed;
|
|
33
|
-
const match = trimmed.match(FORK_TITLE_SUFFIX_PATTERN);
|
|
34
|
-
const index = Number(match?.[1]);
|
|
35
|
-
if (!match || index < 2)
|
|
36
|
-
return trimmed;
|
|
37
|
-
for (const familyTitle of familyTitles) {
|
|
38
|
-
const candidateBase = familyTitle.trim();
|
|
39
|
-
if (!candidateBase || candidateBase === trimmed)
|
|
40
|
-
continue;
|
|
41
|
-
if (numberedForkTitle(candidateBase, index) !== trimmed)
|
|
42
|
-
continue;
|
|
43
|
-
if (index === 2 || familyTitles.has(numberedForkTitle(candidateBase, index - 1))) {
|
|
44
|
-
return candidateBase;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return trimmed;
|
|
48
|
-
}
|
|
49
|
-
function numberedForkTitle(baseTitle, index) {
|
|
50
|
-
const suffix = ` (${index})`;
|
|
51
|
-
const availableBaseLength = CHAT_TITLE_MAX_LENGTH - suffix.length;
|
|
52
|
-
const truncatedBase = baseTitle.slice(0, availableBaseLength).trimEnd() || "Forked conversation";
|
|
53
|
-
return `${truncatedBase}${suffix}`;
|
|
54
|
-
}
|
|
55
|
-
function nextForkTitle(source, familyTitles) {
|
|
56
|
-
const existingTitles = new Set(familyTitles);
|
|
57
|
-
const baseTitle = baseForkTitle(source.title, Boolean(source.forkedFromConversationId), existingTitles);
|
|
58
|
-
let index = 2;
|
|
59
|
-
while (existingTitles.has(numberedForkTitle(baseTitle, index)))
|
|
60
|
-
index += 1;
|
|
61
|
-
return numberedForkTitle(baseTitle, index);
|
|
62
|
-
}
|
|
63
|
-
function conversationMutability(row, sourceMetadata, sourceMetadataByConversationId) {
|
|
64
|
-
if (sourceMetadata)
|
|
65
|
-
return "external_bound_chat";
|
|
66
|
-
if ((row.forkedFromConversationId && sourceMetadataByConversationId.has(row.forkedFromConversationId)) ||
|
|
67
|
-
(row.forkRootConversationId && sourceMetadataByConversationId.has(row.forkRootConversationId))) {
|
|
68
|
-
return "native_fork_from_external";
|
|
69
|
-
}
|
|
70
|
-
return "native_chat";
|
|
71
|
-
}
|
|
72
|
-
import { buildSearchSnippet, CHAT_TRANSCRIPT_KEY, chatTranscriptFromPayload, chatTranscriptSummaryFromEntries, contentPath, escapeLikePattern, incomingMessagePreviewSql, issueProposalFromPayload, isVisibleIncomingChatMessage, listContextLinksForConversationIds, listPrimaryIssues, operationProposalDecisionStatusFromPayload, operationProposalFromPayload, resolveContextEntities, safeTrim, stripChatMetadataFromPayload, textContains, truncatePreview, visibleIncomingMessageSql, withOperationProposalDecisionState, withPersistedTranscript, } from "./chats.helpers.js";
|
|
73
22
|
export function chatService(db) {
|
|
74
23
|
const generationProtocol = chatGenerationProtocolService(db);
|
|
75
24
|
const QUEUED_MESSAGE_CLAIM_LEASE_MS = 2 * 60 * 1000;
|
|
@@ -606,7 +555,7 @@ export function chatService(db) {
|
|
|
606
555
|
const rows = await db
|
|
607
556
|
.select()
|
|
608
557
|
.from(chatQueuedMessages)
|
|
609
|
-
.where(and(eq(chatQueuedMessages.conversationId, conversationId), inArray(chatQueuedMessages.status, [
|
|
558
|
+
.where(and(eq(chatQueuedMessages.conversationId, conversationId), isNull(chatQueuedMessages.cancelledAt), inArray(chatQueuedMessages.status, [
|
|
610
559
|
"queued",
|
|
611
560
|
"steer_pending",
|
|
612
561
|
"acceptance_unknown",
|
|
@@ -1121,6 +1070,28 @@ export function chatService(db) {
|
|
|
1121
1070
|
.returning();
|
|
1122
1071
|
if (!item)
|
|
1123
1072
|
throw conflict("Queued Steer feedback changed while provider evidence was resolving");
|
|
1073
|
+
const linkedSteerMessageId = item.continuationMessageId ?? item.sourceMessageId;
|
|
1074
|
+
if (linkedSteerMessageId) {
|
|
1075
|
+
const linkedSteerMessage = await tx
|
|
1076
|
+
.select({ structuredPayload: chatMessages.structuredPayload })
|
|
1077
|
+
.from(chatMessages)
|
|
1078
|
+
.where(and(eq(chatMessages.id, linkedSteerMessageId), eq(chatMessages.orgId, input.orgId), eq(chatMessages.conversationId, input.conversationId), eq(chatMessages.role, "user")))
|
|
1079
|
+
.limit(1)
|
|
1080
|
+
.then((rows) => rows[0] ?? null);
|
|
1081
|
+
const steerPayload = linkedSteerMessage?.structuredPayload;
|
|
1082
|
+
if (steerPayload && steerPayload.source === "steer") {
|
|
1083
|
+
await tx
|
|
1084
|
+
.update(chatMessages)
|
|
1085
|
+
.set({
|
|
1086
|
+
structuredPayload: {
|
|
1087
|
+
...steerPayload,
|
|
1088
|
+
deliveryDisposition: input.disposition,
|
|
1089
|
+
},
|
|
1090
|
+
updatedAt: now,
|
|
1091
|
+
})
|
|
1092
|
+
.where(eq(chatMessages.id, linkedSteerMessageId));
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1124
1095
|
return { action, item: hydrateQueuedMessage(item), applied: true };
|
|
1125
1096
|
});
|
|
1126
1097
|
}
|
|
@@ -1425,7 +1396,7 @@ export function chatService(db) {
|
|
|
1425
1396
|
const item = await tx
|
|
1426
1397
|
.select()
|
|
1427
1398
|
.from(chatQueuedMessages)
|
|
1428
|
-
.where(and(eq(chatQueuedMessages.id, input.itemId), eq(chatQueuedMessages.orgId, input.orgId), eq(chatQueuedMessages.conversationId, input.conversationId), inArray(chatQueuedMessages.status, ["queued", "steer_pending", "continuation_pending"])))
|
|
1399
|
+
.where(and(eq(chatQueuedMessages.id, input.itemId), eq(chatQueuedMessages.orgId, input.orgId), eq(chatQueuedMessages.conversationId, input.conversationId), isNull(chatQueuedMessages.cancelledAt), inArray(chatQueuedMessages.status, ["queued", "steer_pending", "continuation_pending"])))
|
|
1429
1400
|
.limit(1)
|
|
1430
1401
|
.then((rows) => rows[0] ?? null);
|
|
1431
1402
|
if (!item)
|
|
@@ -1479,7 +1450,7 @@ export function chatService(db) {
|
|
|
1479
1450
|
version: sql `${chatQueuedMessages.version} + 1`,
|
|
1480
1451
|
updatedAt: now,
|
|
1481
1452
|
})
|
|
1482
|
-
.where(and(eq(chatQueuedMessages.id, item.id), eq(chatQueuedMessages.version, item.version)))
|
|
1453
|
+
.where(and(eq(chatQueuedMessages.id, item.id), eq(chatQueuedMessages.version, item.version), isNull(chatQueuedMessages.cancelledAt)))
|
|
1483
1454
|
.returning();
|
|
1484
1455
|
if (!updatedItem)
|
|
1485
1456
|
throw conflict("Queued feedback changed while continuation was being scheduled");
|
|
@@ -1503,7 +1474,7 @@ export function chatService(db) {
|
|
|
1503
1474
|
version: sql `${chatQueuedMessages.version} + 1`,
|
|
1504
1475
|
updatedAt: now,
|
|
1505
1476
|
})
|
|
1506
|
-
.where(and(eq(chatQueuedMessages.conversationId, input.conversationId), eq(chatQueuedMessages.id, input.itemId), eq(chatQueuedMessages.status, "queued")))
|
|
1477
|
+
.where(and(eq(chatQueuedMessages.conversationId, input.conversationId), eq(chatQueuedMessages.id, input.itemId), eq(chatQueuedMessages.status, "queued"), isNull(chatQueuedMessages.cancelledAt)))
|
|
1507
1478
|
.returning();
|
|
1508
1479
|
if (!row)
|
|
1509
1480
|
throw conflict("Queued message was changed or is no longer steerable");
|
|
@@ -1519,12 +1490,12 @@ export function chatService(db) {
|
|
|
1519
1490
|
const candidates = await tx
|
|
1520
1491
|
.select()
|
|
1521
1492
|
.from(chatQueuedMessages)
|
|
1522
|
-
.where(and(inArray(chatQueuedMessages.status, ["continuation_pending", "steer_pending", "queued"]), sql `jsonb_typeof(${chatQueuedMessages.requestActor}) = 'object'`, or(isNull(chatQueuedMessages.deliveryLeaseExpiresAt), lt(chatQueuedMessages.deliveryLeaseExpiresAt, now)), sql
|
|
1493
|
+
.where(and(inArray(chatQueuedMessages.status, ["continuation_pending", "steer_pending", "queued"]), isNull(chatQueuedMessages.cancelledAt), sql `jsonb_typeof(${chatQueuedMessages.requestActor}) = 'object'`, or(isNull(chatQueuedMessages.deliveryLeaseExpiresAt), lt(chatQueuedMessages.deliveryLeaseExpiresAt, now)), sql `(${chatQueuedMessages.status} <> 'steer_pending' or coalesce((
|
|
1523
1494
|
select steer_action.provider_disposition
|
|
1524
1495
|
from ${chatControlActions} as steer_action
|
|
1525
1496
|
where steer_action.id = ${chatQueuedMessages.controlActionId}
|
|
1526
1497
|
limit 1
|
|
1527
|
-
), 'not_sent') in ('not_sent', 'rejected')`))
|
|
1498
|
+
), 'not_sent') in ('not_sent', 'rejected'))`))
|
|
1528
1499
|
.orderBy(sql `case
|
|
1529
1500
|
when ${chatQueuedMessages.status} = 'continuation_pending' then 0
|
|
1530
1501
|
when ${chatQueuedMessages.status} = 'steer_pending' then 1
|
|
@@ -1653,7 +1624,7 @@ export function chatService(db) {
|
|
|
1653
1624
|
version: sql `${chatQueuedMessages.version} + 1`,
|
|
1654
1625
|
updatedAt: now,
|
|
1655
1626
|
})
|
|
1656
|
-
.where(and(eq(chatQueuedMessages.id, candidate.id), eq(chatQueuedMessages.version, candidate.version)))
|
|
1627
|
+
.where(and(eq(chatQueuedMessages.id, candidate.id), eq(chatQueuedMessages.version, candidate.version), isNull(chatQueuedMessages.cancelledAt)))
|
|
1657
1628
|
.returning();
|
|
1658
1629
|
if (!claimed)
|
|
1659
1630
|
throw conflict("Queued continuation changed while being claimed");
|
|
@@ -1689,7 +1660,7 @@ export function chatService(db) {
|
|
|
1689
1660
|
deliveryLeaseExpiresAt: new Date(now.getTime() + input.leaseMs),
|
|
1690
1661
|
updatedAt: now,
|
|
1691
1662
|
})
|
|
1692
|
-
.where(and(eq(chatQueuedMessages.id, input.itemId), eq(chatQueuedMessages.continuationGenerationId, input.generationId), eq(chatQueuedMessages.deliveryLeaseToken, input.leaseToken), eq(chatQueuedMessages.deliveryLeaseEpoch, input.leaseEpoch), inArray(chatQueuedMessages.status, SERVER_QUEUE_RUNNING_STATUSES)))
|
|
1663
|
+
.where(and(eq(chatQueuedMessages.id, input.itemId), eq(chatQueuedMessages.continuationGenerationId, input.generationId), eq(chatQueuedMessages.deliveryLeaseToken, input.leaseToken), eq(chatQueuedMessages.deliveryLeaseEpoch, input.leaseEpoch), isNull(chatQueuedMessages.cancelledAt), inArray(chatQueuedMessages.status, SERVER_QUEUE_RUNNING_STATUSES)))
|
|
1693
1664
|
.returning({ id: chatQueuedMessages.id });
|
|
1694
1665
|
return Boolean(row);
|
|
1695
1666
|
}
|
|
@@ -1705,13 +1676,19 @@ export function chatService(db) {
|
|
|
1705
1676
|
if (!item)
|
|
1706
1677
|
return null;
|
|
1707
1678
|
const isSteer = item.deliveryIntent === "steer" || item.status === "running_next";
|
|
1708
|
-
const
|
|
1709
|
-
const
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1679
|
+
const cancelled = Boolean(item.cancelledAt);
|
|
1680
|
+
const succeeded = !cancelled && input.status === "completed";
|
|
1681
|
+
const nextStatus = cancelled
|
|
1682
|
+
? "cancelled"
|
|
1683
|
+
: succeeded
|
|
1684
|
+
? (isSteer ? "delivered" : "completed")
|
|
1685
|
+
: "failed_actionable";
|
|
1686
|
+
const nextDisposition = cancelled
|
|
1687
|
+
? "cancelled"
|
|
1688
|
+
: succeeded
|
|
1689
|
+
? (isSteer ? "delivered" : null)
|
|
1690
|
+
: "failed_actionable";
|
|
1691
|
+
const terminalReason = cancelled ? "operator_cancelled" : (input.reason ?? input.status);
|
|
1715
1692
|
const [updated] = await tx
|
|
1716
1693
|
.update(chatQueuedMessages)
|
|
1717
1694
|
.set({
|
|
@@ -1720,25 +1697,27 @@ export function chatService(db) {
|
|
|
1720
1697
|
deliveryLeaseToken: null,
|
|
1721
1698
|
deliveryLeaseOwner: null,
|
|
1722
1699
|
deliveryLeaseExpiresAt: null,
|
|
1723
|
-
lastDeliveryReason: succeeded ? null :
|
|
1724
|
-
reconciliationReason: succeeded ? null :
|
|
1700
|
+
lastDeliveryReason: succeeded ? null : terminalReason,
|
|
1701
|
+
reconciliationReason: succeeded ? null : terminalReason,
|
|
1725
1702
|
version: sql `${chatQueuedMessages.version} + 1`,
|
|
1726
1703
|
updatedAt: now,
|
|
1727
1704
|
})
|
|
1728
1705
|
.where(and(eq(chatQueuedMessages.id, item.id), eq(chatQueuedMessages.version, item.version)))
|
|
1729
1706
|
.returning();
|
|
1707
|
+
if (!updated)
|
|
1708
|
+
return null;
|
|
1730
1709
|
if (item.controlActionId) {
|
|
1731
1710
|
await tx
|
|
1732
1711
|
.update(chatControlActions)
|
|
1733
1712
|
.set({
|
|
1734
1713
|
localDisposition: nextDisposition ?? (succeeded ? "delivered" : "failed_actionable"),
|
|
1735
|
-
lastError: succeeded ? null :
|
|
1714
|
+
lastError: succeeded ? null : terminalReason,
|
|
1736
1715
|
resolvedAt: now,
|
|
1737
1716
|
updatedAt: now,
|
|
1738
1717
|
})
|
|
1739
1718
|
.where(eq(chatControlActions.id, item.controlActionId));
|
|
1740
1719
|
}
|
|
1741
|
-
return
|
|
1720
|
+
return hydrateQueuedMessage(updated);
|
|
1742
1721
|
});
|
|
1743
1722
|
}
|
|
1744
1723
|
async function releaseServerQueuedMessageClaim(input) {
|
|
@@ -1764,12 +1743,18 @@ export function chatService(db) {
|
|
|
1764
1743
|
|| generation.status === "tool_busy"
|
|
1765
1744
|
|| generation.status === "closing"));
|
|
1766
1745
|
const isSteer = item.deliveryIntent === "steer" || item.status === "running_next";
|
|
1767
|
-
const
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1746
|
+
const cancelled = Boolean(item.cancelledAt);
|
|
1747
|
+
const nextStatus = cancelled
|
|
1748
|
+
? "cancelled"
|
|
1749
|
+
: providerMayHaveStarted
|
|
1750
|
+
? (isSteer ? "acceptance_unknown" : "failed_actionable")
|
|
1751
|
+
: (isSteer ? "continuation_pending" : "queued");
|
|
1752
|
+
const nextDisposition = cancelled
|
|
1753
|
+
? "cancelled"
|
|
1754
|
+
: providerMayHaveStarted
|
|
1755
|
+
? (isSteer ? "acceptance_unknown" : "failed_actionable")
|
|
1756
|
+
: (isSteer ? "continuation_pending" : null);
|
|
1757
|
+
const releaseReason = cancelled ? "operator_cancelled" : input.reason;
|
|
1773
1758
|
const [updated] = await tx
|
|
1774
1759
|
.update(chatQueuedMessages)
|
|
1775
1760
|
.set({
|
|
@@ -1779,25 +1764,27 @@ export function chatService(db) {
|
|
|
1779
1764
|
deliveryLeaseToken: null,
|
|
1780
1765
|
deliveryLeaseOwner: null,
|
|
1781
1766
|
deliveryLeaseExpiresAt: null,
|
|
1782
|
-
lastDeliveryReason:
|
|
1783
|
-
reconciliationReason:
|
|
1767
|
+
lastDeliveryReason: releaseReason,
|
|
1768
|
+
reconciliationReason: releaseReason,
|
|
1784
1769
|
version: sql `${chatQueuedMessages.version} + 1`,
|
|
1785
1770
|
updatedAt: now,
|
|
1786
1771
|
})
|
|
1787
1772
|
.where(and(eq(chatQueuedMessages.id, item.id), eq(chatQueuedMessages.version, item.version)))
|
|
1788
1773
|
.returning();
|
|
1774
|
+
if (!updated)
|
|
1775
|
+
return null;
|
|
1789
1776
|
if (generation) {
|
|
1790
1777
|
await tx
|
|
1791
1778
|
.update(chatGenerations)
|
|
1792
1779
|
.set({
|
|
1793
1780
|
status: "aborted",
|
|
1794
|
-
terminalReason:
|
|
1781
|
+
terminalReason: releaseReason,
|
|
1795
1782
|
controlState: providerMayHaveStarted ? "control_lost" : "terminal",
|
|
1796
1783
|
runtimeTerminalAt: now,
|
|
1797
1784
|
completedAt: now,
|
|
1798
1785
|
updatedAt: now,
|
|
1799
1786
|
})
|
|
1800
|
-
.where(eq(chatGenerations.id, generation.id));
|
|
1787
|
+
.where(and(eq(chatGenerations.id, generation.id), inArray(chatGenerations.status, ACTIVE_CHAT_GENERATION_STATUSES)));
|
|
1801
1788
|
}
|
|
1802
1789
|
if (item.controlActionId) {
|
|
1803
1790
|
await tx
|
|
@@ -1805,13 +1792,13 @@ export function chatService(db) {
|
|
|
1805
1792
|
.set({
|
|
1806
1793
|
localDisposition: nextDisposition ?? "pending",
|
|
1807
1794
|
providerDisposition: providerMayHaveStarted ? "unverified" : "not_sent",
|
|
1808
|
-
lastError:
|
|
1795
|
+
lastError: releaseReason,
|
|
1809
1796
|
resolvedAt: providerMayHaveStarted ? now : null,
|
|
1810
1797
|
updatedAt: now,
|
|
1811
1798
|
})
|
|
1812
1799
|
.where(eq(chatControlActions.id, item.controlActionId));
|
|
1813
1800
|
}
|
|
1814
|
-
return
|
|
1801
|
+
return hydrateQueuedMessage(updated);
|
|
1815
1802
|
});
|
|
1816
1803
|
}
|
|
1817
1804
|
async function recoverExpiredServerQueueClaims(now = new Date()) {
|
|
@@ -1852,7 +1839,7 @@ export function chatService(db) {
|
|
|
1852
1839
|
const [candidate] = await tx
|
|
1853
1840
|
.select()
|
|
1854
1841
|
.from(chatQueuedMessages)
|
|
1855
|
-
.where(and(eq(chatQueuedMessages.conversationId, conversationId), eq(chatQueuedMessages.status, "queued")))
|
|
1842
|
+
.where(and(eq(chatQueuedMessages.conversationId, conversationId), eq(chatQueuedMessages.status, "queued"), isNull(chatQueuedMessages.cancelledAt)))
|
|
1856
1843
|
.orderBy(asc(chatQueuedMessages.position), asc(chatQueuedMessages.createdAt))
|
|
1857
1844
|
.limit(1);
|
|
1858
1845
|
if (!candidate)
|
|
@@ -1868,13 +1855,26 @@ export function chatService(db) {
|
|
|
1868
1855
|
version: sql `${chatQueuedMessages.version} + 1`,
|
|
1869
1856
|
updatedAt: now,
|
|
1870
1857
|
})
|
|
1871
|
-
.where(and(eq(chatQueuedMessages.id, candidate.id), eq(chatQueuedMessages.conversationId, conversationId), eq(chatQueuedMessages.status, "queued"), eq(chatQueuedMessages.version, candidate.version)))
|
|
1858
|
+
.where(and(eq(chatQueuedMessages.id, candidate.id), eq(chatQueuedMessages.conversationId, conversationId), eq(chatQueuedMessages.status, "queued"), eq(chatQueuedMessages.version, candidate.version), isNull(chatQueuedMessages.cancelledAt)))
|
|
1872
1859
|
.returning();
|
|
1873
1860
|
return row ? hydrateQueuedMessage(row) : null;
|
|
1874
1861
|
});
|
|
1875
1862
|
}
|
|
1876
1863
|
async function releaseQueuedMessageClaim(input) {
|
|
1877
1864
|
const now = new Date();
|
|
1865
|
+
const [cancelledRow] = await db
|
|
1866
|
+
.update(chatQueuedMessages)
|
|
1867
|
+
.set({
|
|
1868
|
+
status: "cancelled",
|
|
1869
|
+
deliveryDisposition: "cancelled",
|
|
1870
|
+
lastDeliveryReason: "operator_cancelled",
|
|
1871
|
+
version: sql `${chatQueuedMessages.version} + 1`,
|
|
1872
|
+
updatedAt: now,
|
|
1873
|
+
})
|
|
1874
|
+
.where(and(eq(chatQueuedMessages.conversationId, input.conversationId), eq(chatQueuedMessages.id, input.itemId), eq(chatQueuedMessages.status, "dequeue_claimed"), isNotNull(chatQueuedMessages.cancelledAt), isNull(chatQueuedMessages.deliveryLeaseToken), isNull(chatQueuedMessages.continuationGenerationId)))
|
|
1875
|
+
.returning();
|
|
1876
|
+
if (cancelledRow)
|
|
1877
|
+
return hydrateQueuedMessage(cancelledRow);
|
|
1878
1878
|
const [row] = await db
|
|
1879
1879
|
.update(chatQueuedMessages)
|
|
1880
1880
|
.set({
|
|
@@ -1883,27 +1883,38 @@ export function chatService(db) {
|
|
|
1883
1883
|
version: sql `${chatQueuedMessages.version} + 1`,
|
|
1884
1884
|
updatedAt: now,
|
|
1885
1885
|
})
|
|
1886
|
-
.where(and(eq(chatQueuedMessages.conversationId, input.conversationId), eq(chatQueuedMessages.id, input.itemId), eq(chatQueuedMessages.status, "dequeue_claimed")))
|
|
1886
|
+
.where(and(eq(chatQueuedMessages.conversationId, input.conversationId), eq(chatQueuedMessages.id, input.itemId), eq(chatQueuedMessages.status, "dequeue_claimed"), isNull(chatQueuedMessages.cancelledAt), isNull(chatQueuedMessages.deliveryLeaseToken), isNull(chatQueuedMessages.continuationGenerationId)))
|
|
1887
1887
|
.returning();
|
|
1888
1888
|
return row ? hydrateQueuedMessage(row) : null;
|
|
1889
1889
|
}
|
|
1890
1890
|
async function reclaimStaleQueuedMessageClaims(conversationId) {
|
|
1891
1891
|
const cutoff = new Date(Date.now() - QUEUED_MESSAGE_CLAIM_LEASE_MS);
|
|
1892
|
+
const now = new Date();
|
|
1893
|
+
await db
|
|
1894
|
+
.update(chatQueuedMessages)
|
|
1895
|
+
.set({
|
|
1896
|
+
status: "cancelled",
|
|
1897
|
+
deliveryDisposition: "cancelled",
|
|
1898
|
+
lastDeliveryReason: "operator_cancelled",
|
|
1899
|
+
version: sql `${chatQueuedMessages.version} + 1`,
|
|
1900
|
+
updatedAt: now,
|
|
1901
|
+
})
|
|
1902
|
+
.where(and(eq(chatQueuedMessages.conversationId, conversationId), eq(chatQueuedMessages.status, "dequeue_claimed"), isNotNull(chatQueuedMessages.cancelledAt), isNull(chatQueuedMessages.deliveryLeaseToken), isNull(chatQueuedMessages.continuationGenerationId), lt(chatQueuedMessages.updatedAt, cutoff)));
|
|
1892
1903
|
await db
|
|
1893
1904
|
.update(chatQueuedMessages)
|
|
1894
1905
|
.set({
|
|
1895
1906
|
status: "queued",
|
|
1896
1907
|
lastDeliveryReason: "claim_expired",
|
|
1897
1908
|
version: sql `${chatQueuedMessages.version} + 1`,
|
|
1898
|
-
updatedAt:
|
|
1909
|
+
updatedAt: now,
|
|
1899
1910
|
})
|
|
1900
|
-
.where(and(eq(chatQueuedMessages.conversationId, conversationId), eq(chatQueuedMessages.status, "dequeue_claimed"), lt(chatQueuedMessages.updatedAt, cutoff)));
|
|
1911
|
+
.where(and(eq(chatQueuedMessages.conversationId, conversationId), eq(chatQueuedMessages.status, "dequeue_claimed"), isNull(chatQueuedMessages.cancelledAt), isNull(chatQueuedMessages.deliveryLeaseToken), isNull(chatQueuedMessages.continuationGenerationId), lt(chatQueuedMessages.updatedAt, cutoff)));
|
|
1901
1912
|
}
|
|
1902
1913
|
async function assertQueuedMessageClaimedForDelivery(input) {
|
|
1903
1914
|
const row = await db
|
|
1904
1915
|
.select()
|
|
1905
1916
|
.from(chatQueuedMessages)
|
|
1906
|
-
.where(and(eq(chatQueuedMessages.conversationId, input.conversationId), eq(chatQueuedMessages.id, input.itemId)))
|
|
1917
|
+
.where(and(eq(chatQueuedMessages.conversationId, input.conversationId), eq(chatQueuedMessages.id, input.itemId), isNull(chatQueuedMessages.cancelledAt)))
|
|
1907
1918
|
.limit(1)
|
|
1908
1919
|
.then((rows) => rows[0] ?? null);
|
|
1909
1920
|
if (!row || row.status !== "dequeue_claimed") {
|
|
@@ -1949,19 +1960,120 @@ export function chatService(db) {
|
|
|
1949
1960
|
}
|
|
1950
1961
|
async function hydrateMessages(rows, options = {}) {
|
|
1951
1962
|
const includeTranscript = options.includeTranscript !== false;
|
|
1952
|
-
const
|
|
1963
|
+
const assistantMessageIds = rows
|
|
1964
|
+
.filter((row) => row.role === "assistant")
|
|
1965
|
+
.map((row) => row.id);
|
|
1966
|
+
const nativeSteerMessageIds = rows
|
|
1967
|
+
.filter((row) => row.role === "user" && row.structuredPayload?.source === "steer")
|
|
1968
|
+
.map((row) => row.id);
|
|
1969
|
+
const [attachmentsByMessageId, approvalsById, generationMessageRows, linkedSteerQueueRows] = await Promise.all([
|
|
1953
1970
|
listAttachmentsForMessageIds(rows.map((row) => row.id)),
|
|
1954
1971
|
listApprovalsForMessages(rows),
|
|
1972
|
+
assistantMessageIds.length > 0
|
|
1973
|
+
? db
|
|
1974
|
+
.select({
|
|
1975
|
+
assistantMessageId: chatGenerationEvents.assistantMessageId,
|
|
1976
|
+
generationId: chatGenerationEvents.generationId,
|
|
1977
|
+
})
|
|
1978
|
+
.from(chatGenerationEvents)
|
|
1979
|
+
.where(inArray(chatGenerationEvents.assistantMessageId, assistantMessageIds))
|
|
1980
|
+
.orderBy(desc(chatGenerationEvents.generationSeq))
|
|
1981
|
+
: Promise.resolve([]),
|
|
1982
|
+
nativeSteerMessageIds.length > 0
|
|
1983
|
+
? db
|
|
1984
|
+
.select({
|
|
1985
|
+
sourceMessageId: chatQueuedMessages.sourceMessageId,
|
|
1986
|
+
continuationMessageId: chatQueuedMessages.continuationMessageId,
|
|
1987
|
+
deliveryDisposition: chatQueuedMessages.deliveryDisposition,
|
|
1988
|
+
continuationGenerationId: chatQueuedMessages.continuationGenerationId,
|
|
1989
|
+
dequeuedAt: chatQueuedMessages.dequeuedAt,
|
|
1990
|
+
})
|
|
1991
|
+
.from(chatQueuedMessages)
|
|
1992
|
+
.where(or(inArray(chatQueuedMessages.sourceMessageId, nativeSteerMessageIds), inArray(chatQueuedMessages.continuationMessageId, nativeSteerMessageIds)))
|
|
1993
|
+
: Promise.resolve([]),
|
|
1955
1994
|
]);
|
|
1995
|
+
const generationIdByAssistantMessageId = new Map();
|
|
1996
|
+
for (const generationMessageRow of generationMessageRows) {
|
|
1997
|
+
if (!generationMessageRow.assistantMessageId)
|
|
1998
|
+
continue;
|
|
1999
|
+
if (generationIdByAssistantMessageId.has(generationMessageRow.assistantMessageId))
|
|
2000
|
+
continue;
|
|
2001
|
+
generationIdByAssistantMessageId.set(generationMessageRow.assistantMessageId, generationMessageRow.generationId);
|
|
2002
|
+
}
|
|
2003
|
+
const steerDispositionByMessageId = new Map();
|
|
2004
|
+
for (const queueRow of linkedSteerQueueRows) {
|
|
2005
|
+
const messageIds = new Set([
|
|
2006
|
+
queueRow.sourceMessageId,
|
|
2007
|
+
queueRow.continuationMessageId,
|
|
2008
|
+
].filter((messageId) => Boolean(messageId)));
|
|
2009
|
+
// `dequeuedAt` is durable provenance that this feedback left the native turn.
|
|
2010
|
+
// A failed continuation claim clears continuationGenerationId and may become
|
|
2011
|
+
// acceptance_unknown, but it must never be projected back into the old transcript.
|
|
2012
|
+
const projectedDisposition = queueRow.continuationGenerationId || queueRow.dequeuedAt
|
|
2013
|
+
? "continuation_pending"
|
|
2014
|
+
: queueRow.deliveryDisposition === "delivered"
|
|
2015
|
+
? "accepted_current"
|
|
2016
|
+
: queueRow.deliveryDisposition;
|
|
2017
|
+
if (!projectedDisposition)
|
|
2018
|
+
continue;
|
|
2019
|
+
for (const messageId of messageIds) {
|
|
2020
|
+
steerDispositionByMessageId.set(messageId, projectedDisposition);
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
const effectiveStructuredPayload = (row) => {
|
|
2024
|
+
const payload = row.structuredPayload;
|
|
2025
|
+
if (!payload || payload.source !== "steer")
|
|
2026
|
+
return payload;
|
|
2027
|
+
const projectedDisposition = steerDispositionByMessageId.get(row.id);
|
|
2028
|
+
return projectedDisposition
|
|
2029
|
+
? { ...payload, deliveryDisposition: projectedDisposition }
|
|
2030
|
+
: payload;
|
|
2031
|
+
};
|
|
2032
|
+
const nativeSteerTargetGenerationIds = new Set();
|
|
2033
|
+
for (const row of rows) {
|
|
2034
|
+
const payload = effectiveStructuredPayload(row);
|
|
2035
|
+
const targetGenerationId = payload?.source === "steer"
|
|
2036
|
+
&& ["pending", "acceptance_unknown", "accepted_current"].includes(typeof payload.deliveryDisposition === "string" ? payload.deliveryDisposition : "")
|
|
2037
|
+
&& typeof payload.targetGenerationId === "string"
|
|
2038
|
+
? payload.targetGenerationId
|
|
2039
|
+
: null;
|
|
2040
|
+
if (targetGenerationId)
|
|
2041
|
+
nativeSteerTargetGenerationIds.add(targetGenerationId);
|
|
2042
|
+
}
|
|
2043
|
+
const nativeSteerAssistantMessageIds = includeTranscript
|
|
2044
|
+
? []
|
|
2045
|
+
: assistantMessageIds.filter((messageId) => {
|
|
2046
|
+
const generationId = generationIdByAssistantMessageId.get(messageId);
|
|
2047
|
+
return Boolean(generationId && nativeSteerTargetGenerationIds.has(generationId));
|
|
2048
|
+
});
|
|
2049
|
+
const nativeSteerTranscriptPayloadByMessageId = new Map();
|
|
2050
|
+
if (nativeSteerAssistantMessageIds.length > 0) {
|
|
2051
|
+
const transcriptPayloadRows = await db
|
|
2052
|
+
.select({
|
|
2053
|
+
id: chatMessages.id,
|
|
2054
|
+
structuredPayload: chatMessages.structuredPayload,
|
|
2055
|
+
})
|
|
2056
|
+
.from(chatMessages)
|
|
2057
|
+
.where(inArray(chatMessages.id, nativeSteerAssistantMessageIds));
|
|
2058
|
+
for (const transcriptPayloadRow of transcriptPayloadRows) {
|
|
2059
|
+
nativeSteerTranscriptPayloadByMessageId.set(transcriptPayloadRow.id, transcriptPayloadRow.structuredPayload);
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
1956
2062
|
return rows.map((row) => {
|
|
1957
|
-
const
|
|
1958
|
-
const
|
|
2063
|
+
const generationId = generationIdByAssistantMessageId.get(row.id) ?? null;
|
|
2064
|
+
const includeRowTranscript = includeTranscript
|
|
2065
|
+
|| Boolean(generationId && nativeSteerTargetGenerationIds.has(generationId));
|
|
2066
|
+
const transcriptPayload = nativeSteerTranscriptPayloadByMessageId.get(row.id) ?? row.structuredPayload;
|
|
2067
|
+
const transcript = includeRowTranscript ? chatTranscriptFromPayload(transcriptPayload) : [];
|
|
2068
|
+
const transcriptSummary = includeRowTranscript
|
|
1959
2069
|
? chatTranscriptSummaryFromEntries(transcript)
|
|
1960
2070
|
: row.transcriptSummary ?? null;
|
|
2071
|
+
const structuredPayload = effectiveStructuredPayload(row);
|
|
1961
2072
|
return {
|
|
1962
2073
|
...row,
|
|
1963
|
-
|
|
1964
|
-
|
|
2074
|
+
generationId,
|
|
2075
|
+
structuredPayload: stripChatMetadataFromPayload(structuredPayload),
|
|
2076
|
+
transcript: includeRowTranscript ? transcript : undefined,
|
|
1965
2077
|
transcriptSummary,
|
|
1966
2078
|
approval: row.approvalId ? (approvalsById.get(row.approvalId) ?? null) : null,
|
|
1967
2079
|
attachments: attachmentsByMessageId.get(row.id) ?? [],
|
|
@@ -2113,107 +2225,16 @@ export function chatService(db) {
|
|
|
2113
2225
|
return conversation ?? null;
|
|
2114
2226
|
}
|
|
2115
2227
|
async function create(orgId, data) {
|
|
2116
|
-
const created = await db
|
|
2117
|
-
const [conversation] = await tx
|
|
2118
|
-
.insert(chatConversations)
|
|
2119
|
-
.values({
|
|
2120
|
-
orgId,
|
|
2121
|
-
title: data.title?.trim() || "New chat",
|
|
2122
|
-
summary: data.summary ?? null,
|
|
2123
|
-
preferredAgentId: data.preferredAgentId ?? null,
|
|
2124
|
-
issueCreationMode: data.issueCreationMode,
|
|
2125
|
-
planMode: data.planMode,
|
|
2126
|
-
createdByUserId: data.createdByUserId,
|
|
2127
|
-
})
|
|
2128
|
-
.returning();
|
|
2129
|
-
if (!conversation)
|
|
2130
|
-
throw new Error("Failed to create chat conversation");
|
|
2131
|
-
const contextLinks = data.contextLinks ?? [];
|
|
2132
|
-
if (contextLinks.length > 0) {
|
|
2133
|
-
await tx
|
|
2134
|
-
.insert(chatContextLinks)
|
|
2135
|
-
.values(contextLinks.map((link) => ({
|
|
2136
|
-
orgId,
|
|
2137
|
-
conversationId: conversation.id,
|
|
2138
|
-
entityType: link.entityType,
|
|
2139
|
-
entityId: link.entityId,
|
|
2140
|
-
metadata: link.metadata ?? null,
|
|
2141
|
-
})))
|
|
2142
|
-
.onConflictDoNothing();
|
|
2143
|
-
}
|
|
2144
|
-
return conversation;
|
|
2145
|
-
});
|
|
2228
|
+
const created = await createChatConversation(db, orgId, data);
|
|
2146
2229
|
return getById(created.id);
|
|
2147
2230
|
}
|
|
2231
|
+
async function createWithInitialMessage(orgId, data, executor) {
|
|
2232
|
+
return createChatWithInitialMessage(db, orgId, data, executor);
|
|
2233
|
+
}
|
|
2148
2234
|
function forkSystemEventBody(sourceConversation, sourceMessageId) {
|
|
2149
2235
|
const messageSuffix = sourceMessageId ? " at message" : "";
|
|
2150
2236
|
return `Forked from [${sourceConversation.title}](chat://${sourceConversation.id})${messageSuffix}.`;
|
|
2151
2237
|
}
|
|
2152
|
-
async function findForkFamilyGroup(client, orgId, userId, rootConversationId) {
|
|
2153
|
-
const rootThreadKey = `chat:${rootConversationId}`;
|
|
2154
|
-
return client
|
|
2155
|
-
.select({ id: messengerCustomGroups.id })
|
|
2156
|
-
.from(messengerCustomGroups)
|
|
2157
|
-
.innerJoin(messengerCustomGroupEntries, eq(messengerCustomGroupEntries.groupId, messengerCustomGroups.id))
|
|
2158
|
-
.where(and(eq(messengerCustomGroups.orgId, orgId), eq(messengerCustomGroups.userId, userId), eq(messengerCustomGroupEntries.orgId, orgId), eq(messengerCustomGroupEntries.userId, userId), eq(messengerCustomGroupEntries.threadKey, rootThreadKey)))
|
|
2159
|
-
.orderBy(asc(messengerCustomGroups.sortOrder), asc(messengerCustomGroups.createdAt))
|
|
2160
|
-
.limit(1)
|
|
2161
|
-
.then((rows) => rows[0] ?? null);
|
|
2162
|
-
}
|
|
2163
|
-
async function createForkFamilyGroup(client, orgId, userId, name) {
|
|
2164
|
-
const [lastGroup] = await client
|
|
2165
|
-
.select({ sortOrder: messengerCustomGroups.sortOrder })
|
|
2166
|
-
.from(messengerCustomGroups)
|
|
2167
|
-
.where(and(eq(messengerCustomGroups.orgId, orgId), eq(messengerCustomGroups.userId, userId)))
|
|
2168
|
-
.orderBy(desc(messengerCustomGroups.sortOrder))
|
|
2169
|
-
.limit(1);
|
|
2170
|
-
const now = new Date();
|
|
2171
|
-
const [group] = await client
|
|
2172
|
-
.insert(messengerCustomGroups)
|
|
2173
|
-
.values({
|
|
2174
|
-
orgId,
|
|
2175
|
-
userId,
|
|
2176
|
-
name: name.trim() || "Forked conversation",
|
|
2177
|
-
icon: MESSENGER_FORK_GROUP_DEFAULT_ICON,
|
|
2178
|
-
sortOrder: (lastGroup?.sortOrder ?? -1) + 1,
|
|
2179
|
-
updatedAt: now,
|
|
2180
|
-
})
|
|
2181
|
-
.returning();
|
|
2182
|
-
if (!group)
|
|
2183
|
-
throw new Error("Failed to create Messenger fork group");
|
|
2184
|
-
return group;
|
|
2185
|
-
}
|
|
2186
|
-
async function assignForkThreadToGroup(client, orgId, userId, groupId, threadKey) {
|
|
2187
|
-
const [lastEntry] = await client
|
|
2188
|
-
.select({ sortOrder: messengerCustomGroupEntries.sortOrder })
|
|
2189
|
-
.from(messengerCustomGroupEntries)
|
|
2190
|
-
.where(and(eq(messengerCustomGroupEntries.orgId, orgId), eq(messengerCustomGroupEntries.userId, userId), eq(messengerCustomGroupEntries.groupId, groupId)))
|
|
2191
|
-
.orderBy(desc(messengerCustomGroupEntries.sortOrder))
|
|
2192
|
-
.limit(1);
|
|
2193
|
-
const now = new Date();
|
|
2194
|
-
await client
|
|
2195
|
-
.insert(messengerCustomGroupEntries)
|
|
2196
|
-
.values({
|
|
2197
|
-
orgId,
|
|
2198
|
-
userId,
|
|
2199
|
-
groupId,
|
|
2200
|
-
threadKey,
|
|
2201
|
-
sortOrder: (lastEntry?.sortOrder ?? -1) + 1,
|
|
2202
|
-
updatedAt: now,
|
|
2203
|
-
})
|
|
2204
|
-
.onConflictDoNothing();
|
|
2205
|
-
}
|
|
2206
|
-
async function ensureForkFamilyGroup(client, orgId, userId, rootConversationId, sourceConversationId, childConversationId, groupName) {
|
|
2207
|
-
const existing = await findForkFamilyGroup(client, orgId, userId, rootConversationId);
|
|
2208
|
-
const group = existing ?? await createForkFamilyGroup(client, orgId, userId, groupName);
|
|
2209
|
-
for (const threadKey of [
|
|
2210
|
-
`chat:${rootConversationId}`,
|
|
2211
|
-
`chat:${sourceConversationId}`,
|
|
2212
|
-
`chat:${childConversationId}`,
|
|
2213
|
-
]) {
|
|
2214
|
-
await assignForkThreadToGroup(client, orgId, userId, group.id, threadKey);
|
|
2215
|
-
}
|
|
2216
|
-
}
|
|
2217
2238
|
async function forkConversation(input) {
|
|
2218
2239
|
const created = await db.transaction(async (tx) => {
|
|
2219
2240
|
const initialSource = await tx
|
|
@@ -2326,79 +2347,13 @@ export function chatService(db) {
|
|
|
2326
2347
|
const forkMessages = input.sourceMessageId
|
|
2327
2348
|
? messagesToCopy.slice(0, messagesToCopy.findIndex((message) => message.id === input.sourceMessageId) + 1)
|
|
2328
2349
|
: messagesToCopy;
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
const copiedAttachmentIdBySourceId = new Map();
|
|
2337
|
-
const pendingVisualAttachments = [];
|
|
2338
|
-
if (readyAttachmentIds.length > 0) {
|
|
2339
|
-
const sourceVisualAttachments = await tx
|
|
2340
|
-
.select({
|
|
2341
|
-
id: chatAttachments.id,
|
|
2342
|
-
assetId: chatAttachments.assetId,
|
|
2343
|
-
contentType: assets.contentType,
|
|
2344
|
-
createdByAgentId: assets.createdByAgentId,
|
|
2345
|
-
createdByUserId: assets.createdByUserId,
|
|
2346
|
-
})
|
|
2347
|
-
.from(chatAttachments)
|
|
2348
|
-
.innerJoin(assets, eq(chatAttachments.assetId, assets.id))
|
|
2349
|
-
.where(and(eq(chatAttachments.conversationId, source.id), eq(chatAttachments.messageId, message.id), inArray(chatAttachments.id, readyAttachmentIds)));
|
|
2350
|
-
const safeVisualAttachments = sourceVisualAttachments.filter((attachment) => attachment.contentType === "text/html"
|
|
2351
|
-
&& Boolean(attachment.createdByAgentId)
|
|
2352
|
-
&& !attachment.createdByUserId);
|
|
2353
|
-
if (safeVisualAttachments.length > 0) {
|
|
2354
|
-
pendingVisualAttachments.push(...safeVisualAttachments.map((attachment) => {
|
|
2355
|
-
const copiedAttachmentId = randomUUID();
|
|
2356
|
-
copiedAttachmentIdBySourceId.set(attachment.id, copiedAttachmentId);
|
|
2357
|
-
return {
|
|
2358
|
-
id: copiedAttachmentId,
|
|
2359
|
-
orgId: input.orgId,
|
|
2360
|
-
conversationId: child.id,
|
|
2361
|
-
messageId: copiedMessageId,
|
|
2362
|
-
assetId: attachment.assetId,
|
|
2363
|
-
};
|
|
2364
|
-
}));
|
|
2365
|
-
}
|
|
2366
|
-
}
|
|
2367
|
-
const copiedVisualMappings = visualMappings.map((mapping) => {
|
|
2368
|
-
if (mapping.status === "unavailable")
|
|
2369
|
-
return mapping;
|
|
2370
|
-
const copiedAttachmentId = copiedAttachmentIdBySourceId.get(mapping.attachmentId);
|
|
2371
|
-
return copiedAttachmentId
|
|
2372
|
-
? { ...mapping, attachmentId: copiedAttachmentId }
|
|
2373
|
-
: {
|
|
2374
|
-
directiveIndex: mapping.directiveIndex,
|
|
2375
|
-
file: mapping.file,
|
|
2376
|
-
status: "unavailable",
|
|
2377
|
-
reason: "fork_source_missing",
|
|
2378
|
-
};
|
|
2379
|
-
});
|
|
2380
|
-
await tx.insert(chatMessages).values({
|
|
2381
|
-
id: copiedMessageId,
|
|
2382
|
-
orgId: input.orgId,
|
|
2383
|
-
conversationId: child.id,
|
|
2384
|
-
role: message.role,
|
|
2385
|
-
kind: message.kind,
|
|
2386
|
-
status: message.status === "streaming" ? "interrupted" : message.status,
|
|
2387
|
-
body: message.body,
|
|
2388
|
-
structuredPayload: copiedVisualMappings.length > 0 ? { inlineVisuals: copiedVisualMappings } : null,
|
|
2389
|
-
approvalId: null,
|
|
2390
|
-
runId: null,
|
|
2391
|
-
replyingAgentId: message.replyingAgentId,
|
|
2392
|
-
chatTurnId: null,
|
|
2393
|
-
turnVariant: 0,
|
|
2394
|
-
createdAt: message.createdAt,
|
|
2395
|
-
updatedAt: message.updatedAt,
|
|
2396
|
-
});
|
|
2397
|
-
if (pendingVisualAttachments.length > 0) {
|
|
2398
|
-
await tx.insert(chatAttachments).values(pendingVisualAttachments);
|
|
2399
|
-
}
|
|
2400
|
-
}
|
|
2401
|
-
}
|
|
2350
|
+
await copyForkInlineVisualMessages({
|
|
2351
|
+
tx,
|
|
2352
|
+
messages: forkMessages,
|
|
2353
|
+
sourceConversationId: source.id,
|
|
2354
|
+
targetConversationId: child.id,
|
|
2355
|
+
orgId: input.orgId,
|
|
2356
|
+
});
|
|
2402
2357
|
const [systemEvent] = await tx
|
|
2403
2358
|
.insert(chatMessages)
|
|
2404
2359
|
.values({
|
|
@@ -2427,7 +2382,14 @@ export function chatService(db) {
|
|
|
2427
2382
|
updatedAt: now,
|
|
2428
2383
|
})
|
|
2429
2384
|
.where(eq(chatConversations.id, child.id));
|
|
2430
|
-
await
|
|
2385
|
+
await ensureChatFamilyGroup(tx, {
|
|
2386
|
+
orgId: input.orgId,
|
|
2387
|
+
userId: input.userId,
|
|
2388
|
+
rootConversationId,
|
|
2389
|
+
sourceConversationId: source.id,
|
|
2390
|
+
childConversationId: child.id,
|
|
2391
|
+
groupName: source.title,
|
|
2392
|
+
});
|
|
2431
2393
|
return child;
|
|
2432
2394
|
});
|
|
2433
2395
|
return getById(created.id, input.userId);
|
|
@@ -2626,13 +2588,21 @@ export function chatService(db) {
|
|
|
2626
2588
|
end
|
|
2627
2589
|
`;
|
|
2628
2590
|
}
|
|
2591
|
+
async function listRecentUserMessages(conversationId, limit) {
|
|
2592
|
+
return listRecentUserChatMessages(db, conversationId, limit);
|
|
2593
|
+
}
|
|
2629
2594
|
async function listMessages(conversationId, options = {}) {
|
|
2630
2595
|
const includeTranscript = options.includeTranscript !== false;
|
|
2596
|
+
const conversationOrgIds = db
|
|
2597
|
+
.select({ orgId: chatConversations.orgId })
|
|
2598
|
+
.from(chatConversations)
|
|
2599
|
+
.where(eq(chatConversations.id, conversationId));
|
|
2600
|
+
const messageConditions = and(eq(chatMessages.conversationId, conversationId), inArray(chatMessages.orgId, conversationOrgIds));
|
|
2631
2601
|
const rows = includeTranscript
|
|
2632
2602
|
? await db
|
|
2633
2603
|
.select()
|
|
2634
2604
|
.from(chatMessages)
|
|
2635
|
-
.where(
|
|
2605
|
+
.where(messageConditions)
|
|
2636
2606
|
.orderBy(chatMessages.createdAt, chatMessages.id)
|
|
2637
2607
|
: await db
|
|
2638
2608
|
.select({
|
|
@@ -2655,7 +2625,7 @@ export function chatService(db) {
|
|
|
2655
2625
|
transcriptSummary: transcriptSummarySql(),
|
|
2656
2626
|
})
|
|
2657
2627
|
.from(chatMessages)
|
|
2658
|
-
.where(
|
|
2628
|
+
.where(messageConditions)
|
|
2659
2629
|
.orderBy(chatMessages.createdAt, chatMessages.id);
|
|
2660
2630
|
return hydrateMessages(rows, { includeTranscript });
|
|
2661
2631
|
}
|
|
@@ -2868,6 +2838,15 @@ export function chatService(db) {
|
|
|
2868
2838
|
const [hydrated] = await hydrateMessages([updated]);
|
|
2869
2839
|
return hydrated ?? null;
|
|
2870
2840
|
}
|
|
2841
|
+
async function updateMessageInternalInlineVisuals(conversationId, messageId, input) {
|
|
2842
|
+
return updateTrustedInlineVisualMappings({
|
|
2843
|
+
db,
|
|
2844
|
+
hydrateMessages,
|
|
2845
|
+
conversationId,
|
|
2846
|
+
messageId,
|
|
2847
|
+
...input,
|
|
2848
|
+
});
|
|
2849
|
+
}
|
|
2871
2850
|
async function markInterruptedStreamingMessages(conversationId) {
|
|
2872
2851
|
const rows = await db
|
|
2873
2852
|
.select()
|
|
@@ -3000,6 +2979,38 @@ export function chatService(db) {
|
|
|
3000
2979
|
};
|
|
3001
2980
|
});
|
|
3002
2981
|
}
|
|
2982
|
+
async function removeAttachment(attachmentId) {
|
|
2983
|
+
return db.transaction(async (tx) => {
|
|
2984
|
+
const existing = await tx
|
|
2985
|
+
.select({
|
|
2986
|
+
id: chatAttachments.id,
|
|
2987
|
+
orgId: chatAttachments.orgId,
|
|
2988
|
+
assetId: chatAttachments.assetId,
|
|
2989
|
+
objectKey: assets.objectKey,
|
|
2990
|
+
})
|
|
2991
|
+
.from(chatAttachments)
|
|
2992
|
+
.innerJoin(assets, eq(chatAttachments.assetId, assets.id))
|
|
2993
|
+
.where(eq(chatAttachments.id, attachmentId))
|
|
2994
|
+
.then((rows) => rows[0] ?? null);
|
|
2995
|
+
if (!existing)
|
|
2996
|
+
return null;
|
|
2997
|
+
await tx.delete(chatAttachments).where(eq(chatAttachments.id, attachmentId));
|
|
2998
|
+
const hasRemainingAttachment = await tx
|
|
2999
|
+
.select({ id: chatAttachments.id })
|
|
3000
|
+
.from(chatAttachments)
|
|
3001
|
+
.where(eq(chatAttachments.assetId, existing.assetId))
|
|
3002
|
+
.limit(1)
|
|
3003
|
+
.then((rows) => rows.length > 0);
|
|
3004
|
+
if (!hasRemainingAttachment) {
|
|
3005
|
+
await tx.delete(assets).where(eq(assets.id, existing.assetId));
|
|
3006
|
+
}
|
|
3007
|
+
return {
|
|
3008
|
+
orgId: existing.orgId,
|
|
3009
|
+
objectKey: existing.objectKey,
|
|
3010
|
+
assetDeleted: !hasRemainingAttachment,
|
|
3011
|
+
};
|
|
3012
|
+
});
|
|
3013
|
+
}
|
|
3003
3014
|
function assertIssueProposalOwnerDecision(issueProposal) {
|
|
3004
3015
|
const hasAssignee = Boolean(safeTrim(issueProposal.assigneeAgentId) || safeTrim(issueProposal.assigneeUserId));
|
|
3005
3016
|
const hasUnassignedReason = Boolean(safeTrim(issueProposal.assigneeUnassignedReason));
|
|
@@ -3408,9 +3419,11 @@ export function chatService(db) {
|
|
|
3408
3419
|
listSummariesByIds,
|
|
3409
3420
|
getById,
|
|
3410
3421
|
create,
|
|
3422
|
+
createWithInitialMessage,
|
|
3411
3423
|
update,
|
|
3412
3424
|
updateDefaultTitle,
|
|
3413
3425
|
replaceSystemGeneratedTitle,
|
|
3426
|
+
listRecentUserMessages,
|
|
3414
3427
|
listAttachmentsForConversation,
|
|
3415
3428
|
assetHasAttachments,
|
|
3416
3429
|
remove,
|
|
@@ -3453,11 +3466,13 @@ export function chatService(db) {
|
|
|
3453
3466
|
getMessageTranscript,
|
|
3454
3467
|
addMessage,
|
|
3455
3468
|
updateMessage,
|
|
3469
|
+
updateMessageInternalInlineVisuals,
|
|
3456
3470
|
markInterruptedStreamingMessages,
|
|
3457
3471
|
addUserChatMessage,
|
|
3458
3472
|
addContextLink,
|
|
3459
3473
|
setProjectContextLink,
|
|
3460
3474
|
createAttachment,
|
|
3475
|
+
removeAttachment,
|
|
3461
3476
|
convertToIssue,
|
|
3462
3477
|
getMessage,
|
|
3463
3478
|
applyApprovedApproval,
|