@rudderhq/server 0.2.0-canary.8 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bootstrap/register-api-routes.d.ts.map +1 -1
- package/dist/bootstrap/register-api-routes.js +2 -0
- package/dist/bootstrap/register-api-routes.js.map +1 -1
- package/dist/bundled-plugins/plugin-linear/dist/ui/index.js +8 -1
- package/dist/bundled-plugins/plugin-linear/dist/ui/index.js.map +2 -2
- package/dist/bundled-plugins/plugin-linear/dist/worker.js +124 -117
- package/dist/bundled-plugins/plugin-linear/dist/worker.js.map +3 -3
- package/dist/home-paths.d.ts +2 -0
- package/dist/home-paths.d.ts.map +1 -1
- package/dist/home-paths.js +6 -1
- package/dist/home-paths.js.map +1 -1
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +55 -2
- package/dist/index.js.map +1 -1
- package/dist/langfuse-transcript.d.ts.map +1 -1
- package/dist/langfuse-transcript.js +16 -2
- package/dist/langfuse-transcript.js.map +1 -1
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +54 -1
- package/dist/middleware/auth.js.map +1 -1
- package/dist/onboarding-assets/ceo/HEARTBEAT.md +8 -4
- package/dist/onboarding-assets/default/HEARTBEAT.md +7 -4
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +62 -3
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/approvals.d.ts.map +1 -1
- package/dist/routes/approvals.js +30 -1
- package/dist/routes/approvals.js.map +1 -1
- package/dist/routes/chats.d.ts.map +1 -1
- package/dist/routes/chats.js +343 -53
- package/dist/routes/chats.js.map +1 -1
- package/dist/routes/costs.d.ts.map +1 -1
- package/dist/routes/costs.js +20 -0
- package/dist/routes/costs.js.map +1 -1
- package/dist/routes/issues.d.ts.map +1 -1
- package/dist/routes/issues.js +229 -19
- package/dist/routes/issues.js.map +1 -1
- package/dist/routes/onboarding.d.ts +3 -0
- package/dist/routes/onboarding.d.ts.map +1 -0
- package/dist/routes/onboarding.js +545 -0
- package/dist/routes/onboarding.js.map +1 -0
- package/dist/routes/orgs.d.ts.map +1 -1
- package/dist/routes/orgs.js +22 -0
- package/dist/routes/orgs.js.map +1 -1
- package/dist/services/activity.d.ts.map +1 -1
- package/dist/services/activity.js +32 -1
- package/dist/services/activity.js.map +1 -1
- package/dist/services/agent-run-context.d.ts +1 -32
- package/dist/services/agent-run-context.d.ts.map +1 -1
- package/dist/services/agent-run-context.js +26 -128
- package/dist/services/agent-run-context.js.map +1 -1
- package/dist/services/agents.d.ts +26 -26
- package/dist/services/agents.d.ts.map +1 -1
- package/dist/services/agents.js +1 -42
- package/dist/services/agents.js.map +1 -1
- package/dist/services/assets.d.ts +2 -2
- package/dist/services/automations.d.ts +2 -2
- package/dist/services/calendar.d.ts +4 -4
- package/dist/services/chat-assistant.d.ts +12 -3
- package/dist/services/chat-assistant.d.ts.map +1 -1
- package/dist/services/chat-assistant.js +126 -99
- package/dist/services/chat-assistant.js.map +1 -1
- package/dist/services/chats.d.ts +88 -15
- package/dist/services/chats.d.ts.map +1 -1
- package/dist/services/chats.js +217 -14
- package/dist/services/chats.js.map +1 -1
- package/dist/services/costs.d.ts +21 -0
- package/dist/services/costs.d.ts.map +1 -1
- package/dist/services/costs.js +76 -2
- package/dist/services/costs.js.map +1 -1
- package/dist/services/finance.d.ts +2 -2
- package/dist/services/goals.d.ts +12 -12
- package/dist/services/instance-settings.d.ts.map +1 -1
- package/dist/services/instance-settings.js +25 -16
- package/dist/services/instance-settings.js.map +1 -1
- package/dist/services/issue-review-wakeup.d.ts +49 -1
- package/dist/services/issue-review-wakeup.d.ts.map +1 -1
- package/dist/services/issue-review-wakeup.js +39 -2
- package/dist/services/issue-review-wakeup.js.map +1 -1
- package/dist/services/issues.d.ts +2 -1
- package/dist/services/issues.d.ts.map +1 -1
- package/dist/services/issues.js +126 -5
- package/dist/services/issues.js.map +1 -1
- package/dist/services/knowledge-portability/organization-skills.d.ts +1 -0
- package/dist/services/knowledge-portability/organization-skills.d.ts.map +1 -1
- package/dist/services/knowledge-portability/organization-skills.js +3 -2
- package/dist/services/knowledge-portability/organization-skills.js.map +1 -1
- package/dist/services/messenger.d.ts +5 -0
- package/dist/services/messenger.d.ts.map +1 -1
- package/dist/services/messenger.js +165 -11
- package/dist/services/messenger.js.map +1 -1
- package/dist/services/organization-workspace-browser.d.ts.map +1 -1
- package/dist/services/organization-workspace-browser.js +64 -9
- package/dist/services/organization-workspace-browser.js.map +1 -1
- package/dist/services/orgs.d.ts +1 -13
- package/dist/services/orgs.d.ts.map +1 -1
- package/dist/services/orgs.js +0 -2
- package/dist/services/orgs.js.map +1 -1
- package/dist/services/plugin-registry.d.ts +4 -4
- package/dist/services/projects.d.ts +1 -1
- package/dist/services/runtime-kernel/heartbeat.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.js +567 -29
- package/dist/services/runtime-kernel/heartbeat.js.map +1 -1
- package/dist/services/secrets.d.ts +5 -5
- package/dist/services/workspace-backups.d.ts.map +1 -1
- package/dist/services/workspace-backups.js +6 -0
- package/dist/services/workspace-backups.js.map +1 -1
- package/dist/services/workspace-runtime.d.ts.map +1 -1
- package/dist/services/workspace-runtime.js +2 -0
- package/dist/services/workspace-runtime.js.map +1 -1
- package/package.json +13 -13
- package/resources/bundled-skills/rudder/SKILL.md +72 -7
- package/resources/bundled-skills/rudder/references/cli-reference.md +34 -9
- package/resources/bundled-skills/rudder/references/organization-skills.md +12 -7
- package/resources/bundled-skills/rudder-create-agent/references/cli-reference.md +1 -0
- package/skills/rudder/SKILL.md +72 -7
- package/skills/rudder/references/cli-reference.md +34 -9
- package/skills/rudder/references/organization-skills.md +12 -7
- package/skills/rudder-create-agent/references/cli-reference.md +1 -0
- package/ui-dist/assets/{_basePickBy-DfISC403.js → _basePickBy-3Hg7N37c.js} +1 -1
- package/ui-dist/assets/{_baseUniq-s98gUpgR.js → _baseUniq-Bvy8WJh0.js} +1 -1
- package/ui-dist/assets/{arc-CR17323Q.js → arc-DrmvGX4U.js} +1 -1
- package/ui-dist/assets/{architectureDiagram-2XIMDMQ5-BzXAflU_.js → architectureDiagram-2XIMDMQ5-vbevcV-8.js} +1 -1
- package/ui-dist/assets/{blockDiagram-WCTKOSBZ-8TtjJ3eI.js → blockDiagram-WCTKOSBZ-DvupMRN9.js} +1 -1
- package/ui-dist/assets/{c4Diagram-IC4MRINW-CpDAvPEk.js → c4Diagram-IC4MRINW-CbsNVA8e.js} +1 -1
- package/ui-dist/assets/channel-DhW0A-FV.js +1 -0
- package/ui-dist/assets/{chunk-4BX2VUAB-DH5y5IcG.js → chunk-4BX2VUAB-BL4OUqNV.js} +1 -1
- package/ui-dist/assets/{chunk-55IACEB6-HUQ0oHmD.js → chunk-55IACEB6-DFwq2ebc.js} +1 -1
- package/ui-dist/assets/{chunk-FMBD7UC4-B_Tmn_aT.js → chunk-FMBD7UC4-Cyl6kF9G.js} +1 -1
- package/ui-dist/assets/{chunk-JSJVCQXG-COsiBBS-.js → chunk-JSJVCQXG-v4mfLtsY.js} +1 -1
- package/ui-dist/assets/{chunk-KX2RTZJC-Cvg_71ig.js → chunk-KX2RTZJC-Bfg48g5k.js} +1 -1
- package/ui-dist/assets/{chunk-NQ4KR5QH-BEW2kuUb.js → chunk-NQ4KR5QH-BcSdbequ.js} +1 -1
- package/ui-dist/assets/{chunk-QZHKN3VN-Bna2V6NY.js → chunk-QZHKN3VN-BT8QI712.js} +1 -1
- package/ui-dist/assets/{chunk-WL4C6EOR-DZ8gtX-v.js → chunk-WL4C6EOR-CqH2or9g.js} +1 -1
- package/ui-dist/assets/classDiagram-VBA2DB6C-Bw6kzUsz.js +1 -0
- package/ui-dist/assets/classDiagram-v2-RAHNMMFH-Bw6kzUsz.js +1 -0
- package/ui-dist/assets/clone-Luak8Fsn.js +1 -0
- package/ui-dist/assets/{cose-bilkent-S5V4N54A-kr92BRef.js → cose-bilkent-S5V4N54A-CLH06Lnz.js} +1 -1
- package/ui-dist/assets/{dagre-KLK3FWXG-D_g61aoF.js → dagre-KLK3FWXG-DxNQPDBj.js} +1 -1
- package/ui-dist/assets/{diagram-E7M64L7V-1LfSj6n8.js → diagram-E7M64L7V-BOcSeWh0.js} +1 -1
- package/ui-dist/assets/{diagram-IFDJBPK2-DK364c5M.js → diagram-IFDJBPK2-DXyaFKVr.js} +1 -1
- package/ui-dist/assets/{diagram-P4PSJMXO-CIq22L7l.js → diagram-P4PSJMXO-DhY_ls3C.js} +1 -1
- package/ui-dist/assets/{erDiagram-INFDFZHY-C2QX1WzN.js → erDiagram-INFDFZHY-QtL5Yt_b.js} +1 -1
- package/ui-dist/assets/{flowDiagram-PKNHOUZH-BXk0KTTB.js → flowDiagram-PKNHOUZH-BYqyaowc.js} +1 -1
- package/ui-dist/assets/{ganttDiagram-A5KZAMGK-D75CuaPG.js → ganttDiagram-A5KZAMGK-D4xd7J_z.js} +1 -1
- package/ui-dist/assets/{gitGraphDiagram-K3NZZRJ6-C_SvdzO5.js → gitGraphDiagram-K3NZZRJ6-Co9xqKNH.js} +1 -1
- package/ui-dist/assets/{graph-DTC5egc-.js → graph-DEC7S98H.js} +1 -1
- package/ui-dist/assets/{index-CEKv8ksn.js → index-4_gJOU3u.js} +1 -1
- package/ui-dist/assets/{index-CSzr8t_E.js → index-B8QjK4Xd.js} +1 -1
- package/ui-dist/assets/index-BLDnKx7N.js +1478 -0
- package/ui-dist/assets/{index-CqKwXFnI.js → index-BX6QyxsL.js} +1 -1
- package/ui-dist/assets/{index-DmSssfNa.js → index-BZGiyL9p.js} +1 -1
- package/ui-dist/assets/{index-BLvouPW7.js → index-BelfAyHh.js} +1 -1
- package/ui-dist/assets/index-BisI78wU.css +1 -0
- package/ui-dist/assets/{index-BUyOio4T.js → index-Bm86s0IY.js} +1 -1
- package/ui-dist/assets/{index-DLL28Pwh.js → index-Bz0jEwWG.js} +1 -1
- package/ui-dist/assets/{index--j9y8Fm1.js → index-CFANc8oH.js} +1 -1
- package/ui-dist/assets/{index-CjmpD1gl.js → index-CIAMqUzr.js} +1 -1
- package/ui-dist/assets/{index-lXemkB72.js → index-ClrueuiI.js} +1 -1
- package/ui-dist/assets/{index-D9UMKH7j.js → index-CpxwEuIg.js} +1 -1
- package/ui-dist/assets/{index-BI5DxFdZ.js → index-D1ZkASZY.js} +1 -1
- package/ui-dist/assets/{index-BkXN5tcA.js → index-DUP0i_Iv.js} +1 -1
- package/ui-dist/assets/{index-Be2KDBoW.js → index-DawkXomB.js} +1 -1
- package/ui-dist/assets/{index-CO0DiQaO.js → index-DxchV0Z7.js} +1 -1
- package/ui-dist/assets/{index-Bk9vEAxA.js → index-Dzd88G_H.js} +1 -1
- package/ui-dist/assets/{index-CyIEQyck.js → index-SklGX83C.js} +1 -1
- package/ui-dist/assets/{index-DL9Ygef7.js → index-_xX3B4n0.js} +1 -1
- package/ui-dist/assets/{index-8HHVhW-a.js → index-bVqVfFu5.js} +1 -1
- package/ui-dist/assets/{index-Dl-MnVEo.js → index-eIjkqSkc.js} +1 -1
- package/ui-dist/assets/{index-CNkqdDmO.js → index-mIrYeZR2.js} +1 -1
- package/ui-dist/assets/{index-CXBstvbt.js → index-xg2FQeSA.js} +1 -1
- package/ui-dist/assets/{infoDiagram-LFFYTUFH-DN2iczkC.js → infoDiagram-LFFYTUFH-BQ0qsBJ6.js} +1 -1
- package/ui-dist/assets/{ishikawaDiagram-PHBUUO56--Ku5ltXY.js → ishikawaDiagram-PHBUUO56-B1u2RAnY.js} +1 -1
- package/ui-dist/assets/{journeyDiagram-4ABVD52K-9wOJKEaq.js → journeyDiagram-4ABVD52K-Dv5wJGwT.js} +1 -1
- package/ui-dist/assets/{kanban-definition-K7BYSVSG-joaPa9x3.js → kanban-definition-K7BYSVSG-CJOykCsT.js} +1 -1
- package/ui-dist/assets/{layout-bH9QuYBa.js → layout-BDcM6t-f.js} +1 -1
- package/ui-dist/assets/{linear-CnfJ09Re.js → linear-B9Sm5Y96.js} +1 -1
- package/ui-dist/assets/{mermaid.core-CYkJAFnD.js → mermaid.core-lZPaf_Ix.js} +4 -4
- package/ui-dist/assets/{mindmap-definition-YRQLILUH-BQyC_8UY.js → mindmap-definition-YRQLILUH-Cu4HfP8K.js} +1 -1
- package/ui-dist/assets/{pieDiagram-SKSYHLDU-ev5uLtwW.js → pieDiagram-SKSYHLDU-B_v-Vluc.js} +1 -1
- package/ui-dist/assets/{quadrantDiagram-337W2JSQ-CQoe3akb.js → quadrantDiagram-337W2JSQ-BU1ZwGcS.js} +1 -1
- package/ui-dist/assets/{requirementDiagram-Z7DCOOCP-C9fd5-6o.js → requirementDiagram-Z7DCOOCP-DBOqB50G.js} +1 -1
- package/ui-dist/assets/{sankeyDiagram-WA2Y5GQK-Dznsr9L_.js → sankeyDiagram-WA2Y5GQK-CsXDIOlq.js} +1 -1
- package/ui-dist/assets/{sequenceDiagram-2WXFIKYE-jL7GufkU.js → sequenceDiagram-2WXFIKYE-Cmgr7vKy.js} +1 -1
- package/ui-dist/assets/{stateDiagram-RAJIS63D-C_4YyDYV.js → stateDiagram-RAJIS63D-Bd0uRbWd.js} +1 -1
- package/ui-dist/assets/stateDiagram-v2-FVOUBMTO-qGaY7iN1.js +1 -0
- package/ui-dist/assets/{timeline-definition-YZTLITO2-D8jKeAEo.js → timeline-definition-YZTLITO2-B9OfCgYQ.js} +1 -1
- package/ui-dist/assets/{treemap-KZPCXAKY-CV4vBepp.js → treemap-KZPCXAKY-FWWMNo03.js} +1 -1
- package/ui-dist/assets/{vennDiagram-LZ73GAT5-DAk_ThVs.js → vennDiagram-LZ73GAT5-CGs3T7cn.js} +1 -1
- package/ui-dist/assets/{xychartDiagram-JWTSCODW-D8wg1dlm.js → xychartDiagram-JWTSCODW-BJ6DrP1k.js} +1 -1
- package/ui-dist/index.html +2 -2
- package/ui-dist/assets/channel-BDMh8XFu.js +0 -1
- package/ui-dist/assets/classDiagram-VBA2DB6C-B6kvnvP_.js +0 -1
- package/ui-dist/assets/classDiagram-v2-RAHNMMFH-B6kvnvP_.js +0 -1
- package/ui-dist/assets/clone-B5CU-MlO.js +0 -1
- package/ui-dist/assets/index-CLXVCM5X.js +0 -1434
- package/ui-dist/assets/index-DoUUx1qN.css +0 -1
- package/ui-dist/assets/stateDiagram-v2-FVOUBMTO-BAU1MhTJ.js +0 -1
package/dist/services/chats.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ type ApprovalRow = typeof approvals.$inferSelect;
|
|
|
5
5
|
export declare function chatService(db: Db): {
|
|
6
6
|
list: (orgId: string, options?: {
|
|
7
7
|
status?: "active" | "resolved" | "archived" | "all";
|
|
8
|
+
q?: string;
|
|
8
9
|
}, userId?: string | null) => Promise<{
|
|
9
10
|
primaryIssue: {
|
|
10
11
|
id: string;
|
|
@@ -38,8 +39,8 @@ export declare function chatService(db: Db): {
|
|
|
38
39
|
unreadCount: number;
|
|
39
40
|
isUnread: boolean;
|
|
40
41
|
needsAttention: boolean;
|
|
41
|
-
id: string;
|
|
42
42
|
title: string;
|
|
43
|
+
id: string;
|
|
43
44
|
status: string;
|
|
44
45
|
createdByUserId: string | null;
|
|
45
46
|
updatedAt: Date;
|
|
@@ -87,8 +88,8 @@ export declare function chatService(db: Db): {
|
|
|
87
88
|
unreadCount: number;
|
|
88
89
|
isUnread: boolean;
|
|
89
90
|
needsAttention: boolean;
|
|
90
|
-
id: string;
|
|
91
91
|
title: string;
|
|
92
|
+
id: string;
|
|
92
93
|
status: string;
|
|
93
94
|
createdByUserId: string | null;
|
|
94
95
|
updatedAt: Date;
|
|
@@ -148,8 +149,8 @@ export declare function chatService(db: Db): {
|
|
|
148
149
|
unreadCount: number;
|
|
149
150
|
isUnread: boolean;
|
|
150
151
|
needsAttention: boolean;
|
|
151
|
-
id: string;
|
|
152
152
|
title: string;
|
|
153
|
+
id: string;
|
|
153
154
|
status: string;
|
|
154
155
|
createdByUserId: string | null;
|
|
155
156
|
updatedAt: Date;
|
|
@@ -197,8 +198,8 @@ export declare function chatService(db: Db): {
|
|
|
197
198
|
unreadCount: number;
|
|
198
199
|
isUnread: boolean;
|
|
199
200
|
needsAttention: boolean;
|
|
200
|
-
id: string;
|
|
201
201
|
title: string;
|
|
202
|
+
id: string;
|
|
202
203
|
status: string;
|
|
203
204
|
createdByUserId: string | null;
|
|
204
205
|
updatedAt: Date;
|
|
@@ -246,8 +247,8 @@ export declare function chatService(db: Db): {
|
|
|
246
247
|
unreadCount: number;
|
|
247
248
|
isUnread: boolean;
|
|
248
249
|
needsAttention: boolean;
|
|
249
|
-
id: string;
|
|
250
250
|
title: string;
|
|
251
|
+
id: string;
|
|
251
252
|
status: string;
|
|
252
253
|
createdByUserId: string | null;
|
|
253
254
|
updatedAt: Date;
|
|
@@ -319,7 +320,7 @@ export declare function chatService(db: Db): {
|
|
|
319
320
|
orgId: string;
|
|
320
321
|
role: "user" | "assistant" | "system";
|
|
321
322
|
kind: "message" | "issue_proposal" | "operation_proposal" | "routing_suggestion" | "system_event";
|
|
322
|
-
status?: "completed" | "stopped" | "failed";
|
|
323
|
+
status?: "streaming" | "completed" | "stopped" | "failed" | "interrupted";
|
|
323
324
|
body: string;
|
|
324
325
|
structuredPayload?: Record<string, unknown> | null;
|
|
325
326
|
transcript?: ChatStreamTranscriptEntry[];
|
|
@@ -360,6 +361,80 @@ export declare function chatService(db: Db): {
|
|
|
360
361
|
turnVariant: number;
|
|
361
362
|
supersededAt: Date | null;
|
|
362
363
|
}>;
|
|
364
|
+
updateMessage: (conversationId: string, messageId: string, input: {
|
|
365
|
+
kind?: "message" | "issue_proposal" | "operation_proposal" | "routing_suggestion" | "system_event";
|
|
366
|
+
status?: "streaming" | "completed" | "stopped" | "failed" | "interrupted";
|
|
367
|
+
body?: string;
|
|
368
|
+
structuredPayload?: Record<string, unknown> | null;
|
|
369
|
+
transcript?: ChatStreamTranscriptEntry[];
|
|
370
|
+
approvalId?: string | null;
|
|
371
|
+
replyingAgentId?: string | null;
|
|
372
|
+
}) => Promise<{
|
|
373
|
+
structuredPayload: Record<string, unknown> | null;
|
|
374
|
+
transcript: ChatStreamTranscriptEntry[];
|
|
375
|
+
approval: {
|
|
376
|
+
id: string;
|
|
377
|
+
status: string;
|
|
378
|
+
updatedAt: Date;
|
|
379
|
+
orgId: string;
|
|
380
|
+
createdAt: Date;
|
|
381
|
+
type: string;
|
|
382
|
+
decisionNote: string | null;
|
|
383
|
+
payload: Record<string, unknown>;
|
|
384
|
+
requestedByAgentId: string | null;
|
|
385
|
+
decidedByUserId: string | null;
|
|
386
|
+
requestedByUserId: string | null;
|
|
387
|
+
decidedAt: Date | null;
|
|
388
|
+
} | null;
|
|
389
|
+
attachments: any[];
|
|
390
|
+
kind: string;
|
|
391
|
+
id: string;
|
|
392
|
+
status: string;
|
|
393
|
+
updatedAt: Date;
|
|
394
|
+
orgId: string;
|
|
395
|
+
createdAt: Date;
|
|
396
|
+
role: string;
|
|
397
|
+
body: string;
|
|
398
|
+
approvalId: string | null;
|
|
399
|
+
conversationId: string;
|
|
400
|
+
replyingAgentId: string | null;
|
|
401
|
+
chatTurnId: string | null;
|
|
402
|
+
turnVariant: number;
|
|
403
|
+
supersededAt: Date | null;
|
|
404
|
+
} | null>;
|
|
405
|
+
markInterruptedStreamingMessages: (conversationId: string) => Promise<{
|
|
406
|
+
structuredPayload: Record<string, unknown> | null;
|
|
407
|
+
transcript: ChatStreamTranscriptEntry[];
|
|
408
|
+
approval: {
|
|
409
|
+
id: string;
|
|
410
|
+
status: string;
|
|
411
|
+
updatedAt: Date;
|
|
412
|
+
orgId: string;
|
|
413
|
+
createdAt: Date;
|
|
414
|
+
type: string;
|
|
415
|
+
decisionNote: string | null;
|
|
416
|
+
payload: Record<string, unknown>;
|
|
417
|
+
requestedByAgentId: string | null;
|
|
418
|
+
decidedByUserId: string | null;
|
|
419
|
+
requestedByUserId: string | null;
|
|
420
|
+
decidedAt: Date | null;
|
|
421
|
+
} | null;
|
|
422
|
+
attachments: any[];
|
|
423
|
+
kind: string;
|
|
424
|
+
id: string;
|
|
425
|
+
status: string;
|
|
426
|
+
updatedAt: Date;
|
|
427
|
+
orgId: string;
|
|
428
|
+
createdAt: Date;
|
|
429
|
+
role: string;
|
|
430
|
+
body: string;
|
|
431
|
+
approvalId: string | null;
|
|
432
|
+
conversationId: string;
|
|
433
|
+
replyingAgentId: string | null;
|
|
434
|
+
chatTurnId: string | null;
|
|
435
|
+
turnVariant: number;
|
|
436
|
+
supersededAt: Date | null;
|
|
437
|
+
}[]>;
|
|
363
438
|
addUserChatMessage: (conversationId: string, orgId: string, body: string, editUserMessageId?: string | null) => Promise<{
|
|
364
439
|
structuredPayload: Record<string, unknown> | null;
|
|
365
440
|
transcript: ChatStreamTranscriptEntry[];
|
|
@@ -449,8 +524,8 @@ export declare function chatService(db: Db): {
|
|
|
449
524
|
unreadCount: number;
|
|
450
525
|
isUnread: boolean;
|
|
451
526
|
needsAttention: boolean;
|
|
452
|
-
id: string;
|
|
453
527
|
title: string;
|
|
528
|
+
id: string;
|
|
454
529
|
status: string;
|
|
455
530
|
createdByUserId: string | null;
|
|
456
531
|
updatedAt: Date;
|
|
@@ -500,9 +575,10 @@ export declare function chatService(db: Db): {
|
|
|
500
575
|
messageId?: string | null;
|
|
501
576
|
proposal?: Record<string, unknown> | null;
|
|
502
577
|
}) => Promise<{
|
|
503
|
-
id: string;
|
|
504
578
|
identifier: string | null;
|
|
505
579
|
title: string;
|
|
580
|
+
description: string | null;
|
|
581
|
+
id: string;
|
|
506
582
|
status: string;
|
|
507
583
|
priority: string;
|
|
508
584
|
assigneeAgentId: string | null;
|
|
@@ -515,7 +591,6 @@ export declare function chatService(db: Db): {
|
|
|
515
591
|
projectWorkspaceId: string | null;
|
|
516
592
|
goalId: string | null;
|
|
517
593
|
parentId: string | null;
|
|
518
|
-
description: string | null;
|
|
519
594
|
boardOrder: number;
|
|
520
595
|
reviewerAgentId: string | null;
|
|
521
596
|
checkoutRunId: string | null;
|
|
@@ -584,18 +659,18 @@ export declare function chatService(db: Db): {
|
|
|
584
659
|
} | null>;
|
|
585
660
|
applyApprovedApproval: (approval: ApprovalRow, actorUserId: string | null) => Promise<Omit<{
|
|
586
661
|
permissions: import("./agent-permissions.js").NormalizedAgentPermissions;
|
|
587
|
-
id: string;
|
|
588
662
|
title: string | null;
|
|
663
|
+
id: string;
|
|
589
664
|
status: string;
|
|
590
665
|
updatedAt: Date;
|
|
591
666
|
orgId: string;
|
|
592
667
|
createdAt: Date;
|
|
593
668
|
name: string;
|
|
594
|
-
agentRuntimeType: string;
|
|
595
669
|
budgetMonthlyCents: number;
|
|
596
670
|
spentMonthlyCents: number;
|
|
597
671
|
metadata: Record<string, unknown> | null;
|
|
598
672
|
role: string;
|
|
673
|
+
agentRuntimeType: string;
|
|
599
674
|
icon: string | null;
|
|
600
675
|
capabilities: string | null;
|
|
601
676
|
agentRuntimeConfig: Record<string, unknown>;
|
|
@@ -622,8 +697,6 @@ export declare function chatService(db: Db): {
|
|
|
622
697
|
spentMonthlyCents: number;
|
|
623
698
|
requireBoardApprovalForNewAgents: boolean;
|
|
624
699
|
defaultChatIssueCreationMode: string;
|
|
625
|
-
defaultChatAgentRuntimeType: string | null;
|
|
626
|
-
defaultChatAgentRuntimeConfig: Record<string, unknown> | null;
|
|
627
700
|
workspaceConfig: Record<string, unknown> | null;
|
|
628
701
|
brandColor: string | null;
|
|
629
702
|
createdAt: Date;
|
|
@@ -634,9 +707,10 @@ export declare function chatService(db: Db): {
|
|
|
634
707
|
workspace: null;
|
|
635
708
|
logoUrl: string | null;
|
|
636
709
|
}) | ({
|
|
637
|
-
id: string;
|
|
638
710
|
identifier: string | null;
|
|
639
711
|
title: string;
|
|
712
|
+
description: string | null;
|
|
713
|
+
id: string;
|
|
640
714
|
status: string;
|
|
641
715
|
priority: string;
|
|
642
716
|
assigneeAgentId: string | null;
|
|
@@ -649,7 +723,6 @@ export declare function chatService(db: Db): {
|
|
|
649
723
|
projectWorkspaceId: string | null;
|
|
650
724
|
goalId: string | null;
|
|
651
725
|
parentId: string | null;
|
|
652
|
-
description: string | null;
|
|
653
726
|
boardOrder: number;
|
|
654
727
|
reviewerAgentId: string | null;
|
|
655
728
|
checkoutRunId: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chats.d.ts","sourceRoot":"","sources":["../../src/services/chats.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAgD,KAAK,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAChH,OAAO,EAEL,SAAS,EAIT,iBAAiB,EAMlB,MAAM,cAAc,CAAC;AActB,KAAK,WAAW,GAAG,OAAO,SAAS,CAAC,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"chats.d.ts","sourceRoot":"","sources":["../../src/services/chats.ts"],"names":[],"mappings":"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"}
|
package/dist/services/chats.js
CHANGED
|
@@ -11,6 +11,10 @@ import { organizationService } from "./orgs.js";
|
|
|
11
11
|
import { issueApprovalService } from "./issue-approvals.js";
|
|
12
12
|
import { issueService } from "./issues.js";
|
|
13
13
|
const CHAT_TRANSCRIPT_KEY = "__chatTranscript";
|
|
14
|
+
const ISSUE_PROPOSAL_PRIORITIES = ["critical", "high", "medium", "low"];
|
|
15
|
+
function isIssueProposalPriority(value) {
|
|
16
|
+
return typeof value === "string" && ISSUE_PROPOSAL_PRIORITIES.includes(value);
|
|
17
|
+
}
|
|
14
18
|
function contentPath(assetId) {
|
|
15
19
|
return `/api/assets/${assetId}/content`;
|
|
16
20
|
}
|
|
@@ -18,9 +22,47 @@ function safeTrim(value) {
|
|
|
18
22
|
const trimmed = value?.trim();
|
|
19
23
|
return trimmed ? trimmed : null;
|
|
20
24
|
}
|
|
25
|
+
function isVisibleIncomingChatMessage(message) {
|
|
26
|
+
if (message.role === "user")
|
|
27
|
+
return false;
|
|
28
|
+
return Boolean(safeTrim(message.body)) || message.kind !== "message" || Boolean(message.approvalId);
|
|
29
|
+
}
|
|
30
|
+
function visibleIncomingMessageSql() {
|
|
31
|
+
return sql `(
|
|
32
|
+
${chatMessages.role} <> 'user'
|
|
33
|
+
and (
|
|
34
|
+
btrim(${chatMessages.body}) <> ''
|
|
35
|
+
or ${chatMessages.kind} <> 'message'
|
|
36
|
+
or ${chatMessages.approvalId} is not null
|
|
37
|
+
)
|
|
38
|
+
)`;
|
|
39
|
+
}
|
|
40
|
+
function incomingMessagePreviewSql() {
|
|
41
|
+
return sql `(${chatMessages.role} <> 'user' and btrim(${chatMessages.body}) <> '')`;
|
|
42
|
+
}
|
|
21
43
|
function truncatePreview(value, max = 140) {
|
|
22
44
|
return formatMessengerPreview(value, { max });
|
|
23
45
|
}
|
|
46
|
+
function escapeLikePattern(value) {
|
|
47
|
+
return value.replace(/[\\%_]/g, "\\$&");
|
|
48
|
+
}
|
|
49
|
+
function textContains(value, query) {
|
|
50
|
+
return Boolean(value && value.toLowerCase().includes(query.toLowerCase()));
|
|
51
|
+
}
|
|
52
|
+
function buildSearchSnippet(value, query, maxLength = 160) {
|
|
53
|
+
const compact = value.replace(/\s+/g, " ").trim();
|
|
54
|
+
if (compact.length <= maxLength)
|
|
55
|
+
return compact;
|
|
56
|
+
const index = compact.toLowerCase().indexOf(query.toLowerCase());
|
|
57
|
+
if (index < 0)
|
|
58
|
+
return `${compact.slice(0, maxLength - 1).trimEnd()}...`;
|
|
59
|
+
const context = Math.max(20, Math.floor((maxLength - query.length) / 2));
|
|
60
|
+
const start = Math.max(0, index - context);
|
|
61
|
+
const end = Math.min(compact.length, start + maxLength);
|
|
62
|
+
const prefix = start > 0 ? "..." : "";
|
|
63
|
+
const suffix = end < compact.length ? "..." : "";
|
|
64
|
+
return `${prefix}${compact.slice(start, end).trim()}${suffix}`;
|
|
65
|
+
}
|
|
24
66
|
function chatTranscriptFromPayload(payload) {
|
|
25
67
|
const transcript = payload?.[CHAT_TRANSCRIPT_KEY];
|
|
26
68
|
return Array.isArray(transcript) ? transcript : [];
|
|
@@ -55,17 +97,36 @@ function issueProposalFromPayload(payload) {
|
|
|
55
97
|
return {
|
|
56
98
|
title,
|
|
57
99
|
description,
|
|
58
|
-
priority:
|
|
59
|
-
["critical", "high", "medium", "low"].includes(proposal.priority)
|
|
60
|
-
? proposal.priority
|
|
61
|
-
: "medium",
|
|
100
|
+
priority: isIssueProposalPriority(proposal.priority) ? proposal.priority : "medium",
|
|
62
101
|
projectId: safeTrim(typeof proposal.projectId === "string" ? proposal.projectId : null),
|
|
63
102
|
goalId: safeTrim(typeof proposal.goalId === "string" ? proposal.goalId : null),
|
|
64
103
|
parentId: safeTrim(typeof proposal.parentId === "string" ? proposal.parentId : null),
|
|
65
104
|
assigneeAgentId: safeTrim(typeof proposal.assigneeAgentId === "string" ? proposal.assigneeAgentId : null),
|
|
66
105
|
assigneeUserId: safeTrim(typeof proposal.assigneeUserId === "string" ? proposal.assigneeUserId : null),
|
|
106
|
+
reviewerAgentId: safeTrim(typeof proposal.reviewerAgentId === "string" ? proposal.reviewerAgentId : null),
|
|
107
|
+
reviewerUserId: safeTrim(typeof proposal.reviewerUserId === "string" ? proposal.reviewerUserId : null),
|
|
67
108
|
};
|
|
68
109
|
}
|
|
110
|
+
function issueProposalHasAssignee(proposal) {
|
|
111
|
+
return Boolean(proposal.assigneeAgentId || proposal.assigneeUserId);
|
|
112
|
+
}
|
|
113
|
+
async function defaultIssueAssigneeAgentId(db, conversation) {
|
|
114
|
+
const candidateAgentIds = [conversation.preferredAgentId, conversation.routedAgentId]
|
|
115
|
+
.filter((id) => typeof id === "string" && id.trim().length > 0);
|
|
116
|
+
for (const candidateAgentId of candidateAgentIds) {
|
|
117
|
+
const agent = await db
|
|
118
|
+
.select({ id: agents.id, orgId: agents.orgId, status: agents.status })
|
|
119
|
+
.from(agents)
|
|
120
|
+
.where(eq(agents.id, candidateAgentId))
|
|
121
|
+
.then((rows) => rows[0] ?? null);
|
|
122
|
+
if (!agent || agent.orgId !== conversation.orgId)
|
|
123
|
+
continue;
|
|
124
|
+
if (agent.status === "pending_approval" || agent.status === "terminated")
|
|
125
|
+
continue;
|
|
126
|
+
return agent.id;
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
69
130
|
function planDocumentFromPayload(payload, fallbackBody) {
|
|
70
131
|
const root = payload ?? {};
|
|
71
132
|
const rawDocument = root.planDocument && typeof root.planDocument === "object" && !Array.isArray(root.planDocument)
|
|
@@ -284,7 +345,7 @@ export function chatService(db) {
|
|
|
284
345
|
})
|
|
285
346
|
.from(chatMessages)
|
|
286
347
|
.innerJoin(chatConversationUserStates, and(eq(chatConversationUserStates.orgId, orgId), eq(chatConversationUserStates.userId, userId), eq(chatConversationUserStates.conversationId, chatMessages.conversationId)))
|
|
287
|
-
.where(and(eq(chatMessages.orgId, orgId), inArray(chatMessages.conversationId, conversationIds), isNull(chatMessages.supersededAt),
|
|
348
|
+
.where(and(eq(chatMessages.orgId, orgId), inArray(chatMessages.conversationId, conversationIds), isNull(chatMessages.supersededAt), visibleIncomingMessageSql(), gt(chatMessages.createdAt, chatConversationUserStates.lastReadAt)))
|
|
288
349
|
.groupBy(chatMessages.conversationId);
|
|
289
350
|
return new Map(rows.map((row) => [row.conversationId, Number(row.count ?? 0)]));
|
|
290
351
|
}
|
|
@@ -310,7 +371,7 @@ export function chatService(db) {
|
|
|
310
371
|
latestReplyAt: sql `max(${chatMessages.createdAt})`.as("latest_reply_at"),
|
|
311
372
|
})
|
|
312
373
|
.from(chatMessages)
|
|
313
|
-
.where(and(eq(chatMessages.orgId, orgId), inArray(chatMessages.conversationId, conversationIds), isNull(chatMessages.supersededAt),
|
|
374
|
+
.where(and(eq(chatMessages.orgId, orgId), inArray(chatMessages.conversationId, conversationIds), isNull(chatMessages.supersededAt), incomingMessagePreviewSql()))
|
|
314
375
|
.groupBy(chatMessages.conversationId)
|
|
315
376
|
.as("latest_chat_reply_at");
|
|
316
377
|
const rows = await db
|
|
@@ -320,7 +381,7 @@ export function chatService(db) {
|
|
|
320
381
|
})
|
|
321
382
|
.from(chatMessages)
|
|
322
383
|
.innerJoin(latestReplyAt, and(eq(chatMessages.conversationId, latestReplyAt.conversationId), eq(chatMessages.createdAt, latestReplyAt.latestReplyAt)))
|
|
323
|
-
.where(and(eq(chatMessages.orgId, orgId), inArray(chatMessages.conversationId, conversationIds), isNull(chatMessages.supersededAt),
|
|
384
|
+
.where(and(eq(chatMessages.orgId, orgId), inArray(chatMessages.conversationId, conversationIds), isNull(chatMessages.supersededAt), incomingMessagePreviewSql()))
|
|
324
385
|
.orderBy(desc(chatMessages.createdAt));
|
|
325
386
|
const map = new Map();
|
|
326
387
|
for (const row of rows) {
|
|
@@ -330,6 +391,38 @@ export function chatService(db) {
|
|
|
330
391
|
}
|
|
331
392
|
return map;
|
|
332
393
|
}
|
|
394
|
+
async function listSearchPreviews(orgId, rows, query, containsPattern) {
|
|
395
|
+
if (rows.length === 0)
|
|
396
|
+
return new Map();
|
|
397
|
+
const previews = new Map();
|
|
398
|
+
for (const row of rows) {
|
|
399
|
+
if (textContains(row.title, query)) {
|
|
400
|
+
previews.set(row.id, buildSearchSnippet(row.title, query));
|
|
401
|
+
}
|
|
402
|
+
else if (textContains(row.summary, query)) {
|
|
403
|
+
previews.set(row.id, buildSearchSnippet(row.summary, query));
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
const messageSearchIds = rows
|
|
407
|
+
.map((row) => row.id)
|
|
408
|
+
.filter((id) => !previews.has(id));
|
|
409
|
+
if (messageSearchIds.length === 0)
|
|
410
|
+
return previews;
|
|
411
|
+
const messageRows = await db
|
|
412
|
+
.select({
|
|
413
|
+
conversationId: chatMessages.conversationId,
|
|
414
|
+
body: chatMessages.body,
|
|
415
|
+
})
|
|
416
|
+
.from(chatMessages)
|
|
417
|
+
.where(and(eq(chatMessages.orgId, orgId), inArray(chatMessages.conversationId, messageSearchIds), isNull(chatMessages.supersededAt), sql `${chatMessages.body} ILIKE ${containsPattern} ESCAPE '\\'`))
|
|
418
|
+
.orderBy(desc(chatMessages.createdAt));
|
|
419
|
+
for (const message of messageRows) {
|
|
420
|
+
if (previews.has(message.conversationId))
|
|
421
|
+
continue;
|
|
422
|
+
previews.set(message.conversationId, buildSearchSnippet(message.body, query));
|
|
423
|
+
}
|
|
424
|
+
return previews;
|
|
425
|
+
}
|
|
333
426
|
async function hydrateConversations(rows, userId) {
|
|
334
427
|
if (userId) {
|
|
335
428
|
await ensureConversationUserStates(rows, userId);
|
|
@@ -461,15 +554,40 @@ export function chatService(db) {
|
|
|
461
554
|
}
|
|
462
555
|
async function list(orgId, options, userId) {
|
|
463
556
|
const status = options?.status ?? "active";
|
|
464
|
-
const
|
|
465
|
-
|
|
466
|
-
|
|
557
|
+
const rawSearch = options?.q?.trim() ?? "";
|
|
558
|
+
const hasSearch = rawSearch.length > 0;
|
|
559
|
+
const containsPattern = `%${escapeLikePattern(rawSearch)}%`;
|
|
560
|
+
const conditions = [eq(chatConversations.orgId, orgId)];
|
|
561
|
+
if (status !== "all") {
|
|
562
|
+
conditions.push(eq(chatConversations.status, status));
|
|
563
|
+
}
|
|
564
|
+
if (hasSearch) {
|
|
565
|
+
conditions.push(sql `(
|
|
566
|
+
${chatConversations.title} ILIKE ${containsPattern} ESCAPE '\\'
|
|
567
|
+
OR ${chatConversations.summary} ILIKE ${containsPattern} ESCAPE '\\'
|
|
568
|
+
OR EXISTS (
|
|
569
|
+
SELECT 1
|
|
570
|
+
FROM ${chatMessages}
|
|
571
|
+
WHERE ${chatMessages.conversationId} = ${chatConversations.id}
|
|
572
|
+
AND ${chatMessages.orgId} = ${orgId}
|
|
573
|
+
AND ${chatMessages.supersededAt} IS NULL
|
|
574
|
+
AND ${chatMessages.body} ILIKE ${containsPattern} ESCAPE '\\'
|
|
575
|
+
)
|
|
576
|
+
)`);
|
|
577
|
+
}
|
|
467
578
|
const rows = await db
|
|
468
579
|
.select()
|
|
469
580
|
.from(chatConversations)
|
|
470
|
-
.where(
|
|
581
|
+
.where(and(...conditions))
|
|
471
582
|
.orderBy(desc(sql `coalesce(${chatConversations.lastMessageAt}, ${chatConversations.updatedAt})`));
|
|
472
|
-
|
|
583
|
+
const conversations = await hydrateConversations(rows, userId);
|
|
584
|
+
if (!hasSearch)
|
|
585
|
+
return conversations;
|
|
586
|
+
const searchPreviews = await listSearchPreviews(orgId, rows, rawSearch, containsPattern);
|
|
587
|
+
return conversations.map((conversation) => ({
|
|
588
|
+
...conversation,
|
|
589
|
+
searchPreview: searchPreviews.get(conversation.id) ?? null,
|
|
590
|
+
}));
|
|
473
591
|
}
|
|
474
592
|
async function getById(id, userId) {
|
|
475
593
|
const row = await db
|
|
@@ -728,13 +846,86 @@ export function chatService(db) {
|
|
|
728
846
|
.returning();
|
|
729
847
|
if (!message)
|
|
730
848
|
throw new Error("Failed to create chat message");
|
|
731
|
-
|
|
849
|
+
if (input.role === "user" || isVisibleIncomingChatMessage(message)) {
|
|
850
|
+
await refreshConversationTouch(conversationId, message.createdAt);
|
|
851
|
+
}
|
|
732
852
|
if (input.role === "user") {
|
|
733
853
|
await maybePromoteConversationTitle(conversationId, input.body);
|
|
734
854
|
}
|
|
735
855
|
const [hydrated] = await hydrateMessages([message]);
|
|
736
856
|
return hydrated;
|
|
737
857
|
}
|
|
858
|
+
async function updateMessage(conversationId, messageId, input) {
|
|
859
|
+
const existing = await db
|
|
860
|
+
.select()
|
|
861
|
+
.from(chatMessages)
|
|
862
|
+
.where(and(eq(chatMessages.conversationId, conversationId), eq(chatMessages.id, messageId)))
|
|
863
|
+
.then((rows) => rows[0] ?? null);
|
|
864
|
+
if (!existing)
|
|
865
|
+
return null;
|
|
866
|
+
const now = new Date();
|
|
867
|
+
const wasVisibleIncoming = isVisibleIncomingChatMessage(existing);
|
|
868
|
+
const nextMessage = {
|
|
869
|
+
role: existing.role,
|
|
870
|
+
kind: input.kind ?? existing.kind,
|
|
871
|
+
body: input.body ?? existing.body,
|
|
872
|
+
approvalId: input.approvalId !== undefined ? input.approvalId : existing.approvalId,
|
|
873
|
+
};
|
|
874
|
+
const isVisibleIncoming = isVisibleIncomingChatMessage(nextMessage);
|
|
875
|
+
const becameVisibleIncoming = !wasVisibleIncoming && isVisibleIncoming;
|
|
876
|
+
const visibleContentChanged = (input.body !== undefined && safeTrim(input.body) !== safeTrim(existing.body)) ||
|
|
877
|
+
(input.kind !== undefined && input.kind !== existing.kind) ||
|
|
878
|
+
(input.approvalId !== undefined && input.approvalId !== existing.approvalId);
|
|
879
|
+
const [updated] = await db
|
|
880
|
+
.update(chatMessages)
|
|
881
|
+
.set({
|
|
882
|
+
...(becameVisibleIncoming ? { createdAt: now } : {}),
|
|
883
|
+
...(input.kind !== undefined ? { kind: input.kind } : {}),
|
|
884
|
+
...(input.status !== undefined ? { status: input.status } : {}),
|
|
885
|
+
...(input.body !== undefined ? { body: input.body } : {}),
|
|
886
|
+
...(input.structuredPayload !== undefined || input.transcript !== undefined
|
|
887
|
+
? {
|
|
888
|
+
structuredPayload: withPersistedTranscript(input.structuredPayload !== undefined
|
|
889
|
+
? input.structuredPayload
|
|
890
|
+
: stripChatMetadataFromPayload(existing.structuredPayload), input.transcript !== undefined
|
|
891
|
+
? input.transcript
|
|
892
|
+
: chatTranscriptFromPayload(existing.structuredPayload)),
|
|
893
|
+
}
|
|
894
|
+
: {}),
|
|
895
|
+
...(input.approvalId !== undefined ? { approvalId: input.approvalId } : {}),
|
|
896
|
+
...(input.replyingAgentId !== undefined ? { replyingAgentId: input.replyingAgentId } : {}),
|
|
897
|
+
updatedAt: now,
|
|
898
|
+
})
|
|
899
|
+
.where(and(eq(chatMessages.conversationId, conversationId), eq(chatMessages.id, messageId)))
|
|
900
|
+
.returning();
|
|
901
|
+
if (!updated)
|
|
902
|
+
return null;
|
|
903
|
+
if ((existing.role === "user" && input.body !== undefined) ||
|
|
904
|
+
(isVisibleIncoming && (becameVisibleIncoming || visibleContentChanged))) {
|
|
905
|
+
await refreshConversationTouch(conversationId, becameVisibleIncoming ? updated.createdAt : updated.updatedAt);
|
|
906
|
+
}
|
|
907
|
+
const [hydrated] = await hydrateMessages([updated]);
|
|
908
|
+
return hydrated ?? null;
|
|
909
|
+
}
|
|
910
|
+
async function markInterruptedStreamingMessages(conversationId) {
|
|
911
|
+
const rows = await db
|
|
912
|
+
.select()
|
|
913
|
+
.from(chatMessages)
|
|
914
|
+
.where(and(eq(chatMessages.conversationId, conversationId), eq(chatMessages.role, "assistant"), eq(chatMessages.status, "streaming"), isNull(chatMessages.supersededAt)));
|
|
915
|
+
const updatedMessages = [];
|
|
916
|
+
for (const row of rows) {
|
|
917
|
+
const body = row.body.trim().length > 0
|
|
918
|
+
? row.body
|
|
919
|
+
: "Chat run interrupted before a final reply. Continue the conversation to resume from the preserved context.";
|
|
920
|
+
const updated = await updateMessage(conversationId, row.id, {
|
|
921
|
+
status: "interrupted",
|
|
922
|
+
body,
|
|
923
|
+
});
|
|
924
|
+
if (updated)
|
|
925
|
+
updatedMessages.push(updated);
|
|
926
|
+
}
|
|
927
|
+
return updatedMessages;
|
|
928
|
+
}
|
|
738
929
|
async function updateMessageStructuredPayload(conversationId, messageId, structuredPayload) {
|
|
739
930
|
const existing = await db
|
|
740
931
|
.select()
|
|
@@ -879,6 +1070,13 @@ export function chatService(db) {
|
|
|
879
1070
|
if (!issueProposal) {
|
|
880
1071
|
throw unprocessable("Issue proposal payload was incomplete");
|
|
881
1072
|
}
|
|
1073
|
+
const fallbackAssigneeAgentId = await defaultIssueAssigneeAgentId(db, conversation);
|
|
1074
|
+
if (!issueProposalHasAssignee(issueProposal) && fallbackAssigneeAgentId) {
|
|
1075
|
+
issueProposal = {
|
|
1076
|
+
...issueProposal,
|
|
1077
|
+
assigneeAgentId: fallbackAssigneeAgentId,
|
|
1078
|
+
};
|
|
1079
|
+
}
|
|
882
1080
|
const issue = await issuesSvc.create(conversation.orgId, {
|
|
883
1081
|
...issueProposal,
|
|
884
1082
|
createdByUserId: input.actorUserId,
|
|
@@ -1076,10 +1274,13 @@ export function chatService(db) {
|
|
|
1076
1274
|
const proposedIssue = payload.proposedIssue && typeof payload.proposedIssue === "object" && !Array.isArray(payload.proposedIssue)
|
|
1077
1275
|
? payload.proposedIssue
|
|
1078
1276
|
: null;
|
|
1277
|
+
const planDocument = payload.planDocument && typeof payload.planDocument === "object" && !Array.isArray(payload.planDocument)
|
|
1278
|
+
? payload.planDocument
|
|
1279
|
+
: null;
|
|
1079
1280
|
const issue = await convertToIssue(conversationId, {
|
|
1080
1281
|
actorUserId,
|
|
1081
1282
|
messageId,
|
|
1082
|
-
proposal: proposedIssue,
|
|
1283
|
+
proposal: planDocument ? { issueProposal: proposedIssue, planDocument } : proposedIssue,
|
|
1083
1284
|
});
|
|
1084
1285
|
await issueApprovalsSvc.linkManyForApproval(approval.id, [issue.id], {
|
|
1085
1286
|
agentId: null,
|
|
@@ -1201,6 +1402,8 @@ export function chatService(db) {
|
|
|
1201
1402
|
setPinned,
|
|
1202
1403
|
listMessages,
|
|
1203
1404
|
addMessage,
|
|
1405
|
+
updateMessage,
|
|
1406
|
+
markInterruptedStreamingMessages,
|
|
1204
1407
|
addUserChatMessage,
|
|
1205
1408
|
addContextLink,
|
|
1206
1409
|
setProjectContextLink,
|