@rudderhq/server 0.7.10 → 0.7.12
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/bootstrap/register-api-routes.d.ts.map +1 -1
- package/dist/bootstrap/register-api-routes.js +1 -1
- package/dist/bootstrap/register-api-routes.js.map +1 -1
- package/dist/bootstrap/types.d.ts +7 -0
- package/dist/bootstrap/types.d.ts.map +1 -1
- package/dist/index.js +18 -3
- package/dist/index.js.map +1 -1
- package/dist/routes/agents.management-routes.d.ts.map +1 -1
- package/dist/routes/agents.management-routes.js +2 -0
- package/dist/routes/agents.management-routes.js.map +1 -1
- package/dist/routes/chats.d.ts +2 -1
- package/dist/routes/chats.d.ts.map +1 -1
- package/dist/routes/chats.js +356 -7
- 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 +55 -3
- package/dist/routes/chats.stream-routes.js.map +1 -1
- package/dist/routes/goals.d.ts.map +1 -1
- package/dist/routes/goals.js +68 -7
- package/dist/routes/goals.js.map +1 -1
- package/dist/routes/issues.mutations.d.ts.map +1 -1
- package/dist/routes/issues.mutations.js +3 -0
- package/dist/routes/issues.mutations.js.map +1 -1
- package/dist/routes/orgs.d.ts.map +1 -1
- package/dist/routes/orgs.js +22 -1
- package/dist/routes/orgs.js.map +1 -1
- package/dist/routes/run-intelligence.d.ts.map +1 -1
- package/dist/routes/run-intelligence.js +9 -0
- package/dist/routes/run-intelligence.js.map +1 -1
- package/dist/services/agent-instructions.d.ts +1 -0
- package/dist/services/agent-instructions.d.ts.map +1 -1
- package/dist/services/agent-instructions.js +124 -6
- package/dist/services/agent-instructions.js.map +1 -1
- package/dist/services/agent-run-context.d.ts.map +1 -1
- package/dist/services/agent-run-context.js +15 -0
- package/dist/services/agent-run-context.js.map +1 -1
- package/dist/services/agent-startup-context.d.ts +5 -1
- package/dist/services/agent-startup-context.d.ts.map +1 -1
- package/dist/services/agent-startup-context.js +67 -14
- package/dist/services/agent-startup-context.js.map +1 -1
- package/dist/services/agents.d.ts +218 -0
- package/dist/services/agents.d.ts.map +1 -1
- package/dist/services/automations.d.ts.map +1 -1
- package/dist/services/automations.js +3 -0
- package/dist/services/automations.js.map +1 -1
- package/dist/services/chat-agent-runs.d.ts +47 -1
- package/dist/services/chat-agent-runs.d.ts.map +1 -1
- package/dist/services/chat-agent-runs.js +91 -1
- 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 +12 -3
- package/dist/services/chat-assistant.helpers.d.ts.map +1 -1
- package/dist/services/chat-assistant.helpers.js +3 -0
- package/dist/services/chat-assistant.helpers.js.map +1 -1
- package/dist/services/chat-assistant.js +65 -19
- package/dist/services/chat-assistant.js.map +1 -1
- package/dist/services/chat-generation-protocol.d.ts +119 -0
- package/dist/services/chat-generation-protocol.d.ts.map +1 -1
- package/dist/services/chat-generation-protocol.js +65 -0
- package/dist/services/chat-generation-protocol.js.map +1 -1
- package/dist/services/chats.constants.d.ts +1 -1
- package/dist/services/chats.constants.d.ts.map +1 -1
- package/dist/services/chats.constants.js +1 -0
- package/dist/services/chats.constants.js.map +1 -1
- package/dist/services/chats.d.ts +213 -0
- package/dist/services/chats.d.ts.map +1 -1
- package/dist/services/chats.js +46 -1
- package/dist/services/chats.js.map +1 -1
- package/dist/services/goals.d.ts +133 -5
- package/dist/services/goals.d.ts.map +1 -1
- package/dist/services/goals.js +260 -3
- package/dist/services/goals.js.map +1 -1
- package/dist/services/heartbeat-run-reference.d.ts.map +1 -1
- package/dist/services/heartbeat-run-reference.js +11 -5
- package/dist/services/heartbeat-run-reference.js.map +1 -1
- package/dist/services/index.d.ts +2 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +2 -1
- package/dist/services/index.js.map +1 -1
- package/dist/services/integrations/feishu/runtime.d.ts +8 -0
- package/dist/services/integrations/feishu/runtime.d.ts.map +1 -1
- package/dist/services/integrations/feishu/runtime.js +124 -1
- package/dist/services/integrations/feishu/runtime.js.map +1 -1
- package/dist/services/issues.d.ts.map +1 -1
- package/dist/services/issues.helpers.d.ts +8 -0
- package/dist/services/issues.helpers.d.ts.map +1 -1
- package/dist/services/issues.helpers.js +17 -1
- package/dist/services/issues.helpers.js.map +1 -1
- package/dist/services/issues.js +108 -15
- package/dist/services/issues.js.map +1 -1
- package/dist/services/messenger.d.ts.map +1 -1
- package/dist/services/messenger.js +12 -3
- package/dist/services/messenger.js.map +1 -1
- package/dist/services/organization-members.d.ts +27 -0
- package/dist/services/organization-members.d.ts.map +1 -0
- package/dist/services/organization-members.js +169 -0
- package/dist/services/organization-members.js.map +1 -0
- package/dist/services/organization-workspace-browser.d.ts.map +1 -1
- package/dist/services/organization-workspace-browser.js +44 -10
- package/dist/services/organization-workspace-browser.js.map +1 -1
- package/dist/services/product-intelligence.d.ts.map +1 -1
- package/dist/services/product-intelligence.js +4 -0
- package/dist/services/product-intelligence.js.map +1 -1
- package/dist/services/projects.d.ts +1 -4
- package/dist/services/projects.d.ts.map +1 -1
- package/dist/services/projects.js +27 -2
- package/dist/services/projects.js.map +1 -1
- package/dist/services/rudder-plugin-catalog.d.ts +1 -1
- package/dist/services/rudder-plugin-catalog.d.ts.map +1 -1
- package/dist/services/rudder-plugin-catalog.js +281 -15
- package/dist/services/rudder-plugin-catalog.js.map +1 -1
- package/dist/services/rudder-plugin-catalog.test.js +55 -0
- package/dist/services/rudder-plugin-catalog.test.js.map +1 -1
- package/dist/services/run-intelligence.d.ts.map +1 -1
- package/dist/services/run-intelligence.js +2 -1
- package/dist/services/run-intelligence.js.map +1 -1
- package/dist/services/run-log-store.d.ts +3 -0
- package/dist/services/run-log-store.d.ts.map +1 -1
- package/dist/services/run-log-store.js +124 -18
- package/dist/services/run-log-store.js.map +1 -1
- package/dist/services/runtime-kernel/assignment-run-guardrail.d.ts +80 -23
- package/dist/services/runtime-kernel/assignment-run-guardrail.d.ts.map +1 -1
- package/dist/services/runtime-kernel/assignment-run-guardrail.js +230 -5
- package/dist/services/runtime-kernel/assignment-run-guardrail.js.map +1 -1
- package/dist/services/runtime-kernel/assignment-run-guardrail.test.js +122 -2
- package/dist/services/runtime-kernel/assignment-run-guardrail.test.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat-attempt-ledger.d.ts +124 -0
- package/dist/services/runtime-kernel/heartbeat-attempt-ledger.d.ts.map +1 -0
- package/dist/services/runtime-kernel/heartbeat-attempt-ledger.js +108 -0
- package/dist/services/runtime-kernel/heartbeat-attempt-ledger.js.map +1 -0
- package/dist/services/runtime-kernel/heartbeat.core.d.ts +111 -0
- package/dist/services/runtime-kernel/heartbeat.core.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.core.js +13 -0
- package/dist/services/runtime-kernel/heartbeat.core.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.d.ts +34 -0
- package/dist/services/runtime-kernel/heartbeat.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.execute.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.execute.js +312 -16
- package/dist/services/runtime-kernel/heartbeat.execute.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.js +205 -8
- package/dist/services/runtime-kernel/heartbeat.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.sessions.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.sessions.js +15 -3
- package/dist/services/runtime-kernel/heartbeat.sessions.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.terminal.d.ts +48 -0
- package/dist/services/runtime-kernel/heartbeat.terminal.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.wakeup.js +1 -1
- package/dist/services/runtime-kernel/heartbeat.wakeup.js.map +1 -1
- package/dist/services/runtime-kernel/model-fallback.d.ts +4 -0
- package/dist/services/runtime-kernel/model-fallback.d.ts.map +1 -1
- package/dist/services/runtime-kernel/model-fallback.js +25 -4
- package/dist/services/runtime-kernel/model-fallback.js.map +1 -1
- package/dist/services/workspace-backup-v2.d.ts +20 -0
- package/dist/services/workspace-backup-v2.d.ts.map +1 -1
- package/dist/services/workspace-backup-v2.js +155 -23
- package/dist/services/workspace-backup-v2.js.map +1 -1
- package/dist/services/workspace-backup-v2.test.js +34 -2
- package/dist/services/workspace-backup-v2.test.js.map +1 -1
- package/dist/services/workspace-backups.d.ts +0 -1
- package/dist/services/workspace-backups.d.ts.map +1 -1
- package/dist/services/workspace-backups.js +18 -19
- package/dist/services/workspace-backups.js.map +1 -1
- package/dist/services/workspace-manifest-native.d.ts +10 -0
- package/dist/services/workspace-manifest-native.d.ts.map +1 -0
- package/dist/services/workspace-manifest-native.js +219 -0
- package/dist/services/workspace-manifest-native.js.map +1 -0
- package/dist/services/workspace-restore-reconciliation.d.ts +11 -0
- package/dist/services/workspace-restore-reconciliation.d.ts.map +1 -0
- package/dist/services/workspace-restore-reconciliation.js +165 -0
- package/dist/services/workspace-restore-reconciliation.js.map +1 -0
- package/package.json +14 -14
- package/resources/bundled-skills/rudder-docs/references/api-reference.md +8 -0
- package/resources/bundled-skills/rudder-docs/references/cli-reference.md +14 -8
- package/skills/rudder-docs/references/api-reference.md +8 -0
- package/skills/rudder-docs/references/cli-reference.md +14 -8
- package/ui-dist/assets/LibraryLiveSurface-tCWxJKp5.js +1 -0
- package/ui-dist/assets/{abnfDiagram-VRR7QNED-CG3j5RmW.js → abnfDiagram-VRR7QNED-BcCms-hs.js} +1 -1
- package/ui-dist/assets/{addon-fit-D07m_e8_.js → addon-fit-CH3xNHN4.js} +1 -1
- package/ui-dist/assets/{arc-B2RI9_Dw.js → arc-h5W-EkRK.js} +1 -1
- package/ui-dist/assets/{architectureDiagram-ZJ3FMSHR-C5v1tMZi.js → architectureDiagram-ZJ3FMSHR-Bdehm1PB.js} +1 -1
- package/ui-dist/assets/{blockDiagram-677ZJIJ3-CgcSNhl8.js → blockDiagram-677ZJIJ3-BJ3W91Su.js} +1 -1
- package/ui-dist/assets/{c4Diagram-LMCZKHZV-B7qmWb0f.js → c4Diagram-LMCZKHZV-Bnft_fRy.js} +1 -1
- package/ui-dist/assets/channel-G6qIOCiV.js +1 -0
- package/ui-dist/assets/{chunk-2Q5K7J3B-cNlq0MJR.js → chunk-2Q5K7J3B-w1SF0tSk.js} +1 -1
- package/ui-dist/assets/{chunk-32BRIVSS-rcxFQzYk.js → chunk-32BRIVSS-C1UzXTFZ.js} +1 -1
- package/ui-dist/assets/{chunk-5VM5RSS4-9PSO_t10.js → chunk-5VM5RSS4-COVI3rNd.js} +1 -1
- package/ui-dist/assets/{chunk-EX3LRPZG-BlOFcT4O.js → chunk-EX3LRPZG-DxQOLy7z.js} +1 -1
- package/ui-dist/assets/{chunk-JWPE2WC7-B2Jgd3wO.js → chunk-JWPE2WC7-KTwmElcL.js} +1 -1
- package/ui-dist/assets/{chunk-MOJQB5TN-CaAqG9fp.js → chunk-MOJQB5TN-BynL4lzA.js} +1 -1
- package/ui-dist/assets/{chunk-RYQCIY6F-BDI7azm6.js → chunk-RYQCIY6F-CJksBfuJ.js} +1 -1
- package/ui-dist/assets/{chunk-V7JOEXUC-B-P0KC6p.js → chunk-V7JOEXUC-C_zED5WJ.js} +1 -1
- package/ui-dist/assets/{chunk-VR4S4FIN-CMfw-kF9.js → chunk-VR4S4FIN-BHDtMeiT.js} +1 -1
- package/ui-dist/assets/{chunk-XXDRQBXY-BBVqU1YP.js → chunk-XXDRQBXY-C0VvJgte.js} +1 -1
- package/ui-dist/assets/classDiagram-OUVF2IWQ-D15_PFCL.js +1 -0
- package/ui-dist/assets/classDiagram-v2-EOCWNBFH-D15_PFCL.js +1 -0
- package/ui-dist/assets/{cose-bilkent-JH36ORCC-B_hARQDI.js → cose-bilkent-JH36ORCC-DsTTzpP7.js} +1 -1
- package/ui-dist/assets/{cynefin-VYW2F7L2-CTcM0j1n.js → cynefin-VYW2F7L2-BfULw90s.js} +1 -1
- package/ui-dist/assets/{cynefinDiagram-TSTJHNR4-CL7MmdPn.js → cynefinDiagram-TSTJHNR4-BukSzKVC.js} +1 -1
- package/ui-dist/assets/{dagre-VKFMJZFB-mhGwmtXN.js → dagre-VKFMJZFB-BbZY_Ipf.js} +1 -1
- package/ui-dist/assets/{diagram-FQU43EPY-BMjw7iEL.js → diagram-FQU43EPY-BTYIYn2p.js} +1 -1
- package/ui-dist/assets/{diagram-G47NLZAW-BsTpJwdG.js → diagram-G47NLZAW-CikY_FKi.js} +1 -1
- package/ui-dist/assets/{diagram-NH7WQ7WH-Ne5TlLrd.js → diagram-NH7WQ7WH-BfZ7AlT8.js} +1 -1
- package/ui-dist/assets/{diagram-OA4YK3LP-YVpFkzL5.js → diagram-OA4YK3LP-f5AikxJj.js} +1 -1
- package/ui-dist/assets/{diagram-WEI45ONY-B5uEnE3n.js → diagram-WEI45ONY-BCbG5yas.js} +1 -1
- package/ui-dist/assets/{ebnfDiagram-CCIWWBDH-i74y0Dqq.js → ebnfDiagram-CCIWWBDH-DT-3mJLY.js} +1 -1
- package/ui-dist/assets/{erDiagram-Q63AITRT-46MUSamZ.js → erDiagram-Q63AITRT-BsfOhDfe.js} +1 -1
- package/ui-dist/assets/{flowDiagram-23GEKE2U-C9jQx1Z9.js → flowDiagram-23GEKE2U-BfaeQCsg.js} +1 -1
- package/ui-dist/assets/{ganttDiagram-NO4QXBWP-BHoVYgnd.js → ganttDiagram-NO4QXBWP-CgPQruVz.js} +1 -1
- package/ui-dist/assets/{gitGraphDiagram-IHSO6WYX-BxCaqc4K.js → gitGraphDiagram-IHSO6WYX-CNrBFzjY.js} +1 -1
- package/ui-dist/assets/{graph-7yEA7MiX.js → graph-QqDTzUUJ.js} +1 -1
- package/ui-dist/assets/{index-55mSol35.js → index-2ZQZC89T.js} +1 -1
- package/ui-dist/assets/{index-Y9EFmtGV.js → index-2cYcOpZB.js} +1 -1
- package/ui-dist/assets/{index-Bk4h2xgb.js → index-BAt16m_U.js} +1 -1
- package/ui-dist/assets/{index-SnNVv85r.js → index-BY8xCKIE.js} +1 -1
- package/ui-dist/assets/{index-Bbr_dltJ.js → index-Befy20DN.js} +1 -1
- package/ui-dist/assets/{index-2l0f_0un.js → index-BfAP3xNl.js} +1 -1
- package/ui-dist/assets/{index-Cr_0vHJF.js → index-BogOyxlk.js} +1 -1
- package/ui-dist/assets/{index-BM2yCFug.js → index-BuIyK71w.js} +562 -557
- package/ui-dist/assets/{index-8SjcJx20.js → index-CQ92CxVC.js} +1 -1
- package/ui-dist/assets/{index-BMbspMfV.js → index-CQFwlD-o.js} +1 -1
- package/ui-dist/assets/{index-DEDA9JuC.js → index-Cu4qo_D7.js} +1 -1
- package/ui-dist/assets/index-DRuC5g8V.css +32 -0
- package/ui-dist/assets/{index-BYHrPlW0.js → index-DZ4gAeDM.js} +1 -1
- package/ui-dist/assets/{index-zsia7wHf.js → index-Dc_DUpPj.js} +1 -1
- package/ui-dist/assets/{index-CTe7L-bN.js → index-Dqv46mWS.js} +1 -1
- package/ui-dist/assets/{index-sorUqxO4.js → index-sFJMMyA3.js} +1 -1
- package/ui-dist/assets/{infoDiagram-FWYZ7A6U-tKN_HUk-.js → infoDiagram-FWYZ7A6U-BJHuaNA9.js} +1 -1
- package/ui-dist/assets/{ishikawaDiagram-FXEZZL3T-z7MJkWMv.js → ishikawaDiagram-FXEZZL3T-CmsA1Knp.js} +1 -1
- package/ui-dist/assets/{journeyDiagram-5HDEW3XC-CY9IRx-1.js → journeyDiagram-5HDEW3XC-iV_Nt9d4.js} +1 -1
- package/ui-dist/assets/{kanban-definition-HUTT4EX6-R6xzFCHM.js → kanban-definition-HUTT4EX6-D45s70Ny.js} +1 -1
- package/ui-dist/assets/{layout-BQx6ln2a.js → layout-DDC-iOzY.js} +1 -1
- package/ui-dist/assets/{linear-CH-dQ7Bg.js → linear-DCTJ7Pq3.js} +1 -1
- package/ui-dist/assets/{map-DmEHxVn2.js → map-RGy5k616.js} +1 -1
- package/ui-dist/assets/{mermaid.core-8TMqfMCO.js → mermaid.core-6MH04cvi.js} +4 -4
- package/ui-dist/assets/{mindmap-definition-LN4V7U3C-ClYlc1ss.js → mindmap-definition-LN4V7U3C-CA2LFmda.js} +1 -1
- package/ui-dist/assets/{pegDiagram-2B236MQR-DuQPcIJk.js → pegDiagram-2B236MQR-DDsUr2du.js} +1 -1
- package/ui-dist/assets/{pieDiagram-ENE6RG2P-Bc1fELpd.js → pieDiagram-ENE6RG2P-D7jEL8xK.js} +1 -1
- package/ui-dist/assets/{quadrantDiagram-ABIIQ3AL-DS9-N5ZO.js → quadrantDiagram-ABIIQ3AL-BsJxgVLb.js} +1 -1
- package/ui-dist/assets/{railroadDiagram-RFXS5EU6-BBAeUuch.js → railroadDiagram-RFXS5EU6-CBI457f6.js} +1 -1
- package/ui-dist/assets/{requirementDiagram-TGXJPOKE-BmDkrDi3.js → requirementDiagram-TGXJPOKE-_GAc0NOO.js} +1 -1
- package/ui-dist/assets/{sankeyDiagram-HTMAVEWB-APPAQqTz.js → sankeyDiagram-HTMAVEWB-DNIaj5hu.js} +1 -1
- package/ui-dist/assets/{sequenceDiagram-DBY2YBRQ-B9G01Gl-.js → sequenceDiagram-DBY2YBRQ-BHDZs2dc.js} +1 -1
- package/ui-dist/assets/{sizeCapture-X5ZJPWSS-BYjnDqoI.js → sizeCapture-X5ZJPWSS-DwKT6aTP.js} +1 -1
- package/ui-dist/assets/{stateDiagram-2N3HPSRC-BQkWPBAj.js → stateDiagram-2N3HPSRC-D2hDsltG.js} +1 -1
- package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-CMTeJdkk.js +1 -0
- package/ui-dist/assets/{swimlanes-5IMT3BWC-Cacv4UUq.js → swimlanes-5IMT3BWC-BV8xA0iq.js} +2 -2
- package/ui-dist/assets/swimlanesDiagram-G3AALYLV-ChF8QLeM.js +8 -0
- package/ui-dist/assets/{timeline-definition-FHXFAJF6-COt3U2Pi.js → timeline-definition-FHXFAJF6-BPJMubhV.js} +1 -1
- package/ui-dist/assets/{vennDiagram-L72KCM5P-C7eLlxvT.js → vennDiagram-L72KCM5P-CY76J0Px.js} +1 -1
- package/ui-dist/assets/{wardleyDiagram-EHGQE667-Bufv0x60.js → wardleyDiagram-EHGQE667-pmNWLdE_.js} +1 -1
- package/ui-dist/assets/{xterm-BuWLsUNc.js → xterm-UByodpzD.js} +1 -1
- package/ui-dist/assets/{xychartDiagram-FW5EYKEG-9RQAf_Zw.js → xychartDiagram-FW5EYKEG-BWZC7gWV.js} +1 -1
- package/ui-dist/index.html +2 -2
- package/ui-dist/assets/LibraryLiveSurface-YMhPWwag.js +0 -1
- package/ui-dist/assets/channel-Cbzk2971.js +0 -1
- package/ui-dist/assets/classDiagram-OUVF2IWQ-hBDf22nr.js +0 -1
- package/ui-dist/assets/classDiagram-v2-EOCWNBFH-hBDf22nr.js +0 -1
- package/ui-dist/assets/index-B_CDj4oF.css +0 -32
- package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-BucPPlgK.js +0 -1
- package/ui-dist/assets/swimlanesDiagram-G3AALYLV-DPpGouCd.js +0 -8
package/dist/routes/chats.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { addChatMessageSchema, cancelChatQueuedMessageSchema, chatAutomationCreateFromStructuredPayload, chatDraftSchema, createChatConversationSchema, createChatQueuedMessageSchema, createSideChatSchema, forkChatConversationSchema, steerChatQueuedMessageSchema, updateChatConversationSchema, updateChatQueuedMessageSchema, } from "@rudderhq/shared";
|
|
1
|
+
import { addChatMessageSchema, cancelChatQueuedMessageSchema, chatAutomationCreateFromStructuredPayload, chatDraftSchema, createChatConversationSchema, createChatQueuedMessageSchema, createSideChatSchema, forkChatConversationSchema, parseShortRef, steerChatQueuedMessageSchema, updateChatConversationSchema, updateChatQueuedMessageSchema, } from "@rudderhq/shared";
|
|
2
2
|
import { Router } from "express";
|
|
3
3
|
import multer from "multer";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { isAllowedContentType, MAX_ATTACHMENT_BYTES } from "../attachment-types.js";
|
|
6
|
-
import { conflict, forbidden, HttpError, unauthorized, unprocessable } from "../errors.js";
|
|
6
|
+
import { conflict, forbidden, HttpError, notFound, unauthorized, unprocessable } from "../errors.js";
|
|
7
7
|
import { logger } from "../middleware/logger.js";
|
|
8
8
|
import { validate } from "../middleware/validate.js";
|
|
9
9
|
import { assertTimeZone } from "../services/automations.scheduler.js";
|
|
@@ -18,8 +18,9 @@ import { buildChatTitlePromptFromMessages, chatTitleGenerationService, } from ".
|
|
|
18
18
|
import { chatWorkManifestService } from "../services/chat-work-manifest.js";
|
|
19
19
|
import { validateCron } from "../services/cron.js";
|
|
20
20
|
import { accessService, agentService, automationService, chatService, goalService, heartbeatService, issueService, logActivity, operatorProfileService, organizationService, productIntelligenceService, projectService, sideChatService, } from "../services/index.js";
|
|
21
|
+
import { NETWORK_WAIT_EXHAUSTED_ERROR, NETWORK_WAIT_EXHAUSTED_ERROR_CODE, } from "../services/runtime-kernel/heartbeat.core.js";
|
|
21
22
|
import { runtimeResultText, sanitizeGeneratedTitle, } from "../services/title-generation.js";
|
|
22
|
-
import { assertBoard, assertCompanyAccess, getActorInfo } from "./authz.js";
|
|
23
|
+
import { assertBoard, assertCompanyAccess, getActorInfo, getAuthorizedOrgScope } from "./authz.js";
|
|
23
24
|
import { createChatBackgroundRuntime, } from "./chat-background-runtime.js";
|
|
24
25
|
import { wakeIssueAssigneeAfterChatConversion } from "./chat-issue-assignment-wakeup.js";
|
|
25
26
|
import { createChatAnnotationRouteHelpers, turnContextFromUserMessage, } from "./chats.annotation-routes.js";
|
|
@@ -33,7 +34,7 @@ function chatVisibleOutputAdmissionClosed(error) {
|
|
|
33
34
|
&& error.status === 409
|
|
34
35
|
&& error.message === "Chat-visible output admission is closed for this generation";
|
|
35
36
|
}
|
|
36
|
-
export function chatRoutes(db, storage, backgroundRuntime = createChatBackgroundRuntime()) {
|
|
37
|
+
export function chatRoutes(db, storage, backgroundRuntime = createChatBackgroundRuntime(), registerNetworkWaitingRunHandler) {
|
|
37
38
|
const router = Router();
|
|
38
39
|
const svc = chatService(db);
|
|
39
40
|
const organizationsSvc = organizationService(db);
|
|
@@ -47,7 +48,14 @@ export function chatRoutes(db, storage, backgroundRuntime = createChatBackground
|
|
|
47
48
|
const chatRunsSvc = chatAgentRunService(db);
|
|
48
49
|
const workManifestSvc = chatWorkManifestService(db);
|
|
49
50
|
const operatorProfiles = operatorProfileService(db);
|
|
50
|
-
|
|
51
|
+
let recoverNetworkWaitingChatRun = null;
|
|
52
|
+
const heartbeat = heartbeatService(db, {
|
|
53
|
+
onNetworkWaitingRun: async (run) => {
|
|
54
|
+
if (!recoverNetworkWaitingChatRun)
|
|
55
|
+
return false;
|
|
56
|
+
return recoverNetworkWaitingChatRun(run);
|
|
57
|
+
},
|
|
58
|
+
});
|
|
51
59
|
const productIntelligence = productIntelligenceService(db);
|
|
52
60
|
const chatTitles = chatTitleGenerationService({ chats: svc, productIntelligence });
|
|
53
61
|
const steerMessages = chatSteerMessageService(db);
|
|
@@ -76,6 +84,25 @@ export function chatRoutes(db, storage, backgroundRuntime = createChatBackground
|
|
|
76
84
|
storage: multer.memoryStorage(),
|
|
77
85
|
limits: { fileSize: MAX_ATTACHMENT_BYTES, files: 10 },
|
|
78
86
|
});
|
|
87
|
+
router.param("id", async (req, _res, next, rawId) => {
|
|
88
|
+
try {
|
|
89
|
+
if (parseShortRef(rawId)?.kind !== "chat") {
|
|
90
|
+
next();
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const resolved = await svc.resolveByReference(rawId, getAuthorizedOrgScope(req));
|
|
94
|
+
if (resolved.ambiguous) {
|
|
95
|
+
throw conflict(`Chat reference ${rawId} is ambiguous; use a longer reference or the full UUID`);
|
|
96
|
+
}
|
|
97
|
+
if (!resolved.conversation)
|
|
98
|
+
throw notFound("Chat conversation not found");
|
|
99
|
+
req.params.id = resolved.conversation.id;
|
|
100
|
+
next();
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
next(error);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
79
106
|
async function runSingleFileUpload(req, res) {
|
|
80
107
|
await new Promise((resolve, reject) => {
|
|
81
108
|
upload.single("file")(req, res, (err) => {
|
|
@@ -1088,6 +1115,7 @@ export function chatRoutes(db, storage, backgroundRuntime = createChatBackground
|
|
|
1088
1115
|
userMessageId: userMessage.id,
|
|
1089
1116
|
chatTurnId: turnContext.chatTurnId,
|
|
1090
1117
|
turnVariant: turnContext.turnVariant,
|
|
1118
|
+
runContext: { chatGenerationId: claim.generationId },
|
|
1091
1119
|
stream: false,
|
|
1092
1120
|
abortSignal: abortController.signal,
|
|
1093
1121
|
controlCoordinator: createChatRuntimeControlCoordinator(conversation.id, claim.generationId, {
|
|
@@ -1193,6 +1221,11 @@ export function chatRoutes(db, storage, backgroundRuntime = createChatBackground
|
|
|
1193
1221
|
});
|
|
1194
1222
|
}
|
|
1195
1223
|
}
|
|
1224
|
+
else if (streamed.outcome === "waiting_for_network") {
|
|
1225
|
+
// The durable generation remains open; the background recovery path
|
|
1226
|
+
// will reattach and project the eventual assistant result.
|
|
1227
|
+
return;
|
|
1228
|
+
}
|
|
1196
1229
|
else {
|
|
1197
1230
|
let completionMessageId = null;
|
|
1198
1231
|
try {
|
|
@@ -1304,6 +1337,310 @@ export function chatRoutes(db, storage, backgroundRuntime = createChatBackground
|
|
|
1304
1337
|
managedAbort.release();
|
|
1305
1338
|
}
|
|
1306
1339
|
}
|
|
1340
|
+
/** Resume a Chat generation that the heartbeat coordinator woke from a
|
|
1341
|
+
* durable network wait. This path deliberately shares the existing
|
|
1342
|
+
* generation/run rows instead of creating a second active Chat run. */
|
|
1343
|
+
async function runRecoveredNetworkWaitingChatRun(run) {
|
|
1344
|
+
const context = run.contextSnapshot && typeof run.contextSnapshot === "object"
|
|
1345
|
+
&& !Array.isArray(run.contextSnapshot)
|
|
1346
|
+
? run.contextSnapshot
|
|
1347
|
+
: {};
|
|
1348
|
+
const conversationId = run.chatConversationId
|
|
1349
|
+
?? (typeof context.conversationId === "string" ? context.conversationId : null);
|
|
1350
|
+
const generationId = typeof context.chatGenerationId === "string"
|
|
1351
|
+
? context.chatGenerationId
|
|
1352
|
+
: null;
|
|
1353
|
+
const nonStreamChatRun = context.chatMode === "non_stream";
|
|
1354
|
+
const userMessageId = typeof context.userMessageId === "string"
|
|
1355
|
+
? context.userMessageId
|
|
1356
|
+
: typeof context.messageId === "string"
|
|
1357
|
+
? context.messageId
|
|
1358
|
+
: null;
|
|
1359
|
+
const ownerToken = typeof run.executionOwnerToken === "string" ? run.executionOwnerToken : null;
|
|
1360
|
+
if (!conversationId || (!generationId && !nonStreamChatRun) || !userMessageId || !ownerToken) {
|
|
1361
|
+
logger.error({ runId: run.id }, "network-wait Chat run is missing recovery context");
|
|
1362
|
+
return false;
|
|
1363
|
+
}
|
|
1364
|
+
const conversation = await svc.getById(conversationId);
|
|
1365
|
+
const userMessage = conversation
|
|
1366
|
+
? await svc.getMessage(conversation.id, userMessageId)
|
|
1367
|
+
: null;
|
|
1368
|
+
if (!conversation || !userMessage) {
|
|
1369
|
+
logger.error({ runId: run.id, conversationId, generationId }, "network-wait Chat recovery target is missing");
|
|
1370
|
+
return false;
|
|
1371
|
+
}
|
|
1372
|
+
const abortController = new AbortController();
|
|
1373
|
+
const managedAbort = backgroundRuntime.manageAbortController(abortController);
|
|
1374
|
+
const releaseGeneration = claimChatGeneration(conversation.id, abortController, generationId);
|
|
1375
|
+
if (!releaseGeneration) {
|
|
1376
|
+
managedAbort.release();
|
|
1377
|
+
return true;
|
|
1378
|
+
}
|
|
1379
|
+
const request = requestForQueuedActor({
|
|
1380
|
+
type: "board",
|
|
1381
|
+
source: "local_implicit",
|
|
1382
|
+
userId: "local-board",
|
|
1383
|
+
isInstanceAdmin: true,
|
|
1384
|
+
}, conversation.orgId);
|
|
1385
|
+
const actor = getActorInfo(request);
|
|
1386
|
+
let assistantConversation = conversation;
|
|
1387
|
+
let activeAttemptEpoch = Math.max(1, Number(context.attemptEpoch) || 1);
|
|
1388
|
+
let activeChatRunId = run.id;
|
|
1389
|
+
let partialBody = "";
|
|
1390
|
+
let assistantProjectionMessageId = null;
|
|
1391
|
+
let transcript = [];
|
|
1392
|
+
let terminalStatus = "failed";
|
|
1393
|
+
let terminalReason = null;
|
|
1394
|
+
let waitingAgain = false;
|
|
1395
|
+
try {
|
|
1396
|
+
if (generationId) {
|
|
1397
|
+
const frozen = await svc.generationProtocol.getFrozenVisibleProjection({
|
|
1398
|
+
orgId: conversation.orgId,
|
|
1399
|
+
conversationId: conversation.id,
|
|
1400
|
+
generationId,
|
|
1401
|
+
});
|
|
1402
|
+
partialBody = frozen.projection.body;
|
|
1403
|
+
assistantProjectionMessageId = frozen.projection.assistantMessageId;
|
|
1404
|
+
transcript = [...frozen.projection.transcript];
|
|
1405
|
+
activeAttemptEpoch = Math.max(1, frozen.generation.attemptEpoch);
|
|
1406
|
+
if (!run.networkRecoveryExhausted) {
|
|
1407
|
+
await svc.generationProtocol.markNetworkResumed({
|
|
1408
|
+
orgId: conversation.orgId,
|
|
1409
|
+
conversationId: conversation.id,
|
|
1410
|
+
generationId,
|
|
1411
|
+
expectedAttemptEpoch: activeAttemptEpoch,
|
|
1412
|
+
});
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
if (run.networkRecoveryExhausted) {
|
|
1416
|
+
throw new ChatAssistantStreamError(NETWORK_WAIT_EXHAUSTED_ERROR, partialBody, [], {
|
|
1417
|
+
errorCode: NETWORK_WAIT_EXHAUSTED_ERROR_CODE,
|
|
1418
|
+
userMessage: "Network recovery retries were exhausted. Check connectivity, then retry this reply.",
|
|
1419
|
+
retryable: true,
|
|
1420
|
+
failurePhase: "model_generation",
|
|
1421
|
+
action: "retry",
|
|
1422
|
+
});
|
|
1423
|
+
}
|
|
1424
|
+
const turnContext = turnContextFromUserMessage(userMessage);
|
|
1425
|
+
const assistantInput = await loadAssistantInput(conversation, actor);
|
|
1426
|
+
assistantConversation = assistantInput.conversation;
|
|
1427
|
+
const controlCoordinator = generationId
|
|
1428
|
+
? createChatRuntimeControlCoordinator(conversation.id, generationId, {
|
|
1429
|
+
onAttemptStarted: async ({ generationId: currentGenerationId, attemptEpoch, ownerToken: attemptOwnerToken, attempt }) => {
|
|
1430
|
+
activeAttemptEpoch = attemptEpoch;
|
|
1431
|
+
await svc.beginGenerationControlAttempt({
|
|
1432
|
+
orgId: conversation.orgId,
|
|
1433
|
+
conversationId: conversation.id,
|
|
1434
|
+
generationId: currentGenerationId,
|
|
1435
|
+
attemptEpoch,
|
|
1436
|
+
ownerToken: attemptOwnerToken,
|
|
1437
|
+
runtimeType: attempt.runtimeType,
|
|
1438
|
+
});
|
|
1439
|
+
},
|
|
1440
|
+
onHandleRegistered: async ({ generationId: currentGenerationId, attemptEpoch, ownerToken: attemptOwnerToken, handle }) => {
|
|
1441
|
+
await svc.markGenerationControlReady({
|
|
1442
|
+
generationId: currentGenerationId,
|
|
1443
|
+
attemptEpoch,
|
|
1444
|
+
ownerToken: attemptOwnerToken,
|
|
1445
|
+
runtimeType: handle.runtimeType,
|
|
1446
|
+
providerThreadId: handle.providerThreadId ?? null,
|
|
1447
|
+
providerTurnId: handle.providerTurnId ?? null,
|
|
1448
|
+
});
|
|
1449
|
+
},
|
|
1450
|
+
onAttemptLeaseRenewed: async ({ generationId: currentGenerationId, attemptEpoch, ownerToken: attemptOwnerToken }) => {
|
|
1451
|
+
await svc.renewGenerationControlLease({
|
|
1452
|
+
generationId: currentGenerationId,
|
|
1453
|
+
attemptEpoch,
|
|
1454
|
+
ownerToken: attemptOwnerToken,
|
|
1455
|
+
});
|
|
1456
|
+
},
|
|
1457
|
+
onAttemptCompleted: async ({ generationId: currentGenerationId, attemptEpoch, ownerToken: attemptOwnerToken }) => {
|
|
1458
|
+
await svc.markGenerationControlAttemptCompleted({
|
|
1459
|
+
generationId: currentGenerationId,
|
|
1460
|
+
attemptEpoch,
|
|
1461
|
+
ownerToken: attemptOwnerToken,
|
|
1462
|
+
});
|
|
1463
|
+
},
|
|
1464
|
+
})
|
|
1465
|
+
: undefined;
|
|
1466
|
+
const streamed = await assistantSvc.streamChatAssistantReply({
|
|
1467
|
+
...assistantInput,
|
|
1468
|
+
userMessageId: userMessage.id,
|
|
1469
|
+
chatTurnId: turnContext.chatTurnId,
|
|
1470
|
+
turnVariant: turnContext.turnVariant,
|
|
1471
|
+
runContext: { chatGenerationId: generationId },
|
|
1472
|
+
resumeRunId: run.id,
|
|
1473
|
+
resumeRunOwnerToken: ownerToken,
|
|
1474
|
+
stream: false,
|
|
1475
|
+
abortSignal: abortController.signal,
|
|
1476
|
+
controlCoordinator,
|
|
1477
|
+
onRunCreated: (recoveredRunId) => {
|
|
1478
|
+
activeChatRunId = recoveredRunId;
|
|
1479
|
+
},
|
|
1480
|
+
onWaitingForNetwork: async (suspension) => {
|
|
1481
|
+
if (!generationId) {
|
|
1482
|
+
waitingAgain = true;
|
|
1483
|
+
return;
|
|
1484
|
+
}
|
|
1485
|
+
const marked = await svc.generationProtocol.markWaitingForNetwork({
|
|
1486
|
+
orgId: conversation.orgId,
|
|
1487
|
+
conversationId: conversation.id,
|
|
1488
|
+
generationId,
|
|
1489
|
+
expectedAttemptEpoch: activeAttemptEpoch,
|
|
1490
|
+
suspension: suspension,
|
|
1491
|
+
});
|
|
1492
|
+
if (marked.stopped) {
|
|
1493
|
+
terminalStatus = "stopped";
|
|
1494
|
+
terminalReason = "operator_stop";
|
|
1495
|
+
if (!abortController.signal.aborted)
|
|
1496
|
+
abortController.abort();
|
|
1497
|
+
return;
|
|
1498
|
+
}
|
|
1499
|
+
waitingAgain = true;
|
|
1500
|
+
},
|
|
1501
|
+
onAssistantDelta: async (delta) => {
|
|
1502
|
+
if (abortController.signal.aborted)
|
|
1503
|
+
return;
|
|
1504
|
+
const projectedBody = `${partialBody}${delta}`;
|
|
1505
|
+
if (!generationId) {
|
|
1506
|
+
partialBody = projectedBody;
|
|
1507
|
+
return;
|
|
1508
|
+
}
|
|
1509
|
+
const projection = await svc.generationProtocol.appendVisibleEventAndProject({
|
|
1510
|
+
orgId: conversation.orgId,
|
|
1511
|
+
conversationId: conversation.id,
|
|
1512
|
+
generationId,
|
|
1513
|
+
expectedAttemptEpoch: activeAttemptEpoch,
|
|
1514
|
+
eventKind: "assistant_delta",
|
|
1515
|
+
payload: { delta },
|
|
1516
|
+
bodyOffset: partialBody.length,
|
|
1517
|
+
bodyLength: delta.length,
|
|
1518
|
+
messageId: assistantProjectionMessageId,
|
|
1519
|
+
runId: activeChatRunId,
|
|
1520
|
+
bodyHash: hashChatGenerationBody(projectedBody),
|
|
1521
|
+
body: projectedBody,
|
|
1522
|
+
replyingAgentId: chatReplyingAgentId(assistantConversation),
|
|
1523
|
+
chatTurnId: turnContext.chatTurnId,
|
|
1524
|
+
turnVariant: turnContext.turnVariant,
|
|
1525
|
+
});
|
|
1526
|
+
assistantProjectionMessageId = projection.message.id;
|
|
1527
|
+
partialBody = projectedBody;
|
|
1528
|
+
},
|
|
1529
|
+
onTranscriptEntry: async (entry) => {
|
|
1530
|
+
if (abortController.signal.aborted)
|
|
1531
|
+
return;
|
|
1532
|
+
transcript.push(entry);
|
|
1533
|
+
if (!generationId)
|
|
1534
|
+
return;
|
|
1535
|
+
const projection = await svc.generationProtocol.appendVisibleEventAndProject({
|
|
1536
|
+
orgId: conversation.orgId,
|
|
1537
|
+
conversationId: conversation.id,
|
|
1538
|
+
generationId,
|
|
1539
|
+
expectedAttemptEpoch: activeAttemptEpoch,
|
|
1540
|
+
eventKind: "transcript",
|
|
1541
|
+
payload: { entry },
|
|
1542
|
+
messageId: assistantProjectionMessageId,
|
|
1543
|
+
runId: activeChatRunId,
|
|
1544
|
+
bodyHash: hashChatGenerationBody(partialBody),
|
|
1545
|
+
body: partialBody,
|
|
1546
|
+
replyingAgentId: chatReplyingAgentId(assistantConversation),
|
|
1547
|
+
chatTurnId: turnContext.chatTurnId,
|
|
1548
|
+
turnVariant: turnContext.turnVariant,
|
|
1549
|
+
});
|
|
1550
|
+
assistantProjectionMessageId = projection.message.id;
|
|
1551
|
+
},
|
|
1552
|
+
});
|
|
1553
|
+
partialBody = streamed.partialBody || partialBody;
|
|
1554
|
+
if (waitingAgain || streamed.outcome === "waiting_for_network")
|
|
1555
|
+
return true;
|
|
1556
|
+
if (abortController.signal.aborted || streamed.outcome === "stopped") {
|
|
1557
|
+
terminalStatus = "stopped";
|
|
1558
|
+
terminalReason = "operator_stop";
|
|
1559
|
+
const stoppedMessage = await persistPartialAssistantMessage(assistantConversation, partialBody, "stopped", turnContext, transcript, streamed.replyingAgentId, assistantProjectionMessageId, activeChatRunId, undefined, false);
|
|
1560
|
+
if (stoppedMessage) {
|
|
1561
|
+
await linkChatRunMessages(assistantConversation, activeChatRunId, [stoppedMessage]);
|
|
1562
|
+
await logChatMessagesAdded(assistantConversation, [stoppedMessage], {
|
|
1563
|
+
actorType: "system",
|
|
1564
|
+
actorId: "chat-assistant",
|
|
1565
|
+
agentId: streamed.replyingAgentId,
|
|
1566
|
+
});
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
else {
|
|
1570
|
+
const completionMessageId = generationId
|
|
1571
|
+
? (await svc.generationProtocol.appendVisibleEventAndProject({
|
|
1572
|
+
orgId: conversation.orgId,
|
|
1573
|
+
conversationId: conversation.id,
|
|
1574
|
+
generationId,
|
|
1575
|
+
expectedAttemptEpoch: activeAttemptEpoch,
|
|
1576
|
+
eventKind: "runtime_output",
|
|
1577
|
+
payload: { resultKind: streamed.reply.kind, body: streamed.reply.body },
|
|
1578
|
+
bodyOffset: 0,
|
|
1579
|
+
bodyLength: streamed.reply.body.length,
|
|
1580
|
+
messageId: assistantProjectionMessageId,
|
|
1581
|
+
runId: activeChatRunId,
|
|
1582
|
+
bodyHash: hashChatGenerationBody(streamed.reply.body),
|
|
1583
|
+
body: streamed.reply.body,
|
|
1584
|
+
replyingAgentId: streamed.replyingAgentId,
|
|
1585
|
+
chatTurnId: turnContext.chatTurnId,
|
|
1586
|
+
turnVariant: turnContext.turnVariant,
|
|
1587
|
+
})).message.id
|
|
1588
|
+
: null;
|
|
1589
|
+
const createdMessages = await persistAssistantReply(request, assistantConversation, actor, streamed.reply, turnContext, transcript, streamed.replyingAgentId, completionMessageId, activeChatRunId, false);
|
|
1590
|
+
await linkChatRunMessages(assistantConversation, activeChatRunId, createdMessages);
|
|
1591
|
+
await logChatMessagesAdded(assistantConversation, createdMessages, {
|
|
1592
|
+
actorType: "system",
|
|
1593
|
+
actorId: "chat-assistant",
|
|
1594
|
+
agentId: streamed.replyingAgentId,
|
|
1595
|
+
});
|
|
1596
|
+
terminalStatus = "completed";
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
catch (error) {
|
|
1600
|
+
terminalStatus = abortController.signal.aborted ? "aborted" : "failed";
|
|
1601
|
+
terminalReason = error instanceof Error ? error.message : "network_wait_chat_recovery_failed";
|
|
1602
|
+
const failurePayload = recoverableFailurePayload(error, activeChatRunId);
|
|
1603
|
+
const failureBody = userVisiblePartialBodyFromError(error)
|
|
1604
|
+
|| recoverableFailureBody(failurePayload)
|
|
1605
|
+
|| CHAT_ASSISTANT_USER_ERROR_MESSAGE;
|
|
1606
|
+
const failedMessage = await persistPartialAssistantMessage(assistantConversation, failureBody, "failed", null, transcript, chatReplyingAgentId(assistantConversation), assistantProjectionMessageId, activeChatRunId, failurePayload, false).catch(() => null);
|
|
1607
|
+
if (failedMessage) {
|
|
1608
|
+
await linkChatRunMessages(assistantConversation, activeChatRunId, [failedMessage]).catch(() => undefined);
|
|
1609
|
+
await logChatMessagesAdded(assistantConversation, [failedMessage], {
|
|
1610
|
+
actorType: "system",
|
|
1611
|
+
actorId: "chat-assistant",
|
|
1612
|
+
agentId: chatReplyingAgentId(assistantConversation),
|
|
1613
|
+
}).catch(() => undefined);
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
finally {
|
|
1617
|
+
if (!waitingAgain && generationId) {
|
|
1618
|
+
const latestGeneration = await svc.getLatestGeneration(conversation.id).catch(() => null);
|
|
1619
|
+
if (latestGeneration?.id === generationId) {
|
|
1620
|
+
const terminalEvidence = await svc.generationProtocol.recordRuntimeTerminal({
|
|
1621
|
+
orgId: conversation.orgId,
|
|
1622
|
+
conversationId: conversation.id,
|
|
1623
|
+
generationId,
|
|
1624
|
+
expectedAttemptEpoch: latestGeneration.attemptEpoch,
|
|
1625
|
+
expectedOwnerToken: latestGeneration.controlOwnerToken,
|
|
1626
|
+
finalStatus: terminalStatus,
|
|
1627
|
+
terminalReason: terminalReason ?? terminalStatus,
|
|
1628
|
+
}).catch((error) => {
|
|
1629
|
+
logger.warn({ err: error, generationId }, "failed to record recovered Chat terminal evidence");
|
|
1630
|
+
return null;
|
|
1631
|
+
});
|
|
1632
|
+
if (terminalEvidence)
|
|
1633
|
+
wakeTerminalProjector();
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
chatRunsSvc.releaseOwnedRun(run.id, ownerToken);
|
|
1637
|
+
releaseGeneration();
|
|
1638
|
+
managedAbort.release();
|
|
1639
|
+
}
|
|
1640
|
+
return true;
|
|
1641
|
+
}
|
|
1642
|
+
recoverNetworkWaitingChatRun = runRecoveredNetworkWaitingChatRun;
|
|
1643
|
+
registerNetworkWaitingRunHandler?.(runRecoveredNetworkWaitingChatRun);
|
|
1307
1644
|
async function drainServerQueue() {
|
|
1308
1645
|
await svc.recoverExpiredServerQueueClaims();
|
|
1309
1646
|
while (backgroundRuntime.acceptingWork
|
|
@@ -1760,7 +2097,10 @@ export function chatRoutes(db, storage, backgroundRuntime = createChatBackground
|
|
|
1760
2097
|
return;
|
|
1761
2098
|
}
|
|
1762
2099
|
const active = getActiveChatGeneration(conversation.id);
|
|
1763
|
-
|
|
2100
|
+
const snapshot = active
|
|
2101
|
+
? await svc.getQueueSnapshot(conversation.id, active.generationId)
|
|
2102
|
+
: await svc.getQueueSnapshot(conversation.id);
|
|
2103
|
+
res.json(snapshot);
|
|
1764
2104
|
});
|
|
1765
2105
|
router.post("/chats/:id/queue", async (req, res) => {
|
|
1766
2106
|
const conversation = await assertConversationAccess(req, req.params.id);
|
|
@@ -2484,6 +2824,7 @@ export function chatRoutes(db, storage, backgroundRuntime = createChatBackground
|
|
|
2484
2824
|
}
|
|
2485
2825
|
const turnContext = turnContextFromUserMessage(userMessage);
|
|
2486
2826
|
let activeChatRunId = null;
|
|
2827
|
+
let networkWaiting = false;
|
|
2487
2828
|
const persistedAssistantMessages = await (async () => {
|
|
2488
2829
|
const assistantInput = await loadAssistantInput(conversation, actor);
|
|
2489
2830
|
const transcript = [];
|
|
@@ -2495,6 +2836,7 @@ export function chatRoutes(db, storage, backgroundRuntime = createChatBackground
|
|
|
2495
2836
|
userMessageId: userMessage.id,
|
|
2496
2837
|
chatTurnId: turnContext.chatTurnId,
|
|
2497
2838
|
turnVariant: turnContext.turnVariant,
|
|
2839
|
+
runContext: { chatMode: "non_stream" },
|
|
2498
2840
|
stream: false,
|
|
2499
2841
|
onRunCreated: (runId) => {
|
|
2500
2842
|
activeChatRunId = runId;
|
|
@@ -2504,6 +2846,10 @@ export function chatRoutes(db, storage, backgroundRuntime = createChatBackground
|
|
|
2504
2846
|
},
|
|
2505
2847
|
});
|
|
2506
2848
|
fallbackOutput = streamed.partialBody;
|
|
2849
|
+
if (streamed.outcome === "waiting_for_network") {
|
|
2850
|
+
networkWaiting = true;
|
|
2851
|
+
return [];
|
|
2852
|
+
}
|
|
2507
2853
|
if (streamed.outcome !== "completed") {
|
|
2508
2854
|
throw new Error("Chat assistant reply was stopped before completion");
|
|
2509
2855
|
}
|
|
@@ -2538,7 +2884,10 @@ export function chatRoutes(db, storage, backgroundRuntime = createChatBackground
|
|
|
2538
2884
|
}
|
|
2539
2885
|
})();
|
|
2540
2886
|
const createdMessages = [userMessage, ...persistedAssistantMessages];
|
|
2541
|
-
res.status(201).json({
|
|
2887
|
+
res.status(networkWaiting ? 202 : 201).json({
|
|
2888
|
+
messages: createdMessages,
|
|
2889
|
+
...(networkWaiting ? { waitingForNetwork: true, runId: activeChatRunId } : {}),
|
|
2890
|
+
});
|
|
2542
2891
|
}
|
|
2543
2892
|
catch (err) {
|
|
2544
2893
|
logger.warn({
|