beast-agent 2.23.2 → 2.24.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "beast-agent",
3
3
  "productName": "Beast Agent",
4
- "version": "2.23.2",
4
+ "version": "2.24.1",
5
5
  "description": "Ultra-fast local agent shell for Windows.",
6
6
  "author": "algokodcom (AlgoKod)",
7
7
  "license": "MIT",
@@ -2934,6 +2934,8 @@ class Engine {
2934
2934
  this._bgMeta = this._bgMeta || new Map();
2935
2935
  this._bgMeta.set(bg.id, { parentId: parent, title: ttl });
2936
2936
  this._bgEmit();
2937
+ /* EKİP GRUBU: aynı görevde koşan paralel ajanlar otomatik ortak DM grubuna girer */
2938
+ try { this._agentTeamJoin(this._bgJobs.get(bg.id)); } catch {}
2937
2939
  setTimeout(() => this._bgAdmit(bg.id, t), 60);
2938
2940
  return { ok: true, backgroundId: bg.id, code: bg.code };
2939
2941
  }
@@ -3208,6 +3210,12 @@ class Engine {
3208
3210
  }
3209
3211
  /* #17 öz-kurtarma hakları tükendi → owner'a anlık altyapı uyarısı */
3210
3212
  this._notifyOwnerTaskFailed(job, msg);
3213
+ /* EKİP GRUBU: kapanış postu — ekibe hata bildirilir */
3214
+ if (job.teamGid) {
3215
+ try {
3216
+ this._agentTeamPost(job.teamGid, sid, job.title, '[EKİP] ' + job.title + ' HATA ile bitti: ' + String(msg || '').slice(0, 150));
3217
+ } catch {}
3218
+ }
3211
3219
  /* AJAN DM: işi kesin bitti — ajanın DM/grup sohbetleri kapanır */
3212
3220
  try { this._agentDmClose(sid); } catch {}
3213
3221
  if (grouped) {
@@ -3233,9 +3241,21 @@ class Engine {
3233
3241
  this._pendingReports.push({ parentId: job.parentId, text });
3234
3242
  this.flushPendingReports(job.parentId);
3235
3243
  }
3244
+ /* EKİP GRUBU: kapanış postu — iptal ekipçe bilinir */
3245
+ if (job.teamGid) {
3246
+ try {
3247
+ this._agentTeamPost(job.teamGid, sid, job.title, '[EKİP] ' + job.title + ' İPTAL edildi — sebep: ' + String(why || '').slice(0, 120));
3248
+ } catch {}
3249
+ }
3236
3250
  /* AJAN DM: işi bitti (kullanıcı iptali dahil) — sohbetler kapanır */
3237
3251
  try { this._agentDmClose(sid); } catch {}
3238
3252
  } else if (status === 'done') {
3253
+ /* EKİP GRUBU: kapanış postu */
3254
+ if (job.teamGid) {
3255
+ try {
3256
+ this._agentTeamPost(job.teamGid, sid, job.title, '[EKİP] ' + job.title + ' görevini TAMAMLADI.');
3257
+ } catch {}
3258
+ }
3239
3259
  /* AJAN DM: görev tamamlandı — ajanın DM/grup sohbetleri kapanır */
3240
3260
  try { this._agentDmClose(sid); } catch {}
3241
3261
  }
@@ -3499,6 +3519,7 @@ class Engine {
3499
3519
  `- PDF gerekirse pip\u2019ten paket kurma (Türkçe bozar); Node\u2019un kurulu \`pdf-lib\`+fontkit\u2019iyle .js script yazıp \`node\` ile çalıştır. md→pdf çevirme: belge çıktısını doğrudan PDF olarak üret.\n` +
3500
3520
  `- ARAŞTIRMA SINIRI: 3-5 kaynak yeter; süre hedefi ~3 dakika. 2-3 denemede bulunamayan bilgiyi BIRAK — bulabildiğin kısmi sonucu raporla ve neyi bulamadığını yaz. Kapalı/gizli içerik peşinde koşma.\n` +
3501
3521
  `AJAN KOORDİNASYONU: diğer koşan ajanlarla (paralel işler, finance ajanları) konuşman gerekiyorsa agent_dm aracını kullan — to: hedefin başlığındaki anahtar kelime (örn "GOLD", "Trader"), message: 1-3 cümlelik net mesaj. Senden istenen görevde başka bir ajanın zaten yaptığın işe ihtiyacı varsa DM ile haber ver. Birden fazla ajanla ORTAK KARAR almanız gerekiyorsa group: "İSİM" vererek grup sohbeti kur — mesajın tüm üyelere düşer, cevaplar aynı gruba gelir. Görevin bitince DM/grup sohbetleri otomatik KAPANIR (geçmiş panelde kalır).\n` +
3522
+ (job.teamGid ? this._agentTeamPromptLine(job.teamGid) : '') +
3502
3523
  FORMAT_RULES + '\n' +
3503
3524
  `SON ÇIKTI: 3-5 satırlık net sonuç raporu, madde madde. Soru sorma, sohbet etme.`
3504
3525
  );
@@ -6327,9 +6348,10 @@ Engine.prototype._agentDmSend = function (fromSid, args) {
6327
6348
  text,
6328
6349
  };
6329
6350
  this._pushAgentDm(dm);
6351
+ /* canlı event TEK SEFER — üye başına emit edilirse panelde çoğalır */
6352
+ emitSafe(this, target || g.members[0], { type: 'agent-dm', ...dm });
6330
6353
  for (const m of g.members) {
6331
6354
  if (m === String(fromSid) || !jobs.has(m)) continue;
6332
- emitSafe(this, m, { type: 'agent-dm', ...dm });
6333
6355
  (this._pendingReports = this._pendingReports || []).push({
6334
6356
  parentId: m,
6335
6357
  text:
@@ -6375,6 +6397,98 @@ Engine.prototype._pushAgentDm = function (dm) {
6375
6397
  if (this._agentDms.length > 600) this._agentDms.splice(0, this._agentDms.length - 600);
6376
6398
  };
6377
6399
 
6400
+ /* ---------- EKİP GRUBU: aynı görevde koşan paralel ajanlar otomatik
6401
+ ortak DM grubuna girer — tartışma ZORUNLU (sistem promptuyla). ---------- */
6402
+
6403
+ /* İş başlarken çağrılır: aynı parent / bg-gruptan başka ajan varsa (varsa
6404
+ önceden kurulmuştur) hepsini TEK ekip grubuna katar + katılım postu düşer. */
6405
+ Engine.prototype._agentTeamJoin = function (job) {
6406
+ try {
6407
+ if (!job || !job.id) return;
6408
+ const parent = String(job.parentId || '');
6409
+ if (!parent) return;
6410
+ const gid = 'team:' + (job.groupId || parent);
6411
+ const base =
6412
+ String(job.task || job.title || 'ortak görev').replace(/\s+/g, ' ').trim().slice(0, 28) || 'ortak görev';
6413
+ let g = this._agentGroups.get(gid);
6414
+ if (!g) {
6415
+ g = { id: gid, title: base + ' EKİP', members: [], titles: {}, createdAt: nowIso(), closed: false, team: true };
6416
+ this._agentGroups.set(gid, g);
6417
+ }
6418
+ g.closed = false;
6419
+ delete g.closedAt;
6420
+ g.titles = g.titles || {};
6421
+ const add = (id, title) => {
6422
+ id = String(id);
6423
+ if (!g.members.includes(id)) g.members.push(id);
6424
+ if (title) g.titles[id] = String(title);
6425
+ };
6426
+ /* aynı ortak görevdeki DİĞER ajanlar (aborted olanlar hariç) */
6427
+ const mates = [...this._bgJobs.values()].filter(
6428
+ (j) => j && String(j.id) !== String(job.id) && String(j.parentId) === parent && j.status !== 'aborted'
6429
+ );
6430
+ add(job.id, job.title);
6431
+ for (const m of mates) add(m.id, m.title);
6432
+ job.teamGid = gid;
6433
+ for (const m of mates) m.teamGid = gid;
6434
+ this._persistAgentDms();
6435
+ this._bgEmit();
6436
+ /* katılım postu: gruptaki DİĞER koşan ajanlara bildirim olarak düşer */
6437
+ const names = mates.map((m) => m.title).filter(Boolean);
6438
+ this._agentTeamPost(
6439
+ gid,
6440
+ job.id,
6441
+ job.title,
6442
+ names.length
6443
+ ? '[EKİP] ' + job.title + ' ortak göreve katıldı — ekip: ' + names.join(', ') + '. Planı ve kararları grupta paylaş.'
6444
+ : '[EKİP] ' + job.title + ' göreve başladı.'
6445
+ );
6446
+ } catch {}
6447
+ };
6448
+
6449
+ /* Ekip grubuna sistem postu: panelde görünür + koşan üye ajanlara bildirim */
6450
+ Engine.prototype._agentTeamPost = function (gid, fromSid, fromTitle, text) {
6451
+ try {
6452
+ const g = this._agentGroups.get(String(gid));
6453
+ if (!g) return;
6454
+ const dm = {
6455
+ at: nowIso(),
6456
+ from: String(fromSid || ''),
6457
+ fromTitle: String(fromTitle || 'EKİP'),
6458
+ to: '',
6459
+ toTitle: 'ekip',
6460
+ group: gid,
6461
+ groupTitle: g.title,
6462
+ topic: 'ortak görev',
6463
+ text: String(text || '').slice(0, 600),
6464
+ system: true,
6465
+ };
6466
+ this._pushAgentDm(dm);
6467
+ /* Sistem postları YALNIZ panelde görünür — modele pendingReports ile
6468
+ enjekte EDİLMEZ (mid-task müdahale + kuyruk/konkürans bozulmasın).
6469
+ Üyeler ekibi her turda sistem promptundaki ZORUNLU satırdan bilir;
6470
+ gerçek ajan mesajları (agent_dm) normal teslim akışıyla düşer. */
6471
+ /* canlı event TEK SEFER (ilk koşan üyeye) — üye başına emit edilmez */
6472
+ const firstRunning = (g.members || []).find((m) => {
6473
+ const j = this._bgJobs && this._bgJobs.get(m);
6474
+ return j && j.status === 'running';
6475
+ });
6476
+ if (firstRunning) emitSafe(this, firstRunning, { type: 'agent-dm', ...dm });
6477
+ this._persistAgentDms();
6478
+ } catch {}
6479
+ };
6480
+
6481
+ /* Sistem promptuna ekip zorunluluğu */
6482
+ Engine.prototype._agentTeamPromptLine = function (gid) {
6483
+ const g = this._agentGroups && this._agentGroups.get(String(gid));
6484
+ if (!g) return '';
6485
+ return (
6486
+ `EKİP GRUBU (ZORUNLU): bu ortak görevde birlikte çalışan ajanlarla "${g.title}" DM grubundasın — ` +
6487
+ `her önemli bulgu/karar/durum değişiminde agent_dm aracıyla GRUBA yaz (group: "${g.title}", topic: "ortak görev"); ` +
6488
+ `işin SONUNDA 1-2 cümlelik kapanış raporunu da gruba bırak. Gruba düşen mesajlar sana da gelir — ekiple çelişen hareket etme.\n`
6489
+ );
6490
+ };
6491
+
6378
6492
  Engine.prototype._persistAgentDms = function () {
6379
6493
  try {
6380
6494
  const groups = {};
@@ -5590,9 +5590,11 @@ function onEvent(ev) {
5590
5590
  scheduleAgentsRender();
5591
5591
  return;
5592
5592
  }
5593
- /* AJAN DM: ajanlar arası mesaj — açık görünümde canlı düşer (modal/sütun) */
5593
+ /* AJAN DM: ajanlar arası mesaj — açık görünümde canlı düşer (modal/sütun).
5594
+ group alanı MUTLAKA taşınır — yoksa grup mesajı 1:1 DM gibi görünür ve
5595
+ refresh'te "silinir" (server doğrusu gruba koyar, yerel kopya uçuşur). */
5594
5596
  if (ev.type === 'agent-dm') {
5595
- dmState.dms.push({
5597
+ const rec = {
5596
5598
  at: ev.at,
5597
5599
  from: ev.from,
5598
5600
  fromTitle: ev.fromTitle,
@@ -5600,8 +5602,17 @@ function onEvent(ev) {
5600
5602
  toTitle: ev.toTitle,
5601
5603
  topic: ev.topic,
5602
5604
  text: ev.text,
5603
- });
5604
- if (dmState.dms.length > 400) dmState.dms.splice(0, dmState.dms.length - 400);
5605
+ ...(ev.group ? { group: ev.group, groupTitle: ev.groupTitle } : {}),
5606
+ ...(ev.closed ? { closed: true, closedAt: ev.closedAt } : {}),
5607
+ };
5608
+ /* aynı mesaj birden çok üyeye emit edilmiş olabilir — TEK kopya */
5609
+ const dup = dmState.dms.find(
5610
+ (d) => d.at === rec.at && d.from === rec.from && d.text === rec.text && dmThreadOf(d) === dmThreadOf(rec)
5611
+ );
5612
+ if (!dup) {
5613
+ dmState.dms.push(rec);
5614
+ if (dmState.dms.length > 400) dmState.dms.splice(0, dmState.dms.length - 400);
5615
+ }
5605
5616
  if (els.dmOverlay && !els.dmOverlay.hidden) renderDmModal();
5606
5617
  if ($('#dmRail') && !$('#dmRail').classList.contains('dm-hidden')) renderDmRail();
5607
5618
  return;