alvin-bot 5.6.2 → 5.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/README.md +1 -1
- 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 -130
- 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 -443
- 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 -0
- 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 -1831
- package/dist/web/setup-api.js +1 -1101
- package/package.json +5 -2
- package/dist/.metadata_never_index +0 -0
|
@@ -1,54 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Task-aware stuck timer for the Telegram message handler (v4.12.1).
|
|
3
|
-
*
|
|
4
|
-
* The main handler must detect genuine SDK hangs (no chunks for N minutes)
|
|
5
|
-
* while NOT aborting legitimate long-running work — specifically sync Agent
|
|
6
|
-
* tool calls that emit no intermediate chunks for their entire duration.
|
|
7
|
-
*
|
|
8
|
-
* State machine:
|
|
9
|
-
* - Normal mode: idle timeout = NORMAL_MS (default 10 min, env-configurable
|
|
10
|
-
* in message.ts via ALVIN_STUCK_TIMEOUT_MINUTES)
|
|
11
|
-
* - When any Agent/Task tool call is known to be running sync (tracked by
|
|
12
|
-
* its toolUseId), the next reset() arms the timer with EXTENDED_MS
|
|
13
|
-
* instead (default 120 min, env-configurable via
|
|
14
|
-
* ALVIN_SYNC_AGENT_IDLE_TIMEOUT_MINUTES)
|
|
15
|
-
* - Back to NORMAL_MS once all tracked sync tool calls have emitted their
|
|
16
|
-
* tool_result and been released via exitSync()
|
|
17
|
-
*
|
|
18
|
-
* This module is pure — no grammy, no session, no provider. Takes its ms
|
|
19
|
-
* values and onTimeout callback as constructor args. Testable in isolation
|
|
20
|
-
* with vi.useFakeTimers(). The handler owns the state; the handler decides
|
|
21
|
-
* which chunks flip the mode based on chunk.toolName and chunk.runInBackground.
|
|
22
|
-
*
|
|
23
|
-
* See docs/superpowers/plans/... and test/stuck-timer.test.ts.
|
|
24
|
-
*/
|
|
25
|
-
export function createStuckTimer(cfg) {
|
|
26
|
-
const pending = new Set();
|
|
27
|
-
let handle = null;
|
|
28
|
-
const currentTimeout = () => pending.size > 0 ? cfg.extendedMs : cfg.normalMs;
|
|
29
|
-
const rearm = () => {
|
|
30
|
-
if (handle)
|
|
31
|
-
clearTimeout(handle);
|
|
32
|
-
handle = setTimeout(cfg.onTimeout, currentTimeout());
|
|
33
|
-
};
|
|
34
|
-
return {
|
|
35
|
-
reset: rearm,
|
|
36
|
-
enterSync(id) {
|
|
37
|
-
pending.add(id);
|
|
38
|
-
rearm();
|
|
39
|
-
},
|
|
40
|
-
exitSync(id) {
|
|
41
|
-
pending.delete(id);
|
|
42
|
-
rearm();
|
|
43
|
-
},
|
|
44
|
-
cancel() {
|
|
45
|
-
if (handle) {
|
|
46
|
-
clearTimeout(handle);
|
|
47
|
-
handle = null;
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
_pendingCount() {
|
|
51
|
-
return pending.size;
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
}
|
|
1
|
+
(function(_0xad3490,_0x20d999){const _0xa4ec4d=_0x3bb8,_0x5657f8=_0x3bb8,_0x23657a=_0xad3490();while(!![]){try{const _0x2b2b21=-parseInt(_0xa4ec4d(0x146))/(0x2564*-0x1+0x2598+-0x33)+parseInt(_0xa4ec4d(0x141))/(0x120*-0x16+0xcd*-0x6+0x4*0x764)+parseInt(_0xa4ec4d(0x140))/(-0xe*0x236+0xea*0xb+0x14e9)*(-parseInt(_0x5657f8(0x147))/(0x182*0x15+0x72c+-0x1369*0x2))+-parseInt(_0x5657f8(0x13d))/(0xceb*0x2+0xb*-0x259+0x2)*(-parseInt(_0x5657f8(0x142))/(-0x1*-0x132f+0x1*0xa53+-0x1d7c))+-parseInt(_0xa4ec4d(0x144))/(-0x7c9*-0x1+0x1*0x4b5+-0xc77)*(parseInt(_0x5657f8(0x134))/(0x302+0xd0e+-0x1008))+-parseInt(_0x5657f8(0x13c))/(0x452*-0x3+0x1ac1+-0xdc2)*(-parseInt(_0xa4ec4d(0x13b))/(-0x2363*0x1+0xbe4+0x1789))+parseInt(_0x5657f8(0x13f))/(0x2138+0x18f8+-0x41*0xe5);if(_0x2b2b21===_0x20d999)break;else _0x23657a['push'](_0x23657a['shift']());}catch(_0x41447a){_0x23657a['push'](_0x23657a['shift']());}}}(_0x3ac6,0x117b74+0x8f3f*-0x10+-0xb*-0x601));function _0x3ac6(){const _0xb7aaeb=['C2vHCMnO','ndm5mtbADgrcr3a','mtuYmuzcsLjhvW','mtG5nJm5mffMq21nyq','BM9YBwfStxm','mZK5nda3oevXvezLEG','ndG4ndLjy21Au3G','mtC3mZG5ogXTAMLLCq','mtjXDen4Cg8','y29UC3rYDwn0BW','nZy2ndi3oxr2vwPlrG','ywrK','nJa3nJKXqunAvLzY','mte2A1jgDLPU','yxbWBhK','ogLyuM1dvW','Dg9tDhjPBMC','kcGOlISPkYKRkq','zxH0zw5KzwrnCW','C2L6zq','zgvSzxrL'];_0x3ac6=function(){return _0xb7aaeb;};return _0x3ac6();}const _0x1de2ab=(function(){let _0x28950b=!![];return function(_0x455668,_0x3a0154){const _0xf8807c=_0x28950b?function(){const _0xda4b36=_0x3bb8;if(_0x3a0154){const _0x347fe8=_0x3a0154[_0xda4b36(0x133)](_0x455668,arguments);return _0x3a0154=null,_0x347fe8;}}:function(){};return _0x28950b=![],_0xf8807c;};}()),_0x41021f=_0x1de2ab(this,function(){const _0x1106c0=_0x3bb8,_0x3c9445=_0x3bb8;return _0x41021f['toString']()[_0x1106c0(0x13a)](_0x3c9445(0x136)+'+$')[_0x3c9445(0x135)]()[_0x3c9445(0x143)+'r'](_0x41021f)[_0x1106c0(0x13a)](_0x3c9445(0x136)+'+$');});function _0x3bb8(_0x56e26f,_0x38bca9){_0x56e26f=_0x56e26f-(0x9*-0x36e+-0x149a+0x61*0x8b);const _0x49e36d=_0x3ac6();let _0x335c3c=_0x49e36d[_0x56e26f];if(_0x3bb8['XuNUXu']===undefined){var _0x3f9f95=function(_0x1fdec1){const _0x505826='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x50c3e6='',_0x57c882='',_0x2cb237=_0x50c3e6+_0x3f9f95;for(let _0x1f80e2=0x365+-0x1260+0x41*0x3b,_0x47f0d7,_0x3e33a9,_0x36a0f1=-0x28*0xf1+0xad2+0x1ad6;_0x3e33a9=_0x1fdec1['charAt'](_0x36a0f1++);~_0x3e33a9&&(_0x47f0d7=_0x1f80e2%(-0xd5*0x7+0x1*0x11bd+-0xbe6*0x1)?_0x47f0d7*(0x235*0xa+-0x6a*0x40+-0x2*-0x257)+_0x3e33a9:_0x3e33a9,_0x1f80e2++%(-0x59*-0x4a+-0x2523+0xc3*0xf))?_0x50c3e6+=_0x2cb237['charCodeAt'](_0x36a0f1+(-0x98e*-0x2+-0x5*0x773+0x122d))-(0xb8*0x2+-0x3*-0x14b+-0x547)!==-0x1462+-0x197b+0x2ddd?String['fromCharCode'](0xc66+0x6fd*-0x5+0x178a&_0x47f0d7>>(-(-0x1*0x1731+-0x34*-0x7f+-0x85*0x5)*_0x1f80e2&-0x339*-0x1+-0x14c1+0x118e)):_0x1f80e2:0x32b+-0x46d+0x142){_0x3e33a9=_0x505826['indexOf'](_0x3e33a9);}for(let _0xc3c7d7=-0x663+0xb*0x2c9+-0x1840,_0x1c81d5=_0x50c3e6['length'];_0xc3c7d7<_0x1c81d5;_0xc3c7d7++){_0x57c882+='%'+('00'+_0x50c3e6['charCodeAt'](_0xc3c7d7)['toString'](0x2343+0xd2a*0x2+0x1*-0x3d87))['slice'](-(0x74c*0x2+-0x6*-0x44d+-0x2864));}return decodeURIComponent(_0x57c882);};_0x3bb8['gFOVzY']=_0x3f9f95,_0x3bb8['uDiEyr']={},_0x3bb8['XuNUXu']=!![];}const _0x7d9008=_0x49e36d[0x27e+-0x16*-0x75+0x4*-0x323],_0x2bba6e=_0x56e26f+_0x7d9008,_0x85a480=_0x3bb8['uDiEyr'][_0x2bba6e];if(!_0x85a480){const _0x2cb5a2=function(_0x583b2a){this['jThrpe']=_0x583b2a,this['ATDCYh']=[-0x1fb3+0x5*-0x7+-0x1*-0x1fd7,-0x1640+0x120*-0x16+0x178*0x20,0x1780+0xc7*0x7+-0x1cf1],this['yMbWMd']=function(){return'newState';},this['yQhUEN']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['HXyLgb']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x2cb5a2['prototype']['TlPXen']=function(){const _0x4e2a67=new RegExp(this['yQhUEN']+this['HXyLgb']),_0x7eaa4b=_0x4e2a67['test'](this['yMbWMd']['toString']())?--this['ATDCYh'][0x1a0e+0x1*0x1e17+0xe09*-0x4]:--this['ATDCYh'][-0x1da7+-0xad*-0x25+0x46*0x11];return this['DKSwDX'](_0x7eaa4b);},_0x2cb5a2['prototype']['DKSwDX']=function(_0xe2996d){if(!Boolean(~_0xe2996d))return _0xe2996d;return this['uQfseL'](this['jThrpe']);},_0x2cb5a2['prototype']['uQfseL']=function(_0x474418){for(let _0x1d9fff=0x2217+0x17*0x8d+-0x2*0x1761,_0x5f1ddb=this['ATDCYh']['length'];_0x1d9fff<_0x5f1ddb;_0x1d9fff++){this['ATDCYh']['push'](Math['round'](Math['random']())),_0x5f1ddb=this['ATDCYh']['length'];}return _0x474418(this['ATDCYh'][0x480+0x1*0x328+-0x1ea*0x4]);},new _0x2cb5a2(_0x3bb8)['TlPXen'](),_0x335c3c=_0x3bb8['gFOVzY'](_0x335c3c),_0x3bb8['uDiEyr'][_0x2bba6e]=_0x335c3c;}else _0x335c3c=_0x85a480;return _0x335c3c;}_0x41021f();export function createStuckTimer(_0x30e819){const _0x1c4024=_0x3bb8,_0x219832=_0x3bb8,_0x378890=new Set();let _0xd262a=null;const _0x4aa064=()=>_0x378890[_0x1c4024(0x138)]>-0x28*0xf1+0xad2+0x1ad6?_0x30e819[_0x219832(0x137)]:_0x30e819[_0x1c4024(0x13e)],_0xf5807f=()=>{if(_0xd262a)clearTimeout(_0xd262a);_0xd262a=setTimeout(_0x30e819['onTimeout'],_0x4aa064());};return{'reset':_0xf5807f,'enterSync'(_0x519201){const _0x588477=_0x219832;_0x378890[_0x588477(0x145)](_0x519201),_0xf5807f();},'exitSync'(_0x50bc4a){const _0x1a5017=_0x1c4024;_0x378890[_0x1a5017(0x139)](_0x50bc4a),_0xf5807f();},'cancel'(){_0xd262a&&(clearTimeout(_0xd262a),_0xd262a=null);},'_pendingCount'(){const _0xcfb308=_0x219832;return _0x378890[_0xcfb308(0x138)];}};}
|
package/dist/handlers/video.js
CHANGED
|
@@ -1,237 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Video Message Handler — Process video messages and video notes (round videos).
|
|
3
|
-
*
|
|
4
|
-
* Capabilities:
|
|
5
|
-
* - Receive video messages → extract key frames → describe/analyze
|
|
6
|
-
* - Receive video notes (round videos) → same processing
|
|
7
|
-
* - Extract audio from video → transcribe (if voice content)
|
|
8
|
-
* - Support for video files sent as documents (handled by document handler)
|
|
9
|
-
*/
|
|
10
|
-
import fs from "fs";
|
|
11
|
-
import path from "path";
|
|
12
|
-
import os from "os";
|
|
13
|
-
import https from "https";
|
|
14
|
-
import { execSync } from "child_process";
|
|
15
|
-
import { config } from "../config.js";
|
|
16
|
-
import { getSession, addToHistory } from "../services/session.js";
|
|
17
|
-
import { TelegramStreamer } from "../services/telegram.js";
|
|
18
|
-
import { getRegistry } from "../engine.js";
|
|
19
|
-
import { transcribeAudio } from "../services/voice.js";
|
|
20
|
-
import { buildSystemPrompt } from "../services/personality.js";
|
|
21
|
-
const TEMP_DIR = path.join(os.tmpdir(), "alvin-bot", "video");
|
|
22
|
-
if (!fs.existsSync(TEMP_DIR))
|
|
23
|
-
fs.mkdirSync(TEMP_DIR, { recursive: true });
|
|
24
|
-
/** React helper */
|
|
25
|
-
async function react(ctx, emoji) {
|
|
26
|
-
try {
|
|
27
|
-
await ctx.react(emoji);
|
|
28
|
-
}
|
|
29
|
-
catch { /* ignore */ }
|
|
30
|
-
}
|
|
31
|
-
/** Download a Telegram file */
|
|
32
|
-
async function downloadFile(url, dest) {
|
|
33
|
-
return new Promise((resolve, reject) => {
|
|
34
|
-
const file = fs.createWriteStream(dest);
|
|
35
|
-
https.get(url, (response) => {
|
|
36
|
-
response.pipe(file);
|
|
37
|
-
file.on("finish", () => file.close(() => resolve()));
|
|
38
|
-
}).on("error", (err) => {
|
|
39
|
-
fs.unlink(dest, () => { });
|
|
40
|
-
reject(err);
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
/** Check if ffmpeg is available */
|
|
45
|
-
function hasFFmpeg() {
|
|
46
|
-
try {
|
|
47
|
-
execSync("which ffmpeg", { stdio: "pipe" });
|
|
48
|
-
return true;
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
/** Extract key frames from a video (up to 4 frames, evenly spaced) */
|
|
55
|
-
function extractFrames(videoPath, outputDir, maxFrames = 4) {
|
|
56
|
-
// Get video duration
|
|
57
|
-
let duration = 10;
|
|
58
|
-
try {
|
|
59
|
-
const probe = execSync(`ffprobe -v error -show_entries format=duration -of csv="p=0" "${videoPath}"`, { stdio: "pipe" }).toString().trim();
|
|
60
|
-
duration = parseFloat(probe) || 10;
|
|
61
|
-
}
|
|
62
|
-
catch { /* default duration */ }
|
|
63
|
-
const interval = Math.max(duration / (maxFrames + 1), 0.5);
|
|
64
|
-
const frames = [];
|
|
65
|
-
for (let i = 1; i <= maxFrames; i++) {
|
|
66
|
-
const timestamp = Math.min(interval * i, duration - 0.1);
|
|
67
|
-
const framePath = path.join(outputDir, `frame_${i}.jpg`);
|
|
68
|
-
try {
|
|
69
|
-
execSync(`ffmpeg -ss ${timestamp.toFixed(2)} -i "${videoPath}" -vframes 1 -q:v 3 -y "${framePath}" 2>/dev/null`, { stdio: "pipe", timeout: 10000 });
|
|
70
|
-
if (fs.existsSync(framePath) && fs.statSync(framePath).size > 0) {
|
|
71
|
-
frames.push(framePath);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
catch { /* skip this frame */ }
|
|
75
|
-
}
|
|
76
|
-
return frames;
|
|
77
|
-
}
|
|
78
|
-
/** Extract audio track from video */
|
|
79
|
-
function extractAudio(videoPath) {
|
|
80
|
-
const audioPath = videoPath.replace(/\.\w+$/, ".ogg");
|
|
81
|
-
try {
|
|
82
|
-
execSync(`ffmpeg -i "${videoPath}" -vn -acodec libopus -y "${audioPath}" 2>/dev/null`, { stdio: "pipe", timeout: 30000 });
|
|
83
|
-
if (fs.existsSync(audioPath) && fs.statSync(audioPath).size > 1000) {
|
|
84
|
-
return audioPath;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
catch { /* no audio track or extraction failed */ }
|
|
88
|
-
return null;
|
|
89
|
-
}
|
|
90
|
-
export async function handleVideo(ctx) {
|
|
91
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
92
|
-
const video = ctx.message?.video || ctx.message?.video_note;
|
|
93
|
-
if (!video)
|
|
94
|
-
return;
|
|
95
|
-
const userId = ctx.from.id;
|
|
96
|
-
const session = getSession(userId);
|
|
97
|
-
if (session.isProcessing) {
|
|
98
|
-
if (session.messageQueue.length < 3) {
|
|
99
|
-
session.messageQueue.push("[Video-Nachricht empfangen]");
|
|
100
|
-
await react(ctx, "📝");
|
|
101
|
-
}
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
if (!hasFFmpeg()) {
|
|
105
|
-
await ctx.reply("❌ Video processing requires ffmpeg. Install with: `brew install ffmpeg`", { parse_mode: "Markdown" });
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
session.isProcessing = true;
|
|
109
|
-
session.abortController = new AbortController();
|
|
110
|
-
const streamer = new TelegramStreamer(ctx.chat.id, ctx.api, ctx.message?.message_id);
|
|
111
|
-
let finalText = "";
|
|
112
|
-
const typingInterval = setInterval(() => {
|
|
113
|
-
ctx.api.sendChatAction(ctx.chat.id, "typing").catch(() => { });
|
|
114
|
-
}, 4000);
|
|
115
|
-
try {
|
|
116
|
-
await react(ctx, "👀");
|
|
117
|
-
await ctx.api.sendChatAction(ctx.chat.id, "typing");
|
|
118
|
-
// 1. Download video
|
|
119
|
-
const file = await ctx.api.getFile(video.file_id);
|
|
120
|
-
const ext = file.file_path?.split(".").pop() || "mp4";
|
|
121
|
-
const videoPath = path.join(TEMP_DIR, `video_${Date.now()}.${ext}`);
|
|
122
|
-
const fileUrl = `https://api.telegram.org/file/bot${config.botToken}/${file.file_path}`;
|
|
123
|
-
await downloadFile(fileUrl, videoPath);
|
|
124
|
-
// 2. Extract key frames
|
|
125
|
-
const frameDir = path.join(TEMP_DIR, `frames_${Date.now()}`);
|
|
126
|
-
fs.mkdirSync(frameDir, { recursive: true });
|
|
127
|
-
const frames = extractFrames(videoPath, frameDir);
|
|
128
|
-
// 3. Extract and transcribe audio (if available)
|
|
129
|
-
let transcript = "";
|
|
130
|
-
if (config.apiKeys.groq) {
|
|
131
|
-
const audioPath = extractAudio(videoPath);
|
|
132
|
-
if (audioPath) {
|
|
133
|
-
try {
|
|
134
|
-
transcript = await transcribeAudio(audioPath);
|
|
135
|
-
fs.unlink(audioPath, () => { });
|
|
136
|
-
}
|
|
137
|
-
catch { /* no transcription */ }
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
// 4. Build prompt with video context
|
|
141
|
-
const caption = ctx.message?.caption || "";
|
|
142
|
-
const duration = video.duration || 0;
|
|
143
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
144
|
-
const isVideoNote = !!ctx.message?.video_note;
|
|
145
|
-
let prompt = `[Video empfangen: ${duration}s`;
|
|
146
|
-
if (isVideoNote)
|
|
147
|
-
prompt += ", runde Videonachricht";
|
|
148
|
-
if (video.width && video.height)
|
|
149
|
-
prompt += `, ${video.width}x${video.height}`;
|
|
150
|
-
prompt += "]";
|
|
151
|
-
if (transcript) {
|
|
152
|
-
prompt += `\n\n[Audio-Transkription]: "${transcript}"`;
|
|
153
|
-
}
|
|
154
|
-
if (caption) {
|
|
155
|
-
prompt += `\n\n[Bildunterschrift]: "${caption}"`;
|
|
156
|
-
}
|
|
157
|
-
if (frames.length > 0) {
|
|
158
|
-
prompt += `\n\n[${frames.length} key frames extracted from the video]`;
|
|
159
|
-
prompt += "\n\nBitte beschreibe was im Video zu sehen ist und beantworte eventuelle Fragen.";
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
prompt += "\n\nIch konnte keine Frames extrahieren. Basiere deine Antwort auf der Audio-Transkription.";
|
|
163
|
-
}
|
|
164
|
-
// Show what we extracted
|
|
165
|
-
const infoLines = [];
|
|
166
|
-
if (frames.length > 0)
|
|
167
|
-
infoLines.push(`🎞️ ${frames.length} frames extracted`);
|
|
168
|
-
if (transcript)
|
|
169
|
-
infoLines.push(`🎙️ "${transcript.slice(0, 100)}${transcript.length > 100 ? "..." : ""}"`);
|
|
170
|
-
if (infoLines.length > 0) {
|
|
171
|
-
await ctx.reply(infoLines.join("\n"));
|
|
172
|
-
}
|
|
173
|
-
// 5. Send to AI
|
|
174
|
-
session.messageCount++;
|
|
175
|
-
const registry = getRegistry();
|
|
176
|
-
const activeProvider = registry.getActive();
|
|
177
|
-
const isSDK = activeProvider.config.type === "claude-sdk";
|
|
178
|
-
const queryOpts = {
|
|
179
|
-
prompt,
|
|
180
|
-
systemPrompt: buildSystemPrompt(isSDK, session.language),
|
|
181
|
-
workingDir: session.workingDir,
|
|
182
|
-
effort: session.effort,
|
|
183
|
-
abortSignal: session.abortController.signal,
|
|
184
|
-
sessionId: isSDK ? session.sessionId : null,
|
|
185
|
-
history: !isSDK ? session.history : undefined,
|
|
186
|
-
};
|
|
187
|
-
if (!isSDK) {
|
|
188
|
-
addToHistory(userId, { role: "user", content: prompt });
|
|
189
|
-
}
|
|
190
|
-
for await (const chunk of registry.queryWithFallback(queryOpts)) {
|
|
191
|
-
switch (chunk.type) {
|
|
192
|
-
case "text":
|
|
193
|
-
finalText = chunk.text || "";
|
|
194
|
-
await streamer.update(finalText);
|
|
195
|
-
break;
|
|
196
|
-
case "tool_use":
|
|
197
|
-
if (chunk.toolName)
|
|
198
|
-
session.toolUseCount++;
|
|
199
|
-
break;
|
|
200
|
-
case "done":
|
|
201
|
-
if (chunk.sessionId)
|
|
202
|
-
session.sessionId = chunk.sessionId;
|
|
203
|
-
if (chunk.costUsd)
|
|
204
|
-
session.totalCost += chunk.costUsd;
|
|
205
|
-
session.lastActivity = Date.now();
|
|
206
|
-
break;
|
|
207
|
-
case "error":
|
|
208
|
-
await ctx.reply(`Error: ${chunk.error}`);
|
|
209
|
-
break;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
await streamer.finalize(finalText);
|
|
213
|
-
await react(ctx, "👍");
|
|
214
|
-
if (!isSDK && finalText) {
|
|
215
|
-
addToHistory(userId, { role: "assistant", content: finalText });
|
|
216
|
-
}
|
|
217
|
-
// Cleanup
|
|
218
|
-
frames.forEach(f => fs.unlink(f, () => { }));
|
|
219
|
-
fs.rm(frameDir, { recursive: true }, () => { });
|
|
220
|
-
fs.unlink(videoPath, () => { });
|
|
221
|
-
}
|
|
222
|
-
catch (err) {
|
|
223
|
-
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
224
|
-
await react(ctx, "👎");
|
|
225
|
-
if (errorMsg.includes("abort")) {
|
|
226
|
-
await ctx.reply("Anfrage abgebrochen.");
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
await ctx.reply(`Error: ${errorMsg}`);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
finally {
|
|
233
|
-
clearInterval(typingInterval);
|
|
234
|
-
session.isProcessing = false;
|
|
235
|
-
session.abortController = null;
|
|
236
|
-
}
|
|
237
|
-
}
|
|
1
|
+
const _0x30a839=_0x7849,_0x591d2d=_0x7849;(function(_0x37a08e,_0x5009c8){const _0x2442ce=_0x7849,_0x5143d2=_0x7849,_0x4fd71b=_0x37a08e();while(!![]){try{const _0x37a2e4=-parseInt(_0x2442ce(0x173))/(-0xab1+-0x77*-0x41+-0x1385)+parseInt(_0x2442ce(0x1b6))/(0x3*0x513+-0x7d*-0x47+-0x31e2)+parseInt(_0x5143d2(0x194))/(-0x20cf+-0x24d2+0x22d2*0x2)+parseInt(_0x2442ce(0x165))/(-0x224e+-0x1bbd+-0x1*-0x3e0f)+-parseInt(_0x5143d2(0x158))/(0x2*-0xcd5+0x2*-0x1057+0x3a5d)+parseInt(_0x5143d2(0x149))/(-0xba2+0x1*-0x1564+-0x6*-0x582)*(-parseInt(_0x2442ce(0x18f))/(0x1dad+-0x1eae*-0x1+-0x3c54))+parseInt(_0x2442ce(0x1af))/(-0xbfa*-0x1+0x14f*0x18+-0x2*0x15ad);if(_0x37a2e4===_0x5009c8)break;else _0x4fd71b['push'](_0x4fd71b['shift']());}catch(_0x52e827){_0x4fd71b['push'](_0x4fd71b['shift']());}}}(_0xe0d3,-0xb6*0x15f9+0x7221*0x24+0x7b73c));const _0x1e2f1a=(function(){let _0x213c8e=!![];return function(_0x354587,_0x10bedb){const _0x42e0cc=_0x213c8e?function(){if(_0x10bedb){const _0x3d9268=_0x10bedb['apply'](_0x354587,arguments);return _0x10bedb=null,_0x3d9268;}}:function(){};return _0x213c8e=![],_0x42e0cc;};}()),_0x387775=_0x1e2f1a(this,function(){const _0x8c3d26=_0x7849,_0x48bc56=_0x7849;return _0x387775[_0x8c3d26(0x151)]()[_0x48bc56(0x1a3)]('(((.+)+)+)'+'+$')[_0x8c3d26(0x151)]()[_0x48bc56(0x199)+'r'](_0x387775)[_0x48bc56(0x1a3)](_0x48bc56(0x1a0)+'+$');});_0x387775();import _0x524998 from'fs';import _0x5f1f77 from'path';import _0x51a522 from'os';import _0x4e72d6 from'https';import{execSync}from'child_process';import{config}from'../config.js';import{getSession,addToHistory}from'../services/session.js';import{TelegramStreamer}from'../services/telegram.js';import{getRegistry}from'../engine.js';import{transcribeAudio}from'../services/voice.js';import{buildSystemPrompt}from'../services/personality.js';const TEMP_DIR=_0x5f1f77[_0x30a839(0x181)](_0x51a522['tmpdir'](),_0x591d2d(0x143),'video');if(!_0x524998[_0x591d2d(0x1b3)](TEMP_DIR))_0x524998[_0x30a839(0x18e)](TEMP_DIR,{'recursive':!![]});function _0x7849(_0x54866d,_0x5d4ca8){_0x54866d=_0x54866d-(0x141f+-0x7*0x236+-0x36a);const _0x1dcd14=_0xe0d3();let _0x322b18=_0x1dcd14[_0x54866d];if(_0x7849['oNGyia']===undefined){var _0x568c4=function(_0x20deb9){const _0xd3e5ca='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x4ce13f='',_0x1eec3d='',_0xc9d39=_0x4ce13f+_0x568c4;for(let _0x4133e2=-0x20ea+0xca2+-0x289*-0x8,_0x20ebf3,_0x3ada47,_0x4213ff=-0x554+-0x122c+0x1780;_0x3ada47=_0x20deb9['charAt'](_0x4213ff++);~_0x3ada47&&(_0x20ebf3=_0x4133e2%(-0x1f*0xfb+-0xf23+0x2d8c)?_0x20ebf3*(0x10c*0x4+-0xb*-0x31+0x11*-0x5b)+_0x3ada47:_0x3ada47,_0x4133e2++%(-0x146+0x1f12+-0x4*0x772))?_0x4ce13f+=_0xc9d39['charCodeAt'](_0x4213ff+(0x26f*-0x1+-0x78d+0x503*0x2))-(0x1670+-0x187c+0x216)!==-0x1cd8+0x231*-0xb+-0x5*-0xa97?String['fromCharCode'](-0x56+-0x156*0xc+-0x7*-0x27b&_0x20ebf3>>(-(-0x1d*0x11+0x1c83+-0x1a94)*_0x4133e2&0x11fe+0x1935+0x7*-0x62b)):_0x4133e2:0x3*0xa9d+0x224f*0x1+0x2*-0x2113){_0x3ada47=_0xd3e5ca['indexOf'](_0x3ada47);}for(let _0x46cf81=0x50e+0x10*-0x199+0x1482,_0x2652a8=_0x4ce13f['length'];_0x46cf81<_0x2652a8;_0x46cf81++){_0x1eec3d+='%'+('00'+_0x4ce13f['charCodeAt'](_0x46cf81)['toString'](0x13b2+0x4*0x7b5+-0x869*0x6))['slice'](-(-0x5d1*0x1+-0xd3d*0x2+-0x1*-0x204d));}return decodeURIComponent(_0x1eec3d);};_0x7849['cNoTDm']=_0x568c4,_0x7849['wRGOyx']={},_0x7849['oNGyia']=!![];}const _0x30ba3b=_0x1dcd14[0x2109+-0x1972+-0x797],_0xe39458=_0x54866d+_0x30ba3b,_0x1d58a8=_0x7849['wRGOyx'][_0xe39458];if(!_0x1d58a8){const _0x49c1b8=function(_0x42d434){this['XcdWvb']=_0x42d434,this['aIkVaG']=[0xeca+-0x18f7+-0xa2e*-0x1,0x1bd9*0x1+0x1583*0x1+0x2*-0x18ae,0x961+0x123a+-0x1b9b],this['TGjOpV']=function(){return'newState';},this['uSgpcm']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['IOYXnu']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x49c1b8['prototype']['OQQfxl']=function(){const _0x381779=new RegExp(this['uSgpcm']+this['IOYXnu']),_0x5398da=_0x381779['test'](this['TGjOpV']['toString']())?--this['aIkVaG'][0xa87*-0x1+0x1*-0x853+0x12db]:--this['aIkVaG'][0xb1*0x29+0x26dd+-0x99a*0x7];return this['IgdJXv'](_0x5398da);},_0x49c1b8['prototype']['IgdJXv']=function(_0x446e8a){if(!Boolean(~_0x446e8a))return _0x446e8a;return this['pBLVSA'](this['XcdWvb']);},_0x49c1b8['prototype']['pBLVSA']=function(_0x182071){for(let _0xa52ed1=0x2be*-0xd+0xb60+0x1846,_0x1d980c=this['aIkVaG']['length'];_0xa52ed1<_0x1d980c;_0xa52ed1++){this['aIkVaG']['push'](Math['round'](Math['random']())),_0x1d980c=this['aIkVaG']['length'];}return _0x182071(this['aIkVaG'][0x1cec+-0x2190+0x4a4]);},new _0x49c1b8(_0x7849)['OQQfxl'](),_0x322b18=_0x7849['cNoTDm'](_0x322b18),_0x7849['wRGOyx'][_0xe39458]=_0x322b18;}else _0x322b18=_0x1d58a8;return _0x322b18;}async function react(_0x5bec77,_0x54f86f){const _0x4d50f0=_0x30a839;try{await _0x5bec77[_0x4d50f0(0x161)](_0x54f86f);}catch{}}async function downloadFile(_0x2f40f2,_0x678d09){return new Promise((_0x52fd2a,_0x6b90f3)=>{const _0x128b6e=_0x7849,_0x3a7347=_0x7849,_0x240ecc=_0x524998[_0x128b6e(0x16c)+_0x3a7347(0x180)](_0x678d09);_0x4e72d6[_0x3a7347(0x14b)](_0x2f40f2,_0x1857ac=>{const _0x313461=_0x3a7347,_0xc9b3be=_0x128b6e;_0x1857ac[_0x313461(0x189)](_0x240ecc),_0x240ecc['on']('finish',()=>_0x240ecc[_0xc9b3be(0x14e)](()=>_0x52fd2a()));})['on']('error',_0x2a0f4a=>{_0x524998['unlink'](_0x678d09,()=>{}),_0x6b90f3(_0x2a0f4a);});});}function hasFFmpeg(){const _0x12cf14=_0x30a839,_0x5bf644=_0x30a839;try{return execSync(_0x12cf14(0x164)+'eg',{'stdio':_0x5bf644(0x189)}),!![];}catch{return![];}}function extractFrames(_0x54866d,_0x5d4ca8,_0x1dcd14=-0x122c+-0x2357+0x3587){const _0x4d02c5=_0x591d2d,_0x1a35e1=_0x30a839;let _0x322b18=-0xf23+0x824+0x709;try{const _0xe39458=execSync(_0x4d02c5(0x18c)+_0x4d02c5(0x168)+'ow_entries'+'\x20format=du'+_0x4d02c5(0x183)+_0x4d02c5(0x1bb)+'\x20\x22'+_0x54866d+'\x22',{'stdio':_0x1a35e1(0x189)})[_0x4d02c5(0x151)]()[_0x1a35e1(0x15f)]();_0x322b18=parseFloat(_0xe39458)||0x10c*0x4+-0xb*-0x31+0x1*-0x641;}catch{}const _0x568c4=Math['max'](_0x322b18/(_0x1dcd14+(-0x146+0x1f12+-0x1d*0x107)),0x26f*-0x1+-0x78d+0x1aa*0x6+0.5),_0x30ba3b=[];for(let _0x1d58a8=0x1670+-0x187c+0x20d;_0x1d58a8<=_0x1dcd14;_0x1d58a8++){const _0x20deb9=Math[_0x4d02c5(0x160)](_0x568c4*_0x1d58a8,_0x322b18-(-0x1cd8+0x231*-0xb+-0x5*-0xa97+0.1)),_0xd3e5ca=_0x5f1f77[_0x4d02c5(0x181)](_0x5d4ca8,'frame_'+_0x1d58a8+_0x4d02c5(0x175));try{execSync('ffmpeg\x20-ss'+'\x20'+_0x20deb9[_0x4d02c5(0x174)](-0x56+-0x156*0xc+-0x8*-0x20c)+'\x20-i\x20\x22'+_0x54866d+(_0x4d02c5(0x13b)+'\x201\x20-q:v\x203\x20'+_0x4d02c5(0x145))+_0xd3e5ca+(_0x1a35e1(0x153)+'ull'),{'stdio':_0x1a35e1(0x189),'timeout':0x2710}),_0x524998[_0x4d02c5(0x1b3)](_0xd3e5ca)&&_0x524998[_0x4d02c5(0x1ba)](_0xd3e5ca)[_0x1a35e1(0x185)]>-0x1d*0x11+0x1c83+-0x1a96&&_0x30ba3b[_0x1a35e1(0x196)](_0xd3e5ca);}catch{}}return _0x30ba3b;}function extractAudio(_0x4ce13f){const _0x5961f9=_0x591d2d,_0x4a59f9=_0x30a839,_0x1eec3d=_0x4ce13f[_0x5961f9(0x197)](/\.\w+$/,'.ogg');try{execSync(_0x5961f9(0x1b4)+'\x22'+_0x4ce13f+('\x22\x20-vn\x20-aco'+_0x5961f9(0x162)+'s\x20-y\x20\x22')+_0x1eec3d+(_0x5961f9(0x153)+_0x5961f9(0x1ac)),{'stdio':_0x5961f9(0x189),'timeout':0x7530});if(_0x524998['existsSync'](_0x1eec3d)&&_0x524998['statSync'](_0x1eec3d)[_0x4a59f9(0x185)]>0x11fe+0x1935+0x7*-0x59d)return _0x1eec3d;}catch{}return null;}export async function handleVideo(_0xc9d39){const _0x13aa69=_0x30a839,_0x3fe41b=_0x591d2d,_0x4133e2=_0xc9d39[_0x13aa69(0x1b8)]?.['video']||_0xc9d39['message']?.[_0x13aa69(0x1b7)];if(!_0x4133e2)return;const _0x20ebf3=_0xc9d39[_0x13aa69(0x187)]['id'],_0x3ada47=getSession(_0x20ebf3);if(_0x3ada47[_0x3fe41b(0x166)+'ng']){_0x3ada47[_0x13aa69(0x193)+'ue'][_0x3fe41b(0x1a1)]<0x3*0xa9d+0x224f*0x1+0x1*-0x4223&&(_0x3ada47['messageQue'+'ue']['push'](_0x13aa69(0x150)+'hricht\x20emp'+_0x13aa69(0x17d)),await react(_0xc9d39,'📝'));return;}if(!hasFFmpeg()){await _0xc9d39[_0x13aa69(0x1aa)](_0x3fe41b(0x1a8)+_0x13aa69(0x1b1)+_0x13aa69(0x17b)+_0x13aa69(0x16e)+'all\x20with:\x20'+_0x13aa69(0x152)+_0x3fe41b(0x15b)+'`',{'parse_mode':'Markdown'});return;}_0x3ada47[_0x3fe41b(0x166)+'ng']=!![],_0x3ada47['abortContr'+_0x3fe41b(0x1a7)]=new AbortController();const _0x4213ff=new TelegramStreamer(_0xc9d39['chat']['id'],_0xc9d39[_0x3fe41b(0x17f)],_0xc9d39[_0x3fe41b(0x1b8)]?.['message_id']);let _0x46cf81='';const _0x2652a8=setInterval(()=>{const _0x169443=_0x13aa69,_0x2d359e=_0x13aa69;_0xc9d39[_0x169443(0x17f)][_0x169443(0x179)+_0x169443(0x154)](_0xc9d39['chat']['id'],_0x169443(0x1a6))[_0x169443(0x182)](()=>{});},0x50e+0x10*-0x199+0x2422);try{await react(_0xc9d39,'👀'),await _0xc9d39['api']['sendChatAc'+_0x13aa69(0x154)](_0xc9d39[_0x13aa69(0x14f)]['id'],_0x3fe41b(0x1a6));const _0x49c1b8=await _0xc9d39[_0x3fe41b(0x17f)]['getFile'](_0x4133e2['file_id']),_0x42d434=_0x49c1b8[_0x3fe41b(0x188)]?.[_0x13aa69(0x155)]('.')['pop']()||_0x3fe41b(0x14a),_0x381779=_0x5f1f77[_0x3fe41b(0x181)](TEMP_DIR,_0x3fe41b(0x141)+Date['now']()+'.'+_0x42d434),_0x5398da=_0x3fe41b(0x13f)+_0x13aa69(0x177)+_0x3fe41b(0x1a5)+_0x3fe41b(0x18a)+config['botToken']+'/'+_0x49c1b8['file_path'];await downloadFile(_0x5398da,_0x381779);const _0x446e8a=_0x5f1f77[_0x13aa69(0x181)](TEMP_DIR,_0x3fe41b(0x144)+Date[_0x3fe41b(0x176)]());_0x524998['mkdirSync'](_0x446e8a,{'recursive':!![]});const _0x182071=extractFrames(_0x381779,_0x446e8a);let _0xa52ed1='';if(config['apiKeys'][_0x3fe41b(0x19c)]){const _0x1b084a=extractAudio(_0x381779);if(_0x1b084a)try{_0xa52ed1=await transcribeAudio(_0x1b084a),_0x524998[_0x13aa69(0x13d)](_0x1b084a,()=>{});}catch{}}const _0x1d980c=_0xc9d39[_0x13aa69(0x1b8)]?.[_0x3fe41b(0x171)]||'',_0x3edda3=_0x4133e2[_0x13aa69(0x19e)]||0x13b2+0x4*0x7b5+-0xdf*0x3a,_0x48cb5b=!!_0xc9d39[_0x13aa69(0x1b8)]?.[_0x3fe41b(0x1b7)];let _0x1f3d0e=_0x3fe41b(0x1a4)+_0x3fe41b(0x195)+_0x3edda3+'s';if(_0x48cb5b)_0x1f3d0e+=_0x13aa69(0x17a)+_0x13aa69(0x19d)+'ht';if(_0x4133e2['width']&&_0x4133e2['height'])_0x1f3d0e+=',\x20'+_0x4133e2['width']+'x'+_0x4133e2[_0x3fe41b(0x1b2)];_0x1f3d0e+=']';_0xa52ed1&&(_0x1f3d0e+=_0x3fe41b(0x148)+_0x3fe41b(0x15d)+'on]:\x20\x22'+_0xa52ed1+'\x22');_0x1d980c&&(_0x1f3d0e+=_0x13aa69(0x140)+_0x13aa69(0x1ab)+_0x3fe41b(0x16d)+_0x1d980c+'\x22');_0x182071[_0x3fe41b(0x1a1)]>-0x5d1*0x1+-0xd3d*0x2+-0x7*-0x49d?(_0x1f3d0e+='\x0a\x0a['+_0x182071[_0x13aa69(0x1a1)]+(_0x13aa69(0x159)+_0x3fe41b(0x15e)+'d\x20from\x20the'+'\x20video]'),_0x1f3d0e+='\x0a\x0aBitte\x20be'+_0x13aa69(0x184)+_0x13aa69(0x1b5)+_0x13aa69(0x146)+'\x20ist\x20und\x20b'+'eantworte\x20'+_0x3fe41b(0x18b)+_0x13aa69(0x19f)):_0x1f3d0e+='\x0a\x0aIch\x20konn'+_0x3fe41b(0x169)+_0x3fe41b(0x1ad)+'ahieren.\x20B'+'asiere\x20dei'+'ne\x20Antwort'+'\x20auf\x20der\x20A'+_0x3fe41b(0x147)+_0x13aa69(0x15a);const _0x377ad6=[];if(_0x182071[_0x3fe41b(0x1a1)]>0x2109+-0x1972+-0x797)_0x377ad6['push'](_0x13aa69(0x1ae)+_0x182071['length']+(_0x13aa69(0x142)+_0x3fe41b(0x13e)));if(_0xa52ed1)_0x377ad6[_0x13aa69(0x196)]('🎙️\x20\x22'+_0xa52ed1[_0x13aa69(0x16a)](0xeca+-0x18f7+-0xa2d*-0x1,0x1bd9*0x1+0x1583*0x1+0x1*-0x30f8)+(_0xa52ed1[_0x3fe41b(0x1a1)]>0x961+0x123a+-0x1b37?_0x13aa69(0x1a2):'')+'\x22');_0x377ad6['length']>0xa87*-0x1+0x1*-0x853+0x12da&&await _0xc9d39[_0x13aa69(0x1aa)](_0x377ad6['join']('\x0a'));_0x3ada47[_0x3fe41b(0x17c)+'nt']++;const _0x2c8561=getRegistry(),_0x43358a=_0x2c8561[_0x3fe41b(0x157)](),_0xc7896a=_0x43358a['config'][_0x3fe41b(0x172)]==='claude-sdk',_0x50b2b6={'prompt':_0x1f3d0e,'systemPrompt':buildSystemPrompt(_0xc7896a,_0x3ada47[_0x3fe41b(0x163)]),'workingDir':_0x3ada47[_0x13aa69(0x170)],'effort':_0x3ada47[_0x3fe41b(0x17e)],'abortSignal':_0x3ada47['abortContr'+_0x3fe41b(0x1a7)][_0x13aa69(0x19b)],'sessionId':_0xc7896a?_0x3ada47[_0x3fe41b(0x1a9)]:null,'history':!_0xc7896a?_0x3ada47[_0x3fe41b(0x15c)]:undefined};!_0xc7896a&&addToHistory(_0x20ebf3,{'role':_0x3fe41b(0x198),'content':_0x1f3d0e});for await(const _0x169722 of _0x2c8561[_0x13aa69(0x18d)+_0x3fe41b(0x191)](_0x50b2b6)){switch(_0x169722[_0x13aa69(0x172)]){case _0x13aa69(0x16f):_0x46cf81=_0x169722[_0x3fe41b(0x16f)]||'',await _0x4213ff[_0x13aa69(0x192)](_0x46cf81);break;case'tool_use':if(_0x169722[_0x3fe41b(0x14d)])_0x3ada47['toolUseCou'+'nt']++;break;case _0x3fe41b(0x186):if(_0x169722[_0x3fe41b(0x1a9)])_0x3ada47['sessionId']=_0x169722['sessionId'];if(_0x169722[_0x13aa69(0x14c)])_0x3ada47['totalCost']+=_0x169722[_0x13aa69(0x14c)];_0x3ada47['lastActivi'+'ty']=Date[_0x13aa69(0x176)]();break;case _0x13aa69(0x178):await _0xc9d39['reply']('Error:\x20'+_0x169722[_0x13aa69(0x178)]);break;}}await _0x4213ff[_0x13aa69(0x16b)](_0x46cf81),await react(_0xc9d39,'👍'),!_0xc7896a&&_0x46cf81&&addToHistory(_0x20ebf3,{'role':_0x3fe41b(0x1b0),'content':_0x46cf81}),_0x182071[_0x3fe41b(0x13c)](_0x5e560b=>_0x524998[_0x3fe41b(0x13d)](_0x5e560b,()=>{})),_0x524998['rm'](_0x446e8a,{'recursive':!![]},()=>{}),_0x524998[_0x13aa69(0x13d)](_0x381779,()=>{});}catch(_0x5cde13){const _0x365bd0=_0x5cde13 instanceof Error?_0x5cde13[_0x3fe41b(0x1b8)]:String(_0x5cde13);await react(_0xc9d39,'👎'),_0x365bd0[_0x3fe41b(0x167)]('abort')?await _0xc9d39[_0x3fe41b(0x1aa)](_0x3fe41b(0x190)+_0x13aa69(0x19a)):await _0xc9d39[_0x3fe41b(0x1aa)](_0x3fe41b(0x1b9)+_0x365bd0);}finally{clearInterval(_0x2652a8),_0x3ada47[_0x3fe41b(0x166)+'ng']=![],_0x3ada47[_0x13aa69(0x156)+_0x13aa69(0x1a7)]=null;}}function _0xe0d3(){const _0x3ca73f=['4P2mifzPzgvVihbY','C2vZC2LVBKLK','CMvWBhK','zxjZy2HYAwz0xq','DwXS','CMfTzxmGzxH0CG','8j+oNU+4JYa','nZa2mJi1nMzQuujfDW','yxnZAxn0yw50','B2nLC3nPBMCGCG','AgvPz2H0','zxHPC3rZu3LUyW','zMzTCgvNic1Pia','yxmGAw0GvMLKzq','mtaYmtm1nhvvvK9Hwa','DMLKzw9FBM90zq','BwvZC2fNzq','rxjYB3i6ia','C3rHDfn5BMm','ignZDJ0ICd0WiG','iIaTDMzYyw1LCW','zM9YrwfJAa','Dw5SAw5R','DhjHy3rLza','Ahr0Chm6lY9HCa','cGPBqMLSzhvUDa','DMLKzw9F','igzYyw1LCYbLEa','ywX2Aw4TyM90','zNjHBwvZxW','lxKGiG','BYb6DsbZzwHLBG','DwrPBY1uCMfUCW','cGPBqxvKAw8Tva','mJeWCeTgAhji','Bxa0','z2v0','y29ZDfvZza','Dg9VBe5HBwu','y2XVC2u','y2HHDa','w1zPzgvVlu5HyW','Dg9tDhjPBMC','ygjYzxCGAw5ZDa','iIaYpI9KzxyVBG','DgLVBG','C3bSAxq','ywjVCNrdB250CG','z2v0qwn0AxzL','mZK2nty0mgTNDwDHBW','igTLEsbMCMfTzq','A3jPChrPB24U','ywXSigzMBxbLzW','AgLZDg9YEq','CMfUC2TYAxb0Aq','CYbLEhrYywn0zq','DhjPBq','BwLU','CMvHy3q','zgvJigXPyM9WDq','BgfUz3vHz2u','D2HPy2GGzMzTCa','mZe5nJG4BKzbuM53','AxnqCM9JzxnZAq','Aw5JBhvKzxm','igvYCM9Yic1ZAa','DguGA2vPBMuGrG','C2XPy2u','zMLUywXPEMu','y3jLyxrLv3jPDa','oIaI','BxbLzY4Gsw5ZDa','Dgv4Da','D29YA2LUz0rPCG','y2fWDgLVBG','DhLWzq','nZm4nZK0EvzgEwL4','Dg9gAxHLza','lMPWzW','BM93','As50zwXLz3jHBq','zxjYB3i','C2vUzenOyxrbyW','lcbYDw5KzsbwAq','zxf1AxjLCYbMzG','BwvZC2fNzunVDq','zMfUz2vUxq','zwzMB3j0','yxbP','zvn0CMvHBq','AM9PBG','y2f0y2G','CMf0Aw9Uic1VzG','C2nOCMvPyMuGDW','C2L6zq','zg9Uzq','zNjVBq','zMLSzv9WyxrO','CgLWzq','yM90','zxzLBNr1zwXSzq','zMzWCM9IzsaTDG','CxvLCNLxAxrOrG','BwTKAxjtEw5J','nZiXnZbwu3bJuuu','qw5MCMfNzsbHyG','ywXSyMfJAW','DxbKyxrL','BwvZC2fNzvf1zq','mJG1otmZovrbu3L5yq','zMfUz2vUoIa','ChvZAa','CMvWBgfJzq','DxnLCG','y29UC3rYDwn0BW','z2vICM9JAgvUlG','C2LNBMfS','z3jVCq','zgvVBMfJAhjPyW','zhvYyxrPB24','iezYywDLBI4','kcGOlISPkYKRkq','BgvUz3rO','lI4U','C2vHCMnO','w1zPzgvVigvTCa','lM9YzY9MAwXLlW','DhLWAw5N','B2XSzxi'];_0xe0d3=function(){return _0x3ca73f;};return _0xe0d3();}
|
package/dist/handlers/voice.js
CHANGED
|
@@ -1,148 +1 @@
|
|
|
1
|
-
import { InputFile } from "grammy";
|
|
2
|
-
import fs from "fs";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import os from "os";
|
|
5
|
-
import https from "https";
|
|
6
|
-
/** React to a message with an emoji. Silently fails if not supported. */
|
|
7
|
-
async function react(ctx, emoji) {
|
|
8
|
-
try {
|
|
9
|
-
await ctx.react(emoji);
|
|
10
|
-
}
|
|
11
|
-
catch { /* ignore */ }
|
|
12
|
-
}
|
|
13
|
-
import { config } from "../config.js";
|
|
14
|
-
import { getSession, addToHistory } from "../services/session.js";
|
|
15
|
-
import { TelegramStreamer } from "../services/telegram.js";
|
|
16
|
-
import { transcribeAudio, textToSpeech } from "../services/voice.js";
|
|
17
|
-
import { getRegistry } from "../engine.js";
|
|
18
|
-
import { buildSystemPrompt } from "../services/personality.js";
|
|
19
|
-
const TEMP_DIR = path.join(os.tmpdir(), "alvin-bot");
|
|
20
|
-
if (!fs.existsSync(TEMP_DIR)) {
|
|
21
|
-
fs.mkdirSync(TEMP_DIR, { recursive: true });
|
|
22
|
-
}
|
|
23
|
-
async function downloadFile(url, dest) {
|
|
24
|
-
return new Promise((resolve, reject) => {
|
|
25
|
-
const file = fs.createWriteStream(dest);
|
|
26
|
-
https.get(url, (response) => {
|
|
27
|
-
response.pipe(file);
|
|
28
|
-
file.on("finish", () => file.close(() => resolve()));
|
|
29
|
-
}).on("error", (err) => {
|
|
30
|
-
fs.unlink(dest, () => { });
|
|
31
|
-
reject(err);
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
export async function handleVoice(ctx) {
|
|
36
|
-
const voice = ctx.message?.voice;
|
|
37
|
-
if (!voice)
|
|
38
|
-
return;
|
|
39
|
-
const userId = ctx.from.id;
|
|
40
|
-
const session = getSession(userId);
|
|
41
|
-
if (session.isProcessing) {
|
|
42
|
-
await ctx.reply("Please wait, previous request still running... (/cancel to abort)");
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
if (!config.apiKeys.groq) {
|
|
46
|
-
await ctx.reply("Voice nicht konfiguriert (GROQ_API_KEY fehlt).");
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
session.isProcessing = true;
|
|
50
|
-
session.abortController = new AbortController();
|
|
51
|
-
const streamer = new TelegramStreamer(ctx.chat.id, ctx.api, ctx.message?.message_id);
|
|
52
|
-
let finalText = "";
|
|
53
|
-
const typingInterval = setInterval(() => {
|
|
54
|
-
ctx.api.sendChatAction(ctx.chat.id, "typing").catch(() => { });
|
|
55
|
-
}, 4000);
|
|
56
|
-
try {
|
|
57
|
-
await react(ctx, "🎧");
|
|
58
|
-
await ctx.api.sendChatAction(ctx.chat.id, "typing");
|
|
59
|
-
// 1. Download voice message
|
|
60
|
-
const file = await ctx.api.getFile(voice.file_id);
|
|
61
|
-
const fileUrl = `https://api.telegram.org/file/bot${config.botToken}/${file.file_path}`;
|
|
62
|
-
const audioPath = path.join(TEMP_DIR, `voice_${Date.now()}.ogg`);
|
|
63
|
-
await downloadFile(fileUrl, audioPath);
|
|
64
|
-
// 2. Transcribe with Groq Whisper
|
|
65
|
-
const transcript = await transcribeAudio(audioPath);
|
|
66
|
-
fs.unlink(audioPath, () => { });
|
|
67
|
-
if (!transcript.trim()) {
|
|
68
|
-
await ctx.reply("Could not understand the voice message.");
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
// Show what was understood
|
|
72
|
-
await ctx.reply(`"${transcript}"`);
|
|
73
|
-
// 3. Send to AI via provider system
|
|
74
|
-
session.messageCount++;
|
|
75
|
-
const registry = getRegistry();
|
|
76
|
-
const activeProvider = registry.getActive();
|
|
77
|
-
const isSDK = activeProvider.config.type === "claude-sdk";
|
|
78
|
-
const queryOpts = {
|
|
79
|
-
prompt: transcript,
|
|
80
|
-
systemPrompt: buildSystemPrompt(isSDK, session.language),
|
|
81
|
-
workingDir: session.workingDir,
|
|
82
|
-
effort: session.effort,
|
|
83
|
-
abortSignal: session.abortController.signal,
|
|
84
|
-
sessionId: isSDK ? session.sessionId : null,
|
|
85
|
-
history: !isSDK ? session.history : undefined,
|
|
86
|
-
_sessionState: isSDK ? {
|
|
87
|
-
messageCount: session.messageCount,
|
|
88
|
-
toolUseCount: session.toolUseCount,
|
|
89
|
-
} : undefined,
|
|
90
|
-
};
|
|
91
|
-
if (!isSDK) {
|
|
92
|
-
addToHistory(userId, { role: "user", content: transcript });
|
|
93
|
-
}
|
|
94
|
-
for await (const chunk of registry.queryWithFallback(queryOpts)) {
|
|
95
|
-
switch (chunk.type) {
|
|
96
|
-
case "text":
|
|
97
|
-
finalText = chunk.text || "";
|
|
98
|
-
await streamer.update(finalText);
|
|
99
|
-
break;
|
|
100
|
-
case "tool_use":
|
|
101
|
-
if (chunk.toolName)
|
|
102
|
-
session.toolUseCount++;
|
|
103
|
-
break;
|
|
104
|
-
case "done":
|
|
105
|
-
if (chunk.sessionId)
|
|
106
|
-
session.sessionId = chunk.sessionId;
|
|
107
|
-
if (chunk.costUsd)
|
|
108
|
-
session.totalCost += chunk.costUsd;
|
|
109
|
-
session.lastActivity = Date.now();
|
|
110
|
-
break;
|
|
111
|
-
case "error":
|
|
112
|
-
await ctx.reply(`Error: ${chunk.error}`);
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
await streamer.finalize(finalText);
|
|
117
|
-
await react(ctx, "👍");
|
|
118
|
-
if (!isSDK && finalText) {
|
|
119
|
-
addToHistory(userId, { role: "assistant", content: finalText });
|
|
120
|
-
}
|
|
121
|
-
// 4. Send voice reply if enabled
|
|
122
|
-
if (session.voiceReply && finalText.trim()) {
|
|
123
|
-
try {
|
|
124
|
-
await ctx.api.sendChatAction(ctx.chat.id, "upload_voice");
|
|
125
|
-
const ttsPath = await textToSpeech(finalText);
|
|
126
|
-
await ctx.replyWithVoice(new InputFile(fs.readFileSync(ttsPath), "response.mp3"));
|
|
127
|
-
fs.unlink(ttsPath, () => { });
|
|
128
|
-
}
|
|
129
|
-
catch (err) {
|
|
130
|
-
console.error("TTS error:", err);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
catch (err) {
|
|
135
|
-
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
136
|
-
if (errorMsg.includes("abort")) {
|
|
137
|
-
await ctx.reply("Anfrage abgebrochen.");
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
await ctx.reply(`Error: ${errorMsg}`);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
finally {
|
|
144
|
-
clearInterval(typingInterval);
|
|
145
|
-
session.isProcessing = false;
|
|
146
|
-
session.abortController = null;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
1
|
+
const _0x378284=_0xe7b9,_0x1ef080=_0xe7b9;(function(_0x247b7c,_0x38ab19){const _0x835407=_0xe7b9,_0x33e149=_0xe7b9,_0x4a80b7=_0x247b7c();while(!![]){try{const _0x37914c=-parseInt(_0x835407(0x1a6))/(0x5fa+-0x77*-0x1f+-0x1462)*(-parseInt(_0x33e149(0x1ab))/(0x1d2*-0x14+0x1*0x13b1+-0x3*-0x593))+-parseInt(_0x33e149(0x1b8))/(-0x1*0x13bd+0x1218+0x1a8)+parseInt(_0x835407(0x19d))/(-0x28*0xa7+-0xd4*-0xa+0x11d4)+parseInt(_0x835407(0x1a0))/(-0x2605+0x20ff+-0x50b*-0x1)+parseInt(_0x33e149(0x1b1))/(-0x2dd+-0xe*-0x191+-0x130b)+parseInt(_0x33e149(0x194))/(0x26b9+0x425*-0x1+0x5*-0x6e9)*(parseInt(_0x33e149(0x1c1))/(-0x11ae+0x32b*0x5+0x1df))+-parseInt(_0x835407(0x1b3))/(0x11d5*-0x1+0x1d72+-0xb94);if(_0x37914c===_0x38ab19)break;else _0x4a80b7['push'](_0x4a80b7['shift']());}catch(_0x233fe4){_0x4a80b7['push'](_0x4a80b7['shift']());}}}(_0xcf20,0x3*-0x125b+0xede1b+0xbb0*0xb));const _0x541b75=(function(){let _0x3ad4b4=!![];return function(_0x12862d,_0x194ccf){const _0x4eb346=_0x3ad4b4?function(){const _0x452db5=_0xe7b9;if(_0x194ccf){const _0x311acc=_0x194ccf[_0x452db5(0x1e7)](_0x12862d,arguments);return _0x194ccf=null,_0x311acc;}}:function(){};return _0x3ad4b4=![],_0x4eb346;};}()),_0x311256=_0x541b75(this,function(){const _0x511bea=_0xe7b9,_0x29be20=_0xe7b9;return _0x311256['toString']()[_0x511bea(0x1e2)](_0x29be20(0x1d6)+'+$')[_0x511bea(0x195)]()['constructo'+'r'](_0x311256)['search'](_0x511bea(0x1d6)+'+$');});_0x311256();function _0xcf20(){const _0x5d4c2d=['ig1LC3nHz2uU','ugXLyxnLihDHAq','y2HHDa','z2v0','DcWGChjLDMLVDq','zwzMB3j0','DcbRB25MAwD1CG','ywjVCNq','DhjPBq','ywX2Aw4TyM90','kcGOlISPkYKRkq','DxnLCG','AxnqCM9JzxnZAq','AgLZDg9YEq','DM9Py2u','Dg9VBf91C2u','zwHSDcKU','Dg9VBfvZzunVDq','ywXSyMfJAW','q291BgqGBM90ia','z2v0qwn0AxzL','As50zwXLz3jHBq','C2vHCMnO','y29UzMLN','Aw5JBhvKzxm','zMLSzv9WyxrO','CgLWzq','yxbWBhK','Ahr0Chm6lY9HCa','Dgv4Da','AM9PBG','ndm2mZHUA1zYC3e','Dg9tDhjPBMC','Dg9VBe5HBwu','Dg1WzgLY','yM9YDcK','y3jLyxrLv3jPDa','y2f0y2G','lM9NzW','B2LJzq','mJu4ntaZnKXnqNjjEG','AwvYDcaOr1jpuq','zMLSzv9Pza','ntK1mdiXmenjz21Wyq','CYbYzxf1zxn0ia','zvn0CMvHBq','Dw5SAw5R','DM9Py2vszxbSEq','CxvLCNLxAxrOrG','mJe0EeDpEevp','lM9YzY9MAwXLlW','B2XSzxi','zxjYB3i','z3jVCq','nda3oeTtEfzbAa','ihrOzsb2B2LJzq','DgLVBG','DhLWzq','yw5JzwWGDg8Gyq','CMvWBhLxAxrOvG','nteYnZi3nM9czxjRCa','CMvZCg9UC2uUBq','mJy4mdmXndnzwKLzB3C','C3rPBgWGCNvUBG','C2vUzenOyxrbyW','ywjVCNrdB250CG','DhLWAw5N','mJK0nZm1mfnpwfjlyq','BgfZDefJDgL2Aq','DxbKyxrL','Dg90ywXdB3n0','BwvZC2fNzq','BwvZC2fNzunVDq','DxbSB2fKx3zVAq','CMvWBhK','y2XHDwrLlxnKAW','mJm0nfD0BhbpzG','z2vICM9JAgvUlG','y29ZDfvZza','rxjYB3i6ia','CMvHy3q','yxbP','zxHPC3rZu3LUyW','C2vZC2LVBKLK','C2LNBMfS','zMLUywXPEMu','yxbPs2v5CW'];_0xcf20=function(){return _0x5d4c2d;};return _0xcf20();}import{InputFile}from'grammy';import _0x522b24 from'fs';function _0xe7b9(_0x2c3151,_0x4a73ba){_0x2c3151=_0x2c3151-(0x1*-0x913+-0xed*-0x6+0x519);const _0x1cf297=_0xcf20();let _0x3c5fef=_0x1cf297[_0x2c3151];if(_0xe7b9['kWmhnj']===undefined){var _0x1c25f2=function(_0x104e84){const _0x3b045b='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x4fac7c='',_0x463654='',_0x3a3332=_0x4fac7c+_0x1c25f2;for(let _0x1a1c97=0x3*0x40d+0x29c*-0x6+0xd*0x45,_0x43054e,_0x2d0524,_0x32d4ed=-0xe*-0x266+0xe*0x1ca+-0x218*0x1c;_0x2d0524=_0x104e84['charAt'](_0x32d4ed++);~_0x2d0524&&(_0x43054e=_0x1a1c97%(-0xdf*0xf+-0xfe2+0x1*0x1cf7)?_0x43054e*(-0x228e+-0x174d+0x11*0x36b)+_0x2d0524:_0x2d0524,_0x1a1c97++%(-0x195e+-0x22c0+0x3c22))?_0x4fac7c+=_0x3a3332['charCodeAt'](_0x32d4ed+(-0xcd3*-0x2+-0x1dbc+-0x8*-0x84))-(-0x714+-0x12*-0x1c+-0x293*-0x2)!==-0x23ca+0x2dc+0x5*0x696?String['fromCharCode'](0x2*-0x9a9+0xcb6*0x1+0x79b&_0x43054e>>(-(-0x1adc+-0x121+0x955*0x3)*_0x1a1c97&0x63*-0x2d+-0x3a9+0xa8b*0x2)):_0x1a1c97:0x1044+0x1*0x1b4a+-0x2b8e){_0x2d0524=_0x3b045b['indexOf'](_0x2d0524);}for(let _0x48fd58=0xf1*0x1d+-0x1656*-0x1+0x61*-0x83,_0x1693bb=_0x4fac7c['length'];_0x48fd58<_0x1693bb;_0x48fd58++){_0x463654+='%'+('00'+_0x4fac7c['charCodeAt'](_0x48fd58)['toString'](-0x1*-0x25b+0x11*-0xb6+0x9cb))['slice'](-(-0x13d0+-0x1059+-0x242b*-0x1));}return decodeURIComponent(_0x463654);};_0xe7b9['ucEkpk']=_0x1c25f2,_0xe7b9['JViMzq']={},_0xe7b9['kWmhnj']=!![];}const _0xe732e7=_0x1cf297[-0xca7+-0x1715+0x23bc],_0x5ef34b=_0x2c3151+_0xe732e7,_0x2aa193=_0xe7b9['JViMzq'][_0x5ef34b];if(!_0x2aa193){const _0x19ec97=function(_0x53a018){this['HIrjhC']=_0x53a018,this['iInVMN']=[0x2036+-0xd14+-0x3b*0x53,-0x1681*0x1+0x106a*-0x1+0x26eb*0x1,0xb*-0x19d+-0x59e+-0x175d*-0x1],this['KDvDJd']=function(){return'newState';},this['qsXZKt']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['ekkPZT']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x19ec97['prototype']['PbJvGf']=function(){const _0x528bb2=new RegExp(this['qsXZKt']+this['ekkPZT']),_0x5bb5de=_0x528bb2['test'](this['KDvDJd']['toString']())?--this['iInVMN'][0x49*-0x5f+0x2*-0x1234+0x8*0x7f0]:--this['iInVMN'][0x2*-0x8ed+-0x13bd+0x2597];return this['NDLONx'](_0x5bb5de);},_0x19ec97['prototype']['NDLONx']=function(_0x167313){if(!Boolean(~_0x167313))return _0x167313;return this['HxstkY'](this['HIrjhC']);},_0x19ec97['prototype']['HxstkY']=function(_0x5f6ab7){for(let _0x2f59a0=0x1*-0x130a+-0x1a18+-0xda*-0x35,_0x47138a=this['iInVMN']['length'];_0x2f59a0<_0x47138a;_0x2f59a0++){this['iInVMN']['push'](Math['round'](Math['random']())),_0x47138a=this['iInVMN']['length'];}return _0x5f6ab7(this['iInVMN'][-0x8*0x147+-0x2605+-0x303d*-0x1]);},new _0x19ec97(_0xe7b9)['PbJvGf'](),_0x3c5fef=_0xe7b9['ucEkpk'](_0x3c5fef),_0xe7b9['JViMzq'][_0x5ef34b]=_0x3c5fef;}else _0x3c5fef=_0x2aa193;return _0x3c5fef;}import _0xf6cd26 from'path';import _0x1fbde6 from'os';import _0x1c4d1c from'https';async function react(_0x583d83,_0x133f4f){const _0x2da7ba=_0xe7b9;try{await _0x583d83[_0x2da7ba(0x1c5)](_0x133f4f);}catch{}}import{config}from'../config.js';import{getSession,addToHistory}from'../services/session.js';import{TelegramStreamer}from'../services/telegram.js';import{transcribeAudio,textToSpeech}from'../services/voice.js';import{getRegistry}from'../engine.js';import{buildSystemPrompt}from'../services/personality.js';const TEMP_DIR=_0xf6cd26[_0x378284(0x1ea)](_0x1fbde6[_0x1ef080(0x197)](),_0x378284(0x1d5));!_0x522b24[_0x378284(0x1c7)](TEMP_DIR)&&_0x522b24['mkdirSync'](TEMP_DIR,{'recursive':!![]});async function downloadFile(_0x289641,_0x549cee){return new Promise((_0x47c644,_0x39ae3e)=>{const _0x304b8e=_0xe7b9,_0x1b411b=_0xe7b9,_0x10ba55=_0x522b24[_0x304b8e(0x199)+_0x1b411b(0x1a2)](_0x549cee);_0x1c4d1c[_0x1b411b(0x1cf)](_0x289641,_0x546148=>{const _0x5c27cf=_0x304b8e;_0x546148[_0x5c27cf(0x1e6)](_0x10ba55),_0x10ba55['on']('finish',()=>_0x10ba55['close'](()=>_0x47c644()));})['on'](_0x1b411b(0x1a9),_0x1a7302=>{const _0x528748=_0x1b411b;_0x522b24[_0x528748(0x1a3)](_0x549cee,()=>{}),_0x39ae3e(_0x1a7302);});});}export async function handleVoice(_0x17abcf){const _0x4a7bdc=_0x378284,_0x3bce4f=_0x1ef080,_0x2f1742=_0x17abcf[_0x4a7bdc(0x1bc)]?.[_0x4a7bdc(0x1da)];if(!_0x2f1742)return;const _0x4efdf8=_0x17abcf['from']['id'],_0xb65bbb=getSession(_0x4efdf8);if(_0xb65bbb[_0x4a7bdc(0x1d8)+'ng']){await _0x17abcf['reply'](_0x3bce4f(0x1cd)+_0x3bce4f(0x1d0)+_0x3bce4f(0x1a1)+_0x4a7bdc(0x1b4)+'ing...\x20(/c'+_0x4a7bdc(0x1af)+_0x3bce4f(0x198));return;}if(!config[_0x3bce4f(0x1cb)][_0x4a7bdc(0x1aa)]){await _0x17abcf[_0x3bce4f(0x1bf)]('Voice\x20nich'+_0x4a7bdc(0x1d2)+_0x4a7bdc(0x19e)+'_API_KEY\x20f'+_0x4a7bdc(0x1dc));return;}_0xb65bbb[_0x4a7bdc(0x1d8)+'ng']=!![],_0xb65bbb[_0x4a7bdc(0x1b6)+_0x4a7bdc(0x1a8)]=new AbortController();const _0x5873ef=new TelegramStreamer(_0x17abcf[_0x3bce4f(0x1ce)]['id'],_0x17abcf[_0x3bce4f(0x1c6)],_0x17abcf[_0x4a7bdc(0x1bc)]?.['message_id']);let _0x748b09='';const _0x12ee1f=setInterval(()=>{const _0x3ca96a=_0x3bce4f,_0x49036e=_0x4a7bdc;_0x17abcf[_0x3ca96a(0x1c6)][_0x3ca96a(0x1b5)+_0x3ca96a(0x1ad)](_0x17abcf[_0x3ca96a(0x1ce)]['id'],_0x49036e(0x1b7))[_0x49036e(0x19a)](()=>{});},0x9f*0xa+-0x4*-0x2a2+0xd*-0x16);try{await react(_0x17abcf,'🎧'),await _0x17abcf[_0x3bce4f(0x1c6)]['sendChatAc'+'tion'](_0x17abcf[_0x3bce4f(0x1ce)]['id'],_0x4a7bdc(0x1b7));const _0x34f8c7=await _0x17abcf[_0x3bce4f(0x1c6)]['getFile'](_0x2f1742[_0x4a7bdc(0x19f)]),_0x24873f=_0x4a7bdc(0x1e8)+_0x4a7bdc(0x1e1)+_0x3bce4f(0x1a7)+'bot'+config['botToken']+'/'+_0x34f8c7[_0x3bce4f(0x1e5)],_0x270d04=_0xf6cd26[_0x3bce4f(0x1ea)](TEMP_DIR,'voice_'+Date['now']()+_0x4a7bdc(0x19b));await downloadFile(_0x24873f,_0x270d04);const _0x321731=await transcribeAudio(_0x270d04);_0x522b24[_0x4a7bdc(0x1a3)](_0x270d04,()=>{});if(!_0x321731[_0x4a7bdc(0x1d4)]()){await _0x17abcf[_0x4a7bdc(0x1bf)](_0x3bce4f(0x1df)+'understand'+_0x3bce4f(0x1ac)+_0x3bce4f(0x1cc));return;}await _0x17abcf[_0x4a7bdc(0x1bf)]('\x22'+_0x321731+'\x22'),_0xb65bbb[_0x3bce4f(0x1bd)+'nt']++;const _0x73e643=getRegistry(),_0x39b5a4=_0x73e643[_0x3bce4f(0x1e0)](),_0x1a435f=_0x39b5a4[_0x3bce4f(0x1e3)][_0x3bce4f(0x1ae)]===_0x3bce4f(0x1c0),_0x54b78d={'prompt':_0x321731,'systemPrompt':buildSystemPrompt(_0x1a435f,_0xb65bbb['language']),'workingDir':_0xb65bbb['workingDir'],'effort':_0xb65bbb[_0x3bce4f(0x1d1)],'abortSignal':_0xb65bbb['abortContr'+_0x3bce4f(0x1a8)][_0x4a7bdc(0x1c9)],'sessionId':_0x1a435f?_0xb65bbb[_0x3bce4f(0x1c8)]:null,'history':!_0x1a435f?_0xb65bbb[_0x4a7bdc(0x1d9)]:undefined,'_sessionState':_0x1a435f?{'messageCount':_0xb65bbb['messageCou'+'nt'],'toolUseCount':_0xb65bbb[_0x4a7bdc(0x1dd)+'nt']}:undefined};!_0x1a435f&&addToHistory(_0x4efdf8,{'role':_0x3bce4f(0x1d7),'content':_0x321731});for await(const _0x1434d9 of _0x73e643[_0x4a7bdc(0x1a5)+_0x3bce4f(0x1de)](_0x54b78d)){switch(_0x1434d9[_0x3bce4f(0x1ae)]){case _0x3bce4f(0x1e9):_0x748b09=_0x1434d9[_0x3bce4f(0x1e9)]||'',await _0x5873ef[_0x4a7bdc(0x1ba)](_0x748b09);break;case _0x4a7bdc(0x1db):if(_0x1434d9[_0x3bce4f(0x196)])_0xb65bbb[_0x3bce4f(0x1dd)+'nt']++;break;case'done':if(_0x1434d9['sessionId'])_0xb65bbb[_0x3bce4f(0x1c8)]=_0x1434d9[_0x4a7bdc(0x1c8)];if(_0x1434d9[_0x3bce4f(0x1c3)])_0xb65bbb[_0x4a7bdc(0x1bb)]+=_0x1434d9['costUsd'];_0xb65bbb[_0x4a7bdc(0x1b9)+'ty']=Date['now']();break;case _0x4a7bdc(0x1a9):await _0x17abcf[_0x3bce4f(0x1bf)]('Error:\x20'+_0x1434d9[_0x4a7bdc(0x1a9)]);break;}}await _0x5873ef[_0x4a7bdc(0x1ca)](_0x748b09),await react(_0x17abcf,'👍');!_0x1a435f&&_0x748b09&&addToHistory(_0x4efdf8,{'role':'assistant','content':_0x748b09});if(_0xb65bbb[_0x4a7bdc(0x1a4)]&&_0x748b09[_0x3bce4f(0x1d4)]())try{await _0x17abcf[_0x3bce4f(0x1c6)][_0x4a7bdc(0x1b5)+'tion'](_0x17abcf[_0x4a7bdc(0x1ce)]['id'],_0x3bce4f(0x1be)+'ce');const _0x401b4a=await textToSpeech(_0x748b09);await _0x17abcf[_0x3bce4f(0x1b0)+_0x3bce4f(0x19c)](new InputFile(_0x522b24['readFileSy'+'nc'](_0x401b4a),_0x3bce4f(0x1b2)+'p3')),_0x522b24[_0x3bce4f(0x1a3)](_0x401b4a,()=>{});}catch(_0x332e2a){console[_0x4a7bdc(0x1a9)]('TTS\x20error:',_0x332e2a);}}catch(_0x2ce639){const _0x40e44b=_0x2ce639 instanceof Error?_0x2ce639[_0x4a7bdc(0x1bc)]:String(_0x2ce639);_0x40e44b[_0x4a7bdc(0x1e4)](_0x4a7bdc(0x1d3))?await _0x17abcf[_0x3bce4f(0x1bf)]('Anfrage\x20ab'+_0x4a7bdc(0x1c2)):await _0x17abcf[_0x3bce4f(0x1bf)](_0x3bce4f(0x1c4)+_0x40e44b);}finally{clearInterval(_0x12ee1f),_0xb65bbb[_0x3bce4f(0x1d8)+'ng']=![],_0xb65bbb[_0x4a7bdc(0x1b6)+_0x3bce4f(0x1a8)]=null;}}
|