beast-agent 2.3.4 → 2.4.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/package.json +1 -1
- package/src/agent/perception.js +616 -0
- package/src/main.js +223 -0
- package/src/preload.js +6 -0
- package/src/renderer/i18n.js +100 -12
- package/src/renderer/index.html +2 -0
- package/src/renderer/renderer.js +214 -26
package/src/main.js
CHANGED
|
@@ -2937,6 +2937,7 @@ function reloadBackend() {
|
|
|
2937
2937
|
},
|
|
2938
2938
|
emit: (ev) => {
|
|
2939
2939
|
if (win && !win.isDestroyed()) win.webContents.send('agent:event', ev);
|
|
2940
|
+
try { empatiRememberFromEvent(ev); } catch {} /* empati hafızası: sohbet → kayıt + ilgi öğrenme */
|
|
2940
2941
|
flushDesktopOnDone(ev); /* biriken desktop mesajlarını sıraya bas */
|
|
2941
2942
|
bcFlushOnDone(ev); /* Beast Code kuyruğunu iş bitiminde boşalt */
|
|
2942
2943
|
stFlushOnDone(ev); /* Beast Studio kuyruğunu iş bitiminde boşalt */
|
|
@@ -3256,6 +3257,7 @@ app.whenReady().then(() => {
|
|
|
3256
3257
|
createTray();
|
|
3257
3258
|
cron.init({ onFire: cronFire });
|
|
3258
3259
|
watchers.start({ onTrigger: watcherFire });
|
|
3260
|
+
empatiKickoff(); // empati loop: açılış + 90 sn sonra ilk tarama, sonra cfg aralığı
|
|
3259
3261
|
startEventBus();
|
|
3260
3262
|
ideWatchStart(); // soldaki dosya ağacı canlı izlemede
|
|
3261
3263
|
studioWatchStart(); // Beast Studio klasörü canlı izlemede
|
|
@@ -6187,6 +6189,227 @@ function watcherFire(w, value) {
|
|
|
6187
6189
|
} catch {}
|
|
6188
6190
|
}
|
|
6189
6191
|
|
|
6192
|
+
/* ---------- EMPATİ LOOP: proaktif algı/event alt sistemi ----------
|
|
6193
|
+
Ana sohbet motorundan bağımsız: sinyal topla → ucuz filtre modeliyle puanla →
|
|
6194
|
+
kompozit öncelik → değerliyse ANA modelle kısa proaktif mesaj üret →
|
|
6195
|
+
masaüstü + WA'ya bildir. Önemsiz olaylar yalnız depoya yazılır, rahatsız etmez. */
|
|
6196
|
+
|
|
6197
|
+
const empati = require('./agent/perception');
|
|
6198
|
+
const empatiRuntime = { running: false, timer: null };
|
|
6199
|
+
|
|
6200
|
+
function empatiCfg() {
|
|
6201
|
+
return empati.mergeCfg(settings.empati || {});
|
|
6202
|
+
}
|
|
6203
|
+
|
|
6204
|
+
/* EMPATİ HAFIZASI: sohbet akışını kaydet + kullanıcı ilgi alanlarını öğren.
|
|
6205
|
+
- user mesajı → hafızaya yaz + sık kelimelerden ilgi etiketi öğren
|
|
6206
|
+
- assistant cevabı → hafızaya yaz (konuşmanın iki yanı da kalsın)
|
|
6207
|
+
Beast Code/Studio iş mesajları, /komutlar ve bağlam enjeksiyonları kayda girmez. */
|
|
6208
|
+
function empatiRememberFromEvent(ev) {
|
|
6209
|
+
if (!ev || ev.type !== 'message' || !ev.message || !ev.message.role) return;
|
|
6210
|
+
const m = ev.message;
|
|
6211
|
+
if (m.role !== 'user' && m.role !== 'assistant') return;
|
|
6212
|
+
const txt = typeof m.content === 'string' ? m.content : '';
|
|
6213
|
+
if (!txt.trim()) return;
|
|
6214
|
+
if (txt.startsWith((engine && engine.OBSERVE_MARK) || '[BAĞLAM')) return; /* sessiz bağlam — sohbet değil */
|
|
6215
|
+
if (m.role === 'user' && txt.startsWith('/')) return; /* slash komut gürültüsü */
|
|
6216
|
+
let bc = false;
|
|
6217
|
+
try {
|
|
6218
|
+
const s = engine && engine.cache && engine.cache.get(String(ev.sessionId || ''));
|
|
6219
|
+
bc = !!(s && (s.bcCode || s.bcMode));
|
|
6220
|
+
} catch {}
|
|
6221
|
+
if (bc) return; /* kod işi — ilgi alanını bulanıklaştırır */
|
|
6222
|
+
if (m.role === 'user') {
|
|
6223
|
+
empati.rememberConversation(txt, 'sohbet');
|
|
6224
|
+
empati.learnInterests(txt);
|
|
6225
|
+
} else {
|
|
6226
|
+
empati.rememberConversation(txt, 'beast');
|
|
6227
|
+
}
|
|
6228
|
+
}
|
|
6229
|
+
|
|
6230
|
+
function empatiLog(line) {
|
|
6231
|
+
try { waLog('[EMPATİ] ' + line); } catch {}
|
|
6232
|
+
}
|
|
6233
|
+
|
|
6234
|
+
/* tarama (filtre) modeli: sekmeden seçilmişse onu çöz; seçilmemişse ANA model */
|
|
6235
|
+
function empatiFilterSel() {
|
|
6236
|
+
const fm = empatiCfg().filterModel;
|
|
6237
|
+
if (fm) {
|
|
6238
|
+
try {
|
|
6239
|
+
const r = engine._resolve(fm);
|
|
6240
|
+
if (r) return r;
|
|
6241
|
+
} catch {}
|
|
6242
|
+
}
|
|
6243
|
+
return engine.sel;
|
|
6244
|
+
}
|
|
6245
|
+
|
|
6246
|
+
/* sinyal toplayıcılar — perception modülü saf kalır, engine/köprülerle burada konuşur */
|
|
6247
|
+
async function empatiSignalSelf() {
|
|
6248
|
+
const out = [];
|
|
6249
|
+
try {
|
|
6250
|
+
const w = engine.lastWhereWasI();
|
|
6251
|
+
if (w && w.pendingTodos && w.pendingTodos.length) {
|
|
6252
|
+
out.push({
|
|
6253
|
+
type: 'todo',
|
|
6254
|
+
title: 'Yarım kalan görevler: ' + w.pendingTodos.map((t) => t.title).join(' · ').slice(0, 200),
|
|
6255
|
+
detail: 'oturum ' + (w.code || '') + ' · ' + w.pendingTodos.length + ' görev bekliyor',
|
|
6256
|
+
});
|
|
6257
|
+
}
|
|
6258
|
+
} catch {}
|
|
6259
|
+
return out;
|
|
6260
|
+
}
|
|
6261
|
+
|
|
6262
|
+
async function empatiSignalNews() {
|
|
6263
|
+
const topics = String(empatiCfg().newsTopics || '').split(',').map((s) => s.trim()).filter(Boolean);
|
|
6264
|
+
if (!topics.length) return [];
|
|
6265
|
+
return empati.fetchNews(topics);
|
|
6266
|
+
}
|
|
6267
|
+
|
|
6268
|
+
/* tek toplu filtre çağrısı (maliyet freni); model yok/çökerse boş → deterministik puan */
|
|
6269
|
+
function empatiLlmFilter(prompt) {
|
|
6270
|
+
const sel = empatiFilterSel();
|
|
6271
|
+
if (!sel) return Promise.resolve('');
|
|
6272
|
+
const ctrl = new AbortController();
|
|
6273
|
+
const kill = setTimeout(() => ctrl.abort(), 45000);
|
|
6274
|
+
return require('./agent/llm')
|
|
6275
|
+
.chatOnce(sel, {
|
|
6276
|
+
messages: [
|
|
6277
|
+
{ role: 'system', content: empati.FILTER_SYSTEM },
|
|
6278
|
+
{ role: 'user', content: prompt },
|
|
6279
|
+
],
|
|
6280
|
+
temperature: 0.1,
|
|
6281
|
+
}, { signal: ctrl.signal })
|
|
6282
|
+
.then((r) => String(r.content || ''))
|
|
6283
|
+
.catch(() => '')
|
|
6284
|
+
.finally(() => clearTimeout(kill));
|
|
6285
|
+
}
|
|
6286
|
+
|
|
6287
|
+
/* compose her zaman ANA model kullanır — filtre ucuz, anlamlandırma güçlü */
|
|
6288
|
+
function empatiLlmCompose(prompt) {
|
|
6289
|
+
if (!engine.sel) return Promise.resolve('');
|
|
6290
|
+
const ctrl = new AbortController();
|
|
6291
|
+
const kill = setTimeout(() => ctrl.abort(), 60000);
|
|
6292
|
+
return require('./agent/llm')
|
|
6293
|
+
.chatOnce(engine.sel, {
|
|
6294
|
+
messages: [
|
|
6295
|
+
{ role: 'system', content: empati.COMPOSE_SYSTEM },
|
|
6296
|
+
{ role: 'user', content: prompt },
|
|
6297
|
+
],
|
|
6298
|
+
temperature: 0.6,
|
|
6299
|
+
}, { signal: ctrl.signal })
|
|
6300
|
+
.then((r) => String(r.content || '').trim().slice(0, 600))
|
|
6301
|
+
.catch(() => '')
|
|
6302
|
+
.finally(() => clearTimeout(kill));
|
|
6303
|
+
}
|
|
6304
|
+
|
|
6305
|
+
/* bildirim hedefi: sekmeden seçilen entegrasyon; seçilmemişse bağlı olanlar.
|
|
6306
|
+
Hiçbir entegrasyon yazılamazsa masaüstü chat UI (toast) kalır. */
|
|
6307
|
+
function empatiNotify(text, ev) {
|
|
6308
|
+
const cfg = empatiCfg();
|
|
6309
|
+
const senders = [];
|
|
6310
|
+
const tryWa = () => {
|
|
6311
|
+
try {
|
|
6312
|
+
const own = waOwnerNum();
|
|
6313
|
+
if (own && wa && wa.connected) senders.push(() => sendWaSafe(own + '@s.whatsapp.net', '🫡 *Beast proaktif:*\n' + text));
|
|
6314
|
+
} catch {}
|
|
6315
|
+
};
|
|
6316
|
+
const tryTg = () => {
|
|
6317
|
+
try {
|
|
6318
|
+
if (tg && tg.connected) for (const id of tgOwnerIds()) senders.push(() => sendTgSafe(id, '🫡 *Beast proaktif:*\n' + text));
|
|
6319
|
+
} catch {}
|
|
6320
|
+
};
|
|
6321
|
+
const tryDc = () => {
|
|
6322
|
+
try {
|
|
6323
|
+
if (dc && dc.connected) for (const id of dcOwnerIds()) senders.push(() => sendDcSafe(id, '🫡 **Beast proaktif:**\n' + text));
|
|
6324
|
+
} catch {}
|
|
6325
|
+
};
|
|
6326
|
+
if (cfg.notifyTarget === 'whatsapp') tryWa();
|
|
6327
|
+
else if (cfg.notifyTarget === 'telegram') tryTg();
|
|
6328
|
+
else if (cfg.notifyTarget === 'discord') tryDc();
|
|
6329
|
+
else { tryWa(); tryTg(); tryDc(); } // auto: ekli/bağlı entegrasyonlar
|
|
6330
|
+
let sent = 0;
|
|
6331
|
+
for (const fn of senders) {
|
|
6332
|
+
try { fn(); sent++; } catch {}
|
|
6333
|
+
}
|
|
6334
|
+
/* hiçbir entegrasyona yazılamadıysa yalnız masaüstü chat UI'a düş */
|
|
6335
|
+
try {
|
|
6336
|
+
if (!sent && win && !win.isDestroyed()) {
|
|
6337
|
+
win.webContents.send('agent:event', { type: 'proactive', id: ev.id, level: ev.level, title: ev.title, text });
|
|
6338
|
+
}
|
|
6339
|
+
} catch {}
|
|
6340
|
+
}
|
|
6341
|
+
|
|
6342
|
+
async function empatiCycle(manual) {
|
|
6343
|
+
if (empatiRuntime.running) return { ok: false, error: 'döngü zaten çalışıyor' };
|
|
6344
|
+
const cfg = empatiCfg();
|
|
6345
|
+
if (!cfg.enabled && !manual) return { ok: false, error: 'kapalı' };
|
|
6346
|
+
empatiRuntime.running = true;
|
|
6347
|
+
try {
|
|
6348
|
+
/* zaman aşımı emniyeti: sinyal/LLM takılırsa `running` bayrağı sonsuz kilitlenmesin
|
|
6349
|
+
(yoksa "Şimdi Tara" sürekli 'döngü zaten çalışıyor' der) */
|
|
6350
|
+
const r = await Promise.race([
|
|
6351
|
+
empati.runCycle({
|
|
6352
|
+
cfg,
|
|
6353
|
+
signals: { self: empatiSignalSelf, news: empatiSignalNews },
|
|
6354
|
+
llmFilter: empatiLlmFilter,
|
|
6355
|
+
now: new Date(),
|
|
6356
|
+
log: empatiLog,
|
|
6357
|
+
}),
|
|
6358
|
+
new Promise((_, rej) => setTimeout(() => rej(new Error('döngü zaman aşımı (2 dk)')), 120000).unref()),
|
|
6359
|
+
]);
|
|
6360
|
+
let notified = 0;
|
|
6361
|
+
for (const a of r.actions) {
|
|
6362
|
+
let text = '';
|
|
6363
|
+
try { text = await empatiLlmCompose(empati.composePrompt(a.event, cfg)); } catch {}
|
|
6364
|
+
if (!text) text = empati.composeFallback(a.event);
|
|
6365
|
+
empatiNotify(text, a.event);
|
|
6366
|
+
empati.markNotified(a.event.id, a.level, text, cfg.cooldownMin);
|
|
6367
|
+
try { empati.rememberConversation('[proaktif] ' + text, 'empati'); } catch {}
|
|
6368
|
+
notified++;
|
|
6369
|
+
}
|
|
6370
|
+
if (notified && win && !win.isDestroyed()) {
|
|
6371
|
+
win.webContents.send('agent:event', { type: 'empati', notified });
|
|
6372
|
+
}
|
|
6373
|
+
return { ok: true, ...r.summary, notified };
|
|
6374
|
+
} finally {
|
|
6375
|
+
empatiRuntime.running = false;
|
|
6376
|
+
}
|
|
6377
|
+
}
|
|
6378
|
+
|
|
6379
|
+
function empatiSchedule() {
|
|
6380
|
+
if (empatiRuntime.timer) clearTimeout(empatiRuntime.timer);
|
|
6381
|
+
empatiRuntime.timer = null;
|
|
6382
|
+
const cfg = empatiCfg();
|
|
6383
|
+
if (!cfg.enabled) return;
|
|
6384
|
+
empatiRuntime.timer = setTimeout(async () => {
|
|
6385
|
+
try { await empatiCycle(false); } catch {}
|
|
6386
|
+
empatiSchedule();
|
|
6387
|
+
}, cfg.intervalMin * 60000);
|
|
6388
|
+
}
|
|
6389
|
+
|
|
6390
|
+
/* açılış + 90 sn: ilk tarama (başlangıç fırtınasını önle), sonra cfg aralığı */
|
|
6391
|
+
function empatiKickoff() {
|
|
6392
|
+
setTimeout(() => {
|
|
6393
|
+
empatiCycle(false).catch(() => {});
|
|
6394
|
+
empatiSchedule();
|
|
6395
|
+
}, 90 * 1000);
|
|
6396
|
+
}
|
|
6397
|
+
|
|
6398
|
+
ipcMain.handle('empati:get', () => ({ ...empatiCfg(), running: empatiRuntime.running, lastRunAt: empati.lastRunAt() }));
|
|
6399
|
+
ipcMain.handle('empati:set', (_e, patch) => {
|
|
6400
|
+
const cfg = empati.mergeCfg({ ...empatiCfg(), ...(patch || {}) });
|
|
6401
|
+
settings.empati = cfg;
|
|
6402
|
+
saveSettings();
|
|
6403
|
+
empatiSchedule(); // aralık/model değişmiş olabilir
|
|
6404
|
+
return { ...cfg };
|
|
6405
|
+
});
|
|
6406
|
+
ipcMain.handle('empati:scan', async () => {
|
|
6407
|
+
try { return await empatiCycle(true); } catch (e) { return { ok: false, error: String((e && e.message) || e).slice(0, 200) }; }
|
|
6408
|
+
});
|
|
6409
|
+
ipcMain.handle('empati:events', () => empati.listEvents(80));
|
|
6410
|
+
ipcMain.handle('empati:memory', () => empati.memSnapshot(40));
|
|
6411
|
+
ipcMain.handle('empati:memclear', () => empati.memClear());
|
|
6412
|
+
|
|
6190
6413
|
ipcMain.handle('cron:list', () => cron.list());
|
|
6191
6414
|
/* #23 Fallout: provider → kayıtlı API key haritası.
|
|
6192
6415
|
Birincil kaynak: engine chain (config+custom+env çözülmüş).
|
package/src/preload.js
CHANGED
|
@@ -207,4 +207,10 @@ contextBridge.exposeInMainWorld('beast', {
|
|
|
207
207
|
ideDelete: (rel) => ipcRenderer.invoke('ide:delete', rel),
|
|
208
208
|
onWaEvent: (cb) => ipcRenderer.on('wa:event', (_e, ev) => cb(ev)),
|
|
209
209
|
onEvent: (cb) => ipcRenderer.on('agent:event', (_e, ev) => cb(ev)),
|
|
210
|
+
empatiGet: () => ipcRenderer.invoke('empati:get'),
|
|
211
|
+
empatiSet: (patch) => ipcRenderer.invoke('empati:set', patch),
|
|
212
|
+
empatiScan: () => ipcRenderer.invoke('empati:scan'),
|
|
213
|
+
empatiEvents: () => ipcRenderer.invoke('empati:events'),
|
|
214
|
+
empatiMemory: () => ipcRenderer.invoke('empati:memory'),
|
|
215
|
+
empatiMemClear: () => ipcRenderer.invoke('empati:memclear'),
|
|
210
216
|
});
|
package/src/renderer/i18n.js
CHANGED
|
@@ -114,6 +114,50 @@
|
|
|
114
114
|
up_install_now: 'Yeniden Başlat & Kur',
|
|
115
115
|
up_note: 'Kurulumdan sonra uygulama otomatik yeniden başlar. İstersen WhatsApp\u2019tan /update komutunu da kullanabilirsin.',
|
|
116
116
|
tab_events: 'Olay Merkezi',
|
|
117
|
+
tab_empati: 'Empati Loop',
|
|
118
|
+
em_h2: 'Empati Loop — Proaktif Algı',
|
|
119
|
+
em_sub: 'Beast arka planda periyodik tarar: yarım kalan işler, haber akışı. Boru hattı: sinyal → ucuz filtre modeli → öncelik puanı → bildirim. Önemsiz olaylar yalnız depoya yazılır, seni rahatsız etmez.',
|
|
120
|
+
em_ipc_err: 'Empati servisine ulaşılamadı.',
|
|
121
|
+
em_on: 'Empati Loop açık',
|
|
122
|
+
em_interval: 'Tarama aralığı (dk)',
|
|
123
|
+
em_min_notify: 'Bildirim eşiği (puan)',
|
|
124
|
+
em_cooldown: 'Konu sessizliği (dk)',
|
|
125
|
+
em_model: 'Tarama (filtre) modeli',
|
|
126
|
+
em_model_main: 'Ana model (seçili)',
|
|
127
|
+
em_model_sub: 'Seçmezsen tarama ana modelle yapılır. Anlamlandırma (mesaj yazımı) her zaman ana modelle.',
|
|
128
|
+
em_notify: 'Bildirim hedefi',
|
|
129
|
+
em_notify_auto: 'Otomatik — bağlı entegrasyonlar',
|
|
130
|
+
em_notify_wa: 'WhatsApp',
|
|
131
|
+
em_notify_tg: 'Telegram',
|
|
132
|
+
em_notify_dc: 'Discord',
|
|
133
|
+
em_notify_sub: 'Seçmezsen ekli ve bağlı entegrasyonların hepsine yazar; hiçbiri bağlı değilse masaüstü sohbete düşer.',
|
|
134
|
+
em_interests: 'İlgi alanların — haber filtresi buna göre ağırlıklandırılır',
|
|
135
|
+
em_interests_ph: 'örn: yapay zeka, yazılım, trading, open source',
|
|
136
|
+
em_news: 'Haber kaynağı (Google News)',
|
|
137
|
+
em_news_topics_ph: 'haber konuları, virgülle: yapay zeka, ekonomi…',
|
|
138
|
+
em_scan: 'Şimdi Tara',
|
|
139
|
+
em_scan_ok: 'Tarama: {raw} sinyal · {queued} bildirim · {stored} depo',
|
|
140
|
+
em_events: 'Son olaylar',
|
|
141
|
+
em_no_events: 'Henüz olay yok — Şimdi Tara ile deneyebilirsin.',
|
|
142
|
+
em_saved: 'Empati ayarları kaydedildi',
|
|
143
|
+
em_lastrun: 'Son tarama',
|
|
144
|
+
em_note: 'İzleyiciler (watchers) kendi bildirimlerini zaten yapıyor; Empati Loop onları tekrar bildirmez. Filtre modeli tek toplu çağrıyla çalışır; model yoksa puanlama deterministik yapılır.',
|
|
145
|
+
em_st_notified: 'bildirildi',
|
|
146
|
+
em_st_queued: 'kuyrukta',
|
|
147
|
+
em_st_stored: 'depo',
|
|
148
|
+
em_st_ignored: 'yok sayıldı',
|
|
149
|
+
em_lv_high: 'YÜKSEK',
|
|
150
|
+
em_lv_medium: 'ORTA',
|
|
151
|
+
em_interests_auto: 'Bunlara ek olarak sohbetlerinden öğrenilen ilgi alanları da otomatik devreye girer.',
|
|
152
|
+
em_scan_busy: 'Tarama hâlâ çalışıyor — birkaç saniye sonra tekrar dene.',
|
|
153
|
+
em_mem_h2: 'Empati Hafızası',
|
|
154
|
+
em_mem_sub: 'Konuşmalarınız burada birikir; sohbetlerinden ilgi alanların öğrenilir. Tarama ve bildirim mesajları bu hafızayla sana göre kişiselleşir.',
|
|
155
|
+
em_mem_learned: 'Sohbetlerden öğrenilen ilgi alanları',
|
|
156
|
+
em_mem_no_learned: 'Henüz öğrenilen ilgi yok — sohbet ettikçe burada birikir.',
|
|
157
|
+
em_mem_recent: 'Son konuşma kayıtları',
|
|
158
|
+
em_mem_no_recent: 'Henüz kayıt yok.',
|
|
159
|
+
em_mem_clear: 'Hafızayı Temizle',
|
|
160
|
+
em_mem_cleared: 'Empati hafızası temizlendi',
|
|
117
161
|
tab_cron: 'Cron',
|
|
118
162
|
tab_usage: 'Maliyet · Limit',
|
|
119
163
|
tab_logs: 'Log',
|
|
@@ -153,7 +197,6 @@
|
|
|
153
197
|
btn_close: 'Kapat',
|
|
154
198
|
tip_win_min: 'Simge durumunda küçült',
|
|
155
199
|
tip_win_max: 'Pencereyi büyüt/küçült',
|
|
156
|
-
em_pass_masked: 'Mevcut şifre korunuyor — değiştirmek için yeniden gir',
|
|
157
200
|
p_h2: 'Provider',
|
|
158
201
|
p_sub: 'Beast config.yaml\u2019dan gelen modeller — aktif olanı seç',
|
|
159
202
|
p_del_title: 'Modeli listeden sil',
|
|
@@ -223,11 +266,12 @@
|
|
|
223
266
|
tts_chat_auto: 'Chat\'te ajanın yazdıklarını otomatik seslendir',
|
|
224
267
|
tts_on: 'TTS açık — cevaplar sesli de gider',
|
|
225
268
|
tts_off: 'TTS kapalı',
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
269
|
+
mail_h2: 'E-posta (Gmail)',
|
|
270
|
+
mail_sub: 'IMAP/SMTP — Gmail hesabında "Uygulama Şifresi" oluşturup buraya gir. Agent mailleri okur, özetler ve senin adına gönderir.',
|
|
271
|
+
mail_save: 'E-posta Kaydet',
|
|
272
|
+
mail_note: 'Kaydettikten sonra agent\u2019a "gelen mailleri özetle", "X\u2019e mail at" gibi komutlar verebilirsin.',
|
|
273
|
+
mail_saved: 'E-posta kaydedildi — agent artık maillere erişebilir',
|
|
274
|
+
mail_pass_masked: 'Mevcut şifre korunuyor — değiştirmek için yeniden gir',
|
|
231
275
|
it_h2: 'Entegrasyonlar',
|
|
232
276
|
it_sub: 'Mesajlaşma köprüleri — gelen mesajlar Beast\u2019e gider, cevap geri döner',
|
|
233
277
|
it_wa_sub: 'Özel mesajlar · gruplar (@mention ile) · slash komutları (/help)',
|
|
@@ -691,6 +735,50 @@
|
|
|
691
735
|
up_install_now: 'Restart & Install',
|
|
692
736
|
up_note: 'The app restarts itself after installing. You can also use the /update command from WhatsApp.',
|
|
693
737
|
tab_events: 'Event Center',
|
|
738
|
+
tab_empati: 'Empathy Loop',
|
|
739
|
+
em_h2: 'Empathy Loop — Proactive Perception',
|
|
740
|
+
em_sub: 'Beast scans periodically in the background: half-done work, news flow. Pipeline: signal → cheap filter model → priority score → notification. Unimportant events are only stored, they never bother you.',
|
|
741
|
+
em_ipc_err: 'Could not reach the empathy service.',
|
|
742
|
+
em_on: 'Empathy Loop enabled',
|
|
743
|
+
em_interval: 'Scan interval (min)',
|
|
744
|
+
em_min_notify: 'Notify threshold (score)',
|
|
745
|
+
em_cooldown: 'Topic silence (min)',
|
|
746
|
+
em_model: 'Scan (filter) model',
|
|
747
|
+
em_model_main: 'Main model (selected)',
|
|
748
|
+
em_model_sub: 'If left empty, scanning uses the main model. Composing the message always uses the main model.',
|
|
749
|
+
em_notify: 'Notification target',
|
|
750
|
+
em_notify_auto: 'Auto — connected integrations',
|
|
751
|
+
em_notify_wa: 'WhatsApp',
|
|
752
|
+
em_notify_tg: 'Telegram',
|
|
753
|
+
em_notify_dc: 'Discord',
|
|
754
|
+
em_notify_sub: 'If left empty, it writes to all connected integrations; with none connected it lands in the desktop chat.',
|
|
755
|
+
em_interests: 'Your interests — news filtering is weighted by these',
|
|
756
|
+
em_interests_ph: 'e.g. AI, software, trading, open source',
|
|
757
|
+
em_news: 'News source (Google News)',
|
|
758
|
+
em_news_topics_ph: 'news topics, comma separated: AI, economy…',
|
|
759
|
+
em_scan: 'Scan Now',
|
|
760
|
+
em_scan_ok: 'Scan: {raw} signals · {queued} notify · {stored} stored',
|
|
761
|
+
em_events: 'Recent events',
|
|
762
|
+
em_no_events: 'No events yet — try Scan Now.',
|
|
763
|
+
em_saved: 'Empathy settings saved',
|
|
764
|
+
em_lastrun: 'Last scan',
|
|
765
|
+
em_note: 'Watchers already notify on their own; the Empathy Loop does not repeat them. The filter model runs in a single batched call; without a model, scoring is deterministic.',
|
|
766
|
+
em_st_notified: 'notified',
|
|
767
|
+
em_st_queued: 'queued',
|
|
768
|
+
em_st_stored: 'stored',
|
|
769
|
+
em_st_ignored: 'ignored',
|
|
770
|
+
em_lv_high: 'HIGH',
|
|
771
|
+
em_lv_medium: 'MEDIUM',
|
|
772
|
+
em_interests_auto: 'On top of these, interest areas learned from your chats kick in automatically.',
|
|
773
|
+
em_scan_busy: 'A scan is still running — try again in a few seconds.',
|
|
774
|
+
em_mem_h2: 'Empathy Memory',
|
|
775
|
+
em_mem_sub: 'Your conversations accumulate here; interest areas are learned from your chats. Scans and notification texts are personalized with this memory.',
|
|
776
|
+
em_mem_learned: 'Interest areas learned from chats',
|
|
777
|
+
em_mem_no_learned: 'No learned interests yet — they accumulate as you chat.',
|
|
778
|
+
em_mem_recent: 'Recent conversation records',
|
|
779
|
+
em_mem_no_recent: 'No records yet.',
|
|
780
|
+
em_mem_clear: 'Clear Memory',
|
|
781
|
+
em_mem_cleared: 'Empathy memory cleared',
|
|
694
782
|
tab_cron: 'Cron',
|
|
695
783
|
tab_usage: 'Cost · Limit',
|
|
696
784
|
tab_logs: 'Logs',
|
|
@@ -730,7 +818,6 @@
|
|
|
730
818
|
btn_close: 'Close',
|
|
731
819
|
tip_win_min: 'Minimize',
|
|
732
820
|
tip_win_max: 'Maximize/Restore',
|
|
733
|
-
em_pass_masked: 'Current password kept — type a new one to change it',
|
|
734
821
|
p_h2: 'Provider',
|
|
735
822
|
p_sub: 'Models from Beast config.yaml — pick the active one',
|
|
736
823
|
p_del_title: 'Remove model from list',
|
|
@@ -800,11 +887,12 @@
|
|
|
800
887
|
tts_chat_auto: 'Auto-speak agent replies in chat',
|
|
801
888
|
tts_on: 'TTS on — replies also go as voice',
|
|
802
889
|
tts_off: 'TTS off',
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
890
|
+
mail_h2: 'E-mail (Gmail)',
|
|
891
|
+
mail_sub: 'IMAP/SMTP — create an "App Password" in your Gmail account and enter it here. The agent reads, summarizes and sends mail on your behalf.',
|
|
892
|
+
mail_save: 'Save E-mail',
|
|
893
|
+
mail_note: 'After saving you can give the agent commands like "summarize incoming mail", "send mail to X".',
|
|
894
|
+
mail_saved: 'E-mail saved — the agent can now access mail',
|
|
895
|
+
mail_pass_masked: 'Current password kept — type a new one to change it',
|
|
808
896
|
it_h2: 'Integrations',
|
|
809
897
|
it_sub: 'Messaging bridges — incoming messages go to Beast, replies come back',
|
|
810
898
|
it_wa_sub: 'Private messages · groups (@mention) · slash commands (/help)',
|
package/src/renderer/index.html
CHANGED
|
@@ -239,6 +239,7 @@
|
|
|
239
239
|
<button class="tab" data-tab="websearch" data-i18n="tab_websearch">Web Arama</button>
|
|
240
240
|
<button class="tab" data-tab="mcp" data-i18n="tab_mcp">MCP</button>
|
|
241
241
|
<button class="tab" data-tab="events" data-i18n="tab_events">Olay Merkezi</button>
|
|
242
|
+
<button class="tab" data-tab="empati" data-i18n="tab_empati">Empati Loop</button>
|
|
242
243
|
<button class="tab" data-tab="cron" data-i18n="tab_cron">Cron</button>
|
|
243
244
|
<button class="tab" data-tab="usage" data-i18n="tab_usage">Maliyet · Limit</button>
|
|
244
245
|
<button class="tab" data-tab="logs" data-i18n="tab_logs">Log</button>
|
|
@@ -264,6 +265,7 @@
|
|
|
264
265
|
<div id="tab-websearch" class="pane" hidden></div>
|
|
265
266
|
<div id="tab-mcp" class="pane" hidden></div>
|
|
266
267
|
<div id="tab-events" class="pane" hidden></div>
|
|
268
|
+
<div id="tab-empati" class="pane" hidden></div>
|
|
267
269
|
<div id="tab-usage" class="pane" hidden></div>
|
|
268
270
|
<div id="tab-logs" class="pane" hidden></div>
|
|
269
271
|
<div id="tab-dash" class="pane" hidden></div>
|