@cossistant/core 0.0.28 → 0.0.30

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.
Files changed (54) hide show
  1. package/_virtual/rolldown_runtime.js +27 -12
  2. package/ai-sdk-utils.d.ts +141 -0
  3. package/ai-sdk-utils.d.ts.map +1 -0
  4. package/ai-sdk-utils.js +255 -0
  5. package/ai-sdk-utils.js.map +1 -0
  6. package/client.d.ts +17 -7
  7. package/client.d.ts.map +1 -1
  8. package/client.js +34 -3
  9. package/client.js.map +1 -1
  10. package/index.d.ts +3 -1
  11. package/index.js +3 -1
  12. package/package.json +1 -1
  13. package/privacy-filter.d.ts +112 -0
  14. package/privacy-filter.d.ts.map +1 -0
  15. package/privacy-filter.js +170 -0
  16. package/privacy-filter.js.map +1 -0
  17. package/rest-client.d.ts +4 -4
  18. package/rest-client.d.ts.map +1 -1
  19. package/rest-client.js +4 -4
  20. package/rest-client.js.map +1 -1
  21. package/store/conversations-store.d.ts +1 -1
  22. package/store/seen-store.d.ts +2 -2
  23. package/store/timeline-items-store.d.ts +5 -5
  24. package/store/timeline-items-store.d.ts.map +1 -1
  25. package/store/timeline-items-store.js +1 -1
  26. package/store/timeline-items-store.js.map +1 -1
  27. package/store/typing-store.d.ts +1 -1
  28. package/store/typing-store.d.ts.map +1 -1
  29. package/store/typing-store.js +12 -19
  30. package/store/typing-store.js.map +1 -1
  31. package/types/src/api/contact.d.ts.map +1 -0
  32. package/{conversation.d.ts → types/src/api/conversation.d.ts} +458 -78
  33. package/types/src/api/conversation.d.ts.map +1 -0
  34. package/types/src/api/timeline-item.d.ts +602 -0
  35. package/types/src/api/timeline-item.d.ts.map +1 -0
  36. package/types/src/api/timeline-item.js +67 -19
  37. package/types/src/api/timeline-item.js.map +1 -1
  38. package/types/src/api/upload.d.ts.map +1 -0
  39. package/types/src/enums.js +4 -1
  40. package/types/src/enums.js.map +1 -1
  41. package/types/src/realtime-events.d.ts +1000 -0
  42. package/types/src/realtime-events.d.ts.map +1 -0
  43. package/{schemas.d.ts → types/src/schemas.d.ts} +92 -16
  44. package/types/src/schemas.d.ts.map +1 -0
  45. package/contact.d.ts.map +0 -1
  46. package/conversation.d.ts.map +0 -1
  47. package/realtime-events.d.ts +0 -478
  48. package/realtime-events.d.ts.map +0 -1
  49. package/schemas.d.ts.map +0 -1
  50. package/timeline-item.d.ts +0 -298
  51. package/timeline-item.d.ts.map +0 -1
  52. package/upload.d.ts.map +0 -1
  53. /package/{contact.d.ts → types/src/api/contact.d.ts} +0 -0
  54. /package/{upload.d.ts → types/src/api/upload.d.ts} +0 -0
@@ -3,25 +3,40 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (all) => {
6
+ var __export = (all, symbols) => {
7
7
  let target = {};
8
- for (var name in all) __defProp(target, name, {
9
- get: all[name],
10
- enumerable: true
11
- });
8
+ for (var name in all) {
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true
12
+ });
13
+ }
14
+ if (symbols) {
15
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
16
+ }
12
17
  return target;
13
18
  };
14
19
  var __copyProps = (to, from, except, desc) => {
15
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
16
- key = keys[i];
17
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
18
- get: ((k) => from[k]).bind(null, key),
19
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
20
- });
20
+ if (from && typeof from === "object" || typeof from === "function") {
21
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
22
+ key = keys[i];
23
+ if (!__hasOwnProp.call(to, key) && key !== except) {
24
+ __defProp(to, key, {
25
+ get: ((k) => from[k]).bind(null, key),
26
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
27
+ });
28
+ }
29
+ }
21
30
  }
22
31
  return to;
23
32
  };
24
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
33
+ var __reExport = (target, mod, secondTarget, symbols) => {
34
+ if (symbols) {
35
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
36
+ secondTarget && __defProp(secondTarget, Symbol.toStringTag, { value: "Module" });
37
+ }
38
+ __copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default");
39
+ };
25
40
 
26
41
  //#endregion
27
42
  export { __export, __reExport };
@@ -0,0 +1,141 @@
1
+ import { TimelineItem, TimelineItemParts } from "@cossistant/types";
2
+
3
+ //#region src/ai-sdk-utils.d.ts
4
+
5
+ /**
6
+ * AI SDK UIMessage part types - these are the standard AI SDK v6 parts
7
+ */
8
+ type AISDKTextPart = {
9
+ type: "text";
10
+ text: string;
11
+ state?: "streaming" | "done";
12
+ };
13
+ type AISDKReasoningPart = {
14
+ type: "reasoning";
15
+ text: string;
16
+ state?: "streaming" | "done";
17
+ providerMetadata?: Record<string, unknown>;
18
+ };
19
+ type AISDKToolPart = {
20
+ type: `tool-${string}`;
21
+ toolCallId: string;
22
+ toolName: string;
23
+ input: Record<string, unknown>;
24
+ output?: unknown;
25
+ state: "partial" | "result" | "error";
26
+ errorText?: string;
27
+ providerMetadata?: Record<string, unknown>;
28
+ };
29
+ type AISDKSourceUrlPart = {
30
+ type: "source-url";
31
+ sourceId: string;
32
+ url: string;
33
+ title?: string;
34
+ providerMetadata?: Record<string, unknown>;
35
+ };
36
+ type AISDKSourceDocumentPart = {
37
+ type: "source-document";
38
+ sourceId: string;
39
+ mediaType: string;
40
+ title: string;
41
+ filename?: string;
42
+ providerMetadata?: Record<string, unknown>;
43
+ };
44
+ type AISDKStepStartPart = {
45
+ type: "step-start";
46
+ };
47
+ type AISDKFilePart = {
48
+ type: "file";
49
+ url: string;
50
+ mediaType: string;
51
+ filename?: string;
52
+ };
53
+ /**
54
+ * Cossistant-specific metadata stored in UIMessage.metadata
55
+ */
56
+ type CossistantMessageMetadata = {
57
+ conversationId: string;
58
+ organizationId: string;
59
+ visibility: "public" | "private";
60
+ userId: string | null;
61
+ aiAgentId: string | null;
62
+ visitorId: string | null;
63
+ replyToId?: string | null;
64
+ createdAt: string;
65
+ deletedAt?: string | null;
66
+ tool?: string | null;
67
+ };
68
+ /**
69
+ * Cossistant-specific metadata stored in part.providerMetadata.cossistant
70
+ */
71
+ type CossistantPartMetadata = {
72
+ visibility?: "public" | "private";
73
+ progressMessage?: string;
74
+ knowledgeId?: string;
75
+ };
76
+ type AISDKPart = AISDKTextPart | AISDKReasoningPart | AISDKToolPart | AISDKSourceUrlPart | AISDKSourceDocumentPart | AISDKStepStartPart | AISDKFilePart;
77
+ type CossistantPart = TimelineItemParts[number];
78
+ /**
79
+ * Cossistant-compatible UIMessage type
80
+ * This is structurally compatible with AI SDK v6 UIMessage
81
+ * but uses our own part types for flexibility
82
+ */
83
+ type CossistantUIMessage = {
84
+ id: string;
85
+ role: "user" | "assistant" | "system";
86
+ metadata: CossistantMessageMetadata;
87
+ parts: AISDKPart[];
88
+ };
89
+ /**
90
+ * Convert a Cossistant TimelineItem to AI SDK UIMessage format
91
+ *
92
+ * @param item - The Cossistant TimelineItem to convert
93
+ * @returns AI SDK compatible UIMessage with Cossistant metadata
94
+ */
95
+ declare function toUIMessage(item: TimelineItem): CossistantUIMessage;
96
+ /**
97
+ * Convert multiple TimelineItems to UIMessages
98
+ */
99
+ declare function toUIMessages(items: TimelineItem[]): CossistantUIMessage[];
100
+ /**
101
+ * Context required to create a TimelineItem from UIMessage
102
+ */
103
+ type FromUIMessageContext = {
104
+ conversationId: string;
105
+ organizationId: string;
106
+ aiAgentId?: string | null;
107
+ userId?: string | null;
108
+ visitorId?: string | null;
109
+ visibility?: "public" | "private";
110
+ };
111
+ /**
112
+ * Convert an AI SDK UIMessage to Cossistant TimelineItem format
113
+ *
114
+ * @param message - The AI SDK UIMessage to convert
115
+ * @param context - Context for creating the TimelineItem
116
+ * @returns Cossistant TimelineItem
117
+ */
118
+ declare function fromUIMessage(message: CossistantUIMessage, context: FromUIMessageContext): TimelineItem;
119
+ /**
120
+ * Convert multiple UIMessages to TimelineItems
121
+ */
122
+ declare function fromUIMessages(messages: CossistantUIMessage[], context: FromUIMessageContext): TimelineItem[];
123
+ /**
124
+ * Check if a part is an AI SDK compatible part type
125
+ */
126
+ declare function isAISDKCompatiblePart(part: CossistantPart): boolean;
127
+ /**
128
+ * Extract all sources from a message's parts
129
+ */
130
+ declare function extractSources(parts: AISDKPart[]): (AISDKSourceUrlPart | AISDKSourceDocumentPart)[];
131
+ /**
132
+ * Extract all tool calls from a message's parts
133
+ */
134
+ declare function extractToolCalls(parts: AISDKPart[]): AISDKToolPart[];
135
+ /**
136
+ * Check if any parts are still processing
137
+ */
138
+ declare function hasProcessingParts(parts: AISDKPart[]): boolean;
139
+ //#endregion
140
+ export { AISDKFilePart, AISDKPart, AISDKReasoningPart, AISDKSourceDocumentPart, AISDKSourceUrlPart, AISDKStepStartPart, AISDKTextPart, AISDKToolPart, CossistantMessageMetadata, CossistantPartMetadata, CossistantUIMessage, FromUIMessageContext, extractSources, extractToolCalls, fromUIMessage, fromUIMessages, hasProcessingParts, isAISDKCompatiblePart, toUIMessage, toUIMessages };
141
+ //# sourceMappingURL=ai-sdk-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-sdk-utils.d.ts","names":[],"sources":["../src/ai-sdk-utils.ts"],"sourcesContent":[],"mappings":";;;;;;;AA+GG,KAzFS,aAAA,GAyFT;EACA,IAAA,EAAA,MAAA;EACA,IAAA,EAAA,MAAA;EACA,KAAA,CAAA,EAAA,WAAA,GAAA,MAAA;CAAa;AAEX,KAxFO,kBAAA,GAwFU;EA2FV,IAAA,EAAA,WAAA;EAaI,IAAA,EAAA,MAAA;EAsBA,KAAA,CAAA,EAAA,WAAY,GAAA,MAAQ;EAyHxB,gBAAA,CAAA,EA3UQ,MA2UY,CAAA,MAAA,EAAA,OAAA,CAAA;AAgBhC,CAAA;AACU,KAzVE,aAAA,GAyVF;EACA,IAAA,EAAA,QAAA,MAAA,EAAA;EACP,UAAA,EAAA,MAAA;EAAY,QAAA,EAAA,MAAA;EA0BC,KAAA,EAjXR,MAiXQ,CAAA,MAAc,EAAA,OAAA,CAAA;EACnB,MAAA,CAAA,EAAA,OAAA;EACD,KAAA,EAAA,SAAA,GAAA,QAAA,GAAA,OAAA;EACP,SAAA,CAAA,EAAA,MAAA;EAAY,gBAAA,CAAA,EAhXK,MAgXL,CAAA,MAAA,EAAA,OAAA,CAAA;AAkHf,CAAA;AAUgB,KAzeJ,kBAAA,GAyekB;EACtB,IAAA,EAAA,YAAA;EACJ,QAAA,EAAA,MAAA;EAAqB,GAAA,EAAA,MAAA;EAAuB,KAAA,CAAA,EAAA,MAAA;EAUhC,gBAAA,CAAA,EAhfI,MAgfY,CAAA,MAAQ,EAAA,OAAA,CAAc;AAUtD,CAAA;KAvfY,uBAAA;;;;;;qBAMQ;;KAGR,kBAAA;;;KAIA,aAAA;;;;;;;;;KAcA,yBAAA;;;;;;;;;;;;;;;KAgBA,sBAAA;;;;;KAUA,SAAA,GACT,gBACA,qBACA,gBACA,qBACA,0BACA,qBACA;KAEE,cAAA,GAAiB;;;;;;KA2FV,mBAAA;;;YAGD;SACH;;;;;;;;iBASQ,WAAA,OAAkB,eAAe;;;;iBAsBjC,YAAA,QAAoB,iBAAiB;;;;KAyHzC,oBAAA;;;;;;;;;;;;;;;iBAgBI,aAAA,UACN,8BACA,uBACP;;;;iBA0Ba,cAAA,WACL,gCACD,uBACP;;;;iBAkHa,qBAAA,OAA4B;;;;iBAU5B,cAAA,QACR,eACJ,qBAAqB;;;;iBAUT,gBAAA,QAAwB,cAAc;;;;iBAUtC,kBAAA,QAA0B"}
@@ -0,0 +1,255 @@
1
+ //#region src/ai-sdk-utils.ts
2
+ function isTextPart(part) {
3
+ return part.type === "text" && "text" in part;
4
+ }
5
+ function isReasoningPart(part) {
6
+ return part.type === "reasoning" && "text" in part;
7
+ }
8
+ function isSourceUrlPart(part) {
9
+ return part.type === "source-url" && "sourceId" in part && "url" in part;
10
+ }
11
+ function isSourceDocumentPart(part) {
12
+ return part.type === "source-document" && "sourceId" in part && "mediaType" in part && "title" in part;
13
+ }
14
+ function isStepStartPart(part) {
15
+ return part.type === "step-start";
16
+ }
17
+ function isFilePart(part) {
18
+ return part.type === "file" && "url" in part && "mediaType" in part;
19
+ }
20
+ function isImagePart(part) {
21
+ return part.type === "image" && "url" in part && "mediaType" in part;
22
+ }
23
+ function isToolPart(part) {
24
+ return typeof part.type === "string" && part.type.startsWith("tool-") && "toolCallId" in part && "toolName" in part;
25
+ }
26
+ function isEventPart(part) {
27
+ return part.type === "event";
28
+ }
29
+ function isMetadataPart(part) {
30
+ return part.type === "metadata";
31
+ }
32
+ /**
33
+ * Convert a Cossistant TimelineItem to AI SDK UIMessage format
34
+ *
35
+ * @param item - The Cossistant TimelineItem to convert
36
+ * @returns AI SDK compatible UIMessage with Cossistant metadata
37
+ */
38
+ function toUIMessage(item) {
39
+ return {
40
+ id: item.id ?? "",
41
+ role: getAISDKRole(item),
42
+ metadata: {
43
+ conversationId: item.conversationId,
44
+ organizationId: item.organizationId,
45
+ visibility: item.visibility,
46
+ userId: item.userId,
47
+ aiAgentId: item.aiAgentId,
48
+ visitorId: item.visitorId,
49
+ createdAt: item.createdAt,
50
+ deletedAt: item.deletedAt ?? null,
51
+ tool: item.tool ?? null
52
+ },
53
+ parts: item.parts.map(toAISDKPart).filter(Boolean)
54
+ };
55
+ }
56
+ /**
57
+ * Convert multiple TimelineItems to UIMessages
58
+ */
59
+ function toUIMessages(items) {
60
+ return items.map(toUIMessage);
61
+ }
62
+ /**
63
+ * Determine AI SDK role from TimelineItem sender fields
64
+ */
65
+ function getAISDKRole(item) {
66
+ if (item.aiAgentId) return "assistant";
67
+ return "user";
68
+ }
69
+ /**
70
+ * Convert a Cossistant part to AI SDK part format
71
+ */
72
+ function toAISDKPart(part) {
73
+ if (isTextPart(part)) return {
74
+ type: "text",
75
+ text: part.text,
76
+ state: part.state
77
+ };
78
+ if (isReasoningPart(part)) return {
79
+ type: "reasoning",
80
+ text: part.text,
81
+ state: part.state,
82
+ providerMetadata: part.providerMetadata
83
+ };
84
+ if (isSourceUrlPart(part)) return {
85
+ type: "source-url",
86
+ sourceId: part.sourceId,
87
+ url: part.url,
88
+ title: part.title,
89
+ providerMetadata: part.providerMetadata
90
+ };
91
+ if (isSourceDocumentPart(part)) return {
92
+ type: "source-document",
93
+ sourceId: part.sourceId,
94
+ mediaType: part.mediaType,
95
+ title: part.title,
96
+ filename: part.filename,
97
+ providerMetadata: part.providerMetadata
98
+ };
99
+ if (isStepStartPart(part)) return { type: "step-start" };
100
+ if (isFilePart(part)) {
101
+ const typedPart = part;
102
+ return {
103
+ type: "file",
104
+ url: part.url,
105
+ mediaType: part.mediaType,
106
+ filename: typedPart.filename ?? typedPart.fileName
107
+ };
108
+ }
109
+ if (isImagePart(part)) {
110
+ const typedPart = part;
111
+ return {
112
+ type: "file",
113
+ url: part.url,
114
+ mediaType: part.mediaType,
115
+ filename: typedPart.filename ?? typedPart.fileName
116
+ };
117
+ }
118
+ if (isToolPart(part)) return {
119
+ type: part.type,
120
+ toolCallId: part.toolCallId,
121
+ toolName: part.toolName,
122
+ input: part.input,
123
+ output: part.output,
124
+ state: part.state,
125
+ errorText: part.errorText,
126
+ providerMetadata: part.providerMetadata
127
+ };
128
+ if (isEventPart(part) || isMetadataPart(part)) return null;
129
+ return null;
130
+ }
131
+ /**
132
+ * Convert an AI SDK UIMessage to Cossistant TimelineItem format
133
+ *
134
+ * @param message - The AI SDK UIMessage to convert
135
+ * @param context - Context for creating the TimelineItem
136
+ * @returns Cossistant TimelineItem
137
+ */
138
+ function fromUIMessage(message, context) {
139
+ const metadata = message.metadata;
140
+ return {
141
+ id: message.id,
142
+ conversationId: metadata?.conversationId ?? context.conversationId,
143
+ organizationId: metadata?.organizationId ?? context.organizationId,
144
+ visibility: metadata?.visibility ?? context.visibility ?? "public",
145
+ type: "message",
146
+ text: extractTextFromParts(message.parts),
147
+ parts: message.parts.map(fromAISDKPart).filter(Boolean),
148
+ userId: metadata?.userId ?? context.userId ?? null,
149
+ aiAgentId: metadata?.aiAgentId ?? context.aiAgentId ?? null,
150
+ visitorId: metadata?.visitorId ?? context.visitorId ?? null,
151
+ createdAt: metadata?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
152
+ deletedAt: metadata?.deletedAt ?? null,
153
+ tool: metadata?.tool ?? null
154
+ };
155
+ }
156
+ /**
157
+ * Convert multiple UIMessages to TimelineItems
158
+ */
159
+ function fromUIMessages(messages, context) {
160
+ return messages.map((msg) => fromUIMessage(msg, context));
161
+ }
162
+ /**
163
+ * Extract plain text content from message parts
164
+ */
165
+ function extractTextFromParts(parts) {
166
+ const textParts = parts.filter((part) => typeof part === "object" && part !== null && "type" in part && part.type === "text");
167
+ if (textParts.length === 0) return null;
168
+ return textParts.map((p) => p.text).join("\n");
169
+ }
170
+ /**
171
+ * Convert an AI SDK part to Cossistant part format
172
+ */
173
+ function fromAISDKPart(part) {
174
+ if (typeof part !== "object" || part === null || !("type" in part)) return null;
175
+ const typedPart = part;
176
+ switch (typedPart.type) {
177
+ case "text": return {
178
+ type: "text",
179
+ text: String(typedPart.text ?? ""),
180
+ state: typedPart.state
181
+ };
182
+ case "reasoning": return {
183
+ type: "reasoning",
184
+ text: String(typedPart.text ?? ""),
185
+ state: typedPart.state,
186
+ providerMetadata: typedPart.providerMetadata
187
+ };
188
+ case "source-url": return {
189
+ type: "source-url",
190
+ sourceId: String(typedPart.sourceId ?? ""),
191
+ url: String(typedPart.url ?? ""),
192
+ title: typedPart.title,
193
+ providerMetadata: typedPart.providerMetadata
194
+ };
195
+ case "source-document": return {
196
+ type: "source-document",
197
+ sourceId: String(typedPart.sourceId ?? ""),
198
+ mediaType: String(typedPart.mediaType ?? ""),
199
+ title: String(typedPart.title ?? ""),
200
+ filename: typedPart.filename,
201
+ providerMetadata: typedPart.providerMetadata
202
+ };
203
+ case "step-start": return { type: "step-start" };
204
+ case "file": return {
205
+ type: "file",
206
+ url: String(typedPart.url ?? ""),
207
+ mediaType: String(typedPart.mediaType ?? ""),
208
+ filename: typedPart.filename
209
+ };
210
+ default:
211
+ if (typedPart.type.startsWith("tool-")) return {
212
+ type: typedPart.type,
213
+ toolCallId: String(typedPart.toolCallId ?? ""),
214
+ toolName: String(typedPart.toolName ?? ""),
215
+ input: typedPart.input ?? {},
216
+ output: typedPart.output,
217
+ state: typedPart.state ?? "partial",
218
+ errorText: typedPart.errorText,
219
+ providerMetadata: typedPart.providerMetadata
220
+ };
221
+ return null;
222
+ }
223
+ }
224
+ /**
225
+ * Check if a part is an AI SDK compatible part type
226
+ */
227
+ function isAISDKCompatiblePart(part) {
228
+ if (part.type === "event" || part.type === "metadata") return false;
229
+ return true;
230
+ }
231
+ /**
232
+ * Extract all sources from a message's parts
233
+ */
234
+ function extractSources(parts) {
235
+ return parts.filter((part) => part.type === "source-url" || part.type === "source-document");
236
+ }
237
+ /**
238
+ * Extract all tool calls from a message's parts
239
+ */
240
+ function extractToolCalls(parts) {
241
+ return parts.filter((part) => typeof part.type === "string" && part.type.startsWith("tool-"));
242
+ }
243
+ /**
244
+ * Check if any parts are still processing
245
+ */
246
+ function hasProcessingParts(parts) {
247
+ return parts.some((part) => {
248
+ if ("state" in part && (part.state === "streaming" || part.state === "partial")) return true;
249
+ return false;
250
+ });
251
+ }
252
+
253
+ //#endregion
254
+ export { extractSources, extractToolCalls, fromUIMessage, fromUIMessages, hasProcessingParts, isAISDKCompatiblePart, toUIMessage, toUIMessages };
255
+ //# sourceMappingURL=ai-sdk-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-sdk-utils.js","names":[],"sources":["../src/ai-sdk-utils.ts"],"sourcesContent":["/**\n * AI SDK v6 Conversion Utilities\n *\n * This module provides utilities for converting between Cossistant's\n * TimelineItem format and Vercel AI SDK v6's UIMessage format.\n *\n * Key concepts:\n * - Cossistant uses TimelineItem with userId/aiAgentId/visitorId\n * - AI SDK uses UIMessage with role: 'user' | 'assistant' | 'system'\n * - Both use a parts array for content\n * - Extensions go in metadata (message level) and providerMetadata (part level)\n */\n\nimport type { TimelineItem, TimelineItemParts } from \"@cossistant/types\";\n\n// ============================================================================\n// AI SDK TYPES (re-export for convenience)\n// ============================================================================\n\n/**\n * AI SDK UIMessage part types - these are the standard AI SDK v6 parts\n */\nexport type AISDKTextPart = {\n\ttype: \"text\";\n\ttext: string;\n\tstate?: \"streaming\" | \"done\";\n};\n\nexport type AISDKReasoningPart = {\n\ttype: \"reasoning\";\n\ttext: string;\n\tstate?: \"streaming\" | \"done\";\n\tproviderMetadata?: Record<string, unknown>;\n};\n\nexport type AISDKToolPart = {\n\ttype: `tool-${string}`;\n\ttoolCallId: string;\n\ttoolName: string;\n\tinput: Record<string, unknown>;\n\toutput?: unknown;\n\tstate: \"partial\" | \"result\" | \"error\";\n\terrorText?: string;\n\tproviderMetadata?: Record<string, unknown>;\n};\n\nexport type AISDKSourceUrlPart = {\n\ttype: \"source-url\";\n\tsourceId: string;\n\turl: string;\n\ttitle?: string;\n\tproviderMetadata?: Record<string, unknown>;\n};\n\nexport type AISDKSourceDocumentPart = {\n\ttype: \"source-document\";\n\tsourceId: string;\n\tmediaType: string;\n\ttitle: string;\n\tfilename?: string;\n\tproviderMetadata?: Record<string, unknown>;\n};\n\nexport type AISDKStepStartPart = {\n\ttype: \"step-start\";\n};\n\nexport type AISDKFilePart = {\n\ttype: \"file\";\n\turl: string;\n\tmediaType: string;\n\tfilename?: string;\n};\n\n// ============================================================================\n// COSSISTANT METADATA TYPES\n// ============================================================================\n\n/**\n * Cossistant-specific metadata stored in UIMessage.metadata\n */\nexport type CossistantMessageMetadata = {\n\tconversationId: string;\n\torganizationId: string;\n\tvisibility: \"public\" | \"private\";\n\tuserId: string | null;\n\taiAgentId: string | null;\n\tvisitorId: string | null;\n\treplyToId?: string | null;\n\tcreatedAt: string;\n\tdeletedAt?: string | null;\n\ttool?: string | null;\n};\n\n/**\n * Cossistant-specific metadata stored in part.providerMetadata.cossistant\n */\nexport type CossistantPartMetadata = {\n\tvisibility?: \"public\" | \"private\";\n\tprogressMessage?: string;\n\tknowledgeId?: string;\n};\n\n// ============================================================================\n// TYPE HELPERS\n// ============================================================================\n\nexport type AISDKPart =\n\t| AISDKTextPart\n\t| AISDKReasoningPart\n\t| AISDKToolPart\n\t| AISDKSourceUrlPart\n\t| AISDKSourceDocumentPart\n\t| AISDKStepStartPart\n\t| AISDKFilePart;\n\ntype CossistantPart = TimelineItemParts[number];\n\n// Type guards for Cossistant parts\nfunction isTextPart(\n\tpart: CossistantPart\n): part is CossistantPart & { type: \"text\"; text: string } {\n\treturn part.type === \"text\" && \"text\" in part;\n}\n\nfunction isReasoningPart(\n\tpart: CossistantPart\n): part is CossistantPart & { type: \"reasoning\"; text: string } {\n\treturn part.type === \"reasoning\" && \"text\" in part;\n}\n\nfunction isSourceUrlPart(part: CossistantPart): part is CossistantPart & {\n\ttype: \"source-url\";\n\tsourceId: string;\n\turl: string;\n} {\n\treturn part.type === \"source-url\" && \"sourceId\" in part && \"url\" in part;\n}\n\nfunction isSourceDocumentPart(part: CossistantPart): part is CossistantPart & {\n\ttype: \"source-document\";\n\tsourceId: string;\n\tmediaType: string;\n\ttitle: string;\n} {\n\treturn (\n\t\tpart.type === \"source-document\" &&\n\t\t\"sourceId\" in part &&\n\t\t\"mediaType\" in part &&\n\t\t\"title\" in part\n\t);\n}\n\nfunction isStepStartPart(\n\tpart: CossistantPart\n): part is CossistantPart & { type: \"step-start\" } {\n\treturn part.type === \"step-start\";\n}\n\nfunction isFilePart(\n\tpart: CossistantPart\n): part is CossistantPart & { type: \"file\"; url: string; mediaType: string } {\n\treturn part.type === \"file\" && \"url\" in part && \"mediaType\" in part;\n}\n\nfunction isImagePart(\n\tpart: CossistantPart\n): part is CossistantPart & { type: \"image\"; url: string; mediaType: string } {\n\treturn part.type === \"image\" && \"url\" in part && \"mediaType\" in part;\n}\n\nfunction isToolPart(part: CossistantPart): part is CossistantPart & {\n\ttype: string;\n\ttoolCallId: string;\n\ttoolName: string;\n\tinput: Record<string, unknown>;\n\tstate: \"partial\" | \"result\" | \"error\";\n} {\n\treturn (\n\t\ttypeof part.type === \"string\" &&\n\t\tpart.type.startsWith(\"tool-\") &&\n\t\t\"toolCallId\" in part &&\n\t\t\"toolName\" in part\n\t);\n}\n\nfunction isEventPart(\n\tpart: CossistantPart\n): part is CossistantPart & { type: \"event\" } {\n\treturn part.type === \"event\";\n}\n\nfunction isMetadataPart(\n\tpart: CossistantPart\n): part is CossistantPart & { type: \"metadata\" } {\n\treturn part.type === \"metadata\";\n}\n\n// ============================================================================\n// CONVERSION: TIMELINE ITEM -> UI MESSAGE\n// ============================================================================\n\n/**\n * Cossistant-compatible UIMessage type\n * This is structurally compatible with AI SDK v6 UIMessage\n * but uses our own part types for flexibility\n */\nexport type CossistantUIMessage = {\n\tid: string;\n\trole: \"user\" | \"assistant\" | \"system\";\n\tmetadata: CossistantMessageMetadata;\n\tparts: AISDKPart[];\n};\n\n/**\n * Convert a Cossistant TimelineItem to AI SDK UIMessage format\n *\n * @param item - The Cossistant TimelineItem to convert\n * @returns AI SDK compatible UIMessage with Cossistant metadata\n */\nexport function toUIMessage(item: TimelineItem): CossistantUIMessage {\n\treturn {\n\t\tid: item.id ?? \"\",\n\t\trole: getAISDKRole(item),\n\t\tmetadata: {\n\t\t\tconversationId: item.conversationId,\n\t\t\torganizationId: item.organizationId,\n\t\t\tvisibility: item.visibility,\n\t\t\tuserId: item.userId,\n\t\t\taiAgentId: item.aiAgentId,\n\t\t\tvisitorId: item.visitorId,\n\t\t\tcreatedAt: item.createdAt,\n\t\t\tdeletedAt: item.deletedAt ?? null,\n\t\t\ttool: item.tool ?? null,\n\t\t},\n\t\tparts: item.parts.map(toAISDKPart).filter(Boolean) as AISDKPart[],\n\t};\n}\n\n/**\n * Convert multiple TimelineItems to UIMessages\n */\nexport function toUIMessages(items: TimelineItem[]): CossistantUIMessage[] {\n\treturn items.map(toUIMessage);\n}\n\n/**\n * Determine AI SDK role from TimelineItem sender fields\n */\nfunction getAISDKRole(item: TimelineItem): \"user\" | \"assistant\" | \"system\" {\n\t// AI agent messages become assistant\n\tif (item.aiAgentId) {\n\t\treturn \"assistant\";\n\t}\n\n\t// Both visitor and human user messages become user\n\t// (AI SDK doesn't distinguish between these)\n\treturn \"user\";\n}\n\n/**\n * Convert a Cossistant part to AI SDK part format\n */\nfunction toAISDKPart(part: CossistantPart): AISDKPart | null {\n\tif (isTextPart(part)) {\n\t\treturn {\n\t\t\ttype: \"text\",\n\t\t\ttext: part.text,\n\t\t\tstate: (part as { state?: \"streaming\" | \"done\" }).state,\n\t\t};\n\t}\n\n\tif (isReasoningPart(part)) {\n\t\treturn {\n\t\t\ttype: \"reasoning\",\n\t\t\ttext: part.text,\n\t\t\tstate: (part as { state?: \"streaming\" | \"done\" }).state,\n\t\t\tproviderMetadata: (part as { providerMetadata?: Record<string, unknown> })\n\t\t\t\t.providerMetadata,\n\t\t};\n\t}\n\n\tif (isSourceUrlPart(part)) {\n\t\treturn {\n\t\t\ttype: \"source-url\",\n\t\t\tsourceId: part.sourceId,\n\t\t\turl: part.url,\n\t\t\ttitle: (part as { title?: string }).title,\n\t\t\tproviderMetadata: (part as { providerMetadata?: Record<string, unknown> })\n\t\t\t\t.providerMetadata,\n\t\t};\n\t}\n\n\tif (isSourceDocumentPart(part)) {\n\t\treturn {\n\t\t\ttype: \"source-document\",\n\t\t\tsourceId: part.sourceId,\n\t\t\tmediaType: part.mediaType,\n\t\t\ttitle: part.title,\n\t\t\tfilename: (part as { filename?: string }).filename,\n\t\t\tproviderMetadata: (part as { providerMetadata?: Record<string, unknown> })\n\t\t\t\t.providerMetadata,\n\t\t};\n\t}\n\n\tif (isStepStartPart(part)) {\n\t\treturn {\n\t\t\ttype: \"step-start\",\n\t\t};\n\t}\n\n\tif (isFilePart(part)) {\n\t\t// Support both 'filename' (new) and 'fileName' (legacy) for backward compatibility\n\t\tconst typedPart = part as { filename?: string; fileName?: string };\n\t\treturn {\n\t\t\ttype: \"file\",\n\t\t\turl: part.url,\n\t\t\tmediaType: part.mediaType,\n\t\t\tfilename: typedPart.filename ?? typedPart.fileName,\n\t\t};\n\t}\n\n\tif (isImagePart(part)) {\n\t\t// Convert image to file part (AI SDK uses file for all media)\n\t\t// Support both 'filename' (new) and 'fileName' (legacy) for backward compatibility\n\t\tconst typedPart = part as { filename?: string; fileName?: string };\n\t\treturn {\n\t\t\ttype: \"file\",\n\t\t\turl: part.url,\n\t\t\tmediaType: part.mediaType,\n\t\t\tfilename: typedPart.filename ?? typedPart.fileName,\n\t\t};\n\t}\n\n\tif (isToolPart(part)) {\n\t\treturn {\n\t\t\ttype: part.type as `tool-${string}`,\n\t\t\ttoolCallId: part.toolCallId,\n\t\t\ttoolName: part.toolName,\n\t\t\tinput: part.input,\n\t\t\toutput: (part as { output?: unknown }).output,\n\t\t\tstate: part.state,\n\t\t\terrorText: (part as { errorText?: string }).errorText,\n\t\t\tproviderMetadata: (part as { providerMetadata?: Record<string, unknown> })\n\t\t\t\t.providerMetadata,\n\t\t};\n\t}\n\n\t// Event and metadata parts are Cossistant-specific, skip for AI SDK\n\tif (isEventPart(part) || isMetadataPart(part)) {\n\t\treturn null;\n\t}\n\n\treturn null;\n}\n\n// ============================================================================\n// CONVERSION: UI MESSAGE -> TIMELINE ITEM\n// ============================================================================\n\n/**\n * Context required to create a TimelineItem from UIMessage\n */\nexport type FromUIMessageContext = {\n\tconversationId: string;\n\torganizationId: string;\n\taiAgentId?: string | null;\n\tuserId?: string | null;\n\tvisitorId?: string | null;\n\tvisibility?: \"public\" | \"private\";\n};\n\n/**\n * Convert an AI SDK UIMessage to Cossistant TimelineItem format\n *\n * @param message - The AI SDK UIMessage to convert\n * @param context - Context for creating the TimelineItem\n * @returns Cossistant TimelineItem\n */\nexport function fromUIMessage(\n\tmessage: CossistantUIMessage,\n\tcontext: FromUIMessageContext\n): TimelineItem {\n\t// Extract metadata if available\n\tconst metadata = message.metadata;\n\n\treturn {\n\t\tid: message.id,\n\t\tconversationId: metadata?.conversationId ?? context.conversationId,\n\t\torganizationId: metadata?.organizationId ?? context.organizationId,\n\t\tvisibility: metadata?.visibility ?? context.visibility ?? \"public\",\n\t\ttype: \"message\",\n\t\ttext: extractTextFromParts(message.parts),\n\t\tparts: message.parts\n\t\t\t.map(fromAISDKPart)\n\t\t\t.filter(Boolean) as TimelineItemParts,\n\t\tuserId: metadata?.userId ?? context.userId ?? null,\n\t\taiAgentId: metadata?.aiAgentId ?? context.aiAgentId ?? null,\n\t\tvisitorId: metadata?.visitorId ?? context.visitorId ?? null,\n\t\tcreatedAt: metadata?.createdAt ?? new Date().toISOString(),\n\t\tdeletedAt: metadata?.deletedAt ?? null,\n\t\ttool: metadata?.tool ?? null,\n\t};\n}\n\n/**\n * Convert multiple UIMessages to TimelineItems\n */\nexport function fromUIMessages(\n\tmessages: CossistantUIMessage[],\n\tcontext: FromUIMessageContext\n): TimelineItem[] {\n\treturn messages.map((msg) => fromUIMessage(msg, context));\n}\n\n/**\n * Extract plain text content from message parts\n */\nfunction extractTextFromParts(parts: unknown[]): string | null {\n\tconst textParts = parts.filter(\n\t\t(part): part is AISDKTextPart =>\n\t\t\ttypeof part === \"object\" &&\n\t\t\tpart !== null &&\n\t\t\t\"type\" in part &&\n\t\t\tpart.type === \"text\"\n\t);\n\n\tif (textParts.length === 0) {\n\t\treturn null;\n\t}\n\treturn textParts.map((p) => p.text).join(\"\\n\");\n}\n\n/**\n * Convert an AI SDK part to Cossistant part format\n */\nfunction fromAISDKPart(part: unknown): CossistantPart | null {\n\tif (typeof part !== \"object\" || part === null || !(\"type\" in part)) {\n\t\treturn null;\n\t}\n\n\tconst typedPart = part as { type: string; [key: string]: unknown };\n\n\tswitch (typedPart.type) {\n\t\tcase \"text\":\n\t\t\treturn {\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: String(typedPart.text ?? \"\"),\n\t\t\t\tstate: typedPart.state as \"streaming\" | \"done\" | undefined,\n\t\t\t};\n\n\t\tcase \"reasoning\":\n\t\t\treturn {\n\t\t\t\ttype: \"reasoning\",\n\t\t\t\ttext: String(typedPart.text ?? \"\"),\n\t\t\t\tstate: typedPart.state as \"streaming\" | \"done\" | undefined,\n\t\t\t\tproviderMetadata: typedPart.providerMetadata as\n\t\t\t\t\t| Record<string, unknown>\n\t\t\t\t\t| undefined,\n\t\t\t};\n\n\t\tcase \"source-url\":\n\t\t\treturn {\n\t\t\t\ttype: \"source-url\",\n\t\t\t\tsourceId: String(typedPart.sourceId ?? \"\"),\n\t\t\t\turl: String(typedPart.url ?? \"\"),\n\t\t\t\ttitle: typedPart.title as string | undefined,\n\t\t\t\tproviderMetadata: typedPart.providerMetadata as\n\t\t\t\t\t| Record<string, unknown>\n\t\t\t\t\t| undefined,\n\t\t\t};\n\n\t\tcase \"source-document\":\n\t\t\treturn {\n\t\t\t\ttype: \"source-document\",\n\t\t\t\tsourceId: String(typedPart.sourceId ?? \"\"),\n\t\t\t\tmediaType: String(typedPart.mediaType ?? \"\"),\n\t\t\t\ttitle: String(typedPart.title ?? \"\"),\n\t\t\t\tfilename: typedPart.filename as string | undefined,\n\t\t\t\tproviderMetadata: typedPart.providerMetadata as\n\t\t\t\t\t| Record<string, unknown>\n\t\t\t\t\t| undefined,\n\t\t\t};\n\n\t\tcase \"step-start\":\n\t\t\treturn {\n\t\t\t\ttype: \"step-start\",\n\t\t\t};\n\n\t\tcase \"file\":\n\t\t\treturn {\n\t\t\t\ttype: \"file\",\n\t\t\t\turl: String(typedPart.url ?? \"\"),\n\t\t\t\tmediaType: String(typedPart.mediaType ?? \"\"),\n\t\t\t\tfilename: typedPart.filename as string | undefined,\n\t\t\t};\n\n\t\tdefault:\n\t\t\t// Handle tool-* pattern\n\t\t\tif (typedPart.type.startsWith(\"tool-\")) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: typedPart.type,\n\t\t\t\t\ttoolCallId: String(typedPart.toolCallId ?? \"\"),\n\t\t\t\t\ttoolName: String(typedPart.toolName ?? \"\"),\n\t\t\t\t\tinput: (typedPart.input as Record<string, unknown>) ?? {},\n\t\t\t\t\toutput: typedPart.output,\n\t\t\t\t\tstate:\n\t\t\t\t\t\t(typedPart.state as \"partial\" | \"result\" | \"error\") ?? \"partial\",\n\t\t\t\t\terrorText: typedPart.errorText as string | undefined,\n\t\t\t\t\tproviderMetadata: typedPart.providerMetadata as\n\t\t\t\t\t\t| Record<string, unknown>\n\t\t\t\t\t\t| undefined,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn null;\n\t}\n}\n\n// ============================================================================\n// HELPER UTILITIES\n// ============================================================================\n\n/**\n * Check if a part is an AI SDK compatible part type\n */\nexport function isAISDKCompatiblePart(part: CossistantPart): boolean {\n\tif (part.type === \"event\" || part.type === \"metadata\") {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n/**\n * Extract all sources from a message's parts\n */\nexport function extractSources(\n\tparts: AISDKPart[]\n): (AISDKSourceUrlPart | AISDKSourceDocumentPart)[] {\n\treturn parts.filter(\n\t\t(part): part is AISDKSourceUrlPart | AISDKSourceDocumentPart =>\n\t\t\tpart.type === \"source-url\" || part.type === \"source-document\"\n\t);\n}\n\n/**\n * Extract all tool calls from a message's parts\n */\nexport function extractToolCalls(parts: AISDKPart[]): AISDKToolPart[] {\n\treturn parts.filter(\n\t\t(part): part is AISDKToolPart =>\n\t\t\ttypeof part.type === \"string\" && part.type.startsWith(\"tool-\")\n\t);\n}\n\n/**\n * Check if any parts are still processing\n */\nexport function hasProcessingParts(parts: AISDKPart[]): boolean {\n\treturn parts.some((part) => {\n\t\tif (\n\t\t\t\"state\" in part &&\n\t\t\t(part.state === \"streaming\" || part.state === \"partial\")\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t});\n}\n"],"mappings":"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"}
package/client.d.ts CHANGED
@@ -1,12 +1,12 @@
1
- import { CreateConversationRequestBody, CreateConversationResponseBody, GetConversationRequest, GetConversationResponse, ListConversationsRequest, ListConversationsResponse, MarkConversationSeenRequestBody, MarkConversationSeenResponseBody, SetConversationTypingResponseBody } from "./conversation.js";
2
- import { GetConversationTimelineItemsRequest, GetConversationTimelineItemsResponse, SendTimelineItemRequest, SendTimelineItemResponse, TimelineItem } from "./timeline-item.js";
3
- import { Conversation } from "./schemas.js";
1
+ import { CreateConversationRequestBody, CreateConversationResponseBody, GetConversationRequest, GetConversationResponse, ListConversationsRequest, ListConversationsResponse, MarkConversationSeenRequestBody, MarkConversationSeenResponseBody, SetConversationTypingResponseBody } from "./types/src/api/conversation.js";
2
+ import { GetConversationTimelineItemsRequest, GetConversationTimelineItemsResponse, SendTimelineItemRequest, SendTimelineItemResponse, TimelineItem as TimelineItem$1 } from "./types/src/api/timeline-item.js";
3
+ import { Conversation } from "./types/src/schemas.js";
4
4
  import { types_d_exports } from "./types.js";
5
5
  import { CossistantRestClient } from "./rest-client.js";
6
6
  import { ConversationsStore } from "./store/conversations-store.js";
7
7
  import { TimelineItemsStore } from "./store/timeline-items-store.js";
8
8
  import { WebsiteStore } from "./store/website-store.js";
9
- import { AnyRealtimeEvent, DefaultMessage, IdentifyContactResponse } from "@cossistant/types";
9
+ import { AnyRealtimeEvent, DefaultMessage, IdentifyContactResponse, RealtimeEvent } from "@cossistant/types";
10
10
 
11
11
  //#region src/client.d.ts
12
12
  type InitiateConversationParams = {
@@ -15,12 +15,12 @@ type InitiateConversationParams = {
15
15
  websiteId?: string | null;
16
16
  title?: string;
17
17
  status?: Conversation["status"];
18
- defaultTimelineItems?: Array<DefaultMessage | TimelineItem>;
18
+ defaultTimelineItems?: Array<DefaultMessage | TimelineItem$1>;
19
19
  };
20
20
  type InitiateConversationResult = {
21
21
  conversationId: string;
22
22
  conversation: Conversation;
23
- defaultTimelineItems: TimelineItem[];
23
+ defaultTimelineItems: TimelineItem$1[];
24
24
  };
25
25
  declare class CossistantClient {
26
26
  private restClient;
@@ -84,10 +84,20 @@ declare class CossistantClient {
84
84
  createIfPending?: boolean;
85
85
  }): Promise<SendTimelineItemResponse & {
86
86
  conversation?: Conversation;
87
- initialTimelineItems?: TimelineItem[];
87
+ initialTimelineItems?: TimelineItem$1[];
88
88
  wasConversationCreated?: boolean;
89
89
  }>;
90
90
  handleRealtimeEvent(event: AnyRealtimeEvent): void;
91
+ /**
92
+ * Extract conversation status from an event timeline item.
93
+ * Returns the new status if this is a status-changing event, otherwise null.
94
+ */
95
+ private extractStatusFromEventTimelineItem;
96
+ /**
97
+ * Handle conversationUpdated event from realtime
98
+ * Updates conversation with new title (sentiment and escalation are dashboard-only)
99
+ */
100
+ handleConversationUpdated(event: RealtimeEvent<"conversationUpdated">): void;
91
101
  /**
92
102
  * Generate a presigned URL for uploading a file to S3.
93
103
  */
package/client.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":"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"}
package/client.js CHANGED
@@ -143,7 +143,7 @@ var CossistantClient = class {
143
143
  return response;
144
144
  }
145
145
  async sendMessage(params) {
146
- const { createIfPending,...rest } = params;
146
+ const { createIfPending, ...rest } = params;
147
147
  const optimisticId = rest.item.id ?? generateMessageId();
148
148
  const createdAt = rest.item.createdAt ? rest.item.createdAt : typeof window !== "undefined" ? (/* @__PURE__ */ new Date()).toISOString() : "";
149
149
  const optimisticTimelineItem = {
@@ -190,7 +190,7 @@ var CossistantClient = class {
190
190
  this.timelineItemsStore.removeTimelineItem(rest.conversationId, optimisticId);
191
191
  throw error;
192
192
  }
193
- const { createdAt: _createdAt,...restItem } = rest.item;
193
+ const { createdAt: _createdAt, ...restItem } = rest.item;
194
194
  const payload = {
195
195
  ...rest,
196
196
  item: {
@@ -218,16 +218,47 @@ var CossistantClient = class {
218
218
  const timelineItem = this.timelineItemsStore.ingestRealtimeTimelineItem(event);
219
219
  const existingConversation = this.conversationsStore.getState().byId[timelineItem.conversationId];
220
220
  if (existingConversation) {
221
+ const newStatus = this.extractStatusFromEventTimelineItem(timelineItem);
221
222
  const nextConversation = {
222
223
  ...existingConversation,
223
224
  updatedAt: timelineItem.createdAt,
224
- lastTimelineItem: timelineItem
225
+ lastTimelineItem: timelineItem,
226
+ ...newStatus && { status: newStatus }
225
227
  };
226
228
  this.conversationsStore.ingestConversation(nextConversation);
227
229
  }
228
230
  }
229
231
  }
230
232
  /**
233
+ * Extract conversation status from an event timeline item.
234
+ * Returns the new status if this is a status-changing event, otherwise null.
235
+ */
236
+ extractStatusFromEventTimelineItem(timelineItem) {
237
+ if (timelineItem.type !== ConversationTimelineType.EVENT) return null;
238
+ const eventPart = timelineItem.parts?.find((part) => typeof part === "object" && part !== null && "type" in part && part.type === "event");
239
+ if (!eventPart || typeof eventPart !== "object" || !("eventType" in eventPart)) return null;
240
+ switch (eventPart.eventType) {
241
+ case "resolved": return ConversationStatus.RESOLVED;
242
+ case "reopened": return ConversationStatus.OPEN;
243
+ default: return null;
244
+ }
245
+ }
246
+ /**
247
+ * Handle conversationUpdated event from realtime
248
+ * Updates conversation with new title (sentiment and escalation are dashboard-only)
249
+ */
250
+ handleConversationUpdated(event) {
251
+ const { conversationId, updates } = event.payload;
252
+ const existingConversation = this.conversationsStore.getState().byId[conversationId];
253
+ if (!existingConversation) return;
254
+ const nextConversation = {
255
+ ...existingConversation,
256
+ ...updates.title !== void 0 && { title: updates.title ?? void 0 },
257
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
258
+ };
259
+ this.conversationsStore.ingestConversation(nextConversation);
260
+ }
261
+ /**
231
262
  * Generate a presigned URL for uploading a file to S3.
232
263
  */
233
264
  async generateUploadUrl(params) {