beast-agent 2.44.7 → 2.44.9
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/package.json +1 -1
- package/src/agent/computeruse.js +200 -837
- package/src/agent/engine.js +8 -25
- package/src/agent/watext.js +1 -1
- package/src/cron.js +14 -4
- package/src/main.js +100 -79
- package/src/preload.js +0 -1
- package/src/renderer/renderer.js +0 -5
package/src/agent/engine.js
CHANGED
|
@@ -2006,7 +2006,7 @@ class Engine {
|
|
|
2006
2006
|
'- mt5_ea action:"note": grafiğe kısa plan metni + yatay seviye çizgileri yazar (destek/direnç/SL/TP) — sonra tool__mt5_shot ile çekip seviyelerin doğru yerde olduğunu GÖRSEL doğrula.\n' +
|
|
2007
2007
|
'- computer_look: tüm masaüstü ekranı (MT5 dışı pencereler dahil); browser_screenshot: web grafikleri (TradingView/Investing) — browser_open ile aç.\n' +
|
|
2008
2008
|
'- Görsel göremiyorsan (metin-model) ocr_read (source:"screen"/"browser") ile grafikteki fiyat/seviyeleri metne çevir.\n' +
|
|
2009
|
-
'- Grafikte gezinme/ölçek: computer_act ile timeframe, scroll, zoom (
|
|
2009
|
+
'- Grafikte gezinme/ölçek: computer_act ile timeframe, scroll, zoom (yerel fare/klavye sürer — imleci oynatır; kısa tut).\n' +
|
|
2010
2010
|
'- EKİPLE GÖRSEL PAYLAŞIM: chart PNG\'sini agent_dm image:true (son görüntün) ya da image:"<dosya yolu>" (ör. tool__mt5_shot dönen path) ile trader/ekibe gönder — karşı ajan görüntüyü GERÇEKTEN görür, AJAN DM panelinde açılır. Ortak kararlarda grafiği paylaşmak zorunlu disiplindir.\n' +
|
|
2011
2011
|
'- PARALEL EKİP AKIŞI: teknik ajan seviyeleri hesaplar → mt5_ea note ile grafiğe çizer; görsel ajan tool__mt5_shot ile çekip TEYİT eder ve agent_dm ile görseli trader\'a atar; risk ajanı aynı görsel üzerinden SL/TP yerleşimini denetler; trader kararı işleme çevirir. Aynı sembolde koşan ajanlar tek DM grubunda (agent_dm group) toplanır — çelişen hareket etme.\n' +
|
|
2012
2012
|
'- EKSİK ARAÇ: özel grafik aracı gerekiyorsa (ör. çoklu timeframe tek görüntü, indikatör paneli okuma) VAR SAYMA — tool_request ile TOOL botuna yazdır (asenkron çalışır; rapor sohbete düşer, araç doğrulanınca tool__<ad> olarak ANINDA çağrılır); küçük aracı skill("tool-yazma") prosedürüyle kendin de yazabilirsin.\n' +
|
|
@@ -6412,36 +6412,19 @@ const TOOLS = [
|
|
|
6412
6412
|
function: {
|
|
6413
6413
|
name: 'computer_act',
|
|
6414
6414
|
description:
|
|
6415
|
-
'
|
|
6415
|
+
'Control mouse/keyboard on the user\u2019s Windows desktop (GUI automation). Ops: click{x,y}, dblclick{x,y}, rightclick{x,y}, move{x,y}, type{text}, key{combo e.g. "ctrl+s","enter","alt+tab"}, scroll{x,y,dy}. Look first with computer_look, act step by step, look again after acting.',
|
|
6416
6416
|
parameters: {
|
|
6417
6417
|
type: 'object',
|
|
6418
6418
|
properties: {
|
|
6419
6419
|
op: {
|
|
6420
6420
|
type: 'string',
|
|
6421
|
-
enum: ['
|
|
6422
|
-
description: 'capture first (som/vision/ax); click/type/etc act by element or window-local pixel; wait pauses; list_apps enumerates windows; focus_app selects input target (raise_window=true steals focus \u2014 only on explicit request); move = legacy real-cursor move',
|
|
6421
|
+
enum: ['click', 'dblclick', 'rightclick', 'move', 'type', 'key', 'scroll'],
|
|
6423
6422
|
},
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
text: { type: 'string', description: 'for op=type (max 2000 chars); NEVER type passwords or secrets' },
|
|
6430
|
-
keys: { type: 'string', description: 'for op=key: "enter", "ctrl+s", "alt+tab"' },
|
|
6431
|
-
direction: { type: 'string', enum: ['up', 'down', 'left', 'right'], description: 'for op=scroll' },
|
|
6432
|
-
amount: { type: 'number', description: 'for op=scroll: wheel notches 1..50 (default 3)' },
|
|
6433
|
-
from_element: { type: 'number', description: 'for op=drag' },
|
|
6434
|
-
to_element: { type: 'number', description: 'for op=drag' },
|
|
6435
|
-
from_x: { type: 'number', description: 'for op=drag (window-local pixels)' },
|
|
6436
|
-
from_y: { type: 'number', description: 'for op=drag (window-local pixels)' },
|
|
6437
|
-
to_x: { type: 'number', description: 'for op=drag (window-local pixels)' },
|
|
6438
|
-
to_y: { type: 'number', description: 'for op=drag (window-local pixels)' },
|
|
6439
|
-
seconds: { type: 'number', description: 'for op=wait (max 30)' },
|
|
6440
|
-
mode: { type: 'string', enum: ['som', 'vision', 'ax'], description: 'for op=capture: som = screenshot + numbered elements (default), vision = screenshot only, ax = element tree only' },
|
|
6441
|
-
capture_after: { type: 'boolean', description: 're-capture the target right after this action (verify in the same call)' },
|
|
6442
|
-
delivery_mode: { type: 'string', enum: ['background', 'foreground'], description: 'background (default) never raises the window; foreground is the last-resort rung \u2014 use ONLY after effect:"suspected_noop" or background_unavailable' },
|
|
6443
|
-
dy: { type: 'number', description: 'legacy scroll fallback: positive = down (-10..10)' },
|
|
6444
|
-
combo: { type: 'string', description: 'legacy alias for keys' },
|
|
6423
|
+
x: { type: 'number' },
|
|
6424
|
+
y: { type: 'number' },
|
|
6425
|
+
text: { type: 'string', description: 'for op=type (max 2000 chars)' },
|
|
6426
|
+
combo: { type: 'string', description: 'for op=key: "enter", "ctrl+s", "alt+tab", "win"' },
|
|
6427
|
+
dy: { type: 'number', description: 'for op=scroll: positive = down (-10..10)' },
|
|
6445
6428
|
},
|
|
6446
6429
|
required: ['op'],
|
|
6447
6430
|
},
|
package/src/agent/watext.js
CHANGED
|
@@ -70,7 +70,7 @@ const TOOL_LABELS = {
|
|
|
70
70
|
kb_search: (a) => `Bilgi ara: ${String(a.query || '').slice(0, 60)}`,
|
|
71
71
|
memory_hygiene: () => 'Hafıza temizliği',
|
|
72
72
|
computer_look: () => 'Ekranı görüntülüyor',
|
|
73
|
-
computer_act: (a) => `Bilgisayar kullanıyor: ${a.op || ''}${a.
|
|
73
|
+
computer_act: (a) => `Bilgisayar kullanıyor: ${a.op || ''}${a.combo ? ' ' + a.combo : ''}`,
|
|
74
74
|
};
|
|
75
75
|
|
|
76
76
|
function waToolLine(name, args) {
|
package/src/cron.js
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
/* Beast cron: zamanlanmış görevler (%APPDATA%\beast\cron.json).
|
|
4
4
|
5 alanlı cron ifadeleri: dakika saat ayGunu ay haftaGunu
|
|
5
|
-
Desteklenen sözdizimi: * , - / sayılar. Saat geldiğinde onFire tetiklenir.
|
|
5
|
+
Desteklenen sözdizimi: * , - / sayılar. Saat geldiğinde onFire tetiklenir.
|
|
6
|
+
DİKKAT: görevler OTURUMA BAĞLI DEĞİLDİR — sessionId/oturum kodu tutulmaz;
|
|
7
|
+
çalıştırma ve teslimat her kanalın TEK oturumu üzerinden yapılır (main). */
|
|
6
8
|
|
|
7
9
|
const fs = require('fs');
|
|
8
10
|
const path = require('path');
|
|
@@ -24,6 +26,14 @@ function load() {
|
|
|
24
26
|
try {
|
|
25
27
|
const raw = JSON.parse(fs.readFileSync(file(), 'utf8'));
|
|
26
28
|
jobs = Array.isArray(raw.jobs) ? raw.jobs : [];
|
|
29
|
+
/* ESKİ KAYIT GÖÇÜ: görevler artık oturuma bağlı değil — eski sessionId
|
|
30
|
+
(ve varsa oturum kodu) diskte kalırsa görev yanlışlıkla bir oturuma
|
|
31
|
+
çakılı sanılır; yükleme sırasında temizlenir. */
|
|
32
|
+
for (const j of jobs) {
|
|
33
|
+
if (!j || typeof j !== 'object') continue;
|
|
34
|
+
delete j.sessionId;
|
|
35
|
+
delete j.sessionCode;
|
|
36
|
+
}
|
|
27
37
|
} catch {
|
|
28
38
|
jobs = [];
|
|
29
39
|
}
|
|
@@ -136,7 +146,7 @@ function list() {
|
|
|
136
146
|
return jobs.map((j) => ({ ...j }));
|
|
137
147
|
}
|
|
138
148
|
|
|
139
|
-
function add({ name, schedule, prompt, once,
|
|
149
|
+
function add({ name, schedule, prompt, once, kind }) {
|
|
140
150
|
const n = String(name || '').trim().slice(0, 80) || 'Görev';
|
|
141
151
|
const s = String(schedule || '').trim();
|
|
142
152
|
const p = String(prompt || '').trim().slice(0, 4000);
|
|
@@ -148,7 +158,6 @@ function add({ name, schedule, prompt, once, sessionId, kind }) {
|
|
|
148
158
|
name: n,
|
|
149
159
|
schedule: s,
|
|
150
160
|
prompt: p,
|
|
151
|
-
sessionId: sessionId || null,
|
|
152
161
|
once: !!once,
|
|
153
162
|
enabled: true,
|
|
154
163
|
...(k ? { kind: k } : {}),
|
|
@@ -164,7 +173,8 @@ function add({ name, schedule, prompt, once, sessionId, kind }) {
|
|
|
164
173
|
function update(id, patch) {
|
|
165
174
|
const job = jobs.find((j) => j.id === id);
|
|
166
175
|
if (!job) return { ok: false, error: 'görev bulunamadı' };
|
|
167
|
-
|
|
176
|
+
delete job.sessionId;
|
|
177
|
+
delete job.sessionCode;
|
|
168
178
|
if (patch.name !== undefined) job.name = String(patch.name).trim().slice(0, 80) || job.name;
|
|
169
179
|
if (patch.prompt !== undefined) {
|
|
170
180
|
const p = String(patch.prompt).trim().slice(0, 4000);
|
package/src/main.js
CHANGED
|
@@ -1944,7 +1944,8 @@ function ensureWaSession(jid) {
|
|
|
1944
1944
|
waChats.set(String(jid), waSingleSid);
|
|
1945
1945
|
dirty = true;
|
|
1946
1946
|
}
|
|
1947
|
-
|
|
1947
|
+
/* jid'siz çağrı (cron taban oturumu) sohbet geçmişini kirletmez */
|
|
1948
|
+
if (jid != null) waRememberSession(String(jid), waSingleSid);
|
|
1948
1949
|
if (dirty) {
|
|
1949
1950
|
saveWaChats();
|
|
1950
1951
|
if (wa) wa.setWatchJids([...waChats.keys()]);
|
|
@@ -2194,7 +2195,6 @@ function scheduleReminder({ when, message, sessionId, repeat }) {
|
|
|
2194
2195
|
schedule: s.schedule,
|
|
2195
2196
|
prompt: `[TEKRARLI HATIRLATMA] Kullanıcıya şunu hatırlat: "${msg}". Kısaca ve nazikçe bildir.`,
|
|
2196
2197
|
kind: 'reminder',
|
|
2197
|
-
sessionId: sessionId || undefined,
|
|
2198
2198
|
});
|
|
2199
2199
|
if (!r.ok) return r;
|
|
2200
2200
|
waLog(`tekrarlı hatırlatma kuruldu id=${r.job.id} schedule=${s.schedule} sid=${sessionId || '-'}`);
|
|
@@ -2210,7 +2210,6 @@ function scheduleReminder({ when, message, sessionId, repeat }) {
|
|
|
2210
2210
|
prompt: `[HATIRLATMA ZAMANI] Kullanıcıya şunu hatırlat: "${msg}". Kısaca ve nazikçe bildir.`,
|
|
2211
2211
|
kind: 'reminder',
|
|
2212
2212
|
once: true,
|
|
2213
|
-
sessionId: sessionId || undefined,
|
|
2214
2213
|
});
|
|
2215
2214
|
if (!r.ok) return r;
|
|
2216
2215
|
waLog(`reminder kuruldu id=${r.job.id} at=${d.toISOString()} sid=${sessionId || '-'}`);
|
|
@@ -3357,8 +3356,14 @@ function reloadBackend() {
|
|
|
3357
3356
|
});
|
|
3358
3357
|
} catch {}
|
|
3359
3358
|
}
|
|
3359
|
+
/* CRON CEVABI AYRIMI: bu done/error cron işine aitse bekleme kaydını
|
|
3360
|
+
BURADA düş. Cron cevabı normal kanal akışından DEĞİL, aşağıdaki tek
|
|
3361
|
+
noktadan TÜM bağlı entegrasyonlara (WA base + TG + DC) yansıtılır —
|
|
3362
|
+
böylece ham cevap + önekli cevap çift gönderimi olmaz. */
|
|
3363
|
+
const cjob =
|
|
3364
|
+
ev.type === 'done' || ev.type === 'error' ? cronAnswerPendingTake(ev.sessionId) : null;
|
|
3360
3365
|
// WhatsApp oturumlarının son cevabını geri gönder (metin + opsiyonel ses)
|
|
3361
|
-
if ((ev.type === 'done' || ev.type === 'error') && wa && wa.connected) {
|
|
3366
|
+
if ((ev.type === 'done' || ev.type === 'error') && !cjob && wa && wa.connected) {
|
|
3362
3367
|
const wajid = waReplyJid(ev.sessionId);
|
|
3363
3368
|
if (wajid) {
|
|
3364
3369
|
(async () => {
|
|
@@ -3417,7 +3422,7 @@ function reloadBackend() {
|
|
|
3417
3422
|
}
|
|
3418
3423
|
}
|
|
3419
3424
|
// Telegram oturumlarının son cevabını geri gönder (WA ile aynı akış)
|
|
3420
|
-
if ((ev.type === 'done' || ev.type === 'error') && tg && tg.connected) {
|
|
3425
|
+
if ((ev.type === 'done' || ev.type === 'error') && !cjob && tg && tg.connected) {
|
|
3421
3426
|
const hitT = [...tgChats.entries()].find(([, s]) => s === ev.sessionId);
|
|
3422
3427
|
if (hitT) {
|
|
3423
3428
|
const tgid = hitT[0];
|
|
@@ -3438,7 +3443,7 @@ function reloadBackend() {
|
|
|
3438
3443
|
}
|
|
3439
3444
|
}
|
|
3440
3445
|
// Discord oturumlarının son cevabını geri gönder (TG ile aynı akış)
|
|
3441
|
-
if ((ev.type === 'done' || ev.type === 'error') && dc && dc.connected) {
|
|
3446
|
+
if ((ev.type === 'done' || ev.type === 'error') && !cjob && dc && dc.connected) {
|
|
3442
3447
|
const hitD = [...dcChats.entries()].find(([, s]) => s === ev.sessionId);
|
|
3443
3448
|
if (hitD) {
|
|
3444
3449
|
const dchid = hitD[0];
|
|
@@ -3458,34 +3463,32 @@ function reloadBackend() {
|
|
|
3458
3463
|
})();
|
|
3459
3464
|
}
|
|
3460
3465
|
}
|
|
3461
|
-
/* CRON → TÜM
|
|
3462
|
-
hata)
|
|
3463
|
-
|
|
3464
|
-
Bayat (TTL aşımı)
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
})();
|
|
3485
|
-
}
|
|
3466
|
+
/* CRON → TÜM BAĞLI ENTEGRASYONLAR: cron işi bittiğinde cevap (ya da
|
|
3467
|
+
hata) WhatsApp (base) + Telegram + Discord'un hepsine yansıtılır.
|
|
3468
|
+
Yansıtma yalnız cron oturumunun KENDİ kanalına yapılmaz (orası ham
|
|
3469
|
+
cevabı normal akıştan alır). Bayat (TTL aşımı) kayıt Take ile
|
|
3470
|
+
düşer, yansıtılmaz. */
|
|
3471
|
+
if (cjob && !ev.aborted) {
|
|
3472
|
+
(async () => {
|
|
3473
|
+
try {
|
|
3474
|
+
let txt = '';
|
|
3475
|
+
if (ev.type === 'error') {
|
|
3476
|
+
txt = '⚠️ [cron: ' + String((cjob && cjob.name) || 'görev') + ']\nHata: ' + String(ev.error || '').slice(0, 200);
|
|
3477
|
+
} else {
|
|
3478
|
+
const s = engine.openSession(ev.sessionId);
|
|
3479
|
+
const lastA = [...s.messages].reverse().find((m) => m.role === 'assistant' && m.content);
|
|
3480
|
+
txt = typeof (lastA && lastA.content) === 'string' ? lastA.content : '';
|
|
3481
|
+
if (txt.trim()) txt = '⏰ [cron: ' + String((cjob && cjob.name) || 'görev') + ']\n' + txt;
|
|
3482
|
+
}
|
|
3483
|
+
if (!txt.trim()) return;
|
|
3484
|
+
for (const m of cronMirrorTargets(String(ev.sessionId))) {
|
|
3485
|
+
try { await m.send(txt); } catch {}
|
|
3486
|
+
}
|
|
3487
|
+
} catch {}
|
|
3488
|
+
})();
|
|
3486
3489
|
}
|
|
3487
3490
|
},
|
|
3488
|
-
});
|
|
3491
|
+
});
|
|
3489
3492
|
/* PANEL RUN köprüsü: ajanın panel_run aracı → ÇALIŞTIR panelindeki yönetilen
|
|
3490
3493
|
süreç koşucusu (sandbox:run IPC ile aynı makine). */
|
|
3491
3494
|
engine.sbRunHook = sbRunStartManaged;
|
|
@@ -6782,33 +6785,12 @@ ipcMain.handle('install:status', async () => {
|
|
|
6782
6785
|
rows.push({ id: 'python', name: 'Python — betikler / web arama', state: pyVer ? 'ok' : 'optional', detail: pyVer ? 'v' + pyVer : 'sistemde bulunamadı — opsiyonel' });
|
|
6783
6786
|
}
|
|
6784
6787
|
|
|
6785
|
-
/* 7)
|
|
6786
|
-
{
|
|
6787
|
-
const st = await require('./agent/computeruse').probe().catch(() => ({ installed: false }));
|
|
6788
|
-
rows.push({
|
|
6789
|
-
id: 'cua-driver',
|
|
6790
|
-
name: 'cua-driver — Computer Use (masaüstü otomasyonu)',
|
|
6791
|
-
state: st.installed ? 'ok' : (st.installing ? 'loading' : (st.failed ? 'failed' : 'missing')),
|
|
6792
|
-
detail: st.installed
|
|
6793
|
-
? (st.version ? 'kurulu — ' + st.version : 'kurulu')
|
|
6794
|
-
: st.installing
|
|
6795
|
-
? 'cua.ai sürücüsü arka planda kuruluyor'
|
|
6796
|
-
: (st.failed
|
|
6797
|
-
? 'kurulum başarısız — elle: irm https://cua.ai/driver/install.ps1 | iex'
|
|
6798
|
-
: 'ilk Computer Use kullanımında arka planda kurulur'),
|
|
6799
|
-
...(st.installing ? pctFields('cua-driver') : {}),
|
|
6800
|
-
});
|
|
6801
|
-
}
|
|
6802
|
-
|
|
6803
|
-
/* 8) Edge TTS (bulut) */
|
|
6788
|
+
/* 7) Edge TTS (bulut) */
|
|
6804
6789
|
rows.push({ id: 'edge', name: 'Edge TTS — seslendirme', state: 'cloud', detail: 'bulut — kurulum gerekmez' });
|
|
6805
6790
|
|
|
6806
6791
|
return rows;
|
|
6807
6792
|
});
|
|
6808
6793
|
|
|
6809
|
-
/* cua-driver kurulumunu şimdi başlat (Kurulum sekmesi otomatiği + elle tetikleme) */
|
|
6810
|
-
ipcMain.handle('cua:install', () => require('./agent/computeruse').autoInstall());
|
|
6811
|
-
|
|
6812
6794
|
/* SQUEEZE (kendi token sıkıştırıcımız): aç/kapa + durum + istatistik */
|
|
6813
6795
|
ipcMain.handle('squeeze:toggle', (_e, on) => {
|
|
6814
6796
|
settings.squeeze = { ...(settings.squeeze || {}), enabled: !!on };
|
|
@@ -6943,7 +6925,7 @@ function cronAnswerPendingTake(sid) {
|
|
|
6943
6925
|
return job;
|
|
6944
6926
|
}
|
|
6945
6927
|
|
|
6946
|
-
/* OTOMATİK YENİ SOHBET YOK:
|
|
6928
|
+
/* OTOMATİK YENİ SOHBET YOK: izleyici/fallout tetiklendiğinde oturum
|
|
6947
6929
|
seçimi — kayıtlı id'nin DOSYASI hâlâ duruyorsa O, değilse EN GÜNCEL
|
|
6948
6930
|
(meşgul olmayan) oturum kullanılır; hiç oturum yoksa (ilk kurulum) yeni
|
|
6949
6931
|
açılır. Böylece soldaki sohbet geçmişine "+ Yeni Sohbet" olmadan hayalet
|
|
@@ -6951,7 +6933,7 @@ function cronAnswerPendingTake(sid) {
|
|
|
6951
6933
|
DİKKAT: _load(id) silinmiş oturum için bile boş bir hayalet nesne
|
|
6952
6934
|
üretip truthy döner — canlılık kontrolü MUTLAKA sessionFileAlive ile
|
|
6953
6935
|
yapılır (ensureWa/Tg/DcSession ile aynı kural). Ayrıca meşgul oturuma
|
|
6954
|
-
send() mesajı DÜŞÜRÜR (false döner,
|
|
6936
|
+
send() mesajı DÜŞÜRÜR (false döner, cevap kaybolur) — o yüzden
|
|
6955
6937
|
meşgul oturumlar da atlanır. */
|
|
6956
6938
|
function reuseOrLatestSession(preferredId) {
|
|
6957
6939
|
const sid = String(preferredId || '');
|
|
@@ -6969,9 +6951,38 @@ function reuseOrLatestSession(preferredId) {
|
|
|
6969
6951
|
return engine.createSession().id;
|
|
6970
6952
|
}
|
|
6971
6953
|
|
|
6972
|
-
/*
|
|
6973
|
-
|
|
6974
|
-
|
|
6954
|
+
/* CRON TABAN OTURUMU: cron işleri hiçbir oturuma/sessionId'ye BAĞLI DEĞİL.
|
|
6955
|
+
Her kanalın TEK oturumu vardır — taban sırası: bağlı WhatsApp → bağlı
|
|
6956
|
+
Telegram → bağlı Discord → en güncel masaüstü oturumu. WhatsApp
|
|
6957
|
+
kullanılmayan kurulumlarda cron altyapısı Telegram/Discord üzerinden
|
|
6958
|
+
yaşar; hiçbiri yoksa masaüstü sohbete düşer. */
|
|
6959
|
+
function cronBaseSession() {
|
|
6960
|
+
try {
|
|
6961
|
+
if (wa && wa.connected) {
|
|
6962
|
+
if (waSingleSid && sessionFileAlive(waSingleSid)) return waSingleSid;
|
|
6963
|
+
return ensureWaSession();
|
|
6964
|
+
}
|
|
6965
|
+
} catch {}
|
|
6966
|
+
try {
|
|
6967
|
+
if (tg && tg.connected) {
|
|
6968
|
+
if (tgSingleSid && sessionFileAlive(tgSingleSid)) return tgSingleSid;
|
|
6969
|
+
return ensureTgSession();
|
|
6970
|
+
}
|
|
6971
|
+
} catch {}
|
|
6972
|
+
try {
|
|
6973
|
+
if (dc && dc.connected) {
|
|
6974
|
+
if (dcSingleSid && sessionFileAlive(dcSingleSid)) return dcSingleSid;
|
|
6975
|
+
return ensureDcSession();
|
|
6976
|
+
}
|
|
6977
|
+
} catch {}
|
|
6978
|
+
return reuseOrLatestSession('');
|
|
6979
|
+
}
|
|
6980
|
+
|
|
6981
|
+
/* Yansıtma hedefleri: cron cevabı BAĞLI TÜM entegrasyonlara dağıtılır —
|
|
6982
|
+
WhatsApp (base) + Telegram + Discord. Her kanalın TEK oturumu vardır;
|
|
6983
|
+
hedef önce o oturuma bağlı sohbet, yoksa kayıtlı sahip/sahipleridir.
|
|
6984
|
+
Cron oturumunun KENDİ kanalına yansıtılmaz — cevabı zaten kendi normal
|
|
6985
|
+
akışından alır (çift gönderim olmaz). */
|
|
6975
6986
|
function tgOwnerIds() {
|
|
6976
6987
|
const list = settings.tgAllow || [];
|
|
6977
6988
|
const objs = list.filter((e) => e && typeof e === 'object' && e.id && e.id !== '*');
|
|
@@ -6985,30 +6996,39 @@ function dcOwnerIds() {
|
|
|
6985
6996
|
return owner ? [String(owner.id)] : [];
|
|
6986
6997
|
}
|
|
6987
6998
|
function cronMirrorTargets(cronSid) {
|
|
6999
|
+
const sid = String(cronSid || '');
|
|
6988
7000
|
const out = [];
|
|
7001
|
+
/* WHATSAPP (base): normal akış cron oturumuna bağlı sohbete gönderir;
|
|
7002
|
+
bağlı sohbet yoksa (normal akış gönderemez) base sohbet/sahip numarası
|
|
7003
|
+
hedeflenir — cevap kaybolmaz. */
|
|
6989
7004
|
try {
|
|
6990
|
-
if (wa && wa.connected) {
|
|
7005
|
+
if (wa && wa.connected && !waReplyJid(sid)) {
|
|
6991
7006
|
const own = waOwnerNum();
|
|
6992
|
-
|
|
6993
|
-
|
|
6994
|
-
const bound = [...waChats.entries()].some(([j, s]) => j === jid && String(s) === String(cronSid));
|
|
6995
|
-
if (!bound) out.push({ kind: 'wa', send: (t) => sendWaSafe(jid, t) });
|
|
6996
|
-
}
|
|
7007
|
+
const jid = waReplyJid(waSingleSid) || (own ? own + '@s.whatsapp.net' : '');
|
|
7008
|
+
if (jid) out.push({ kind: 'wa', send: (t) => sendWaSafe(jid, t) });
|
|
6997
7009
|
}
|
|
6998
7010
|
} catch {}
|
|
7011
|
+
/* TELEGRAM: normal akış cron oturumuna bağlı sohbete gönderir; o yoksa
|
|
7012
|
+
kanalın tek oturumuna bağlı sohbet(ler), yoksa sahip kaydı hedeflenir */
|
|
6999
7013
|
try {
|
|
7000
|
-
if (tg && tg.connected) {
|
|
7001
|
-
|
|
7002
|
-
|
|
7003
|
-
|
|
7014
|
+
if (tg && tg.connected && ![...tgChats.values()].some((s) => String(s) === sid)) {
|
|
7015
|
+
const bound = [...tgChats.entries()]
|
|
7016
|
+
.filter(([, s]) => String(s) === String(tgSingleSid))
|
|
7017
|
+
.map(([c]) => c);
|
|
7018
|
+
for (const id of (bound.length ? bound : tgOwnerIds())) {
|
|
7019
|
+
out.push({ kind: 'tg', send: (t) => sendTgSafe(id, t) });
|
|
7004
7020
|
}
|
|
7005
7021
|
}
|
|
7006
7022
|
} catch {}
|
|
7023
|
+
/* DISCORD: normal akış cron oturumuna bağlı kanala gönderir; o yoksa
|
|
7024
|
+
kanalın tek oturumuna bağlı kanal(lar), yoksa sahip kaydı hedeflenir */
|
|
7007
7025
|
try {
|
|
7008
|
-
if (dc && dc.connected) {
|
|
7009
|
-
|
|
7010
|
-
|
|
7011
|
-
|
|
7026
|
+
if (dc && dc.connected && ![...dcChats.values()].some((s) => String(s) === sid)) {
|
|
7027
|
+
const bound = [...dcChats.entries()]
|
|
7028
|
+
.filter(([, s]) => String(s) === String(dcSingleSid))
|
|
7029
|
+
.map(([c]) => c);
|
|
7030
|
+
for (const id of (bound.length ? bound : dcOwnerIds())) {
|
|
7031
|
+
out.push({ kind: 'dc', send: (t) => sendDcSafe(id, t) });
|
|
7012
7032
|
}
|
|
7013
7033
|
}
|
|
7014
7034
|
} catch {}
|
|
@@ -7023,10 +7043,9 @@ function cronFire(job) {
|
|
|
7023
7043
|
return;
|
|
7024
7044
|
}
|
|
7025
7045
|
try {
|
|
7026
|
-
|
|
7027
|
-
|
|
7028
|
-
|
|
7029
|
-
}
|
|
7046
|
+
/* OTURUMSUZ ÇALIŞTIRMA: taban oturum WA → TG → DC → masaüstü sırasıyla
|
|
7047
|
+
seçilir; cevap done olayında TÜM bağlı entegrasyonlara yansıtılır. */
|
|
7048
|
+
const sid = cronBaseSession();
|
|
7030
7049
|
cronAnswerPendingSet(sid, job);
|
|
7031
7050
|
const sent = engine.send(sid, {
|
|
7032
7051
|
text: `[cron: ${job.name}]\n${job.prompt}`,
|
|
@@ -7328,7 +7347,8 @@ function ensureTgSession(chatId) {
|
|
|
7328
7347
|
tgChats.set(String(chatId), tgSingleSid);
|
|
7329
7348
|
dirty = true;
|
|
7330
7349
|
}
|
|
7331
|
-
|
|
7350
|
+
/* id'siz çağrı (cron taban oturumu) sohbet geçmişini kirletmez */
|
|
7351
|
+
if (chatId != null) tgRememberSession(String(chatId), tgSingleSid);
|
|
7332
7352
|
if (dirty) saveTgChats();
|
|
7333
7353
|
return tgSingleSid;
|
|
7334
7354
|
}
|
|
@@ -7362,7 +7382,8 @@ function ensureDcSession(channelId) {
|
|
|
7362
7382
|
dcChats.set(String(channelId), dcSingleSid);
|
|
7363
7383
|
dirty = true;
|
|
7364
7384
|
}
|
|
7365
|
-
|
|
7385
|
+
/* id'siz çağrı (cron taban oturumu) sohbet geçmişini kirletmez */
|
|
7386
|
+
if (channelId != null) dcRememberSession(String(channelId), dcSingleSid);
|
|
7366
7387
|
if (dirty) saveDcChats();
|
|
7367
7388
|
return dcSingleSid;
|
|
7368
7389
|
}
|
package/src/preload.js
CHANGED
|
@@ -65,7 +65,6 @@ contextBridge.exposeInMainWorld('beast', {
|
|
|
65
65
|
sttStatus: () => ipcRenderer.invoke('stt:status'),
|
|
66
66
|
sttPrefetchNow: () => ipcRenderer.invoke('stt:prefetch'),
|
|
67
67
|
installStatus: () => ipcRenderer.invoke('install:status'),
|
|
68
|
-
cuaInstall: () => ipcRenderer.invoke('cua:install'),
|
|
69
68
|
embedPrefetch: () => ipcRenderer.invoke('embed:prefetch'),
|
|
70
69
|
sttLangSet: (lang) => ipcRenderer.invoke('stt:lang:set', lang),
|
|
71
70
|
updateStatus: () => ipcRenderer.invoke('update:status'),
|
package/src/renderer/renderer.js
CHANGED
|
@@ -2472,7 +2472,6 @@ async function renderInstallPane() {
|
|
|
2472
2472
|
loading: ['İNİYOR…', '#d9a441'],
|
|
2473
2473
|
partial: ['İNİYOR… (devam)', '#d9a441'],
|
|
2474
2474
|
missing: ['İNDİRİLİYOR…', '#d9a441'],
|
|
2475
|
-
failed: ['HATA', '#c0554d'],
|
|
2476
2475
|
cloud: ['BULUT', 'var(--muted)'],
|
|
2477
2476
|
optional: ['OPSİYONEL', 'var(--muted)'],
|
|
2478
2477
|
};
|
|
@@ -2492,10 +2491,6 @@ async function renderInstallPane() {
|
|
|
2492
2491
|
autoStarted.add('emb');
|
|
2493
2492
|
beast.embedPrefetch().catch(() => {});
|
|
2494
2493
|
}
|
|
2495
|
-
if (r.id === 'cua-driver' && r.state === 'missing') {
|
|
2496
|
-
autoStarted.add('cua-driver');
|
|
2497
|
-
beast.cuaInstall().catch(() => {});
|
|
2498
|
-
}
|
|
2499
2494
|
}
|
|
2500
2495
|
};
|
|
2501
2496
|
|