beast-agent 2.4.1 → 2.4.5
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/engine.js +41 -5
- package/src/main.js +80 -4
package/package.json
CHANGED
package/src/agent/engine.js
CHANGED
|
@@ -987,9 +987,11 @@ class Engine {
|
|
|
987
987
|
if (session.code) this._codeIndex.set(session.code, session.id);
|
|
988
988
|
}
|
|
989
989
|
|
|
990
|
-
/* Oturum dosyasındaki son 'msg' satırını
|
|
991
|
-
yanıtsız kalmış user mesajıyla yeni mesaj birleştirildiğinde
|
|
992
|
-
|
|
990
|
+
/* Oturum dosyasındaki son 'msg' satırını güncel içerikle değiştir —
|
|
991
|
+
yanıtsız kalmış user mesajıyla yeni mesaj birleştirildiğinde (role:'user')
|
|
992
|
+
ya da proaktif not son asistan mesajına birleştirildiğinde (role:'assistant') */
|
|
993
|
+
_rewriteLastMsg(id, content, attachments, role) {
|
|
994
|
+
const wantRole = role === 'assistant' ? 'assistant' : 'user';
|
|
993
995
|
try {
|
|
994
996
|
const file = this._file(String(id));
|
|
995
997
|
const lines = fs.readFileSync(file, 'utf8').split('\n');
|
|
@@ -997,8 +999,8 @@ class Engine {
|
|
|
997
999
|
if (!lines[i].trim()) continue;
|
|
998
1000
|
let r;
|
|
999
1001
|
try { r = JSON.parse(lines[i]); } catch { continue; }
|
|
1000
|
-
if (r.t === 'msg' && r.role ===
|
|
1001
|
-
const out = { t: 'msg', role:
|
|
1002
|
+
if (r.t === 'msg' && r.role === wantRole) {
|
|
1003
|
+
const out = { t: 'msg', role: wantRole, content: String(content || '') };
|
|
1002
1004
|
if (Array.isArray(attachments) && attachments.length) out.attachments = attachments;
|
|
1003
1005
|
lines[i] = JSON.stringify(out);
|
|
1004
1006
|
break;
|
|
@@ -2284,6 +2286,40 @@ class Engine {
|
|
|
2284
2286
|
return true;
|
|
2285
2287
|
}
|
|
2286
2288
|
|
|
2289
|
+
/* PROAKTİF MESAJ ENJEKSİYONU (Empati Loop): ajanın az önce KULLANICIYA
|
|
2290
|
+
bildirdiği metni, yeni bir tur BAŞLATMADAN geçmişe kendi asistan
|
|
2291
|
+
mesajı olarak işler. Model bir sonraki turda bu mesajı bağlamında
|
|
2292
|
+
"benim söylediğim söz" olarak görür — kullanıcı cevap verdiğinde
|
|
2293
|
+
sohbet aynı oturumda kopmadan devam eder. Son mesaj araçsız bir
|
|
2294
|
+
asistan mesajıysa metin ona BİRLEŞTİRİLİR — katı sağlayıcılarda
|
|
2295
|
+
art arda asistan mesajı gitmez. */
|
|
2296
|
+
injectAssistant(sessionId, text) {
|
|
2297
|
+
const s = this._load(String(sessionId));
|
|
2298
|
+
if (!s) return false;
|
|
2299
|
+
const body = String(text || '').slice(0, USER_MAX);
|
|
2300
|
+
if (!body.trim()) return false;
|
|
2301
|
+
const lastMsg = s.messages[s.messages.length - 1];
|
|
2302
|
+
if (
|
|
2303
|
+
lastMsg &&
|
|
2304
|
+
lastMsg.role === 'assistant' &&
|
|
2305
|
+
typeof lastMsg.content === 'string' &&
|
|
2306
|
+
!(Array.isArray(lastMsg.tool_calls) && lastMsg.tool_calls.length)
|
|
2307
|
+
) {
|
|
2308
|
+
lastMsg.content = (lastMsg.content + '\n\n' + body).slice(0, USER_MAX);
|
|
2309
|
+
this._rewriteLastMsg(s.id, lastMsg.content, null, 'assistant');
|
|
2310
|
+
this.emit({ type: 'sessions' });
|
|
2311
|
+
return true;
|
|
2312
|
+
}
|
|
2313
|
+
const msg = { role: 'assistant', content: body };
|
|
2314
|
+
s.messages.push(msg);
|
|
2315
|
+
try {
|
|
2316
|
+
this._append(s, msg);
|
|
2317
|
+
} catch {}
|
|
2318
|
+
this.emit({ type: 'message', sessionId: s.id, message: msg });
|
|
2319
|
+
this.emit({ type: 'sessions' });
|
|
2320
|
+
return true;
|
|
2321
|
+
}
|
|
2322
|
+
|
|
2287
2323
|
/* Paralel ajan GEÇMİŞİNİ topluca sil: çalışanlar/ bekleyenler iptal edilir,
|
|
2288
2324
|
tüm bg oturum dosyaları + kalıcı kayıt temizlenir. Döndürür: silinen iş sayısı */
|
|
2289
2325
|
clearAllBgJobs() {
|
package/src/main.js
CHANGED
|
@@ -6212,6 +6212,7 @@ function empatiRememberFromEvent(ev) {
|
|
|
6212
6212
|
const txt = typeof m.content === 'string' ? m.content : '';
|
|
6213
6213
|
if (!txt.trim()) return;
|
|
6214
6214
|
if (txt.startsWith((engine && engine.OBSERVE_MARK) || '[BAĞLAM')) return; /* sessiz bağlam — sohbet değil */
|
|
6215
|
+
if (txt.startsWith('🫡 *Beast proaktif:') || txt.startsWith('🫡 **Beast proaktif:')) return; /* proaktif not — döngü '[proaktif]' etiketiyle zaten hafızaya yazdı */
|
|
6215
6216
|
if (m.role === 'user' && txt.startsWith('/')) return; /* slash komut gürültüsü */
|
|
6216
6217
|
let bc = false;
|
|
6217
6218
|
try {
|
|
@@ -6302,6 +6303,53 @@ function empatiLlmCompose(prompt) {
|
|
|
6302
6303
|
.finally(() => clearTimeout(kill));
|
|
6303
6304
|
}
|
|
6304
6305
|
|
|
6306
|
+
/* PROAKTİF NOT → OTURUM BAĞLAMI: bildirim hangi kanala gittiyse AYNI metin
|
|
6307
|
+
o kanalın sohbet oturumuna asistan mesajı olarak da işlenir (yeni tur
|
|
6308
|
+
başlamaz). Böylece kullanıcı bildirime cevap verdiğinde model o mesajı
|
|
6309
|
+
KENDİSİNİN attığını bilir — aynı oturum, kesintisiz bağlam. */
|
|
6310
|
+
const PROACTIVE_MARK = '🫡 *Beast proaktif:*';
|
|
6311
|
+
|
|
6312
|
+
function empatiInjectToSession(sid, out) {
|
|
6313
|
+
try {
|
|
6314
|
+
if (!sid || engine.isBusy(sid)) return; /* tur ortasında geçmişi karıştırma — bildirim kanala zaten gitti */
|
|
6315
|
+
engine.injectAssistant(sid, out);
|
|
6316
|
+
} catch {}
|
|
6317
|
+
}
|
|
6318
|
+
|
|
6319
|
+
/* Oturum yoksa oluştur (processTgMessage/processDcMessage ile aynı kalıp) */
|
|
6320
|
+
function ensureTgSession(chatId) {
|
|
6321
|
+
let sid = tgChats.get(chatId);
|
|
6322
|
+
if (!sid) {
|
|
6323
|
+
const v = engine.createSession();
|
|
6324
|
+
sid = v.id;
|
|
6325
|
+
tgChats.set(chatId, sid);
|
|
6326
|
+
tgRememberSession(chatId, sid);
|
|
6327
|
+
saveTgChats();
|
|
6328
|
+
}
|
|
6329
|
+
return sid;
|
|
6330
|
+
}
|
|
6331
|
+
function ensureDcSession(channelId) {
|
|
6332
|
+
let sid = dcChats.get(channelId);
|
|
6333
|
+
if (!sid) {
|
|
6334
|
+
const v = engine.createSession();
|
|
6335
|
+
sid = v.id;
|
|
6336
|
+
dcChats.set(channelId, sid);
|
|
6337
|
+
dcRememberSession(channelId, sid);
|
|
6338
|
+
saveDcChats();
|
|
6339
|
+
}
|
|
6340
|
+
return sid;
|
|
6341
|
+
}
|
|
6342
|
+
|
|
6343
|
+
/* Masaüstü yedeği: en güncel (bg/bot-DM'siz, meşgul olmayan) sohbet — yoksa yeni */
|
|
6344
|
+
function empatiDesktopSid() {
|
|
6345
|
+
try {
|
|
6346
|
+
for (const v of engine.listSessions()) {
|
|
6347
|
+
if (!engine.isBusy(v.id)) return String(v.id);
|
|
6348
|
+
}
|
|
6349
|
+
} catch {}
|
|
6350
|
+
return engine.createSession().id;
|
|
6351
|
+
}
|
|
6352
|
+
|
|
6305
6353
|
/* bildirim hedefi: sekmeden seçilen entegrasyon; seçilmemişse bağlı olanlar.
|
|
6306
6354
|
Hiçbir entegrasyon yazılamazsa masaüstü chat UI (toast) kalır. */
|
|
6307
6355
|
function empatiNotify(text, ev) {
|
|
@@ -6310,17 +6358,43 @@ function empatiNotify(text, ev) {
|
|
|
6310
6358
|
const tryWa = () => {
|
|
6311
6359
|
try {
|
|
6312
6360
|
const own = waOwnerNum();
|
|
6313
|
-
if (own && wa && wa.connected)
|
|
6361
|
+
if (own && wa && wa.connected) {
|
|
6362
|
+
const jid = own + '@s.whatsapp.net';
|
|
6363
|
+
const out = PROACTIVE_MARK + '\n' + text;
|
|
6364
|
+
senders.push(() =>
|
|
6365
|
+
Promise.resolve(sendWaSafe(jid, out))
|
|
6366
|
+
.then(() => empatiInjectToSession(ensureWaSession(jid), out))
|
|
6367
|
+
.catch(() => {})
|
|
6368
|
+
);
|
|
6369
|
+
}
|
|
6314
6370
|
} catch {}
|
|
6315
6371
|
};
|
|
6316
6372
|
const tryTg = () => {
|
|
6317
6373
|
try {
|
|
6318
|
-
if (tg && tg.connected)
|
|
6374
|
+
if (tg && tg.connected) {
|
|
6375
|
+
const out = PROACTIVE_MARK + '\n' + text;
|
|
6376
|
+
for (const id of tgOwnerIds()) {
|
|
6377
|
+
senders.push(() =>
|
|
6378
|
+
Promise.resolve(sendTgSafe(id, out))
|
|
6379
|
+
.then(() => empatiInjectToSession(ensureTgSession(String(id)), out))
|
|
6380
|
+
.catch(() => {})
|
|
6381
|
+
);
|
|
6382
|
+
}
|
|
6383
|
+
}
|
|
6319
6384
|
} catch {}
|
|
6320
6385
|
};
|
|
6321
6386
|
const tryDc = () => {
|
|
6322
6387
|
try {
|
|
6323
|
-
if (dc && dc.connected)
|
|
6388
|
+
if (dc && dc.connected) {
|
|
6389
|
+
const out = '🫡 **Beast proaktif:**\n' + text;
|
|
6390
|
+
for (const id of dcOwnerIds()) {
|
|
6391
|
+
senders.push(() =>
|
|
6392
|
+
Promise.resolve(sendDcSafe(id, out))
|
|
6393
|
+
.then(() => empatiInjectToSession(ensureDcSession(String(id)), out))
|
|
6394
|
+
.catch(() => {})
|
|
6395
|
+
);
|
|
6396
|
+
}
|
|
6397
|
+
}
|
|
6324
6398
|
} catch {}
|
|
6325
6399
|
};
|
|
6326
6400
|
if (cfg.notifyTarget === 'whatsapp') tryWa();
|
|
@@ -6331,9 +6405,11 @@ function empatiNotify(text, ev) {
|
|
|
6331
6405
|
for (const fn of senders) {
|
|
6332
6406
|
try { fn(); sent++; } catch {}
|
|
6333
6407
|
}
|
|
6334
|
-
/* hiçbir entegrasyona yazılamadıysa yalnız masaüstü chat UI'a düş
|
|
6408
|
+
/* hiçbir entegrasyona yazılamadıysa yalnız masaüstü chat UI'a düş —
|
|
6409
|
+
metin güncel sohbete de asistan mesajı olarak işlenir */
|
|
6335
6410
|
try {
|
|
6336
6411
|
if (!sent && win && !win.isDestroyed()) {
|
|
6412
|
+
empatiInjectToSession(empatiDesktopSid(), PROACTIVE_MARK + '\n' + text);
|
|
6337
6413
|
win.webContents.send('agent:event', { type: 'proactive', id: ev.id, level: ev.level, title: ev.title, text });
|
|
6338
6414
|
}
|
|
6339
6415
|
} catch {}
|