chat 4.28.1 → 4.30.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/ai/index.d.ts +501 -0
- package/dist/ai/index.js +500 -0
- package/dist/chat-BPjXsoIl.d.ts +3158 -0
- package/dist/chunk-HD375J7S.js +128 -0
- package/dist/index.d.ts +6 -3143
- package/dist/index.js +45 -139
- package/dist/{jsx-runtime-DxGwoLu2.d.ts → jsx-runtime-CnDs8rPr.d.ts} +1 -1
- package/dist/jsx-runtime.d.ts +1 -1
- package/docs/adapters.mdx +35 -5
- package/docs/ai/ai-sdk-tools.mdx +227 -0
- package/docs/ai/index.mdx +69 -0
- package/docs/ai/meta.json +4 -0
- package/docs/{api → ai}/to-ai-messages.mdx +16 -3
- package/docs/ai/types.mdx +243 -0
- package/docs/api/chat.mdx +50 -10
- package/docs/api/index.mdx +4 -6
- package/docs/api/message.mdx +1 -1
- package/docs/api/meta.json +0 -1
- package/docs/api/postable-message.mdx +3 -3
- package/docs/api/thread.mdx +1 -1
- package/docs/concurrency.mdx +54 -15
- package/docs/contributing/building.mdx +1 -1
- package/docs/contributing/testing.mdx +4 -0
- package/docs/direct-messages.mdx +10 -1
- package/docs/files.mdx +20 -0
- package/docs/getting-started.mdx +5 -1
- package/docs/handling-events.mdx +10 -7
- package/docs/index.mdx +4 -1
- package/docs/meta.json +4 -0
- package/docs/posting-messages.mdx +3 -1
- package/docs/slack-primitives.mdx +320 -0
- package/docs/slash-commands.mdx +4 -4
- package/docs/streaming.mdx +4 -4
- package/docs/subject.mdx +1 -1
- package/docs/testing.mdx +142 -0
- package/docs/threads-messages-channels.mdx +1 -1
- package/docs/usage.mdx +8 -4
- package/package.json +23 -2
- package/resources/guides/create-a-discord-support-bot-with-nuxt-and-redis.md +5 -1
- package/resources/guides/how-to-build-a-slack-bot-with-next-js-and-redis.md +5 -1
- package/resources/guides/how-to-build-an-ai-agent-for-slack-with-chat-sdk-and-ai-sdk.md +1 -1
- package/resources/guides/human-in-the-loop-with-chat-sdk-and-workflow-sdk.md +176 -0
- package/resources/guides/liveblocks-chat-sdk-ai-sdk.md +165 -0
- package/resources/guides/run-and-track-deploys-from-slack.md +7 -5
- package/resources/guides/ship-a-github-code-review-bot-with-hono-and-redis.md +5 -1
- package/resources/guides/slack-bot-vercel-blob.md +254 -0
- package/resources/guides/triage-form-submissions-with-chat-sdk.md +3 -1
- package/resources/templates.json +5 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// src/ai/messages.ts
|
|
2
|
+
var TEXT_MIME_PREFIXES = [
|
|
3
|
+
"text/",
|
|
4
|
+
"application/json",
|
|
5
|
+
"application/xml",
|
|
6
|
+
"application/javascript",
|
|
7
|
+
"application/typescript",
|
|
8
|
+
"application/yaml",
|
|
9
|
+
"application/x-yaml",
|
|
10
|
+
"application/toml"
|
|
11
|
+
];
|
|
12
|
+
function isTextMimeType(mimeType) {
|
|
13
|
+
return TEXT_MIME_PREFIXES.some(
|
|
14
|
+
(prefix) => mimeType === prefix || mimeType.startsWith(prefix)
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
async function attachmentToPart(att) {
|
|
18
|
+
if (att.type === "image") {
|
|
19
|
+
if (att.fetchData) {
|
|
20
|
+
try {
|
|
21
|
+
const buffer = await att.fetchData();
|
|
22
|
+
const mimeType = att.mimeType ?? "image/png";
|
|
23
|
+
return {
|
|
24
|
+
type: "file",
|
|
25
|
+
data: `data:${mimeType};base64,${buffer.toString("base64")}`,
|
|
26
|
+
mediaType: mimeType,
|
|
27
|
+
filename: att.name
|
|
28
|
+
};
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.error("toAiMessages: failed to fetch image data", error);
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
if (att.type === "file" && att.mimeType && isTextMimeType(att.mimeType)) {
|
|
37
|
+
if (att.fetchData) {
|
|
38
|
+
try {
|
|
39
|
+
const buffer = await att.fetchData();
|
|
40
|
+
return {
|
|
41
|
+
type: "file",
|
|
42
|
+
data: `data:${att.mimeType};base64,${buffer.toString("base64")}`,
|
|
43
|
+
filename: att.name,
|
|
44
|
+
mediaType: att.mimeType
|
|
45
|
+
};
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.error("toAiMessages: failed to fetch file data", error);
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
async function toAiMessages(messages, options) {
|
|
56
|
+
const includeNames = options?.includeNames ?? false;
|
|
57
|
+
const transformMessage = options?.transformMessage;
|
|
58
|
+
const onUnsupported = options?.onUnsupportedAttachment ?? ((att) => {
|
|
59
|
+
console.warn(
|
|
60
|
+
`toAiMessages: unsupported attachment type "${att.type}"${att.name ? ` (${att.name})` : ""} \u2014 skipped`
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
const sorted = [...messages].sort(
|
|
64
|
+
(a, b) => (a.metadata.dateSent?.getTime() ?? 0) - (b.metadata.dateSent?.getTime() ?? 0)
|
|
65
|
+
);
|
|
66
|
+
const filtered = sorted.filter((msg) => msg.text.trim());
|
|
67
|
+
const results = await Promise.all(
|
|
68
|
+
filtered.map(async (msg) => {
|
|
69
|
+
const role = msg.author.isMe ? "assistant" : "user";
|
|
70
|
+
let textContent = includeNames && role === "user" ? `[${msg.author.userName}]: ${msg.text}` : msg.text;
|
|
71
|
+
if (msg.links && msg.links.length > 0) {
|
|
72
|
+
const linkParts = msg.links.map((link) => {
|
|
73
|
+
const parts = link.fetchMessage ? [`[Embedded message: ${link.url}]`] : [link.url];
|
|
74
|
+
if (link.title) {
|
|
75
|
+
parts.push(`Title: ${link.title}`);
|
|
76
|
+
}
|
|
77
|
+
if (link.description) {
|
|
78
|
+
parts.push(`Description: ${link.description}`);
|
|
79
|
+
}
|
|
80
|
+
if (link.siteName) {
|
|
81
|
+
parts.push(`Site: ${link.siteName}`);
|
|
82
|
+
}
|
|
83
|
+
return parts.join("\n");
|
|
84
|
+
}).join("\n\n");
|
|
85
|
+
textContent += `
|
|
86
|
+
|
|
87
|
+
Links:
|
|
88
|
+
${linkParts}`;
|
|
89
|
+
}
|
|
90
|
+
let aiMessage;
|
|
91
|
+
if (role === "user") {
|
|
92
|
+
const attachmentParts = [];
|
|
93
|
+
for (const att of msg.attachments ?? []) {
|
|
94
|
+
const part = await attachmentToPart(att);
|
|
95
|
+
if (part) {
|
|
96
|
+
attachmentParts.push(part);
|
|
97
|
+
} else if (att.type === "video" || att.type === "audio") {
|
|
98
|
+
onUnsupported(att, msg);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (attachmentParts.length > 0) {
|
|
102
|
+
aiMessage = {
|
|
103
|
+
role,
|
|
104
|
+
content: [
|
|
105
|
+
{ type: "text", text: textContent },
|
|
106
|
+
...attachmentParts
|
|
107
|
+
]
|
|
108
|
+
};
|
|
109
|
+
} else {
|
|
110
|
+
aiMessage = { role, content: textContent };
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
aiMessage = { role, content: textContent };
|
|
114
|
+
}
|
|
115
|
+
if (transformMessage) {
|
|
116
|
+
return { result: await transformMessage(aiMessage, msg), source: msg };
|
|
117
|
+
}
|
|
118
|
+
return { result: aiMessage, source: msg };
|
|
119
|
+
})
|
|
120
|
+
);
|
|
121
|
+
return results.filter(
|
|
122
|
+
(r) => r.result != null
|
|
123
|
+
).map((r) => r.result);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export {
|
|
127
|
+
toAiMessages
|
|
128
|
+
};
|