alvin-bot 5.7.0 → 5.8.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/CHANGELOG.md +25 -0
- package/README.md +25 -31
- package/dist/claude.js +1 -102
- package/dist/config.js +1 -96
- package/dist/engine.js +1 -90
- package/dist/find-claude-binary.js +1 -98
- package/dist/handlers/async-agent-chunk-handler.js +1 -50
- package/dist/handlers/background-bypass.js +1 -75
- package/dist/handlers/commands.js +1 -2336
- package/dist/handlers/cron-progress.js +1 -52
- package/dist/handlers/document.js +1 -194
- package/dist/handlers/message.js +1 -959
- package/dist/handlers/photo.js +1 -154
- package/dist/handlers/platform-message.js +1 -360
- package/dist/handlers/stuck-timer.js +1 -54
- package/dist/handlers/video.js +1 -237
- package/dist/handlers/voice.js +1 -148
- package/dist/i18n.js +1 -805
- package/dist/index.js +1 -697
- package/dist/init-data-dir.js +1 -98
- package/dist/middleware/auth.js +1 -233
- package/dist/migrate.js +1 -162
- package/dist/paths.js +1 -146
- package/dist/platforms/discord.js +1 -175
- package/dist/platforms/index.js +1 -130
- package/dist/platforms/signal.js +1 -205
- package/dist/platforms/slack-slash-parser.js +1 -32
- package/dist/platforms/slack.js +1 -501
- package/dist/platforms/telegram.js +1 -111
- package/dist/platforms/types.js +1 -8
- package/dist/platforms/whatsapp-auth-helpers.js +1 -53
- package/dist/platforms/whatsapp.js +1 -707
- package/dist/providers/claude-sdk-provider.js +1 -565
- package/dist/providers/codex-cli-provider.js +1 -134
- package/dist/providers/index.js +1 -7
- package/dist/providers/ollama-provider.js +1 -32
- package/dist/providers/openai-compatible.js +1 -406
- package/dist/providers/registry.js +1 -352
- package/dist/providers/runtime-header.js +1 -45
- package/dist/providers/tool-executor.js +1 -475
- package/dist/providers/types.js +1 -227
- package/dist/services/access.js +1 -144
- package/dist/services/allowed-users-gate.js +1 -56
- package/dist/services/alvin-dispatch.js +1 -174
- package/dist/services/alvin-mcp-tools.js +1 -104
- package/dist/services/asset-index.js +1 -224
- package/dist/services/async-agent-parser.js +1 -418
- package/dist/services/async-agent-watcher.js +1 -583
- package/dist/services/auto-diagnostic.js +1 -228
- package/dist/services/broadcast.js +1 -52
- package/dist/services/browser-manager.js +1 -562
- package/dist/services/browser-webfetch.js +1 -127
- package/dist/services/browser.js +1 -121
- package/dist/services/cdp-bootstrap.js +1 -357
- package/dist/services/compaction.js +1 -144
- package/dist/services/critical-notify.js +1 -203
- package/dist/services/cron-resolver.js +1 -58
- package/dist/services/cron-scheduling.js +1 -310
- package/dist/services/cron.js +1 -861
- package/dist/services/custom-tools.js +1 -317
- package/dist/services/delivery-queue.js +1 -173
- package/dist/services/delivery-registry.js +1 -21
- package/dist/services/disk-cleanup.js +1 -203
- package/dist/services/elevenlabs.js +1 -58
- package/dist/services/embeddings/auto-detect.js +1 -74
- package/dist/services/embeddings/fts5.js +1 -108
- package/dist/services/embeddings/gemini.js +1 -65
- package/dist/services/embeddings/index.js +1 -496
- package/dist/services/embeddings/ollama.js +1 -78
- package/dist/services/embeddings/openai.js +1 -49
- package/dist/services/embeddings/provider.js +1 -22
- package/dist/services/embeddings/vector-base.js +1 -113
- package/dist/services/embeddings-migration.js +1 -193
- package/dist/services/embeddings.js +1 -9
- package/dist/services/env-file.js +1 -50
- package/dist/services/exec-guard.js +1 -71
- package/dist/services/fallback-order.js +1 -154
- package/dist/services/file-permissions.js +1 -93
- package/dist/services/heartbeat-file.js +1 -65
- package/dist/services/heartbeat.js +1 -313
- package/dist/services/hooks.js +1 -44
- package/dist/services/imagegen.js +1 -72
- package/dist/services/language-detect.js +1 -154
- package/dist/services/markdown.js +1 -63
- package/dist/services/mcp.js +1 -263
- package/dist/services/memory-extractor.js +1 -178
- package/dist/services/memory-inject-mode.js +1 -43
- package/dist/services/memory-layers.js +1 -156
- package/dist/services/memory.js +1 -146
- package/dist/services/ollama-manager.js +1 -339
- package/dist/services/permissions-wizard.js +1 -291
- package/dist/services/personality.js +1 -376
- package/dist/services/plugins.js +1 -171
- package/dist/services/preflight.js +1 -292
- package/dist/services/process-manager.js +1 -291
- package/dist/services/release-highlights.js +1 -79
- package/dist/services/reminders.js +1 -97
- package/dist/services/restart.js +1 -48
- package/dist/services/security-audit.js +1 -74
- package/dist/services/self-diagnosis.js +1 -272
- package/dist/services/self-search.js +1 -129
- package/dist/services/session-persistence.js +1 -237
- package/dist/services/session.js +1 -282
- package/dist/services/skills.js +1 -290
- package/dist/services/ssrf-guard.js +1 -162
- package/dist/services/standing-orders.js +1 -29
- package/dist/services/steer-channel.js +1 -46
- package/dist/services/stop-controller.js +1 -52
- package/dist/services/subagent-dedup.js +1 -86
- package/dist/services/subagent-delivery.js +1 -452
- package/dist/services/subagent-stats.js +1 -123
- package/dist/services/subagents.js +1 -814
- package/dist/services/sudo.js +1 -329
- package/dist/services/telegram.js +1 -158
- package/dist/services/timing-safe-bearer.js +1 -51
- package/dist/services/tool-discovery.js +1 -214
- package/dist/services/trends.js +1 -580
- package/dist/services/updater.js +1 -291
- package/dist/services/usage-tracker.js +1 -144
- package/dist/services/users.js +1 -271
- package/dist/services/voice.js +1 -104
- package/dist/services/watchdog-brake.js +1 -154
- package/dist/services/watchdog.js +1 -311
- package/dist/services/workspaces.js +1 -276
- package/dist/tui/index.js +1 -667
- package/dist/util/console-formatter.js +1 -109
- package/dist/util/debounce.js +1 -24
- package/dist/util/telegram-error-filter.js +1 -62
- package/dist/version.js +1 -24
- package/dist/web/bind-strategy.js +1 -42
- package/dist/web/canvas.js +1 -30
- package/dist/web/doctor-api.js +1 -604
- package/dist/web/openai-compat.js +1 -252
- package/dist/web/server.js +1 -1902
- package/dist/web/setup-api.js +1 -1101
- package/package.json +5 -2
- package/dist/.metadata_never_index +0 -0
package/dist/handlers/photo.js
CHANGED
|
@@ -1,154 +1 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import os from "os";
|
|
4
|
-
import https from "https";
|
|
5
|
-
/** React to a message with an emoji. Silently fails if not supported. */
|
|
6
|
-
async function react(ctx, emoji) {
|
|
7
|
-
try {
|
|
8
|
-
await ctx.react(emoji);
|
|
9
|
-
}
|
|
10
|
-
catch { /* ignore */ }
|
|
11
|
-
}
|
|
12
|
-
import { config } from "../config.js";
|
|
13
|
-
import { getSession, addToHistory } from "../services/session.js";
|
|
14
|
-
import { TelegramStreamer } from "../services/telegram.js";
|
|
15
|
-
import { getRegistry } from "../engine.js";
|
|
16
|
-
import { buildSystemPrompt } from "../services/personality.js";
|
|
17
|
-
const TEMP_DIR = path.join(os.tmpdir(), "alvin-bot");
|
|
18
|
-
if (!fs.existsSync(TEMP_DIR)) {
|
|
19
|
-
fs.mkdirSync(TEMP_DIR, { recursive: true });
|
|
20
|
-
}
|
|
21
|
-
async function downloadFile(url, dest) {
|
|
22
|
-
return new Promise((resolve, reject) => {
|
|
23
|
-
const file = fs.createWriteStream(dest);
|
|
24
|
-
https.get(url, (response) => {
|
|
25
|
-
response.pipe(file);
|
|
26
|
-
file.on("finish", () => file.close(() => resolve()));
|
|
27
|
-
}).on("error", (err) => {
|
|
28
|
-
fs.unlink(dest, () => { });
|
|
29
|
-
reject(err);
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
export async function handlePhoto(ctx) {
|
|
34
|
-
const photos = ctx.message?.photo;
|
|
35
|
-
if (!photos || photos.length === 0)
|
|
36
|
-
return;
|
|
37
|
-
const userId = ctx.from.id;
|
|
38
|
-
const session = getSession(userId);
|
|
39
|
-
if (session.isProcessing) {
|
|
40
|
-
await ctx.reply("Please wait, previous request still running... (/cancel to abort)");
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
session.isProcessing = true;
|
|
44
|
-
session.abortController = new AbortController();
|
|
45
|
-
const streamer = new TelegramStreamer(ctx.chat.id, ctx.api, ctx.message?.message_id);
|
|
46
|
-
let finalText = "";
|
|
47
|
-
const typingInterval = setInterval(() => {
|
|
48
|
-
ctx.api.sendChatAction(ctx.chat.id, "typing").catch(() => { });
|
|
49
|
-
}, 4000);
|
|
50
|
-
try {
|
|
51
|
-
await react(ctx, "👀");
|
|
52
|
-
await ctx.api.sendChatAction(ctx.chat.id, "typing");
|
|
53
|
-
// Get highest resolution photo
|
|
54
|
-
const photo = photos[photos.length - 1];
|
|
55
|
-
const file = await ctx.api.getFile(photo.file_id);
|
|
56
|
-
const fileUrl = `https://api.telegram.org/file/bot${config.botToken}/${file.file_path}`;
|
|
57
|
-
const ext = path.extname(file.file_path || "") || ".jpg";
|
|
58
|
-
const imagePath = path.join(TEMP_DIR, `photo_${Date.now()}${ext}`);
|
|
59
|
-
await downloadFile(fileUrl, imagePath);
|
|
60
|
-
const caption = ctx.message?.caption || "Analysiere dieses Bild.";
|
|
61
|
-
session.messageCount++;
|
|
62
|
-
const registry = getRegistry();
|
|
63
|
-
const activeProvider = registry.getActive();
|
|
64
|
-
const isSDK = activeProvider.config.type === "claude-sdk";
|
|
65
|
-
let queryOpts;
|
|
66
|
-
if (isSDK) {
|
|
67
|
-
// SDK: pass image path in prompt — SDK's Read tool handles it natively
|
|
68
|
-
queryOpts = {
|
|
69
|
-
prompt: `Analysiere dieses Bild: ${imagePath}\n\n${caption}`,
|
|
70
|
-
systemPrompt: buildSystemPrompt(true, session.language),
|
|
71
|
-
workingDir: session.workingDir,
|
|
72
|
-
effort: session.effort,
|
|
73
|
-
abortSignal: session.abortController.signal,
|
|
74
|
-
sessionId: session.sessionId,
|
|
75
|
-
_sessionState: {
|
|
76
|
-
messageCount: session.messageCount,
|
|
77
|
-
toolUseCount: session.toolUseCount,
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
// Non-SDK: encode image as base64 for vision API
|
|
83
|
-
let imageContent;
|
|
84
|
-
if (activeProvider.config.supportsVision) {
|
|
85
|
-
const imageBuffer = fs.readFileSync(imagePath);
|
|
86
|
-
imageContent = imageBuffer.toString("base64");
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
// No vision support — tell the user
|
|
90
|
-
imageContent = "";
|
|
91
|
-
}
|
|
92
|
-
if (!activeProvider.config.supportsVision) {
|
|
93
|
-
await ctx.reply(`⚠️ The current model (${activeProvider.config.name}) does not support image analysis. Switch to a vision model with /model.`);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
addToHistory(userId, {
|
|
97
|
-
role: "user",
|
|
98
|
-
content: caption,
|
|
99
|
-
images: [imageContent],
|
|
100
|
-
});
|
|
101
|
-
queryOpts = {
|
|
102
|
-
prompt: caption,
|
|
103
|
-
systemPrompt: buildSystemPrompt(false, session.language),
|
|
104
|
-
workingDir: session.workingDir,
|
|
105
|
-
effort: session.effort,
|
|
106
|
-
abortSignal: session.abortController.signal,
|
|
107
|
-
history: session.history,
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
for await (const chunk of registry.queryWithFallback(queryOpts)) {
|
|
111
|
-
switch (chunk.type) {
|
|
112
|
-
case "text":
|
|
113
|
-
finalText = chunk.text || "";
|
|
114
|
-
await streamer.update(finalText);
|
|
115
|
-
break;
|
|
116
|
-
case "tool_use":
|
|
117
|
-
if (chunk.toolName)
|
|
118
|
-
session.toolUseCount++;
|
|
119
|
-
break;
|
|
120
|
-
case "done":
|
|
121
|
-
if (chunk.sessionId)
|
|
122
|
-
session.sessionId = chunk.sessionId;
|
|
123
|
-
if (chunk.costUsd)
|
|
124
|
-
session.totalCost += chunk.costUsd;
|
|
125
|
-
session.lastActivity = Date.now();
|
|
126
|
-
break;
|
|
127
|
-
case "error":
|
|
128
|
-
await ctx.reply(`Error: ${chunk.error}`);
|
|
129
|
-
break;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
await streamer.finalize(finalText);
|
|
133
|
-
await react(ctx, "👍");
|
|
134
|
-
if (!isSDK && finalText) {
|
|
135
|
-
addToHistory(userId, { role: "assistant", content: finalText });
|
|
136
|
-
}
|
|
137
|
-
// Clean up temp file
|
|
138
|
-
fs.unlink(imagePath, () => { });
|
|
139
|
-
}
|
|
140
|
-
catch (err) {
|
|
141
|
-
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
142
|
-
if (errorMsg.includes("abort")) {
|
|
143
|
-
await ctx.reply("Anfrage abgebrochen.");
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
await ctx.reply(`Error: ${errorMsg}`);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
finally {
|
|
150
|
-
clearInterval(typingInterval);
|
|
151
|
-
session.isProcessing = false;
|
|
152
|
-
session.abortController = null;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
1
|
+
const _0x30fe53=_0x2e0d,_0x355512=_0x2e0d;(function(_0x3d6a27,_0x346e90){const _0x2de30e=_0x2e0d,_0x1c5d6f=_0x2e0d,_0x2ec494=_0x3d6a27();while(!![]){try{const _0x502658=-parseInt(_0x2de30e(0x80))/(0x6c3+-0x24b+-0x477)+-parseInt(_0x2de30e(0x99))/(-0x3*-0x20b+0xb*-0x17d+-0x52*-0x20)+-parseInt(_0x2de30e(0xa2))/(-0x38b*-0x3+-0x26*0x103+-0x2*-0xdea)+-parseInt(_0x2de30e(0xbe))/(0x3ad+0xdd3+-0x4*0x45f)*(-parseInt(_0x2de30e(0xd1))/(0xf19+-0x1*-0x49d+-0x13b1))+-parseInt(_0x1c5d6f(0x9c))/(-0x9*-0x3c3+-0x1*-0x2ee+0x1*-0x24c3)*(parseInt(_0x1c5d6f(0x7e))/(-0x1c0*0x10+-0xf3*0x29+-0x13*-0x386))+-parseInt(_0x1c5d6f(0x89))/(0x1e01*-0x1+0xb9*-0x34+0x439d)+-parseInt(_0x1c5d6f(0xb6))/(-0x18ee+0x1182+0x775)*(-parseInt(_0x2de30e(0x83))/(0x2525+-0x8cb*0x4+-0x21*0xf));if(_0x502658===_0x346e90)break;else _0x2ec494['push'](_0x2ec494['shift']());}catch(_0x1360b6){_0x2ec494['push'](_0x2ec494['shift']());}}}(_0x4e76,-0x111*0x731+0xb1a49+0x6793c));function _0x2e0d(_0x212337,_0xad46ca){_0x212337=_0x212337-(-0x2119+-0x1*-0x8b7+-0x18de*-0x1);const _0x372acc=_0x4e76();let _0x1bb566=_0x372acc[_0x212337];if(_0x2e0d['jEmqsy']===undefined){var _0x4fca08=function(_0x3da44c){const _0x128404='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x3ca8ae='',_0xc3d7f='',_0x5cefaf=_0x3ca8ae+_0x4fca08;for(let _0x15a7dd=-0x208c+-0x4f4+0x2580,_0x5b364b,_0x1ae8a7,_0x34120c=0xe*-0x45+0xa*0x1d+0xa9*0x4;_0x1ae8a7=_0x3da44c['charAt'](_0x34120c++);~_0x1ae8a7&&(_0x5b364b=_0x15a7dd%(-0x2*0x1314+-0xe40+0x346c)?_0x5b364b*(-0x1ccb+0x5*-0x5ba+0x1*0x39ad)+_0x1ae8a7:_0x1ae8a7,_0x15a7dd++%(-0x6*-0x496+0x1b14+-0x3694))?_0x3ca8ae+=_0x5cefaf['charCodeAt'](_0x34120c+(-0xd13*0x2+0xb*0x291+-0x20b))-(0x26*-0xb8+0x67*-0x16+0x2434)!==0x4e8*0x1+-0x1*0x1687+0x119f?String['fromCharCode'](0x2a1*0x3+0x2262+-0x2946&_0x5b364b>>(-(0x6ea+-0x14e8+0xe00)*_0x15a7dd&-0x1*0x210a+0xdb2+0x135e)):_0x15a7dd:0x1c50+-0x2278+0x628){_0x1ae8a7=_0x128404['indexOf'](_0x1ae8a7);}for(let _0x2ab9ed=-0x426+-0x6f*-0xb+-0x9f,_0x342c2c=_0x3ca8ae['length'];_0x2ab9ed<_0x342c2c;_0x2ab9ed++){_0xc3d7f+='%'+('00'+_0x3ca8ae['charCodeAt'](_0x2ab9ed)['toString'](-0x94d*-0x4+-0x683+-0x1*0x1ea1))['slice'](-(0x2044+-0x3f5*0x9+0x35b));}return decodeURIComponent(_0xc3d7f);};_0x2e0d['glkXsF']=_0x4fca08,_0x2e0d['LkJJwI']={},_0x2e0d['jEmqsy']=!![];}const _0x2304ce=_0x372acc[-0x3*-0x6cd+-0xf98+0x1*-0x4cf],_0x486d68=_0x212337+_0x2304ce,_0x3dc5d3=_0x2e0d['LkJJwI'][_0x486d68];if(!_0x3dc5d3){const _0x408f2f=function(_0x1eb021){this['yVOyoQ']=_0x1eb021,this['IpGEMq']=[-0x25e0+-0xd8+0x1af*0x17,0x2b6*-0x8+0x5*-0x75+0x17f9,0x228d+-0xeae*0x1+0x1*-0x13df],this['qgjWvj']=function(){return'newState';},this['ZxLJZI']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['ltGTiX']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x408f2f['prototype']['XvRrQU']=function(){const _0x7ecc11=new RegExp(this['ZxLJZI']+this['ltGTiX']),_0x4131e6=_0x7ecc11['test'](this['qgjWvj']['toString']())?--this['IpGEMq'][-0x237d+-0x1075+0x1151*0x3]:--this['IpGEMq'][0x26e7+-0x7*0xd1+0x3b*-0x90];return this['yJJWOD'](_0x4131e6);},_0x408f2f['prototype']['yJJWOD']=function(_0x232c95){if(!Boolean(~_0x232c95))return _0x232c95;return this['tbkiFO'](this['yVOyoQ']);},_0x408f2f['prototype']['tbkiFO']=function(_0x421da6){for(let _0x35511a=0x1841+-0x1*-0x249b+-0x3cdc,_0x13149d=this['IpGEMq']['length'];_0x35511a<_0x13149d;_0x35511a++){this['IpGEMq']['push'](Math['round'](Math['random']())),_0x13149d=this['IpGEMq']['length'];}return _0x421da6(this['IpGEMq'][-0x580+-0x1*0xe7d+0x13fd]);},new _0x408f2f(_0x2e0d)['XvRrQU'](),_0x1bb566=_0x2e0d['glkXsF'](_0x1bb566),_0x2e0d['LkJJwI'][_0x486d68]=_0x1bb566;}else _0x1bb566=_0x3dc5d3;return _0x1bb566;}const _0x2e1461=(function(){let _0x2db945=!![];return function(_0x6573fc,_0xfc6238){const _0x522506=_0x2db945?function(){const _0x20cd01=_0x2e0d;if(_0xfc6238){const _0x584010=_0xfc6238[_0x20cd01(0xcb)](_0x6573fc,arguments);return _0xfc6238=null,_0x584010;}}:function(){};return _0x2db945=![],_0x522506;};}()),_0x4bdfe7=_0x2e1461(this,function(){const _0x27ea55=_0x2e0d;return _0x4bdfe7[_0x27ea55(0x7f)]()['search']('(((.+)+)+)'+'+$')['toString']()['constructo'+'r'](_0x4bdfe7)['search']('(((.+)+)+)'+'+$');});_0x4bdfe7();import _0x51453d from'fs';import _0x50bcc5 from'path';import _0x39daab from'os';function _0x4e76(){const _0x55eb4f=['zxH0BMfTzq','y2HHDa','yxnZAxn0yw50','ywXSyMfJAW','qw5MCMfNzsbHyG','BgvUz3rO','C2LNBMfS','y29UzMLN','yxbWBhK','C3rPBgWGCNvUBG','z2v0','C2vUzenOyxrbyW','BwvZC2fNzq','Dg1WzgLY','mtG4mJi1BhLuuK1h','yw5JzwWGDg8Gyq','DxnLCG','As50zwXLz3jHBq','y2XVC2u','ntuZsK1JCgLN','Dg9tDhjPBMC','mJGWntq2vMPQuxPw','D2L0AcaVBw9Kzq','4PQG77IpifrOzsbJDxjY','otaYmZqYmeHZChDXyq','Aw5JBhvKzxm','zvn0CMvHBq','BwTKAxjtEw5J','BgfUz3vHz2u','B2XSzxi','odi3mtK4nerywNDMva','ugXLyxnLihDHAq','zNjVBq','AM9PBG','AxnqCM9JzxnZAq','lM9YzY9MAwXLlW','BwvZC2fNzv9Pza','y3jLyxrLv3jPDa','C3vWCg9YDhnwAq','CYbYzxf1zxn0ia','ihn1ChbVCNqGAq','zxHPC3rZu3LUyW','ywjVCNq','y2f0y2G','DgLVBG','CgHVDg8','ote2otyWy2nyBw9o','zMLSzv9Pza','z2v0qwn0AxzL','odCWmtH6v3f0vgq','Dg9VBf91C2u','zMLUAxnO','D29YA2LUz0rPCG','zw50ig1VzgvSia','BwvZC2fNzunVDq','mJqWmZe4CeHUDvvf','Aw5NlI4UicGVyW','C2LVBG','Dg9VBfvZzunVDq','zxjYB3i','Dgv4Da','ywjVCNrdB250CG','CMvHzezPBgvtEq','BwfNzsbHBMfSEq','yMfZzty0','ywX2Aw4TyM90','C2vZC2LVBKLK','yM9YDcK','BMfTzq','Bgq6ia','lMPWzW','igrPzxnLCYbcAq','BM93','Dg90ywXdB3n0','yxbP','mJD0sKXrwxK','BgqU','zMLUywXPEMu','Dg9VBe5HBwu','Acb0BYbHihzPCW','z2vICM9JAgvUlG','zMLSzv9WyxrO','yM90vg9Rzw4','mtaWyxPTy0zo','qw5HBhLZAwvYzq','CgLWzq','DcWGChjLDMLVDq','CMvWBhK'];_0x4e76=function(){return _0x55eb4f;};return _0x4e76();}import _0x1d1966 from'https';async function react(_0x15f2f3,_0x4bc24f){try{await _0x15f2f3['react'](_0x4bc24f);}catch{}}import{config}from'../config.js';import{getSession,addToHistory}from'../services/session.js';import{TelegramStreamer}from'../services/telegram.js';import{getRegistry}from'../engine.js';import{buildSystemPrompt}from'../services/personality.js';const TEMP_DIR=_0x50bcc5['join'](_0x39daab[_0x30fe53(0xd0)](),_0x30fe53(0xac));!_0x51453d[_0x30fe53(0x94)](TEMP_DIR)&&_0x51453d[_0x30fe53(0x86)](TEMP_DIR,{'recursive':!![]});async function downloadFile(_0x3be4d2,_0x136165){return new Promise((_0xe5aa47,_0x24e23f)=>{const _0x26943b=_0x2e0d,_0x485f54=_0x2e0d,_0x5bdd1b=_0x51453d[_0x26943b(0x90)+_0x26943b(0x85)](_0x136165);_0x1d1966[_0x485f54(0xcd)](_0x3be4d2,_0x40a02f=>{const _0x3713e6=_0x26943b,_0x34369a=_0x485f54;_0x40a02f[_0x3713e6(0xc0)](_0x5bdd1b),_0x5bdd1b['on'](_0x34369a(0x9e),()=>_0x5bdd1b[_0x3713e6(0x7d)](()=>_0xe5aa47()));})['on'](_0x485f54(0xa6),_0x55af32=>{_0x51453d['unlink'](_0x136165,()=>{}),_0x24e23f(_0x55af32);});});}export async function handlePhoto(_0x4a4cb3){const _0x35cb11=_0x355512,_0xaacbe6=_0x355512,_0x27b3f5=_0x4a4cb3[_0x35cb11(0xcf)]?.[_0x35cb11(0x98)];if(!_0x27b3f5||_0x27b3f5[_0x35cb11(0xc8)]===0x91*0x2+0x10e*0xc+-0xdca*0x1)return;const _0x35adb3=_0x4a4cb3[_0x35cb11(0x8b)]['id'],_0x143153=getSession(_0x35adb3);if(_0x143153[_0x35cb11(0x8d)+'ng']){await _0x4a4cb3['reply'](_0xaacbe6(0x8a)+_0x35cb11(0xc1)+_0xaacbe6(0x92)+_0x35cb11(0xcc)+_0x35cb11(0xa3)+_0xaacbe6(0xd2)+_0x35cb11(0xae));return;}_0x143153[_0x35cb11(0x8d)+'ng']=!![],_0x143153[_0xaacbe6(0xa8)+_0xaacbe6(0x88)]=new AbortController();const _0x3c7c5e=new TelegramStreamer(_0x4a4cb3[_0xaacbe6(0xc4)]['id'],_0x4a4cb3[_0xaacbe6(0xb5)],_0x4a4cb3[_0x35cb11(0xcf)]?.[_0x35cb11(0x8f)]);let _0x5b977f='';const _0x43c4ba=setInterval(()=>{const _0x44f46c=_0x35cb11,_0x16e674=_0xaacbe6;_0x4a4cb3[_0x44f46c(0xb5)][_0x16e674(0xce)+_0x44f46c(0x97)](_0x4a4cb3[_0x44f46c(0xc4)]['id'],'typing')[_0x16e674(0x96)](()=>{});},-0xe40+0x25e6+-0x806);try{await react(_0x4a4cb3,'👀'),await _0x4a4cb3[_0xaacbe6(0xb5)][_0xaacbe6(0xce)+_0xaacbe6(0x97)](_0x4a4cb3[_0x35cb11(0xc4)]['id'],'typing');const _0x26300a=_0x27b3f5[_0x27b3f5['length']-(-0x1ccb+0x5*-0x5ba+0x1*0x396e)],_0x1a1b3b=await _0x4a4cb3[_0xaacbe6(0xb5)]['getFile'](_0x26300a[_0xaacbe6(0x9a)]),_0x394fe6='https://ap'+_0x35cb11(0x7c)+_0x35cb11(0x8e)+'bot'+config[_0x35cb11(0xbd)]+'/'+_0x1a1b3b['file_path'],_0x59a6cb=_0x50bcc5[_0xaacbe6(0xc3)](_0x1a1b3b[_0x35cb11(0xbc)]||'')||_0x35cb11(0xb1),_0x31d1c9=_0x50bcc5[_0x35cb11(0x8c)](TEMP_DIR,'photo_'+Date['now']()+_0x59a6cb);await downloadFile(_0x394fe6,_0x31d1c9);const _0x4ee9c8=_0x4a4cb3[_0xaacbe6(0xcf)]?.['caption']||_0x35cb11(0xbf)+_0xaacbe6(0xb2)+_0xaacbe6(0xb7);_0x143153[_0x35cb11(0xa1)+'nt']++;const _0x22b5d5=getRegistry(),_0x1448b2=_0x22b5d5[_0x35cb11(0x9b)](),_0x38209d=_0x1448b2[_0xaacbe6(0xca)]['type']==='claude-sdk';let _0x162bef;if(_0x38209d)_0x162bef={'prompt':'Analysiere'+'\x20dieses\x20Bi'+_0xaacbe6(0xb0)+_0x31d1c9+'\x0a\x0a'+_0x4ee9c8,'systemPrompt':buildSystemPrompt(!![],_0x143153[_0xaacbe6(0x87)]),'workingDir':_0x143153[_0xaacbe6(0x9f)],'effort':_0x143153['effort'],'abortSignal':_0x143153['abortContr'+_0xaacbe6(0x88)][_0xaacbe6(0xc9)],'sessionId':_0x143153[_0x35cb11(0xad)],'_sessionState':{'messageCount':_0x143153['messageCou'+'nt'],'toolUseCount':_0x143153[_0x35cb11(0xa5)+'nt']}};else{let _0xbc57f3;if(_0x1448b2['config'][_0xaacbe6(0x91)+_0x35cb11(0xa4)]){const _0x161841=_0x51453d[_0x35cb11(0xa9)+'nc'](_0x31d1c9);_0xbc57f3=_0x161841[_0xaacbe6(0x7f)](_0x35cb11(0xab));}else _0xbc57f3='';if(!_0x1448b2[_0xaacbe6(0xca)][_0x35cb11(0x91)+'sion']){await _0x4a4cb3[_0xaacbe6(0xc2)](_0xaacbe6(0x82)+_0x35cb11(0xa0)+'('+_0x1448b2[_0xaacbe6(0xca)][_0x35cb11(0xaf)]+(')\x20does\x20not'+_0x35cb11(0x93)+_0xaacbe6(0xaa)+'sis.\x20Switc'+_0x35cb11(0xba)+'ion\x20model\x20'+_0xaacbe6(0x81)+'l.'));return;}addToHistory(_0x35adb3,{'role':_0x35cb11(0xd3),'content':_0x4ee9c8,'images':[_0xbc57f3]}),_0x162bef={'prompt':_0x4ee9c8,'systemPrompt':buildSystemPrompt(![],_0x143153[_0x35cb11(0x87)]),'workingDir':_0x143153[_0xaacbe6(0x9f)],'effort':_0x143153['effort'],'abortSignal':_0x143153[_0x35cb11(0xa8)+_0xaacbe6(0x88)][_0x35cb11(0xc9)],'history':_0x143153['history']};}for await(const _0x1e505d of _0x22b5d5['queryWithF'+_0xaacbe6(0xc6)](_0x162bef)){switch(_0x1e505d['type']){case _0x35cb11(0xa7):_0x5b977f=_0x1e505d[_0x35cb11(0xa7)]||'',await _0x3c7c5e['update'](_0x5b977f);break;case _0x35cb11(0x9d):if(_0x1e505d[_0x35cb11(0xb9)])_0x143153[_0x35cb11(0xa5)+'nt']++;break;case'done':if(_0x1e505d[_0x35cb11(0xad)])_0x143153[_0xaacbe6(0xad)]=_0x1e505d[_0xaacbe6(0xad)];if(_0x1e505d['costUsd'])_0x143153[_0xaacbe6(0xb4)]+=_0x1e505d['costUsd'];_0x143153['lastActivi'+'ty']=Date[_0xaacbe6(0xb3)]();break;case _0xaacbe6(0xa6):await _0x4a4cb3[_0xaacbe6(0xc2)]('Error:\x20'+_0x1e505d[_0x35cb11(0xa6)]);break;}}await _0x3c7c5e[_0x35cb11(0xb8)](_0x5b977f),await react(_0x4a4cb3,'👍'),!_0x38209d&&_0x5b977f&&addToHistory(_0x35adb3,{'role':_0x35cb11(0xc5),'content':_0x5b977f}),_0x51453d['unlink'](_0x31d1c9,()=>{});}catch(_0x75d071){const _0x406750=_0x75d071 instanceof Error?_0x75d071['message']:String(_0x75d071);_0x406750[_0xaacbe6(0x84)](_0x35cb11(0x95))?await _0x4a4cb3[_0xaacbe6(0xc2)](_0x35cb11(0xc7)+_0xaacbe6(0xbb)):await _0x4a4cb3[_0xaacbe6(0xc2)]('Error:\x20'+_0x406750);}finally{clearInterval(_0x43c4ba),_0x143153[_0xaacbe6(0x8d)+'ng']=![],_0x143153[_0x35cb11(0xa8)+_0xaacbe6(0x88)]=null;}}
|
|
@@ -1,360 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generic Platform Message Handler
|
|
3
|
-
*
|
|
4
|
-
* Processes messages from any platform adapter (WhatsApp, Discord, Signal)
|
|
5
|
-
* through the AI engine and sends the response back.
|
|
6
|
-
*
|
|
7
|
-
* This is the platform-agnostic equivalent of message.ts (which is Telegram-specific).
|
|
8
|
-
*/
|
|
9
|
-
import fs from "fs";
|
|
10
|
-
import { getSession, addToHistory, trackProviderUsage, buildSessionKey, markSessionDirty } from "../services/session.js";
|
|
11
|
-
import { resolveWorkspaceOrDefault } from "../services/workspaces.js";
|
|
12
|
-
import { getRegistry } from "../engine.js";
|
|
13
|
-
import { buildSmartSystemPrompt } from "../services/personality.js";
|
|
14
|
-
import { buildSkillContext } from "../services/skills.js";
|
|
15
|
-
import { touchProfile } from "../services/users.js";
|
|
16
|
-
import { trackAndAdapt } from "../services/language-detect.js";
|
|
17
|
-
import { transcribeAudio } from "../services/voice.js";
|
|
18
|
-
import { config } from "../config.js";
|
|
19
|
-
/** Platform-specific message length limits */
|
|
20
|
-
const PLATFORM_LIMITS = {
|
|
21
|
-
discord: 2000,
|
|
22
|
-
telegram: 4096,
|
|
23
|
-
whatsapp: 4096,
|
|
24
|
-
signal: 6000,
|
|
25
|
-
web: 100_000,
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Handle an incoming message from any platform adapter.
|
|
29
|
-
* Runs the AI query and sends the response back via the adapter's sendText.
|
|
30
|
-
*/
|
|
31
|
-
export async function handlePlatformMessage(msg, adapter) {
|
|
32
|
-
let text = msg.text?.trim();
|
|
33
|
-
// ── Voice message: transcribe first ──────────────────────────────────
|
|
34
|
-
if (msg.media?.type === "voice" && msg.media.path) {
|
|
35
|
-
if (!config.apiKeys.groq) {
|
|
36
|
-
await adapter.sendText(msg.chatId, "⚠️ Voice nicht konfiguriert (GROQ_API_KEY fehlt).");
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
try {
|
|
40
|
-
const transcript = await transcribeAudio(msg.media.path);
|
|
41
|
-
fs.unlink(msg.media.path, () => { });
|
|
42
|
-
if (!transcript.trim()) {
|
|
43
|
-
await adapter.sendText(msg.chatId, "Could not understand the voice message. 🤷");
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
await adapter.sendText(msg.chatId, `🎙️ _"${transcript}"_`);
|
|
47
|
-
text = transcript;
|
|
48
|
-
}
|
|
49
|
-
catch (err) {
|
|
50
|
-
const errMsg = err instanceof Error ? err.message : String(err);
|
|
51
|
-
console.error("Voice transcription error:", errMsg);
|
|
52
|
-
await adapter.sendText(msg.chatId, `⚠️ Voice message error: ${errMsg}`);
|
|
53
|
-
if (msg.media.path)
|
|
54
|
-
fs.unlink(msg.media.path, () => { });
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
// ── Photo with caption: describe as context ──────────────────────────
|
|
59
|
-
if (msg.media?.type === "photo" && msg.media.path) {
|
|
60
|
-
const caption = text || "Beschreibe dieses Bild.";
|
|
61
|
-
text = `[Image attached: ${msg.media.path}]\n\n${caption}`;
|
|
62
|
-
}
|
|
63
|
-
// ── Document: provide path + filename + instructions ──────────────────
|
|
64
|
-
if (msg.media?.type === "document" && msg.media.path) {
|
|
65
|
-
const fname = msg.media.fileName || "Dokument";
|
|
66
|
-
const fpath = msg.media.path;
|
|
67
|
-
const ext = fname.split(".").pop()?.toLowerCase() || "";
|
|
68
|
-
const caption = text || `Analysiere dieses Dokument: ${fname}`;
|
|
69
|
-
// Give the AI concrete instructions based on file type
|
|
70
|
-
const isArchive = ["zip", "tar", "gz", "tgz", "7z", "rar"].includes(ext);
|
|
71
|
-
const isPdf = ext === "pdf";
|
|
72
|
-
const isOffice = ["xlsx", "xls", "docx", "doc", "pptx", "csv"].includes(ext);
|
|
73
|
-
let fileHint = `[Datei empfangen: ${fpath}]\nDateiname: ${fname}\nTyp: ${msg.media.mimeType || "unbekannt"}`;
|
|
74
|
-
if (isArchive) {
|
|
75
|
-
fileHint += `\n\nDiese Datei ist ein Archiv. Entpacke sie mit: unzip "${fpath}" -d "${fpath.replace(/\.[^.]+$/, "")}" oder tar xf "${fpath}" und arbeite dann mit dem Inhalt.`;
|
|
76
|
-
}
|
|
77
|
-
else if (isPdf) {
|
|
78
|
-
fileHint += `\n\nLies den Inhalt mit: pdftotext "${fpath}" - oder python3 mit PyPDF2/pdfplumber.`;
|
|
79
|
-
}
|
|
80
|
-
else if (isOffice) {
|
|
81
|
-
fileHint += `\n\nOpen with python3 (openpyxl for xlsx, python-docx for docx, csv module for csv).`;
|
|
82
|
-
}
|
|
83
|
-
text = `${fileHint}\n\n${caption}`;
|
|
84
|
-
}
|
|
85
|
-
if (!text)
|
|
86
|
-
return;
|
|
87
|
-
// ── Basic command handling for non-Telegram platforms ──────────────
|
|
88
|
-
const cmdHandled = await handlePlatformCommand(text, msg, adapter);
|
|
89
|
-
if (cmdHandled)
|
|
90
|
-
return;
|
|
91
|
-
// v4.12.0 — Use buildSessionKey so each channel on Slack/Discord/WhatsApp
|
|
92
|
-
// gets its own session. Before v4.12.0 we hashed just userId, which
|
|
93
|
-
// collapsed every channel from the same user into one session and broke
|
|
94
|
-
// multi-session completely on non-Telegram platforms.
|
|
95
|
-
const sessionKey = buildSessionKey(msg.platform, msg.chatId, msg.userId);
|
|
96
|
-
const session = getSession(sessionKey);
|
|
97
|
-
// touchProfile still uses a stable userId-based numeric hash for the
|
|
98
|
-
// user profile store — profiles are about *people*, not sessions.
|
|
99
|
-
const profileKey = hashUserId(msg.userId);
|
|
100
|
-
touchProfile(profileKey, msg.userName, msg.userHandle, msg.platform, text);
|
|
101
|
-
// v4.12.0 — Workspace resolution: channel → workspace → persona + cwd.
|
|
102
|
-
// P1 #2 — If the platform has a getChannelName helper (Slack does), use
|
|
103
|
-
// it to enable channel-name-based workspace matching (e.g. #my-project →
|
|
104
|
-
// workspaces/my-project.md). Cached in the adapter, so no extra API call
|
|
105
|
-
// after the first hit per channel.
|
|
106
|
-
let channelName;
|
|
107
|
-
const getChannelName = adapter.getChannelName;
|
|
108
|
-
if (typeof getChannelName === "function") {
|
|
109
|
-
try {
|
|
110
|
-
channelName = await getChannelName.call(adapter, msg.chatId);
|
|
111
|
-
}
|
|
112
|
-
catch {
|
|
113
|
-
channelName = undefined;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
const workspace = resolveWorkspaceOrDefault(msg.platform, msg.chatId, channelName);
|
|
117
|
-
// v4.19.1 — Workspace switch detection. If cwd changes as part of the
|
|
118
|
-
// switch, null out session.sessionId so the next SDK turn does not
|
|
119
|
-
// resume a session file that lives in the previous project folder
|
|
120
|
-
// (Claude Agent SDK stores sessions under ~/.claude/projects/<cwd-hash>/).
|
|
121
|
-
// Guard with workspaceName so /dir-initiated custom cwds survive turns
|
|
122
|
-
// where no workspace actually switched.
|
|
123
|
-
if (session.workspaceName !== workspace.name) {
|
|
124
|
-
const cwdChanged = session.workingDir !== workspace.cwd;
|
|
125
|
-
session.workspaceName = workspace.name;
|
|
126
|
-
session.workingDir = workspace.cwd;
|
|
127
|
-
if (cwdChanged) {
|
|
128
|
-
console.log(`[session] workspace switch changed cwd (→ ${workspace.cwd}) — ` +
|
|
129
|
-
`invalidating SDK resume anchor and skipping bridge`);
|
|
130
|
-
session.sessionId = null;
|
|
131
|
-
// v4.19.2 — Anchor at current last turn so no catch-up bridge is
|
|
132
|
-
// generated for the next turn (see message.ts for full rationale).
|
|
133
|
-
session.lastSdkHistoryIndex = session.history.length - 1;
|
|
134
|
-
markSessionDirty(sessionKey);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
// Skip if already processing (queue up to 3)
|
|
138
|
-
if (session.isProcessing) {
|
|
139
|
-
if (session.messageQueue.length < 3) {
|
|
140
|
-
session.messageQueue.push(text);
|
|
141
|
-
}
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
// Consume queued messages
|
|
145
|
-
let fullText = text;
|
|
146
|
-
if (session.messageQueue.length > 0) {
|
|
147
|
-
const queued = session.messageQueue.splice(0);
|
|
148
|
-
fullText = [...queued, text].join("\n\n");
|
|
149
|
-
}
|
|
150
|
-
// Add reply context
|
|
151
|
-
if (msg.replyToText) {
|
|
152
|
-
const quoted = msg.replyToText.length > 500
|
|
153
|
-
? msg.replyToText.slice(0, 500) + "..."
|
|
154
|
-
: msg.replyToText;
|
|
155
|
-
fullText = `[Bezug auf: "${quoted}"]\n\n${fullText}`;
|
|
156
|
-
}
|
|
157
|
-
session.isProcessing = true;
|
|
158
|
-
let finalText = "";
|
|
159
|
-
// Show typing indicator
|
|
160
|
-
if (adapter.setTyping) {
|
|
161
|
-
adapter.setTyping(msg.chatId).catch(() => { });
|
|
162
|
-
}
|
|
163
|
-
// Keep typing indicator alive during long requests (refresh every 4s)
|
|
164
|
-
const typingInterval = adapter.setTyping
|
|
165
|
-
? setInterval(() => adapter.setTyping(msg.chatId).catch(() => { }), 4000)
|
|
166
|
-
: null;
|
|
167
|
-
try {
|
|
168
|
-
session.messageCount++;
|
|
169
|
-
const adaptedLang = trackAndAdapt(Number(msg.userId) || 0, fullText, session.language);
|
|
170
|
-
if (adaptedLang !== session.language)
|
|
171
|
-
session.language = adaptedLang;
|
|
172
|
-
const registry = getRegistry();
|
|
173
|
-
const activeProvider = registry.getActive();
|
|
174
|
-
const isSDK = activeProvider.config.type === "claude-sdk";
|
|
175
|
-
const skillContext = buildSkillContext(fullText);
|
|
176
|
-
// v4.11.0 P0 #3 — SDK gets semantic recall on first turn (when no resume token yet).
|
|
177
|
-
// v4.12.0 P0 #3 — Workspace persona is forwarded so per-channel personas land
|
|
178
|
-
// in the system prompt for this query.
|
|
179
|
-
const isFirstSDKTurn = isSDK && session.sessionId === null;
|
|
180
|
-
const systemPrompt = (await buildSmartSystemPrompt(isSDK, session.language, fullText, msg.chatId, isFirstSDKTurn, workspace.systemPromptOverride)) + skillContext;
|
|
181
|
-
// v4.19.0 — Per-workspace runtime overrides (model/effort/temperature/toolset).
|
|
182
|
-
const { toolsetToAllowedTools } = await import("../services/workspaces.js");
|
|
183
|
-
const wsAllowed = toolsetToAllowedTools(workspace.toolset);
|
|
184
|
-
const queryOpts = {
|
|
185
|
-
prompt: fullText,
|
|
186
|
-
systemPrompt,
|
|
187
|
-
workingDir: session.workingDir,
|
|
188
|
-
effort: workspace.effort ?? session.effort,
|
|
189
|
-
// v4.15 — Per-workspace model override (optional YAML `model:` field).
|
|
190
|
-
// v4.19 — ditto for temperature and toolset-derived allowedTools.
|
|
191
|
-
...(workspace.model ? { model: workspace.model } : {}),
|
|
192
|
-
...(workspace.temperature !== undefined ? { temperature: workspace.temperature } : {}),
|
|
193
|
-
...(wsAllowed ? { allowedTools: wsAllowed } : {}),
|
|
194
|
-
sessionId: isSDK ? session.sessionId : null,
|
|
195
|
-
history: !isSDK ? session.history : undefined,
|
|
196
|
-
// v4.14 — Expose alvin_dispatch_agent MCP tool on non-Telegram
|
|
197
|
-
// platforms too (Slack/Discord/WhatsApp). The watcher routes the
|
|
198
|
-
// eventual delivery via the platform's registered DeliveryAdapter.
|
|
199
|
-
// Only for SDK provider (where MCP tools are supported).
|
|
200
|
-
alvinDispatchContext: isSDK
|
|
201
|
-
? {
|
|
202
|
-
chatId: msg.chatId,
|
|
203
|
-
userId: msg.userId,
|
|
204
|
-
sessionKey,
|
|
205
|
-
platform: msg.platform,
|
|
206
|
-
}
|
|
207
|
-
: undefined,
|
|
208
|
-
};
|
|
209
|
-
if (!isSDK) {
|
|
210
|
-
addToHistory(sessionKey, { role: "user", content: fullText });
|
|
211
|
-
}
|
|
212
|
-
// v4.19.1 — Track whether the provider requested a session reset during
|
|
213
|
-
// this stream. If it did, the trailing `done` chunk's sessionId MUST be
|
|
214
|
-
// ignored — otherwise it restores the exact sessionId we just cleared
|
|
215
|
-
// and the next turn loops again. Mirror of message.ts.
|
|
216
|
-
let sessionResetInStream = false;
|
|
217
|
-
for await (const chunk of registry.queryWithFallback(queryOpts, workspace.provider)) {
|
|
218
|
-
switch (chunk.type) {
|
|
219
|
-
case "text":
|
|
220
|
-
finalText = chunk.text || "";
|
|
221
|
-
// v4.18.5 — Provider-requested session reset on empty-stream detection.
|
|
222
|
-
// Mirror of the same handling in handlers/message.ts.
|
|
223
|
-
if (chunk.sessionResetRequested) {
|
|
224
|
-
console.warn(`[session] provider requested reset for ${sessionKey} — clearing sessionId + SDK anchor`);
|
|
225
|
-
session.sessionId = null;
|
|
226
|
-
session.lastSdkHistoryIndex = -1;
|
|
227
|
-
sessionResetInStream = true;
|
|
228
|
-
markSessionDirty(sessionKey);
|
|
229
|
-
}
|
|
230
|
-
break;
|
|
231
|
-
case "done":
|
|
232
|
-
// v4.19.1 — Respect in-stream reset: don't let done.sessionId undo
|
|
233
|
-
// the clear from the empty-stream text chunk. See message.ts for
|
|
234
|
-
// full rationale.
|
|
235
|
-
if (chunk.sessionId && !sessionResetInStream)
|
|
236
|
-
session.sessionId = chunk.sessionId;
|
|
237
|
-
if (chunk.costUsd)
|
|
238
|
-
session.totalCost += chunk.costUsd;
|
|
239
|
-
trackProviderUsage(sessionKey, registry.getActiveKey(), chunk.costUsd || 0, chunk.inputTokens, chunk.outputTokens);
|
|
240
|
-
session.lastActivity = Date.now();
|
|
241
|
-
break;
|
|
242
|
-
case "error":
|
|
243
|
-
await adapter.sendText(msg.chatId, `⚠️ Error: ${chunk.error}`);
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
// Send response
|
|
248
|
-
if (finalText.trim()) {
|
|
249
|
-
const maxLen = PLATFORM_LIMITS[msg.platform] || 4096;
|
|
250
|
-
if (finalText.length > maxLen) {
|
|
251
|
-
const chunks = splitMessage(finalText, maxLen);
|
|
252
|
-
for (const chunk of chunks) {
|
|
253
|
-
await adapter.sendText(msg.chatId, chunk);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
else {
|
|
257
|
-
await adapter.sendText(msg.chatId, finalText);
|
|
258
|
-
}
|
|
259
|
-
if (!isSDK && finalText) {
|
|
260
|
-
addToHistory(sessionKey, { role: "assistant", content: finalText });
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
catch (err) {
|
|
265
|
-
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
266
|
-
console.error(`Platform message error (${msg.platform}):`, errorMsg);
|
|
267
|
-
await adapter.sendText(msg.chatId, `⚠️ Error: ${errorMsg}`);
|
|
268
|
-
}
|
|
269
|
-
finally {
|
|
270
|
-
if (typingInterval)
|
|
271
|
-
clearInterval(typingInterval);
|
|
272
|
-
session.isProcessing = false;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Handle basic slash commands on non-Telegram platforms.
|
|
277
|
-
* Returns true if the message was a command and was handled.
|
|
278
|
-
*/
|
|
279
|
-
async function handlePlatformCommand(text, msg, adapter) {
|
|
280
|
-
if (!text.startsWith("/"))
|
|
281
|
-
return false;
|
|
282
|
-
const parts = text.split(/\s+/);
|
|
283
|
-
const cmd = parts[0].toLowerCase();
|
|
284
|
-
// v4.12.0 — Same buildSessionKey routing as the main handler so /new and
|
|
285
|
-
// /status etc operate on the per-channel session, not the per-user one.
|
|
286
|
-
const sessionKey = buildSessionKey(msg.platform, msg.chatId, msg.userId);
|
|
287
|
-
const session = getSession(sessionKey);
|
|
288
|
-
switch (cmd) {
|
|
289
|
-
case "/new": {
|
|
290
|
-
const { resetSession } = await import("../services/session.js");
|
|
291
|
-
resetSession(sessionKey);
|
|
292
|
-
await adapter.sendText(msg.chatId, "🔄 New chat started.");
|
|
293
|
-
return true;
|
|
294
|
-
}
|
|
295
|
-
case "/status": {
|
|
296
|
-
const { getRegistry } = await import("../engine.js");
|
|
297
|
-
const registry = getRegistry();
|
|
298
|
-
const provider = registry.getActiveKey();
|
|
299
|
-
const msgs = session.messageCount;
|
|
300
|
-
const cost = session.totalCost.toFixed(4);
|
|
301
|
-
await adapter.sendText(msg.chatId, `📊 Status\n` +
|
|
302
|
-
`Provider: ${provider}\n` +
|
|
303
|
-
`Messages: ${msgs}\n` +
|
|
304
|
-
`Cost: $${cost}\n` +
|
|
305
|
-
`Effort: ${session.effort}\n` +
|
|
306
|
-
`Platform: ${msg.platform}`);
|
|
307
|
-
return true;
|
|
308
|
-
}
|
|
309
|
-
case "/effort": {
|
|
310
|
-
const level = parts[1]?.toLowerCase();
|
|
311
|
-
if (["low", "medium", "high", "max"].includes(level)) {
|
|
312
|
-
session.effort = level;
|
|
313
|
-
await adapter.sendText(msg.chatId, `🧠 Effort: ${level}`);
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
await adapter.sendText(msg.chatId, `🧠 Current: ${session.effort}\nOptions: /effort low|medium|high|max`);
|
|
317
|
-
}
|
|
318
|
-
return true;
|
|
319
|
-
}
|
|
320
|
-
case "/help": {
|
|
321
|
-
await adapter.sendText(msg.chatId, "🤖 Alvin Bot — Commands\n\n" +
|
|
322
|
-
"/new — New chat\n" +
|
|
323
|
-
"/status — Session info\n" +
|
|
324
|
-
"/effort <low|medium|high|max> — Thinking depth\n" +
|
|
325
|
-
"/help — This help\n\n" +
|
|
326
|
-
"For all features use the Web Dashboard or Telegram.");
|
|
327
|
-
return true;
|
|
328
|
-
}
|
|
329
|
-
default:
|
|
330
|
-
// Unknown command → treat as normal message
|
|
331
|
-
return false;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
/** Hash a string userId to a numeric ID for session compatibility */
|
|
335
|
-
function hashUserId(id) {
|
|
336
|
-
let hash = 0;
|
|
337
|
-
for (let i = 0; i < id.length; i++) {
|
|
338
|
-
const char = id.charCodeAt(i);
|
|
339
|
-
hash = ((hash << 5) - hash) + char;
|
|
340
|
-
hash = hash & hash; // Convert to 32-bit int
|
|
341
|
-
}
|
|
342
|
-
return Math.abs(hash);
|
|
343
|
-
}
|
|
344
|
-
/** Split a message into chunks at word/newline boundaries */
|
|
345
|
-
function splitMessage(text, maxLen) {
|
|
346
|
-
const chunks = [];
|
|
347
|
-
let remaining = text;
|
|
348
|
-
while (remaining.length > maxLen) {
|
|
349
|
-
let splitAt = remaining.lastIndexOf("\n", maxLen);
|
|
350
|
-
if (splitAt < maxLen * 0.5)
|
|
351
|
-
splitAt = remaining.lastIndexOf(" ", maxLen);
|
|
352
|
-
if (splitAt < maxLen * 0.5)
|
|
353
|
-
splitAt = maxLen;
|
|
354
|
-
chunks.push(remaining.slice(0, splitAt));
|
|
355
|
-
remaining = remaining.slice(splitAt).trimStart();
|
|
356
|
-
}
|
|
357
|
-
if (remaining)
|
|
358
|
-
chunks.push(remaining);
|
|
359
|
-
return chunks;
|
|
360
|
-
}
|
|
1
|
+
(function(_0x5486b6,_0x2d52c3){const _0x569a33=_0x2653,_0x51447d=_0x2653,_0x57d1ce=_0x5486b6();while(!![]){try{const _0xcfa4e2=parseInt(_0x569a33(0xee))/(-0x2f*0x4a+0x1173+-0x34*0x13)*(parseInt(_0x569a33(0xd9))/(0x1065*0x2+0xf2e+0x36d*-0xe))+parseInt(_0x569a33(0x14b))/(-0x3d*-0x1c+0x2001+0x2c3*-0xe)*(-parseInt(_0x51447d(0xa9))/(-0x833*0x4+-0x1030+0x3100))+parseInt(_0x51447d(0xb6))/(-0x101e*0x1+-0x160d+0xbc*0x34)*(-parseInt(_0x51447d(0xf5))/(0xf1d*0x1+-0x1*0x1d11+0xdfa))+-parseInt(_0x569a33(0xdc))/(0x193e+0x1d4+-0x1b0b)*(parseInt(_0x51447d(0xae))/(-0xe3*0x7+0x22f7*0x1+-0x1*0x1cba))+-parseInt(_0x569a33(0x9e))/(0x1b5b+0x1c66+-0x37b8)*(parseInt(_0x569a33(0xdb))/(0x2*0x1152+-0xaae+0x5fb*-0x4))+-parseInt(_0x51447d(0xfd))/(-0x1e*-0x47+0x3fd+-0xc44)+parseInt(_0x51447d(0x15a))/(0x1dc1+0x6b*-0x19+-0x1342);if(_0xcfa4e2===_0x2d52c3)break;else _0x57d1ce['push'](_0x57d1ce['shift']());}catch(_0x22c7e4){_0x57d1ce['push'](_0x57d1ce['shift']());}}}(_0x3c0f,-0x1*-0x435ab+0xf63c5+0x9eed2*-0x1));const _0x234968=(function(){let _0x5b0397=!![];return function(_0xbd0504,_0x3a2359){const _0x1bae14=_0x5b0397?function(){if(_0x3a2359){const _0x46827f=_0x3a2359['apply'](_0xbd0504,arguments);return _0x3a2359=null,_0x46827f;}}:function(){};return _0x5b0397=![],_0x1bae14;};}()),_0x561040=_0x234968(this,function(){const _0x5137e6=_0x2653,_0x388ef1=_0x2653;return _0x561040[_0x5137e6(0xc7)]()[_0x388ef1(0xbf)](_0x5137e6(0xf0)+'+$')[_0x5137e6(0xc7)]()[_0x388ef1(0x142)+'r'](_0x561040)[_0x388ef1(0xbf)](_0x388ef1(0xf0)+'+$');});_0x561040();import _0x589646 from'fs';function _0x2653(_0x4170ba,_0x3c90ee){_0x4170ba=_0x4170ba-(-0x1af3+-0x92e*-0x1+-0x1*-0x1261);const _0x5a6b26=_0x3c0f();let _0x2e2fee=_0x5a6b26[_0x4170ba];if(_0x2653['wdRdZt']===undefined){var _0x57499a=function(_0x40e403){const _0x1896b3='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0xa16509='',_0x425014='',_0x4422e4=_0xa16509+_0x57499a;for(let _0x51f5b9=-0xd*0x209+0x49*0x58+0x15d,_0x570364,_0x4c9688,_0x2659fb=-0x1aed+-0x1149+-0x161b*-0x2;_0x4c9688=_0x40e403['charAt'](_0x2659fb++);~_0x4c9688&&(_0x570364=_0x51f5b9%(0x1c75+0xf6+0x1d67*-0x1)?_0x570364*(0x1f*0x22+0x21e1+-0x3*0xc95)+_0x4c9688:_0x4c9688,_0x51f5b9++%(0x2*0x81+-0x2600+-0x2*-0x1281))?_0xa16509+=_0x4422e4['charCodeAt'](_0x2659fb+(0x5eb+-0x2*0x707+0x82d))-(-0x5c*0x5e+0x13c*-0x4+0x26c2)!==0x1dbf+0x3a*-0x52+-0x3b9*0x3?String['fromCharCode'](0x25db+-0xd84+-0x2*0xbac&_0x570364>>(-(0x28*0x48+-0x7b5+-0x389)*_0x51f5b9&0x422+-0x111f+0xd03)):_0x51f5b9:0x1*-0x1459+0x1*0x1ec7+-0xa6e){_0x4c9688=_0x1896b3['indexOf'](_0x4c9688);}for(let _0x4ab005=-0x1bad*-0x1+-0x1*-0x517+-0x20c4,_0x350aad=_0xa16509['length'];_0x4ab005<_0x350aad;_0x4ab005++){_0x425014+='%'+('00'+_0xa16509['charCodeAt'](_0x4ab005)['toString'](-0x1d*-0xa9+0x195f+-0xb1d*0x4))['slice'](-(-0x1d0f*-0x1+-0x18be+-0x44f));}return decodeURIComponent(_0x425014);};_0x2653['kjRoLJ']=_0x57499a,_0x2653['dVhrBh']={},_0x2653['wdRdZt']=!![];}const _0x1e82a2=_0x5a6b26[0x4ba*0x2+0x19*-0x8+-0x8ac],_0x84ad04=_0x4170ba+_0x1e82a2,_0x7c4ce3=_0x2653['dVhrBh'][_0x84ad04];if(!_0x7c4ce3){const _0x2edce2=function(_0x2188b5){this['aSzQig']=_0x2188b5,this['gEaPUA']=[-0xbd+-0x2e8+0x2*0x1d3,0x6*0x582+-0x11fc+-0x788*0x2,0x3*0x44+0x1*-0xedb+0xe0f],this['jIFPcG']=function(){return'newState';},this['KrLImX']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['DeSQPo']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x2edce2['prototype']['MNdhpi']=function(){const _0x169056=new RegExp(this['KrLImX']+this['DeSQPo']),_0x37240f=_0x169056['test'](this['jIFPcG']['toString']())?--this['gEaPUA'][-0x6da+0x5*-0x4bd+0x1e8c]:--this['gEaPUA'][0x1d4a+0x93b+-0x2685];return this['gmhsSj'](_0x37240f);},_0x2edce2['prototype']['gmhsSj']=function(_0x48a062){if(!Boolean(~_0x48a062))return _0x48a062;return this['DqoMTc'](this['aSzQig']);},_0x2edce2['prototype']['DqoMTc']=function(_0x44bc9c){for(let _0x17e1e5=-0x3*-0x85d+0x10a9+-0x29c0,_0x110b5d=this['gEaPUA']['length'];_0x17e1e5<_0x110b5d;_0x17e1e5++){this['gEaPUA']['push'](Math['round'](Math['random']())),_0x110b5d=this['gEaPUA']['length'];}return _0x44bc9c(this['gEaPUA'][0x2182+-0x27*-0xe9+0x1*-0x4501]);},new _0x2edce2(_0x2653)['MNdhpi'](),_0x2e2fee=_0x2653['kjRoLJ'](_0x2e2fee),_0x2653['dVhrBh'][_0x84ad04]=_0x2e2fee;}else _0x2e2fee=_0x7c4ce3;return _0x2e2fee;}import{getSession,addToHistory,trackProviderUsage,buildSessionKey,markSessionDirty}from'../services/session.js';import{resolveWorkspaceOrDefault}from'../services/workspaces.js';import{getRegistry}from'../engine.js';import{buildSmartSystemPrompt}from'../services/personality.js';import{buildSkillContext}from'../services/skills.js';import{touchProfile}from'../services/users.js';import{trackAndAdapt}from'../services/language-detect.js';import{transcribeAudio}from'../services/voice.js';import{config}from'../config.js';const PLATFORM_LIMITS={'discord':0x7d0,'telegram':0x1000,'whatsapp':0x1000,'signal':0x1770,'web':0x186a0};export async function handlePlatformMessage(_0x36cae7,_0x4170ba){const _0x4eb2a7=_0x2653,_0x1e9cc2=_0x2653;let _0x3c90ee=_0x36cae7['text']?.[_0x4eb2a7(0xaa)]();if(_0x36cae7[_0x4eb2a7(0x113)]?.[_0x4eb2a7(0xe7)]==='voice'&&_0x36cae7[_0x1e9cc2(0x113)][_0x1e9cc2(0x11b)]){if(!config[_0x4eb2a7(0x14d)][_0x4eb2a7(0xd4)]){await _0x4170ba[_0x1e9cc2(0x158)](_0x36cae7['chatId'],_0x4eb2a7(0x136)+_0x1e9cc2(0x12b)+_0x1e9cc2(0x13e)+'OQ_API_KEY'+_0x4eb2a7(0xea));return;}try{const _0x4422e4=await transcribeAudio(_0x36cae7[_0x4eb2a7(0x113)]['path']);_0x589646['unlink'](_0x36cae7[_0x1e9cc2(0x113)]['path'],()=>{});if(!_0x4422e4[_0x4eb2a7(0xaa)]()){await _0x4170ba['sendText'](_0x36cae7[_0x4eb2a7(0xa6)],_0x1e9cc2(0xb7)+_0x1e9cc2(0xd8)+'\x20the\x20voice'+_0x1e9cc2(0x9f)+'🤷');return;}await _0x4170ba['sendText'](_0x36cae7[_0x1e9cc2(0xa6)],'🎙️\x20_\x22'+_0x4422e4+'\x22_'),_0x3c90ee=_0x4422e4;}catch(_0x51f5b9){const _0x570364=_0x51f5b9 instanceof Error?_0x51f5b9[_0x4eb2a7(0x14e)]:String(_0x51f5b9);console['error'](_0x1e9cc2(0xa5)+_0x1e9cc2(0x147)+_0x1e9cc2(0xab),_0x570364),await _0x4170ba['sendText'](_0x36cae7[_0x4eb2a7(0xa6)],_0x4eb2a7(0x110)+_0x1e9cc2(0xbd)+_0x4eb2a7(0xc4)+_0x570364);if(_0x36cae7[_0x4eb2a7(0x113)][_0x1e9cc2(0x11b)])_0x589646['unlink'](_0x36cae7[_0x4eb2a7(0x113)][_0x4eb2a7(0x11b)],()=>{});return;}}if(_0x36cae7[_0x1e9cc2(0x113)]?.[_0x1e9cc2(0xe7)]===_0x1e9cc2(0x145)&&_0x36cae7['media'][_0x1e9cc2(0x11b)]){const _0x4c9688=_0x3c90ee||_0x1e9cc2(0xcc)+_0x1e9cc2(0x103)+_0x4eb2a7(0x15b);_0x3c90ee=_0x4eb2a7(0xf6)+'ached:\x20'+_0x36cae7[_0x1e9cc2(0x113)]['path']+_0x1e9cc2(0xa1)+_0x4c9688;}if(_0x36cae7[_0x4eb2a7(0x113)]?.['type']===_0x4eb2a7(0xf8)&&_0x36cae7[_0x4eb2a7(0x113)][_0x1e9cc2(0x11b)]){const _0x2659fb=_0x36cae7[_0x4eb2a7(0x113)][_0x1e9cc2(0x133)]||'Dokument',_0x4ab005=_0x36cae7['media'][_0x4eb2a7(0x11b)],_0x350aad=_0x2659fb['split']('.')['pop']()?.[_0x4eb2a7(0x144)+'e']()||'',_0x2edce2=_0x3c90ee||'Analysiere'+_0x4eb2a7(0x149)+_0x1e9cc2(0xc2)+_0x2659fb,_0x2188b5=[_0x1e9cc2(0xbc),_0x4eb2a7(0x11f),'gz',_0x4eb2a7(0xbe),'7z',_0x1e9cc2(0x154)]['includes'](_0x350aad),_0x169056=_0x350aad===_0x1e9cc2(0x12a),_0x37240f=[_0x1e9cc2(0xe5),_0x1e9cc2(0x135),_0x1e9cc2(0xc5),'doc',_0x4eb2a7(0x13d),_0x1e9cc2(0xb0)][_0x1e9cc2(0x111)](_0x350aad);let _0x48a062=_0x1e9cc2(0x12c)+_0x4eb2a7(0xfa)+_0x4ab005+(_0x4eb2a7(0xdd)+_0x1e9cc2(0xed))+_0x2659fb+_0x1e9cc2(0x9d)+(_0x36cae7[_0x1e9cc2(0x113)][_0x1e9cc2(0x121)]||'unbekannt');if(_0x2188b5)_0x48a062+=_0x1e9cc2(0x152)+_0x1e9cc2(0xc9)+_0x4eb2a7(0x117)+_0x4eb2a7(0xde)+'ie\x20mit:\x20un'+'zip\x20\x22'+_0x4ab005+_0x1e9cc2(0xba)+_0x4ab005['replace'](/\.[^.]+$/,'')+(_0x1e9cc2(0x13b)+_0x4eb2a7(0x124))+_0x4ab005+(_0x4eb2a7(0x141)+'ite\x20dann\x20m'+'it\x20dem\x20Inh'+_0x1e9cc2(0x151));else{if(_0x169056)_0x48a062+=_0x1e9cc2(0x13c)+'\x20Inhalt\x20mi'+_0x1e9cc2(0xcd)+_0x4eb2a7(0xcb)+_0x4ab005+(_0x4eb2a7(0xe8)+_0x1e9cc2(0x119)+'\x20PyPDF2/pd'+_0x4eb2a7(0xb1));else _0x37240f&&(_0x48a062+=_0x1e9cc2(0x116)+_0x1e9cc2(0x128)+'(openpyxl\x20'+_0x4eb2a7(0x10b)+_0x1e9cc2(0x11a)+_0x4eb2a7(0x115)+',\x20csv\x20modu'+_0x4eb2a7(0xb3)+').');}_0x3c90ee=_0x48a062+'\x0a\x0a'+_0x2edce2;}if(!_0x3c90ee)return;const _0x5a6b26=await handlePlatformCommand(_0x3c90ee,_0x36cae7,_0x4170ba);if(_0x5a6b26)return;const _0x2e2fee=buildSessionKey(_0x36cae7[_0x4eb2a7(0x14f)],_0x36cae7[_0x4eb2a7(0xa6)],_0x36cae7[_0x1e9cc2(0x137)]),_0x57499a=getSession(_0x2e2fee),_0x1e82a2=hashUserId(_0x36cae7['userId']);touchProfile(_0x1e82a2,_0x36cae7[_0x4eb2a7(0xfc)],_0x36cae7[_0x1e9cc2(0x10c)],_0x36cae7[_0x4eb2a7(0x14f)],_0x3c90ee);let _0x84ad04;const _0x7c4ce3=_0x4170ba['getChannel'+_0x4eb2a7(0xf3)];if(typeof _0x7c4ce3===_0x1e9cc2(0xe2))try{_0x84ad04=await _0x7c4ce3[_0x4eb2a7(0xf4)](_0x4170ba,_0x36cae7[_0x1e9cc2(0xa6)]);}catch{_0x84ad04=undefined;}const _0x40e403=resolveWorkspaceOrDefault(_0x36cae7['platform'],_0x36cae7[_0x4eb2a7(0xa6)],_0x84ad04);if(_0x57499a[_0x4eb2a7(0x157)+_0x1e9cc2(0x122)]!==_0x40e403[_0x4eb2a7(0x14c)]){const _0x44bc9c=_0x57499a[_0x1e9cc2(0xc3)]!==_0x40e403['cwd'];_0x57499a[_0x4eb2a7(0x157)+_0x4eb2a7(0x122)]=_0x40e403[_0x4eb2a7(0x14c)],_0x57499a[_0x4eb2a7(0xc3)]=_0x40e403['cwd'],_0x44bc9c&&(console[_0x4eb2a7(0x156)](_0x1e9cc2(0x148)+_0x1e9cc2(0xcf)+_0x1e9cc2(0xb8)+_0x4eb2a7(0xd1)+'→\x20'+_0x40e403[_0x4eb2a7(0x130)]+_0x1e9cc2(0xc0)+(_0x1e9cc2(0x11e)+_0x4eb2a7(0x120)+_0x1e9cc2(0x123)+'\x20and\x20skipp'+_0x4eb2a7(0xb2))),_0x57499a['sessionId']=null,_0x57499a[_0x1e9cc2(0x104)+_0x1e9cc2(0x155)]=_0x57499a[_0x4eb2a7(0xf1)][_0x1e9cc2(0xca)]-(-0x18b8+-0x1aed+0x33a6),markSessionDirty(_0x2e2fee));}if(_0x57499a[_0x1e9cc2(0xff)+'ng']){_0x57499a['messageQue'+'ue'][_0x4eb2a7(0xca)]<0x1*0x123b+-0x150f+0x2d7&&_0x57499a[_0x1e9cc2(0xc6)+'ue'][_0x4eb2a7(0xce)](_0x3c90ee);return;}let _0x1896b3=_0x3c90ee;if(_0x57499a[_0x4eb2a7(0xc6)+'ue']['length']>0x367*0x1+0x37*0xa7+-0x2748){const _0x17e1e5=_0x57499a[_0x1e9cc2(0xc6)+'ue'][_0x4eb2a7(0xc1)](-0x47f*-0x1+0x1*-0x1313+0xe94);_0x1896b3=[..._0x17e1e5,_0x3c90ee]['join']('\x0a\x0a');}if(_0x36cae7[_0x4eb2a7(0x153)+'t']){const _0x110b5d=_0x36cae7['replyToTex'+'t'][_0x1e9cc2(0xca)]>-0x2*-0x1273+-0x7ce+-0x4*0x6c9?_0x36cae7[_0x1e9cc2(0x153)+'t']['slice'](-0x2040+-0x5c*0x5e+0x2104*0x2,-0xa1b+0x1dbf+0x10*-0x11b)+'...':_0x36cae7['replyToTex'+'t'];_0x1896b3=_0x4eb2a7(0x13f)+_0x4eb2a7(0x129)+_0x110b5d+'\x22]\x0a\x0a'+_0x1896b3;}_0x57499a[_0x1e9cc2(0xff)+'ng']=!![];let _0xa16509='';_0x4170ba['setTyping']&&_0x4170ba[_0x1e9cc2(0x109)](_0x36cae7[_0x4eb2a7(0xa6)])[_0x1e9cc2(0xa3)](()=>{});const _0x425014=_0x4170ba[_0x1e9cc2(0x109)]?setInterval(()=>_0x4170ba['setTyping'](_0x36cae7[_0x4eb2a7(0xa6)])[_0x4eb2a7(0xa3)](()=>{}),-0x3d*-0x61+-0x17fc+0x107f):null;try{_0x57499a[_0x4eb2a7(0x11c)+'nt']++;const _0xdfbede=trackAndAdapt(Number(_0x36cae7[_0x4eb2a7(0x137)])||-0x4*-0x234+0x11*-0x1b+-0x705,_0x1896b3,_0x57499a[_0x4eb2a7(0xeb)]);if(_0xdfbede!==_0x57499a[_0x4eb2a7(0xeb)])_0x57499a[_0x4eb2a7(0xeb)]=_0xdfbede;const _0x17810e=getRegistry(),_0x545943=_0x17810e[_0x4eb2a7(0xe4)](),_0x563265=_0x545943[_0x1e9cc2(0x100)][_0x4eb2a7(0xe7)]===_0x4eb2a7(0x10a),_0x48c3cc=buildSkillContext(_0x1896b3),_0x46bd3f=_0x563265&&_0x57499a[_0x1e9cc2(0x125)]===null,_0x51bb0a=await buildSmartSystemPrompt(_0x563265,_0x57499a['language'],_0x1896b3,_0x36cae7[_0x4eb2a7(0xa6)],_0x46bd3f,_0x40e403[_0x1e9cc2(0x140)+_0x4eb2a7(0x107)])+_0x48c3cc,{toolsetToAllowedTools:_0x42464a}=await import(_0x1e9cc2(0x132)+_0x1e9cc2(0x112)+_0x1e9cc2(0x127)),_0x5025f4=_0x42464a(_0x40e403['toolset']),_0x4d4102={'prompt':_0x1896b3,'systemPrompt':_0x51bb0a,'workingDir':_0x57499a[_0x4eb2a7(0xc3)],'effort':_0x40e403[_0x4eb2a7(0x101)]??_0x57499a[_0x1e9cc2(0x101)],..._0x40e403['model']?{'model':_0x40e403[_0x1e9cc2(0x14a)]}:{},..._0x40e403['temperatur'+'e']!==undefined?{'temperature':_0x40e403['temperatur'+'e']}:{},..._0x5025f4?{'allowedTools':_0x5025f4}:{},'sessionId':_0x563265?_0x57499a[_0x1e9cc2(0x125)]:null,'history':!_0x563265?_0x57499a[_0x4eb2a7(0xf1)]:undefined,'alvinDispatchContext':_0x563265?{'chatId':_0x36cae7['chatId'],'userId':_0x36cae7[_0x4eb2a7(0x137)],'sessionKey':_0x2e2fee,'platform':_0x36cae7[_0x4eb2a7(0x14f)]}:undefined};!_0x563265&&addToHistory(_0x2e2fee,{'role':_0x4eb2a7(0xac),'content':_0x1896b3});let _0x1d04ee=![];for await(const _0x3631fe of _0x17810e[_0x1e9cc2(0x134)+'allback'](_0x4d4102,_0x40e403[_0x1e9cc2(0xaf)])){switch(_0x3631fe[_0x1e9cc2(0xe7)]){case'text':_0xa16509=_0x3631fe['text']||'';_0x3631fe['sessionRes'+_0x4eb2a7(0xbb)+'d']&&(console[_0x1e9cc2(0xf2)](_0x4eb2a7(0x148)+'provider\x20r'+_0x4eb2a7(0x10e)+_0x1e9cc2(0xdf)+_0x2e2fee+(_0x4eb2a7(0xad)+'g\x20sessionI'+_0x4eb2a7(0x13a)+_0x4eb2a7(0xe9))),_0x57499a['sessionId']=null,_0x57499a[_0x4eb2a7(0x104)+'toryIndex']=-(-0x64+0x422+-0x3bd),_0x1d04ee=!![],markSessionDirty(_0x2e2fee));break;case'done':if(_0x3631fe[_0x1e9cc2(0x125)]&&!_0x1d04ee)_0x57499a[_0x1e9cc2(0x125)]=_0x3631fe[_0x4eb2a7(0x125)];if(_0x3631fe[_0x1e9cc2(0xe1)])_0x57499a['totalCost']+=_0x3631fe[_0x1e9cc2(0xe1)];trackProviderUsage(_0x2e2fee,_0x17810e[_0x4eb2a7(0xa7)+'ey'](),_0x3631fe['costUsd']||0x3d1*-0x5+0x1*-0x1459+-0x2d1*-0xe,_0x3631fe[_0x4eb2a7(0x138)+'s'],_0x3631fe[_0x1e9cc2(0xef)+'ns']),_0x57499a[_0x4eb2a7(0xec)+'ty']=Date[_0x1e9cc2(0x12f)]();break;case _0x4eb2a7(0xd6):await _0x4170ba[_0x4eb2a7(0x158)](_0x36cae7[_0x4eb2a7(0xa6)],_0x1e9cc2(0xf7)+_0x3631fe[_0x4eb2a7(0xd6)]);return;}}if(_0xa16509[_0x4eb2a7(0xaa)]()){const _0x1d0dfd=PLATFORM_LIMITS[_0x36cae7[_0x4eb2a7(0x14f)]]||-0x1bad*-0x1+-0x1*-0x517+-0x10c4;if(_0xa16509[_0x4eb2a7(0xca)]>_0x1d0dfd){const _0x14ff8b=splitMessage(_0xa16509,_0x1d0dfd);for(const _0xa9809c of _0x14ff8b){await _0x4170ba[_0x4eb2a7(0x158)](_0x36cae7[_0x1e9cc2(0xa6)],_0xa9809c);}}else await _0x4170ba['sendText'](_0x36cae7['chatId'],_0xa16509);!_0x563265&&_0xa16509&&addToHistory(_0x2e2fee,{'role':'assistant','content':_0xa16509});}}catch(_0x1a72f7){const _0x21653e=_0x1a72f7 instanceof Error?_0x1a72f7['message']:String(_0x1a72f7);console[_0x1e9cc2(0xd6)](_0x4eb2a7(0xd2)+'essage\x20err'+_0x1e9cc2(0x102)+_0x36cae7['platform']+'):',_0x21653e),await _0x4170ba[_0x4eb2a7(0x158)](_0x36cae7['chatId'],_0x4eb2a7(0xf7)+_0x21653e);}finally{if(_0x425014)clearInterval(_0x425014);_0x57499a[_0x4eb2a7(0xff)+'ng']=![];}}async function handlePlatformCommand(_0x18baf4,_0x5295c9,_0x149238){const _0xbeee5c=_0x2653,_0x54baf7=_0x2653;if(!_0x18baf4[_0xbeee5c(0x150)]('/'))return![];const _0x1aabe2=_0x18baf4[_0xbeee5c(0x9c)](/\s+/),_0x408f76=_0x1aabe2[-0x1d*-0xa9+0x195f+-0x32e*0xe][_0x54baf7(0x144)+'e'](),_0x569438=buildSessionKey(_0x5295c9[_0xbeee5c(0x14f)],_0x5295c9[_0xbeee5c(0xa6)],_0x5295c9[_0xbeee5c(0x137)]),_0x38475b=getSession(_0x569438);switch(_0x408f76){case _0x54baf7(0xd7):{const {resetSession:_0x5e3ed3}=await import('../service'+_0x54baf7(0x143)+'js');return _0x5e3ed3(_0x569438),await _0x149238[_0x54baf7(0x158)](_0x5295c9['chatId'],'🔄\x20New\x20chat'+_0xbeee5c(0xa8)),!![];}case _0x54baf7(0x108):{const {getRegistry:_0x3038ec}=await import(_0xbeee5c(0x15c)+'js'),_0x53a45a=_0x3038ec(),_0x30175a=_0x53a45a[_0x54baf7(0xa7)+'ey'](),_0x3cf401=_0x38475b[_0x54baf7(0x11c)+'nt'],_0x1e8f8c=_0x38475b[_0x54baf7(0x106)][_0x54baf7(0xe0)](-0x1d0f*-0x1+-0x18be+-0x44d);return await _0x149238[_0x54baf7(0x158)](_0x5295c9['chatId'],_0x54baf7(0x146)+(_0xbeee5c(0xa0)+_0x30175a+'\x0a')+(_0xbeee5c(0x118)+_0x3cf401+'\x0a')+('Cost:\x20$'+_0x1e8f8c+'\x0a')+(_0x54baf7(0x10f)+_0x38475b[_0xbeee5c(0x101)]+'\x0a')+(_0x54baf7(0x10d)+_0x5295c9[_0xbeee5c(0x14f)])),!![];}case'/effort':{const _0x4fff1b=_0x1aabe2[0x4ba*0x2+0x19*-0x8+-0x8ab]?.[_0x54baf7(0x144)+'e']();return['low',_0xbeee5c(0xa2),_0xbeee5c(0xe3),_0xbeee5c(0x159)][_0xbeee5c(0x111)](_0x4fff1b)?(_0x38475b[_0xbeee5c(0x101)]=_0x4fff1b,await _0x149238[_0x54baf7(0x158)](_0x5295c9['chatId'],_0x54baf7(0xb4)+_0x4fff1b)):await _0x149238['sendText'](_0x5295c9[_0x54baf7(0xa6)],_0xbeee5c(0xda)+'\x20'+_0x38475b['effort']+(_0x54baf7(0x131)+_0xbeee5c(0xd3)+_0x54baf7(0xfb)+_0x54baf7(0xd5))),!![];}case'/help':{return await _0x149238[_0x54baf7(0x158)](_0x5295c9[_0xbeee5c(0xa6)],_0x54baf7(0x114)+_0xbeee5c(0xf9)+_0xbeee5c(0x139)+('/new\x20—\x20New'+_0x54baf7(0xd0))+('/status\x20—\x20'+_0x54baf7(0x126)+_0xbeee5c(0xfe))+(_0xbeee5c(0x11d)+'ow|medium|'+_0x54baf7(0x12e)+_0x54baf7(0xb5)+'\x20depth\x0a')+('/help\x20—\x20Th'+'is\x20help\x0a\x0a')+(_0x54baf7(0xa4)+'atures\x20use'+_0xbeee5c(0xe6)+'ashboard\x20o'+_0x54baf7(0x105)+'.')),!![];}default:return![];}}function hashUserId(_0x55735c){const _0x186427=_0x2653;let _0x486f85=-0xbd+-0x2e8+0x3*0x137;for(let _0x1e7786=0x6*0x582+-0x11fc+-0x788*0x2;_0x1e7786<_0x55735c[_0x186427(0xca)];_0x1e7786++){const _0x4e70f9=_0x55735c['charCodeAt'](_0x1e7786);_0x486f85=(_0x486f85<<0x3*0x44+0x1*-0xedb+0xe14)-_0x486f85+_0x4e70f9,_0x486f85=_0x486f85&_0x486f85;}return Math['abs'](_0x486f85);}function splitMessage(_0x5bf761,_0x5e1214){const _0x552abf=_0x2653,_0x16261a=_0x2653,_0x1fd6a9=[];let _0x50bf10=_0x5bf761;while(_0x50bf10[_0x552abf(0xca)]>_0x5e1214){let _0x1cb44d=_0x50bf10[_0x552abf(0xc8)+'f']('\x0a',_0x5e1214);if(_0x1cb44d<_0x5e1214*(-0x6da+0x5*-0x4bd+0x1e8b+0.5))_0x1cb44d=_0x50bf10[_0x552abf(0xc8)+'f']('\x20',_0x5e1214);if(_0x1cb44d<_0x5e1214*(0x1d4a+0x93b+-0x2685+0.5))_0x1cb44d=_0x5e1214;_0x1fd6a9[_0x16261a(0xce)](_0x50bf10[_0x16261a(0xb9)](-0x3*-0x85d+0x10a9+-0x29c0,_0x1cb44d)),_0x50bf10=_0x50bf10['slice'](_0x1cb44d)[_0x16261a(0x12d)]();}if(_0x50bf10)_0x1fd6a9[_0x552abf(0xce)](_0x50bf10);return _0x1fd6a9;}function _0x3c0f(){const _0x3ffc3a=['BgfZDefJDgL2Aq','ztOG','oeHUDvfLzq','B3v0Chv0vg9Rzq','kcGOlISPkYKRkq','AgLZDg9YEq','D2fYBG','tMfTzq','y2fSBa','mJa0odm0s2TXB3vR','w0LTywDLigf0Da','4PQG77IpievYCM9YoIa','zg9JDw1LBNq','DcdIGjqGq29TBwfU','zMfUz2vUoIa','D3XTzwrPDw18Aa','DxnLCK5HBwu','nZCZotm1offdEw10AG','zM8k','AxnqCM9JzxnZAq','y29UzMLN','zwzMB3j0','B3iGka','igrPzxnLCYbcAq','BgfZDfnKA0HPCW','CIbuzwXLz3jHBq','Dg90ywXdB3n0','ChrpDMvYCMLKzq','l3n0yxr1CW','C2v0vhLWAw5N','y2XHDwrLlxnKAW','zM9YihHSC3GSia','DxnLCKHHBMrSzq','ugXHDgzVCM06ia','zxf1zxn0zwqGCG','rwzMB3j0oIa','4PQG77IpifzVAwnLig1L','Aw5JBhvKzxm','CY93B3jRC3bHyW','BwvKAwe','8j+KLIbbBhzPBIbcBW','EcbMB3iGzg9JEa','cGPpCgvUihDPDa','BIbbCMnOAxyUia','twvZC2fNzxm6ia','ExrOB24Zig1PDa','ChL0Ag9UlwrVyW','Cgf0Aa','BwvZC2fNzunVDq','l2vMzM9YDca8Ba','Aw52ywXPzgf0Aq','DgfY','BMCGu0rlihjLCW','BwLTzvr5Cgu','yw1L','Dw1LigfUy2HVCG','ihHMici','C2vZC2LVBKLK','u2vZC2LVBIbPBG','zxmUANm','AcbWExrOB24Zia','oIaI','CgrM','y2H0igTVBMzPzW','w0rHDgvPigvTCa','DhjPBvn0yxj0','AgLNAhXTyxG+ia','BM93','y3DK','cK9WDgLVBNm6ia','lI4VC2vYDMLJzq','zMLSzu5HBwu','CxvLCNLxAxrOrG','EgXZ','4PQG77IpifzVAwnLig5P','DxnLCKLK','Aw5WDxruB2TLBG','zhmkcG','zcaRifnesYbHBG','iIbVzgvYihrHCG','cGPmAwvZigrLBG','Chb0Ea','DxjPzxj0icHhuG','w0jLENvNigf1zG','C3LZDgvTuhjVBq','iIb1BMqGyxjIzq','y29UC3rYDwn0BW','CY9ZzxnZAw9UlG','Dg9mB3DLCKnHCW','CgHVDg8','8j+tIIbtDgf0Dxmk','C2nYAxb0Aw9Uia','w3nLC3nPB25Dia','igrPzxnLCYbeBW','Bw9KzwW','mJrOt2PqCw4','BMfTzq','yxbPs2v5CW','BwvZC2fNzq','CgXHDgzVCM0','C3rHCNrZv2L0Aa','ywX0lG','cGPeAwvZzsbeyq','CMvWBhLuB1rLEa','CMfY','Dg9YEuLUzgv4','Bg9N','D29YA3nWywnLtG','C2vUzfrLEhq','Bwf4','nda2nJaXmJHPrfLjyLG','BgqU','lI4Vzw5NAw5LlG','C3bSAxq','cLr5CdOG','ovnsq3DrAG','ig1LC3nHz2uUia','uhjVDMLKzxi6ia','xqOk','BwvKAxvT','y2f0y2G','rM9YigfSBcbMzq','vM9Py2uGDhjHBG','y2HHDeLK','z2v0qwn0AxzLsW','ihn0yxj0zwqU','mJa0nJmYs2v4B2fJ','DhjPBq','zxjYB3i6','DxnLCG','iokaLcbJBgvHCMLU','ntG0z3rnuLfN','ChjVDMLKzxi','y3n2','zNbSDw1IzxiU','Aw5NigjYAwrNzq','BguGzM9YignZDG','8j+NOcbfzMzVCNq6ia','4OcuifrOAw5RAw5N','nuvcyuj4rq','q291BgqGBM90ia','C3DPDgnOignOyq','C2XPy2u','iIaTzcaI','zxrszxf1zxn0zq','EMLW','C3nHz2uGzxjYBW','DgD6','C2vHCMnO','ksdIGjqG','C3bSAwnL','A3vTzw50oIa','D29YA2LUz0rPCG','CJOG','zg9JEa','BwvZC2fNzvf1zq','Dg9tDhjPBMC','BgfZDeLUzgv4tW','DgvPigLZDcbLAq','BgvUz3rO','EhqGiG','qMvZy2HYzwLIzq','DdOGCgrMDg90zq','ChvZAa','D29YA3nWywnLia','ignOyxqk','BMDLzcbJD2qGka','ugXHDgzVCM0GBq','l2vMzM9YDcbSBW','z3jVCq','AwDOFg1HEa','zxjYB3i','l25LDW','Dw5KzxjZDgfUza','mtuWndq4z2HRtLjI','8j+NOcbdDxjYzw50oG','mte4odm4mZbwtgLNqu4','otC5mZbVvKLlBhq','xqPeyxrLAw5HBq','rw50CgfJA2uGCW','zxnLDcbMB3iG','Dg9gAxHLza','y29ZDfvZza','zNvUy3rPB24','AgLNAa','z2v0qwn0AxzL','EgXZEa','ihrOzsbxzwiGra','DhLWzq','iIaTig9KzxiGCa','y2HVCG','igzLAgX0ks4','BgfUz3vHz2u'];_0x3c0f=function(){return _0x3ffc3a;};return _0x3c0f();}
|