botinabox 2.7.10 → 2.8.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/LICENSE +21 -21
- package/README.md +190 -190
- package/bin/botinabox.mjs +1 -1
- package/dist/channel-DziSPayj.d.ts +73 -0
- package/dist/channels/discord/index.d.ts +1 -1
- package/dist/channels/slack/index.d.ts +75 -4
- package/dist/channels/slack/index.js +140 -6
- package/dist/channels/webhook/index.d.ts +1 -1
- package/dist/chat-pipeline-BGgmH_ap.d.ts +655 -0
- package/dist/chat-pipeline-BWrtVqEP.d.ts +652 -0
- package/dist/chunk-OEMM2LEA.js +223 -0
- package/dist/chunk-XYF5PSB2.js +389 -0
- package/dist/cli.js +0 -0
- package/dist/gmail-connector-Z7SO6VOS.js +7 -0
- package/dist/inbound-5FKJBWPL.js +11 -0
- package/dist/index.d.ts +6 -6
- package/dist/provider-BHkqkSdq.d.ts +89 -0
- package/dist/providers/anthropic/index.d.ts +1 -1
- package/dist/providers/ollama/index.d.ts +1 -1
- package/dist/providers/openai/index.d.ts +1 -1
- package/package.json +100 -100
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
extractVoiceTranscript,
|
|
5
5
|
parseSlackEvent,
|
|
6
6
|
transcribeAudio
|
|
7
|
-
} from "../../chunk-
|
|
7
|
+
} from "../../chunk-OEMM2LEA.js";
|
|
8
8
|
import {
|
|
9
9
|
chunkText
|
|
10
10
|
} from "../../chunk-ZTZFPTOQ.js";
|
|
@@ -71,8 +71,8 @@ var SlackAdapter = class {
|
|
|
71
71
|
/** Simulate receiving an inbound message (for testing/webhooks). */
|
|
72
72
|
async receive(event) {
|
|
73
73
|
if (this.onMessage) {
|
|
74
|
-
const { parseSlackEvent: parseSlackEvent2 } = await import("../../inbound-
|
|
75
|
-
const { enrichVoiceMessage: enrichVoiceMessage2 } = await import("../../inbound-
|
|
74
|
+
const { parseSlackEvent: parseSlackEvent2 } = await import("../../inbound-5FKJBWPL.js");
|
|
75
|
+
const { enrichVoiceMessage: enrichVoiceMessage2 } = await import("../../inbound-5FKJBWPL.js");
|
|
76
76
|
let msg = parseSlackEvent2(event);
|
|
77
77
|
if (msg.body.includes("[Voice message") && this.config?.botToken) {
|
|
78
78
|
msg = await enrichVoiceMessage2(msg, this.config.botToken);
|
|
@@ -85,6 +85,33 @@ function createSlackAdapter(client) {
|
|
|
85
85
|
return new SlackAdapter(client);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
// src/channels/slack/enrichers/enrich.ts
|
|
89
|
+
async function enrichAttachments(msg, botToken, enrichers) {
|
|
90
|
+
if (!msg.attachments?.length) return msg;
|
|
91
|
+
const parts = msg.body ? [msg.body] : [];
|
|
92
|
+
for (const att of msg.attachments) {
|
|
93
|
+
const enricher = enrichers[att.type];
|
|
94
|
+
const label = att.filename ?? att.url ?? att.type;
|
|
95
|
+
if (!enricher) {
|
|
96
|
+
parts.push(`[Attached: ${label}]`);
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
let extracted = null;
|
|
100
|
+
try {
|
|
101
|
+
extracted = await enricher(att, botToken);
|
|
102
|
+
} catch {
|
|
103
|
+
extracted = null;
|
|
104
|
+
}
|
|
105
|
+
if (extracted) {
|
|
106
|
+
parts.push(`[Attached: ${label}]
|
|
107
|
+
${extracted}`);
|
|
108
|
+
} else {
|
|
109
|
+
parts.push(`[Attached: ${label}]`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return { ...msg, body: parts.join("\n\n") };
|
|
113
|
+
}
|
|
114
|
+
|
|
88
115
|
// src/channels/slack/bolt-adapter.ts
|
|
89
116
|
var SlackBoltAdapter = class {
|
|
90
117
|
app = null;
|
|
@@ -95,7 +122,7 @@ var SlackBoltAdapter = class {
|
|
|
95
122
|
async start() {
|
|
96
123
|
const boltModule = "@slack/bolt";
|
|
97
124
|
const bolt = await import(boltModule);
|
|
98
|
-
const { enrichVoiceMessage: enrichVoiceMessage2 } = await import("../../inbound-
|
|
125
|
+
const { enrichVoiceMessage: enrichVoiceMessage2 } = await import("../../inbound-5FKJBWPL.js");
|
|
99
126
|
const boltApp = new bolt.App({
|
|
100
127
|
token: this.config.botToken,
|
|
101
128
|
appToken: this.config.appToken,
|
|
@@ -113,6 +140,9 @@ var SlackBoltAdapter = class {
|
|
|
113
140
|
if (inbound.body.includes("[Voice message \u2014 no transcript available]")) {
|
|
114
141
|
inbound = await enrichVoiceMessage2(inbound, botToken);
|
|
115
142
|
}
|
|
143
|
+
if (inbound.attachments?.length && this.config.attachmentEnrichers) {
|
|
144
|
+
inbound = await enrichAttachments(inbound, botToken, this.config.attachmentEnrichers);
|
|
145
|
+
}
|
|
116
146
|
await hooks.emit("message.inbound", inbound);
|
|
117
147
|
});
|
|
118
148
|
hooks.register("response.ready", async (ctx) => {
|
|
@@ -128,7 +158,8 @@ var SlackBoltAdapter = class {
|
|
|
128
158
|
await boltApp.client.chat.postMessage({
|
|
129
159
|
token: botToken,
|
|
130
160
|
channel: channelId,
|
|
131
|
-
text: chunk
|
|
161
|
+
text: chunk,
|
|
162
|
+
...threadId ? { thread_ts: threadId } : {}
|
|
132
163
|
});
|
|
133
164
|
}
|
|
134
165
|
}, { priority: 90 });
|
|
@@ -148,7 +179,8 @@ var SlackBoltAdapter = class {
|
|
|
148
179
|
channel_id: channelId,
|
|
149
180
|
file: createReadStream(filePath),
|
|
150
181
|
filename: basename(filePath),
|
|
151
|
-
title: fileName ?? basename(filePath)
|
|
182
|
+
title: fileName ?? basename(filePath),
|
|
183
|
+
...threadId ? { thread_ts: threadId } : {}
|
|
152
184
|
});
|
|
153
185
|
}
|
|
154
186
|
} catch {
|
|
@@ -162,11 +194,113 @@ var SlackBoltAdapter = class {
|
|
|
162
194
|
}
|
|
163
195
|
}
|
|
164
196
|
};
|
|
197
|
+
|
|
198
|
+
// src/channels/slack/enrichers/image-enricher.ts
|
|
199
|
+
var DEFAULT_PROMPT = "Describe this image in detail. Include any visible text (OCR), objects, people, layout, and context. Be thorough \u2014 the description will be used as input to another agent that cannot see the image.";
|
|
200
|
+
async function downloadAsBase64(urlPrivate, botToken) {
|
|
201
|
+
try {
|
|
202
|
+
const response = await fetch(urlPrivate, {
|
|
203
|
+
headers: { Authorization: `Bearer ${botToken}` },
|
|
204
|
+
signal: AbortSignal.timeout(3e4)
|
|
205
|
+
});
|
|
206
|
+
if (!response.ok) return null;
|
|
207
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
208
|
+
return buffer.toString("base64");
|
|
209
|
+
} catch {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function createImageEnricher(config) {
|
|
214
|
+
const { apiKey, model = "claude-sonnet-4-6", maxTokens = 1024, prompt = DEFAULT_PROMPT } = config;
|
|
215
|
+
return async (att, botToken) => {
|
|
216
|
+
if (!att.url) return null;
|
|
217
|
+
const mediaType = att.mimeType ?? "image/jpeg";
|
|
218
|
+
const base64 = await downloadAsBase64(att.url, botToken);
|
|
219
|
+
if (!base64) return null;
|
|
220
|
+
const anthropicModule = "@anthropic-ai/sdk";
|
|
221
|
+
const sdk = await import(anthropicModule);
|
|
222
|
+
const client = new sdk.default({ apiKey });
|
|
223
|
+
try {
|
|
224
|
+
const message = await client.messages.create({
|
|
225
|
+
model,
|
|
226
|
+
max_tokens: maxTokens,
|
|
227
|
+
messages: [
|
|
228
|
+
{
|
|
229
|
+
role: "user",
|
|
230
|
+
content: [
|
|
231
|
+
{
|
|
232
|
+
type: "image",
|
|
233
|
+
source: { type: "base64", media_type: mediaType, data: base64 }
|
|
234
|
+
},
|
|
235
|
+
{ type: "text", text: prompt }
|
|
236
|
+
]
|
|
237
|
+
}
|
|
238
|
+
]
|
|
239
|
+
});
|
|
240
|
+
const textBlock = message.content.find((c) => c.type === "text");
|
|
241
|
+
return textBlock?.text ?? null;
|
|
242
|
+
} catch {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// src/channels/slack/enrichers/pdf-enricher.ts
|
|
249
|
+
var DEFAULT_PROMPT2 = "Summarize this PDF in detail. Include all key facts, numbers, dates, names, and any structured content (tables, lists). The summary will be used as input to another agent that cannot see the PDF.";
|
|
250
|
+
async function downloadAsBase642(urlPrivate, botToken) {
|
|
251
|
+
try {
|
|
252
|
+
const response = await fetch(urlPrivate, {
|
|
253
|
+
headers: { Authorization: `Bearer ${botToken}` },
|
|
254
|
+
signal: AbortSignal.timeout(6e4)
|
|
255
|
+
});
|
|
256
|
+
if (!response.ok) return null;
|
|
257
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
258
|
+
return buffer.toString("base64");
|
|
259
|
+
} catch {
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
function createPdfEnricher(config) {
|
|
264
|
+
const { apiKey, model = "claude-sonnet-4-6", maxTokens = 4096, prompt = DEFAULT_PROMPT2 } = config;
|
|
265
|
+
return async (att, botToken) => {
|
|
266
|
+
if (!att.url) return null;
|
|
267
|
+
const base64 = await downloadAsBase642(att.url, botToken);
|
|
268
|
+
if (!base64) return null;
|
|
269
|
+
const anthropicModule = "@anthropic-ai/sdk";
|
|
270
|
+
const sdk = await import(anthropicModule);
|
|
271
|
+
const client = new sdk.default({ apiKey });
|
|
272
|
+
try {
|
|
273
|
+
const message = await client.messages.create({
|
|
274
|
+
model,
|
|
275
|
+
max_tokens: maxTokens,
|
|
276
|
+
messages: [
|
|
277
|
+
{
|
|
278
|
+
role: "user",
|
|
279
|
+
content: [
|
|
280
|
+
{
|
|
281
|
+
type: "document",
|
|
282
|
+
source: { type: "base64", media_type: "application/pdf", data: base64 }
|
|
283
|
+
},
|
|
284
|
+
{ type: "text", text: prompt }
|
|
285
|
+
]
|
|
286
|
+
}
|
|
287
|
+
]
|
|
288
|
+
});
|
|
289
|
+
const textBlock = message.content.find((c) => c.type === "text");
|
|
290
|
+
return textBlock?.text ?? null;
|
|
291
|
+
} catch {
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
}
|
|
165
296
|
export {
|
|
166
297
|
SlackAdapter,
|
|
167
298
|
SlackBoltAdapter,
|
|
299
|
+
createImageEnricher,
|
|
300
|
+
createPdfEnricher,
|
|
168
301
|
createSlackAdapter as default,
|
|
169
302
|
downloadAudio,
|
|
303
|
+
enrichAttachments,
|
|
170
304
|
enrichVoiceMessage,
|
|
171
305
|
extractVoiceTranscript,
|
|
172
306
|
formatForSlack,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as ChannelAdapter,
|
|
1
|
+
import { C as ChannelAdapter, d as ChannelMeta, b as ChannelCapabilities, I as InboundMessage, c as ChannelConfig, H as HealthStatus, O as OutboundPayload, S as SendResult } from '../../channel-DziSPayj.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* WebhookAdapter — ChannelAdapter implementation for webhook-based channels.
|