opensentinel 2.1.1
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 -0
- package/README.md +283 -0
- package/dist/bot-KJ26BG56.js +15 -0
- package/dist/bot-KJ26BG56.js.map +1 -0
- package/dist/charts-MMXM6BWW.js +241 -0
- package/dist/charts-MMXM6BWW.js.map +1 -0
- package/dist/chunk-4LVWXUNC.js +1079 -0
- package/dist/chunk-4LVWXUNC.js.map +1 -0
- package/dist/chunk-4TG2IG5K.js +5249 -0
- package/dist/chunk-4TG2IG5K.js.map +1 -0
- package/dist/chunk-6DRDKB45.js +251 -0
- package/dist/chunk-6DRDKB45.js.map +1 -0
- package/dist/chunk-6SNHU3CY.js +123 -0
- package/dist/chunk-6SNHU3CY.js.map +1 -0
- package/dist/chunk-CI6Q63MM.js +1613 -0
- package/dist/chunk-CI6Q63MM.js.map +1 -0
- package/dist/chunk-CQ4JURG7.js +57 -0
- package/dist/chunk-CQ4JURG7.js.map +1 -0
- package/dist/chunk-F6QUZQGI.js +51 -0
- package/dist/chunk-F6QUZQGI.js.map +1 -0
- package/dist/chunk-GK3E2I7A.js +216 -0
- package/dist/chunk-GK3E2I7A.js.map +1 -0
- package/dist/chunk-GUBEEYDW.js +211 -0
- package/dist/chunk-GUBEEYDW.js.map +1 -0
- package/dist/chunk-GVJVEWHI.js +29 -0
- package/dist/chunk-GVJVEWHI.js.map +1 -0
- package/dist/chunk-HH2HBTQM.js +806 -0
- package/dist/chunk-HH2HBTQM.js.map +1 -0
- package/dist/chunk-JXUP2X7V.js +129 -0
- package/dist/chunk-JXUP2X7V.js.map +1 -0
- package/dist/chunk-KHNYJY2Z.js +178 -0
- package/dist/chunk-KHNYJY2Z.js.map +1 -0
- package/dist/chunk-L3F43VPB.js +652 -0
- package/dist/chunk-L3F43VPB.js.map +1 -0
- package/dist/chunk-L3PDU3XN.js +803 -0
- package/dist/chunk-L3PDU3XN.js.map +1 -0
- package/dist/chunk-NSBPE2FW.js +17 -0
- package/dist/chunk-NSBPE2FW.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +52 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/setup.d.ts +9 -0
- package/dist/commands/setup.js +374 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/start.d.ts +8 -0
- package/dist/commands/start.js +27 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +8 -0
- package/dist/commands/status.js +57 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +8 -0
- package/dist/commands/stop.js +37 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/utils.d.ts +50 -0
- package/dist/commands/utils.js +36 -0
- package/dist/commands/utils.js.map +1 -0
- package/dist/discord-ZOJFTVTB.js +49 -0
- package/dist/discord-ZOJFTVTB.js.map +1 -0
- package/dist/imessage-JFRB6EJ7.js +14 -0
- package/dist/imessage-JFRB6EJ7.js.map +1 -0
- package/dist/lib.d.ts +855 -0
- package/dist/lib.js +274 -0
- package/dist/lib.js.map +1 -0
- package/dist/mcp-LS7Q3Z5W.js +30 -0
- package/dist/mcp-LS7Q3Z5W.js.map +1 -0
- package/dist/scheduler-EZ7CZMCS.js +42 -0
- package/dist/scheduler-EZ7CZMCS.js.map +1 -0
- package/dist/signal-T3MCSULM.js +14 -0
- package/dist/signal-T3MCSULM.js.map +1 -0
- package/dist/slack-N2M4FHAJ.js +54 -0
- package/dist/slack-N2M4FHAJ.js.map +1 -0
- package/dist/src-K7GASHRH.js +430 -0
- package/dist/src-K7GASHRH.js.map +1 -0
- package/dist/tools-24GZHYRF.js +16 -0
- package/dist/tools-24GZHYRF.js.map +1 -0
- package/dist/whatsapp-VCRUPAO5.js +14 -0
- package/dist/whatsapp-VCRUPAO5.js.map +1 -0
- package/drizzle/0000_chilly_shinobi_shaw.sql +75 -0
- package/drizzle/0001_freezing_shape.sql +274 -0
- package/drizzle/meta/0000_snapshot.json +529 -0
- package/drizzle/meta/0001_snapshot.json +2576 -0
- package/drizzle/meta/_journal.json +20 -0
- package/package.json +98 -0
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
import {
|
|
2
|
+
app
|
|
3
|
+
} from "./chunk-KHNYJY2Z.js";
|
|
4
|
+
import {
|
|
5
|
+
iMessageBot
|
|
6
|
+
} from "./chunk-GK3E2I7A.js";
|
|
7
|
+
import {
|
|
8
|
+
createBot
|
|
9
|
+
} from "./chunk-6DRDKB45.js";
|
|
10
|
+
import {
|
|
11
|
+
DiscordBot
|
|
12
|
+
} from "./chunk-HH2HBTQM.js";
|
|
13
|
+
import "./chunk-F6QUZQGI.js";
|
|
14
|
+
import {
|
|
15
|
+
SlackBot
|
|
16
|
+
} from "./chunk-L3PDU3XN.js";
|
|
17
|
+
import "./chunk-GVJVEWHI.js";
|
|
18
|
+
import {
|
|
19
|
+
startWorker,
|
|
20
|
+
stopWorker
|
|
21
|
+
} from "./chunk-4LVWXUNC.js";
|
|
22
|
+
import {
|
|
23
|
+
WhatsAppBot
|
|
24
|
+
} from "./chunk-6SNHU3CY.js";
|
|
25
|
+
import {
|
|
26
|
+
SignalBot
|
|
27
|
+
} from "./chunk-JXUP2X7V.js";
|
|
28
|
+
import {
|
|
29
|
+
streamChat,
|
|
30
|
+
streamChatWithTools
|
|
31
|
+
} from "./chunk-CI6Q63MM.js";
|
|
32
|
+
import {
|
|
33
|
+
env,
|
|
34
|
+
setMCPRegistry
|
|
35
|
+
} from "./chunk-4TG2IG5K.js";
|
|
36
|
+
import "./chunk-CQ4JURG7.js";
|
|
37
|
+
import {
|
|
38
|
+
getMCPToolSummary,
|
|
39
|
+
initMCPRegistry
|
|
40
|
+
} from "./chunk-L3F43VPB.js";
|
|
41
|
+
import "./chunk-NSBPE2FW.js";
|
|
42
|
+
|
|
43
|
+
// src/inputs/websocket/index.ts
|
|
44
|
+
import { nanoid } from "nanoid";
|
|
45
|
+
|
|
46
|
+
// src/inputs/websocket/protocol.ts
|
|
47
|
+
function createServerMessage(type, id, payload = {}) {
|
|
48
|
+
const message = { type, id, payload };
|
|
49
|
+
return JSON.stringify(message);
|
|
50
|
+
}
|
|
51
|
+
function parseClientMessage(data) {
|
|
52
|
+
try {
|
|
53
|
+
const parsed = JSON.parse(data);
|
|
54
|
+
if (!parsed.type || !parsed.id) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return parsed;
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function isValidClientMessage(msg) {
|
|
63
|
+
if (!msg || typeof msg !== "object") return false;
|
|
64
|
+
const m = msg;
|
|
65
|
+
return typeof m.type === "string" && typeof m.id === "string" && ["chat", "chat_with_tools", "ping", "cancel"].includes(m.type);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// src/inputs/websocket/index.ts
|
|
69
|
+
var connections = /* @__PURE__ */ new Map();
|
|
70
|
+
function createConnectionState() {
|
|
71
|
+
return {
|
|
72
|
+
id: nanoid(),
|
|
73
|
+
connectedAt: /* @__PURE__ */ new Date(),
|
|
74
|
+
lastActivity: /* @__PURE__ */ new Date(),
|
|
75
|
+
activeRequests: /* @__PURE__ */ new Map()
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
async function handleChat(ws, msg) {
|
|
79
|
+
const { id, payload } = msg;
|
|
80
|
+
const messages = payload.messages || [];
|
|
81
|
+
if (messages.length === 0) {
|
|
82
|
+
ws.send(createServerMessage("error", id, { error: "No messages provided" }));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
let fullContent = "";
|
|
87
|
+
await streamChat(
|
|
88
|
+
messages,
|
|
89
|
+
payload.systemPrompt,
|
|
90
|
+
(chunk) => {
|
|
91
|
+
fullContent += chunk;
|
|
92
|
+
ws.send(createServerMessage("chunk", id, { text: chunk }));
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
ws.send(createServerMessage("complete", id, { content: fullContent }));
|
|
96
|
+
} catch (error) {
|
|
97
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
98
|
+
ws.send(createServerMessage("error", id, { error: errorMessage }));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async function handleChatWithTools(ws, msg) {
|
|
102
|
+
const { id, payload } = msg;
|
|
103
|
+
const messages = payload.messages || [];
|
|
104
|
+
if (messages.length === 0) {
|
|
105
|
+
ws.send(createServerMessage("error", id, { error: "No messages provided" }));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
const stream = streamChatWithTools(messages, payload.userId);
|
|
110
|
+
for await (const event of stream) {
|
|
111
|
+
switch (event.type) {
|
|
112
|
+
case "chunk":
|
|
113
|
+
ws.send(createServerMessage("chunk", id, { text: event.data.text }));
|
|
114
|
+
break;
|
|
115
|
+
case "tool_start":
|
|
116
|
+
ws.send(createServerMessage("tool_start", id, {
|
|
117
|
+
toolName: event.data.toolName,
|
|
118
|
+
toolInput: event.data.toolInput
|
|
119
|
+
}));
|
|
120
|
+
break;
|
|
121
|
+
case "tool_result":
|
|
122
|
+
ws.send(createServerMessage("tool_result", id, {
|
|
123
|
+
toolName: event.data.toolName,
|
|
124
|
+
toolResult: event.data.toolResult
|
|
125
|
+
}));
|
|
126
|
+
break;
|
|
127
|
+
case "complete":
|
|
128
|
+
ws.send(createServerMessage("complete", id, {
|
|
129
|
+
content: event.data.content,
|
|
130
|
+
usage: {
|
|
131
|
+
inputTokens: event.data.inputTokens || 0,
|
|
132
|
+
outputTokens: event.data.outputTokens || 0
|
|
133
|
+
},
|
|
134
|
+
toolsUsed: event.data.toolsUsed
|
|
135
|
+
}));
|
|
136
|
+
break;
|
|
137
|
+
case "error":
|
|
138
|
+
ws.send(createServerMessage("error", id, { error: event.data.error }));
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
} catch (error) {
|
|
143
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
144
|
+
ws.send(createServerMessage("error", id, { error: errorMessage }));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function handlePing(ws, msg) {
|
|
148
|
+
ws.send(createServerMessage("pong", msg.id, {}));
|
|
149
|
+
}
|
|
150
|
+
function handleCancel(ws, msg) {
|
|
151
|
+
const state = connections.get(ws);
|
|
152
|
+
if (state) {
|
|
153
|
+
const controller = state.activeRequests.get(msg.id);
|
|
154
|
+
if (controller) {
|
|
155
|
+
controller.abort();
|
|
156
|
+
state.activeRequests.delete(msg.id);
|
|
157
|
+
ws.send(createServerMessage("complete", msg.id, { content: "Request cancelled" }));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
var websocketHandlers = {
|
|
162
|
+
open(ws) {
|
|
163
|
+
const state = createConnectionState();
|
|
164
|
+
connections.set(ws, state);
|
|
165
|
+
console.log(`[WebSocket] Client connected: ${state.id}`);
|
|
166
|
+
ws.send(createServerMessage("connected", "system", { message: "Connected to OpenSentinel" }));
|
|
167
|
+
},
|
|
168
|
+
close(ws, code, reason) {
|
|
169
|
+
const state = connections.get(ws);
|
|
170
|
+
if (state) {
|
|
171
|
+
for (const controller of state.activeRequests.values()) {
|
|
172
|
+
controller.abort();
|
|
173
|
+
}
|
|
174
|
+
console.log(`[WebSocket] Client disconnected: ${state.id} (${code}: ${reason})`);
|
|
175
|
+
}
|
|
176
|
+
connections.delete(ws);
|
|
177
|
+
},
|
|
178
|
+
async message(ws, message) {
|
|
179
|
+
const state = connections.get(ws);
|
|
180
|
+
if (state) {
|
|
181
|
+
state.lastActivity = /* @__PURE__ */ new Date();
|
|
182
|
+
}
|
|
183
|
+
const data = typeof message === "string" ? message : message.toString();
|
|
184
|
+
const msg = parseClientMessage(data);
|
|
185
|
+
if (!msg || !isValidClientMessage(msg)) {
|
|
186
|
+
ws.send(createServerMessage("error", "unknown", { error: "Invalid message format" }));
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
console.log(`[WebSocket] Received: ${msg.type} (${msg.id})`);
|
|
190
|
+
switch (msg.type) {
|
|
191
|
+
case "chat":
|
|
192
|
+
await handleChat(ws, msg);
|
|
193
|
+
break;
|
|
194
|
+
case "chat_with_tools":
|
|
195
|
+
await handleChatWithTools(ws, msg);
|
|
196
|
+
break;
|
|
197
|
+
case "ping":
|
|
198
|
+
handlePing(ws, msg);
|
|
199
|
+
break;
|
|
200
|
+
case "cancel":
|
|
201
|
+
handleCancel(ws, msg);
|
|
202
|
+
break;
|
|
203
|
+
default:
|
|
204
|
+
ws.send(createServerMessage("error", msg.id, { error: `Unknown message type: ${msg.type}` }));
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
drain(ws) {
|
|
208
|
+
console.log("[WebSocket] Socket drained, ready for more data");
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
function handleUpgrade(req, server) {
|
|
212
|
+
const url = new URL(req.url);
|
|
213
|
+
if (url.pathname !== "/ws") {
|
|
214
|
+
return void 0;
|
|
215
|
+
}
|
|
216
|
+
const state = createConnectionState();
|
|
217
|
+
const success = server.upgrade(req, { data: state });
|
|
218
|
+
if (success) {
|
|
219
|
+
return void 0;
|
|
220
|
+
}
|
|
221
|
+
return new Response("WebSocket upgrade failed", { status: 500 });
|
|
222
|
+
}
|
|
223
|
+
function getConnectionCount() {
|
|
224
|
+
return connections.size;
|
|
225
|
+
}
|
|
226
|
+
function broadcastMessage(message) {
|
|
227
|
+
for (const ws of connections.keys()) {
|
|
228
|
+
ws.send(message);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function closeAllConnections() {
|
|
232
|
+
for (const ws of connections.keys()) {
|
|
233
|
+
ws.close(1e3, "Server shutting down");
|
|
234
|
+
}
|
|
235
|
+
connections.clear();
|
|
236
|
+
}
|
|
237
|
+
var websocket_default = {
|
|
238
|
+
handlers: websocketHandlers,
|
|
239
|
+
handleUpgrade,
|
|
240
|
+
getConnectionCount,
|
|
241
|
+
broadcastMessage,
|
|
242
|
+
closeAllConnections
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
// src/index.ts
|
|
246
|
+
async function main() {
|
|
247
|
+
console.log(`
|
|
248
|
+
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
249
|
+
\u2551 OPENSENTINEL v2.0.0 \u2551
|
|
250
|
+
\u2551 Your Personal AI Assistant \u2551
|
|
251
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
252
|
+
`);
|
|
253
|
+
console.log("[Telegram] Starting bot...");
|
|
254
|
+
const bot = createBot();
|
|
255
|
+
try {
|
|
256
|
+
startWorker(async (task) => {
|
|
257
|
+
console.log(`[Scheduler] Executing task: ${task.type}`);
|
|
258
|
+
if (task.chatId && task.message) {
|
|
259
|
+
try {
|
|
260
|
+
await bot.api.sendMessage(task.chatId, `\u23F0 Reminder: ${task.message}`);
|
|
261
|
+
} catch (err) {
|
|
262
|
+
console.error("[Scheduler] Failed to send reminder:", err);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
} catch (err) {
|
|
267
|
+
console.warn("[Scheduler] Could not start worker (Redis may be unavailable):", err);
|
|
268
|
+
}
|
|
269
|
+
bot.start({
|
|
270
|
+
onStart: (botInfo) => {
|
|
271
|
+
console.log(`[Telegram] Bot started as @${botInfo.username}`);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
let mcpRegistry = null;
|
|
275
|
+
if (env.MCP_ENABLED) {
|
|
276
|
+
try {
|
|
277
|
+
console.log("[MCP] Initializing MCP servers...");
|
|
278
|
+
mcpRegistry = await initMCPRegistry(env.MCP_CONFIG_PATH);
|
|
279
|
+
setMCPRegistry(mcpRegistry);
|
|
280
|
+
if (mcpRegistry.connectedCount > 0) {
|
|
281
|
+
console.log(`[MCP] Connected to ${mcpRegistry.connectedCount} server(s), ${mcpRegistry.totalToolCount} tools available`);
|
|
282
|
+
console.log(getMCPToolSummary(mcpRegistry));
|
|
283
|
+
} else {
|
|
284
|
+
console.log("[MCP] No servers configured (add servers to mcp.json)");
|
|
285
|
+
}
|
|
286
|
+
} catch (err) {
|
|
287
|
+
console.warn("[MCP] Failed to initialize:", err);
|
|
288
|
+
mcpRegistry = null;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
let discordBot = null;
|
|
292
|
+
if (env.DISCORD_BOT_TOKEN) {
|
|
293
|
+
console.log("[Discord] Starting bot...");
|
|
294
|
+
try {
|
|
295
|
+
discordBot = new DiscordBot({
|
|
296
|
+
token: env.DISCORD_BOT_TOKEN,
|
|
297
|
+
clientId: env.DISCORD_CLIENT_ID || "",
|
|
298
|
+
guildId: env.DISCORD_GUILD_ID,
|
|
299
|
+
allowedUserIds: env.DISCORD_ALLOWED_USER_IDS?.split(",") || [],
|
|
300
|
+
allowedRoleIds: env.DISCORD_ALLOWED_ROLE_IDS?.split(",") || []
|
|
301
|
+
});
|
|
302
|
+
await discordBot.start();
|
|
303
|
+
console.log("[Discord] Bot started");
|
|
304
|
+
} catch (err) {
|
|
305
|
+
console.warn("[Discord] Failed to start bot:", err.message);
|
|
306
|
+
if (err.message?.includes("disallowed intents") || err.message?.includes("Disallowed")) {
|
|
307
|
+
console.warn("[Discord] \u26A0\uFE0F Enable Privileged Gateway Intents in Discord Developer Portal:");
|
|
308
|
+
console.warn("[Discord] 1. Go to https://discord.com/developers/applications");
|
|
309
|
+
console.warn("[Discord] 2. Select your bot application");
|
|
310
|
+
console.warn("[Discord] 3. Go to Bot \u2192 Privileged Gateway Intents");
|
|
311
|
+
console.warn("[Discord] 4. Enable: Presence Intent, Server Members Intent, Message Content Intent");
|
|
312
|
+
console.warn("[Discord] 5. Save and restart OpenSentinel");
|
|
313
|
+
}
|
|
314
|
+
discordBot = null;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
let slackBot = null;
|
|
318
|
+
if (env.SLACK_BOT_TOKEN && env.SLACK_SIGNING_SECRET) {
|
|
319
|
+
console.log("[Slack] Starting bot...");
|
|
320
|
+
slackBot = new SlackBot({
|
|
321
|
+
token: env.SLACK_BOT_TOKEN,
|
|
322
|
+
signingSecret: env.SLACK_SIGNING_SECRET,
|
|
323
|
+
appToken: env.SLACK_APP_TOKEN,
|
|
324
|
+
socketMode: env.SLACK_SOCKET_MODE === "true",
|
|
325
|
+
port: parseInt(env.SLACK_PORT || "3000"),
|
|
326
|
+
allowedUserIds: env.SLACK_ALLOWED_USER_IDS?.split(",") || [],
|
|
327
|
+
allowedChannelIds: env.SLACK_ALLOWED_CHANNEL_IDS?.split(",") || []
|
|
328
|
+
});
|
|
329
|
+
await slackBot.start();
|
|
330
|
+
console.log("[Slack] Bot started");
|
|
331
|
+
}
|
|
332
|
+
let whatsappBot = null;
|
|
333
|
+
if (env.WHATSAPP_ENABLED) {
|
|
334
|
+
console.log("[WhatsApp] Starting bot...");
|
|
335
|
+
try {
|
|
336
|
+
whatsappBot = new WhatsAppBot({
|
|
337
|
+
authDir: env.WHATSAPP_AUTH_DIR,
|
|
338
|
+
allowedNumbers: env.WHATSAPP_ALLOWED_NUMBERS?.split(",").filter(Boolean) || [],
|
|
339
|
+
printQR: true
|
|
340
|
+
});
|
|
341
|
+
await whatsappBot.start();
|
|
342
|
+
console.log("[WhatsApp] Bot started (scan QR code if prompted)");
|
|
343
|
+
} catch (err) {
|
|
344
|
+
console.warn("[WhatsApp] Failed to start bot:", err.message);
|
|
345
|
+
whatsappBot = null;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
let signalBot = null;
|
|
349
|
+
if (env.SIGNAL_ENABLED && env.SIGNAL_PHONE_NUMBER) {
|
|
350
|
+
console.log("[Signal] Starting bot...");
|
|
351
|
+
try {
|
|
352
|
+
signalBot = new SignalBot({
|
|
353
|
+
phoneNumber: env.SIGNAL_PHONE_NUMBER,
|
|
354
|
+
signalCliPath: env.SIGNAL_CLI_PATH,
|
|
355
|
+
allowedNumbers: env.SIGNAL_ALLOWED_NUMBERS?.split(",").filter(Boolean) || []
|
|
356
|
+
});
|
|
357
|
+
await signalBot.start();
|
|
358
|
+
console.log("[Signal] Bot started");
|
|
359
|
+
} catch (err) {
|
|
360
|
+
console.warn("[Signal] Failed to start bot:", err.message);
|
|
361
|
+
console.warn("[Signal] Make sure signal-cli is installed and configured");
|
|
362
|
+
signalBot = null;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
let imessageBot = null;
|
|
366
|
+
if (env.IMESSAGE_ENABLED) {
|
|
367
|
+
console.log("[iMessage] Starting bot...");
|
|
368
|
+
try {
|
|
369
|
+
imessageBot = new iMessageBot({
|
|
370
|
+
mode: env.IMESSAGE_MODE,
|
|
371
|
+
serverUrl: env.IMESSAGE_BLUEBUBBLES_URL,
|
|
372
|
+
password: env.IMESSAGE_BLUEBUBBLES_PASSWORD,
|
|
373
|
+
allowedNumbers: env.IMESSAGE_ALLOWED_NUMBERS?.split(",").filter(Boolean) || []
|
|
374
|
+
});
|
|
375
|
+
await imessageBot.start();
|
|
376
|
+
console.log("[iMessage] Bot started");
|
|
377
|
+
} catch (err) {
|
|
378
|
+
console.warn("[iMessage] Failed to start bot:", err.message);
|
|
379
|
+
if (process.platform !== "darwin") {
|
|
380
|
+
console.warn("[iMessage] iMessage is only available on macOS");
|
|
381
|
+
}
|
|
382
|
+
imessageBot = null;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
console.log(`[API] Starting server on port ${env.PORT}...`);
|
|
386
|
+
const server = Bun.serve({
|
|
387
|
+
port: env.PORT,
|
|
388
|
+
fetch: (req, server2) => {
|
|
389
|
+
if (req.headers.get("upgrade") === "websocket") {
|
|
390
|
+
const result = websocket_default.handleUpgrade(req, server2);
|
|
391
|
+
if (result) return result;
|
|
392
|
+
return void 0;
|
|
393
|
+
}
|
|
394
|
+
return app.fetch(req);
|
|
395
|
+
},
|
|
396
|
+
websocket: websocket_default.handlers
|
|
397
|
+
});
|
|
398
|
+
console.log(`[API] Server running at http://localhost:${server.port}`);
|
|
399
|
+
console.log(`[WebSocket] Available at ws://localhost:${server.port}/ws`);
|
|
400
|
+
console.log(`[Web] Dashboard available at http://localhost:${server.port}`);
|
|
401
|
+
console.log("");
|
|
402
|
+
const channels = [
|
|
403
|
+
"Telegram",
|
|
404
|
+
discordBot ? "Discord" : null,
|
|
405
|
+
slackBot ? "Slack" : null,
|
|
406
|
+
whatsappBot ? "WhatsApp" : null,
|
|
407
|
+
signalBot ? "Signal" : null,
|
|
408
|
+
imessageBot ? "iMessage" : null,
|
|
409
|
+
"API",
|
|
410
|
+
"WebSocket"
|
|
411
|
+
].filter(Boolean).join(", ");
|
|
412
|
+
console.log(`OpenSentinel is ready! Send a message via ${channels}.`);
|
|
413
|
+
return async function shutdown() {
|
|
414
|
+
console.log("\nShutting down...");
|
|
415
|
+
stopWorker();
|
|
416
|
+
websocket_default.closeAllConnections();
|
|
417
|
+
if (mcpRegistry) await mcpRegistry.shutdown();
|
|
418
|
+
await bot.stop();
|
|
419
|
+
if (discordBot) await discordBot.stop();
|
|
420
|
+
if (slackBot) await slackBot.stop();
|
|
421
|
+
if (whatsappBot) await whatsappBot.stop();
|
|
422
|
+
if (signalBot) await signalBot.stop();
|
|
423
|
+
if (imessageBot) await imessageBot.stop();
|
|
424
|
+
server.stop();
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
export {
|
|
428
|
+
main
|
|
429
|
+
};
|
|
430
|
+
//# sourceMappingURL=src-K7GASHRH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/inputs/websocket/index.ts","../src/inputs/websocket/protocol.ts","../src/index.ts"],"sourcesContent":["/**\n * WebSocket Handler - Real-time streaming for OpenSentinel\n */\n\n// Generic WebSocket interface compatible with Bun's ServerWebSocket\ninterface ServerWebSocket<T = unknown> {\n send(data: string | Buffer): void;\n close(code?: number, reason?: string): void;\n data: T;\n}\nimport { nanoid } from \"nanoid\";\nimport {\n type WSClientMessage,\n type ConnectionState,\n createServerMessage,\n parseClientMessage,\n isValidClientMessage,\n} from \"./protocol\";\nimport { chat, streamChat, chatWithTools, streamChatWithTools } from \"../../core/brain\";\nimport type { Message } from \"../../core/brain\";\n\n// ============================================\n// CONNECTION MANAGEMENT\n// ============================================\n\nconst connections = new Map<ServerWebSocket<ConnectionState>, ConnectionState>();\n\nfunction createConnectionState(): ConnectionState {\n return {\n id: nanoid(),\n connectedAt: new Date(),\n lastActivity: new Date(),\n activeRequests: new Map(),\n };\n}\n\n// ============================================\n// MESSAGE HANDLERS\n// ============================================\n\nasync function handleChat(\n ws: ServerWebSocket<ConnectionState>,\n msg: WSClientMessage\n): Promise<void> {\n const { id, payload } = msg;\n const messages = payload.messages || [];\n\n if (messages.length === 0) {\n ws.send(createServerMessage(\"error\", id, { error: \"No messages provided\" }));\n return;\n }\n\n try {\n // Use streaming for real-time response\n let fullContent = \"\";\n\n await streamChat(\n messages,\n payload.systemPrompt,\n (chunk) => {\n fullContent += chunk;\n ws.send(createServerMessage(\"chunk\", id, { text: chunk }));\n }\n );\n\n ws.send(createServerMessage(\"complete\", id, { content: fullContent }));\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n ws.send(createServerMessage(\"error\", id, { error: errorMessage }));\n }\n}\n\nasync function handleChatWithTools(\n ws: ServerWebSocket<ConnectionState>,\n msg: WSClientMessage\n): Promise<void> {\n const { id, payload } = msg;\n const messages = payload.messages || [];\n\n if (messages.length === 0) {\n ws.send(createServerMessage(\"error\", id, { error: \"No messages provided\" }));\n return;\n }\n\n try {\n // Use streaming generator for real-time events\n const stream = streamChatWithTools(messages, payload.userId);\n\n for await (const event of stream) {\n switch (event.type) {\n case \"chunk\":\n ws.send(createServerMessage(\"chunk\", id, { text: event.data.text }));\n break;\n case \"tool_start\":\n ws.send(createServerMessage(\"tool_start\", id, {\n toolName: event.data.toolName,\n toolInput: event.data.toolInput,\n }));\n break;\n case \"tool_result\":\n ws.send(createServerMessage(\"tool_result\", id, {\n toolName: event.data.toolName,\n toolResult: event.data.toolResult,\n }));\n break;\n case \"complete\":\n ws.send(createServerMessage(\"complete\", id, {\n content: event.data.content,\n usage: {\n inputTokens: event.data.inputTokens || 0,\n outputTokens: event.data.outputTokens || 0,\n },\n toolsUsed: event.data.toolsUsed,\n }));\n break;\n case \"error\":\n ws.send(createServerMessage(\"error\", id, { error: event.data.error }));\n break;\n }\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n ws.send(createServerMessage(\"error\", id, { error: errorMessage }));\n }\n}\n\nfunction handlePing(ws: ServerWebSocket<ConnectionState>, msg: WSClientMessage): void {\n ws.send(createServerMessage(\"pong\", msg.id, {}));\n}\n\nfunction handleCancel(ws: ServerWebSocket<ConnectionState>, msg: WSClientMessage): void {\n const state = connections.get(ws);\n if (state) {\n const controller = state.activeRequests.get(msg.id);\n if (controller) {\n controller.abort();\n state.activeRequests.delete(msg.id);\n ws.send(createServerMessage(\"complete\", msg.id, { content: \"Request cancelled\" }));\n }\n }\n}\n\n// ============================================\n// WEBSOCKET HANDLERS\n// ============================================\n\nexport const websocketHandlers = {\n open(ws: ServerWebSocket<ConnectionState>) {\n const state = createConnectionState();\n connections.set(ws, state);\n console.log(`[WebSocket] Client connected: ${state.id}`);\n ws.send(createServerMessage(\"connected\", \"system\", { message: \"Connected to OpenSentinel\" }));\n },\n\n close(ws: ServerWebSocket<ConnectionState>, code: number, reason: string) {\n const state = connections.get(ws);\n if (state) {\n // Cancel any active requests\n for (const controller of state.activeRequests.values()) {\n controller.abort();\n }\n console.log(`[WebSocket] Client disconnected: ${state.id} (${code}: ${reason})`);\n }\n connections.delete(ws);\n },\n\n async message(ws: ServerWebSocket<ConnectionState>, message: string | Buffer) {\n const state = connections.get(ws);\n if (state) {\n state.lastActivity = new Date();\n }\n\n const data = typeof message === \"string\" ? message : message.toString();\n const msg = parseClientMessage(data);\n\n if (!msg || !isValidClientMessage(msg)) {\n ws.send(createServerMessage(\"error\", \"unknown\", { error: \"Invalid message format\" }));\n return;\n }\n\n console.log(`[WebSocket] Received: ${msg.type} (${msg.id})`);\n\n switch (msg.type) {\n case \"chat\":\n await handleChat(ws, msg);\n break;\n case \"chat_with_tools\":\n await handleChatWithTools(ws, msg);\n break;\n case \"ping\":\n handlePing(ws, msg);\n break;\n case \"cancel\":\n handleCancel(ws, msg);\n break;\n default:\n ws.send(createServerMessage(\"error\", msg.id, { error: `Unknown message type: ${msg.type}` }));\n }\n },\n\n drain(ws: ServerWebSocket<ConnectionState>) {\n // Called when the socket is ready to receive more data after backpressure\n console.log(\"[WebSocket] Socket drained, ready for more data\");\n },\n};\n\n// ============================================\n// UPGRADE HANDLER\n// ============================================\n\nexport function handleUpgrade(\n req: Request,\n server: { upgrade: (req: Request, options?: { data?: ConnectionState }) => boolean }\n): Response | undefined {\n const url = new URL(req.url);\n\n // Only handle /ws path\n if (url.pathname !== \"/ws\") {\n return undefined;\n }\n\n // Optional: Add authentication here\n // const token = url.searchParams.get(\"token\");\n // if (!validateToken(token)) {\n // return new Response(\"Unauthorized\", { status: 401 });\n // }\n\n const state = createConnectionState();\n const success = server.upgrade(req, { data: state });\n\n if (success) {\n return undefined; // Upgrade successful, Bun handles the response\n }\n\n return new Response(\"WebSocket upgrade failed\", { status: 500 });\n}\n\n// ============================================\n// UTILITIES\n// ============================================\n\nexport function getConnectionCount(): number {\n return connections.size;\n}\n\nexport function broadcastMessage(message: string): void {\n for (const ws of connections.keys()) {\n ws.send(message);\n }\n}\n\nexport function closeAllConnections(): void {\n for (const ws of connections.keys()) {\n ws.close(1000, \"Server shutting down\");\n }\n connections.clear();\n}\n\nexport default {\n handlers: websocketHandlers,\n handleUpgrade,\n getConnectionCount,\n broadcastMessage,\n closeAllConnections,\n};\n","/**\n * WebSocket Protocol - Message types for real-time streaming\n * OpenSentinel WebSocket API\n */\n\nimport type { Message } from \"../../core/brain\";\n\n// ============================================\n// CLIENT → SERVER MESSAGES\n// ============================================\n\nexport type WSClientMessageType = \"chat\" | \"chat_with_tools\" | \"ping\" | \"cancel\";\n\nexport interface WSClientMessage {\n type: WSClientMessageType;\n id: string;\n payload: WSClientPayload;\n}\n\nexport interface WSClientPayload {\n messages?: Message[];\n userId?: string;\n systemPrompt?: string;\n}\n\n// ============================================\n// SERVER → CLIENT MESSAGES\n// ============================================\n\nexport type WSServerMessageType =\n | \"chunk\"\n | \"tool_start\"\n | \"tool_result\"\n | \"complete\"\n | \"error\"\n | \"pong\"\n | \"connected\";\n\nexport interface WSServerMessage {\n type: WSServerMessageType;\n id: string;\n payload: WSServerPayload;\n}\n\nexport interface WSServerPayload {\n // For chunk events\n text?: string;\n\n // For tool events\n toolName?: string;\n toolInput?: unknown;\n toolResult?: unknown;\n\n // For complete events\n content?: string;\n usage?: {\n inputTokens: number;\n outputTokens: number;\n };\n toolsUsed?: string[];\n\n // For error events\n error?: string;\n code?: string;\n\n // For connected events\n message?: string;\n}\n\n// ============================================\n// STREAM EVENTS (internal)\n// ============================================\n\nexport type StreamEventType = \"chunk\" | \"tool_start\" | \"tool_result\" | \"complete\" | \"error\";\n\nexport interface StreamEvent {\n type: StreamEventType;\n data: {\n text?: string;\n toolName?: string;\n toolInput?: unknown;\n toolResult?: unknown;\n content?: string;\n inputTokens?: number;\n outputTokens?: number;\n toolsUsed?: string[];\n error?: string;\n };\n}\n\n// ============================================\n// CONNECTION STATE\n// ============================================\n\nexport interface ConnectionState {\n id: string;\n userId?: string;\n connectedAt: Date;\n lastActivity: Date;\n activeRequests: Map<string, AbortController>;\n}\n\n// ============================================\n// HELPER FUNCTIONS\n// ============================================\n\nexport function createServerMessage(\n type: WSServerMessageType,\n id: string,\n payload: Partial<WSServerPayload> = {}\n): string {\n const message: WSServerMessage = { type, id, payload };\n return JSON.stringify(message);\n}\n\nexport function parseClientMessage(data: string): WSClientMessage | null {\n try {\n const parsed = JSON.parse(data);\n if (!parsed.type || !parsed.id) {\n return null;\n }\n return parsed as WSClientMessage;\n } catch {\n return null;\n }\n}\n\nexport function isValidClientMessage(msg: unknown): msg is WSClientMessage {\n if (!msg || typeof msg !== \"object\") return false;\n const m = msg as Record<string, unknown>;\n return (\n typeof m.type === \"string\" &&\n typeof m.id === \"string\" &&\n [\"chat\", \"chat_with_tools\", \"ping\", \"cancel\"].includes(m.type)\n );\n}\n","import { env } from \"./config/env\";\nimport { createBot } from \"./inputs/telegram/bot\";\nimport { app } from \"./inputs/api/server\";\nimport { startWorker, stopWorker } from \"./core/scheduler\";\nimport { DiscordBot } from \"./inputs/discord\";\nimport { SlackBot } from \"./inputs/slack\";\nimport { WhatsAppBot } from \"./inputs/whatsapp\";\nimport { SignalBot } from \"./inputs/signal\";\nimport { iMessageBot } from \"./inputs/imessage\";\nimport wsHandler from \"./inputs/websocket\";\nimport { initMCPRegistry, type MCPRegistry, getMCPToolSummary } from \"./core/mcp\";\nimport { setMCPRegistry } from \"./tools\";\n\nexport async function main() {\n console.log(`\n╔══════════════════════════════════════════╗\n║ OPENSENTINEL v2.0.0 ║\n║ Your Personal AI Assistant ║\n╚══════════════════════════════════════════╝\n`);\n\n // Start Telegram bot\n console.log(\"[Telegram] Starting bot...\");\n const bot = createBot();\n\n // Start scheduler worker\n try {\n startWorker(async (task) => {\n console.log(`[Scheduler] Executing task: ${task.type}`);\n if (task.chatId && task.message) {\n try {\n await bot.api.sendMessage(task.chatId, `⏰ Reminder: ${task.message}`);\n } catch (err) {\n console.error(\"[Scheduler] Failed to send reminder:\", err);\n }\n }\n });\n } catch (err) {\n console.warn(\"[Scheduler] Could not start worker (Redis may be unavailable):\", err);\n }\n\n bot.start({\n onStart: (botInfo) => {\n console.log(`[Telegram] Bot started as @${botInfo.username}`);\n },\n });\n\n // Initialize MCP (Model Context Protocol) servers\n let mcpRegistry: MCPRegistry | null = null;\n if (env.MCP_ENABLED) {\n try {\n console.log(\"[MCP] Initializing MCP servers...\");\n mcpRegistry = await initMCPRegistry(env.MCP_CONFIG_PATH);\n setMCPRegistry(mcpRegistry);\n\n if (mcpRegistry.connectedCount > 0) {\n console.log(`[MCP] Connected to ${mcpRegistry.connectedCount} server(s), ${mcpRegistry.totalToolCount} tools available`);\n console.log(getMCPToolSummary(mcpRegistry));\n } else {\n console.log(\"[MCP] No servers configured (add servers to mcp.json)\");\n }\n } catch (err) {\n console.warn(\"[MCP] Failed to initialize:\", err);\n mcpRegistry = null;\n }\n }\n\n // Start Discord bot if configured\n let discordBot: DiscordBot | null = null;\n if (env.DISCORD_BOT_TOKEN) {\n console.log(\"[Discord] Starting bot...\");\n try {\n discordBot = new DiscordBot({\n token: env.DISCORD_BOT_TOKEN,\n clientId: env.DISCORD_CLIENT_ID || \"\",\n guildId: env.DISCORD_GUILD_ID,\n allowedUserIds: env.DISCORD_ALLOWED_USER_IDS?.split(\",\") || [],\n allowedRoleIds: env.DISCORD_ALLOWED_ROLE_IDS?.split(\",\") || [],\n });\n await discordBot.start();\n console.log(\"[Discord] Bot started\");\n } catch (err: any) {\n console.warn(\"[Discord] Failed to start bot:\", err.message);\n if (err.message?.includes(\"disallowed intents\") || err.message?.includes(\"Disallowed\")) {\n console.warn(\"[Discord] ⚠️ Enable Privileged Gateway Intents in Discord Developer Portal:\");\n console.warn(\"[Discord] 1. Go to https://discord.com/developers/applications\");\n console.warn(\"[Discord] 2. Select your bot application\");\n console.warn(\"[Discord] 3. Go to Bot → Privileged Gateway Intents\");\n console.warn(\"[Discord] 4. Enable: Presence Intent, Server Members Intent, Message Content Intent\");\n console.warn(\"[Discord] 5. Save and restart OpenSentinel\");\n }\n discordBot = null;\n }\n }\n\n // Start Slack bot if configured\n let slackBot: SlackBot | null = null;\n if (env.SLACK_BOT_TOKEN && env.SLACK_SIGNING_SECRET) {\n console.log(\"[Slack] Starting bot...\");\n slackBot = new SlackBot({\n token: env.SLACK_BOT_TOKEN,\n signingSecret: env.SLACK_SIGNING_SECRET,\n appToken: env.SLACK_APP_TOKEN,\n socketMode: env.SLACK_SOCKET_MODE === \"true\",\n port: parseInt(env.SLACK_PORT || \"3000\"),\n allowedUserIds: env.SLACK_ALLOWED_USER_IDS?.split(\",\") || [],\n allowedChannelIds: env.SLACK_ALLOWED_CHANNEL_IDS?.split(\",\") || [],\n });\n await slackBot.start();\n console.log(\"[Slack] Bot started\");\n }\n\n // Start WhatsApp bot if configured\n let whatsappBot: WhatsAppBot | null = null;\n if (env.WHATSAPP_ENABLED) {\n console.log(\"[WhatsApp] Starting bot...\");\n try {\n whatsappBot = new WhatsAppBot({\n authDir: env.WHATSAPP_AUTH_DIR,\n allowedNumbers: env.WHATSAPP_ALLOWED_NUMBERS?.split(\",\").filter(Boolean) || [],\n printQR: true,\n });\n await whatsappBot.start();\n console.log(\"[WhatsApp] Bot started (scan QR code if prompted)\");\n } catch (err: any) {\n console.warn(\"[WhatsApp] Failed to start bot:\", err.message);\n whatsappBot = null;\n }\n }\n\n // Start Signal bot if configured\n let signalBot: SignalBot | null = null;\n if (env.SIGNAL_ENABLED && env.SIGNAL_PHONE_NUMBER) {\n console.log(\"[Signal] Starting bot...\");\n try {\n signalBot = new SignalBot({\n phoneNumber: env.SIGNAL_PHONE_NUMBER,\n signalCliPath: env.SIGNAL_CLI_PATH,\n allowedNumbers: env.SIGNAL_ALLOWED_NUMBERS?.split(\",\").filter(Boolean) || [],\n });\n await signalBot.start();\n console.log(\"[Signal] Bot started\");\n } catch (err: any) {\n console.warn(\"[Signal] Failed to start bot:\", err.message);\n console.warn(\"[Signal] Make sure signal-cli is installed and configured\");\n signalBot = null;\n }\n }\n\n // Start iMessage bot if configured (macOS only)\n let imessageBot: iMessageBot | null = null;\n if (env.IMESSAGE_ENABLED) {\n console.log(\"[iMessage] Starting bot...\");\n try {\n imessageBot = new iMessageBot({\n mode: env.IMESSAGE_MODE as \"bluebubbles\" | \"applescript\",\n serverUrl: env.IMESSAGE_BLUEBUBBLES_URL,\n password: env.IMESSAGE_BLUEBUBBLES_PASSWORD,\n allowedNumbers: env.IMESSAGE_ALLOWED_NUMBERS?.split(\",\").filter(Boolean) || [],\n });\n await imessageBot.start();\n console.log(\"[iMessage] Bot started\");\n } catch (err: any) {\n console.warn(\"[iMessage] Failed to start bot:\", err.message);\n if (process.platform !== \"darwin\") {\n console.warn(\"[iMessage] iMessage is only available on macOS\");\n }\n imessageBot = null;\n }\n }\n\n // Start API server with WebSocket support\n console.log(`[API] Starting server on port ${env.PORT}...`);\n const server = Bun.serve({\n port: env.PORT,\n fetch: (req, server) => {\n // Handle WebSocket upgrade requests\n if (req.headers.get(\"upgrade\") === \"websocket\") {\n const result = wsHandler.handleUpgrade(req, server);\n if (result) return result;\n // If handleUpgrade returns undefined, the upgrade was successful\n return undefined as unknown as Response;\n }\n // Handle regular HTTP requests\n return app.fetch(req);\n },\n websocket: wsHandler.handlers,\n });\n\n console.log(`[API] Server running at http://localhost:${server.port}`);\n console.log(`[WebSocket] Available at ws://localhost:${server.port}/ws`);\n console.log(`[Web] Dashboard available at http://localhost:${server.port}`);\n console.log(\"\");\n const channels = [\n \"Telegram\",\n discordBot ? \"Discord\" : null,\n slackBot ? \"Slack\" : null,\n whatsappBot ? \"WhatsApp\" : null,\n signalBot ? \"Signal\" : null,\n imessageBot ? \"iMessage\" : null,\n \"API\",\n \"WebSocket\",\n ].filter(Boolean).join(\", \");\n console.log(`OpenSentinel is ready! Send a message via ${channels}.`);\n\n // Return shutdown function for CLI to wire up\n return async function shutdown() {\n console.log(\"\\nShutting down...\");\n stopWorker();\n wsHandler.closeAllConnections();\n if (mcpRegistry) await mcpRegistry.shutdown();\n await bot.stop();\n if (discordBot) await discordBot.stop();\n if (slackBot) await slackBot.stop();\n if (whatsappBot) await whatsappBot.stop();\n if (signalBot) await signalBot.stop();\n if (imessageBot) await imessageBot.stop();\n server.stop();\n };\n}\n"],"mappings":"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","names":["server"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TOOLS,
|
|
3
|
+
executeTool,
|
|
4
|
+
getMCPRegistry,
|
|
5
|
+
setMCPRegistry
|
|
6
|
+
} from "./chunk-4TG2IG5K.js";
|
|
7
|
+
import "./chunk-CQ4JURG7.js";
|
|
8
|
+
import "./chunk-L3F43VPB.js";
|
|
9
|
+
import "./chunk-NSBPE2FW.js";
|
|
10
|
+
export {
|
|
11
|
+
TOOLS,
|
|
12
|
+
executeTool,
|
|
13
|
+
getMCPRegistry,
|
|
14
|
+
setMCPRegistry
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=tools-24GZHYRF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WhatsAppBot,
|
|
3
|
+
whatsapp_default
|
|
4
|
+
} from "./chunk-6SNHU3CY.js";
|
|
5
|
+
import "./chunk-CI6Q63MM.js";
|
|
6
|
+
import "./chunk-4TG2IG5K.js";
|
|
7
|
+
import "./chunk-CQ4JURG7.js";
|
|
8
|
+
import "./chunk-L3F43VPB.js";
|
|
9
|
+
import "./chunk-NSBPE2FW.js";
|
|
10
|
+
export {
|
|
11
|
+
WhatsAppBot,
|
|
12
|
+
whatsapp_default as default
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=whatsapp-VCRUPAO5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
CREATE TABLE "conversations" (
|
|
2
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
3
|
+
"user_id" uuid,
|
|
4
|
+
"title" text,
|
|
5
|
+
"source" text DEFAULT 'telegram' NOT NULL,
|
|
6
|
+
"metadata" jsonb,
|
|
7
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
8
|
+
"updated_at" timestamp DEFAULT now() NOT NULL
|
|
9
|
+
);
|
|
10
|
+
--> statement-breakpoint
|
|
11
|
+
CREATE TABLE "memories" (
|
|
12
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
13
|
+
"user_id" uuid,
|
|
14
|
+
"type" text NOT NULL,
|
|
15
|
+
"content" text NOT NULL,
|
|
16
|
+
"embedding" vector(1536),
|
|
17
|
+
"importance" integer DEFAULT 5,
|
|
18
|
+
"source" text,
|
|
19
|
+
"metadata" jsonb,
|
|
20
|
+
"last_accessed" timestamp DEFAULT now(),
|
|
21
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
22
|
+
);
|
|
23
|
+
--> statement-breakpoint
|
|
24
|
+
CREATE TABLE "messages" (
|
|
25
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
26
|
+
"conversation_id" uuid NOT NULL,
|
|
27
|
+
"role" text NOT NULL,
|
|
28
|
+
"content" text NOT NULL,
|
|
29
|
+
"token_count" integer,
|
|
30
|
+
"metadata" jsonb,
|
|
31
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
32
|
+
);
|
|
33
|
+
--> statement-breakpoint
|
|
34
|
+
CREATE TABLE "scheduled_tasks" (
|
|
35
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
36
|
+
"user_id" uuid,
|
|
37
|
+
"name" text NOT NULL,
|
|
38
|
+
"description" text,
|
|
39
|
+
"cron_expression" text,
|
|
40
|
+
"next_run_at" timestamp,
|
|
41
|
+
"last_run_at" timestamp,
|
|
42
|
+
"enabled" boolean DEFAULT true,
|
|
43
|
+
"action" jsonb,
|
|
44
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
45
|
+
);
|
|
46
|
+
--> statement-breakpoint
|
|
47
|
+
CREATE TABLE "tool_logs" (
|
|
48
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
49
|
+
"conversation_id" uuid,
|
|
50
|
+
"tool_name" text NOT NULL,
|
|
51
|
+
"input" jsonb,
|
|
52
|
+
"output" jsonb,
|
|
53
|
+
"success" boolean NOT NULL,
|
|
54
|
+
"duration_ms" integer,
|
|
55
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
56
|
+
);
|
|
57
|
+
--> statement-breakpoint
|
|
58
|
+
CREATE TABLE "users" (
|
|
59
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
60
|
+
"telegram_id" text,
|
|
61
|
+
"name" text,
|
|
62
|
+
"preferences" jsonb,
|
|
63
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
64
|
+
"updated_at" timestamp DEFAULT now() NOT NULL,
|
|
65
|
+
CONSTRAINT "users_telegram_id_unique" UNIQUE("telegram_id")
|
|
66
|
+
);
|
|
67
|
+
--> statement-breakpoint
|
|
68
|
+
ALTER TABLE "conversations" ADD CONSTRAINT "conversations_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
69
|
+
ALTER TABLE "memories" ADD CONSTRAINT "memories_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
70
|
+
ALTER TABLE "messages" ADD CONSTRAINT "messages_conversation_id_conversations_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "public"."conversations"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
71
|
+
ALTER TABLE "scheduled_tasks" ADD CONSTRAINT "scheduled_tasks_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
72
|
+
ALTER TABLE "tool_logs" ADD CONSTRAINT "tool_logs_conversation_id_conversations_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "public"."conversations"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
73
|
+
CREATE INDEX "memories_user_idx" ON "memories" USING btree ("user_id");--> statement-breakpoint
|
|
74
|
+
CREATE INDEX "messages_conversation_idx" ON "messages" USING btree ("conversation_id");--> statement-breakpoint
|
|
75
|
+
CREATE INDEX "tool_logs_conversation_idx" ON "tool_logs" USING btree ("conversation_id");
|