beast-agent 2.44.4 → 2.44.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/agent/engine.js +145 -24
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "beast-agent",
3
3
  "productName": "Beast Agent",
4
- "version": "2.44.4",
4
+ "version": "2.44.5",
5
5
  "description": "Ultra-fast local agent shell for Windows.",
6
6
  "author": "algokodcom (AlgoKod)",
7
7
  "license": "MIT",
@@ -392,6 +392,11 @@ class Engine {
392
392
  (AJAN DM paneli buradan beslenir; restart sonrası da durur) */
393
393
  this._agentDms = [];
394
394
  this._agentDmsFile = path.join(this.sessionsDir, 'agent-dms.json');
395
+ /* TOOL İSTEKLERİ: tool_request artık SENKRON BEKLEMEZ — istek Tool botunun
396
+ KENDİ oturumunda arka planda koşar; bitince rapor isteyene düşer.
397
+ toolSid -> [{id, requesterSid, requesterTitle, task, before, at}] */
398
+ this._toolPending = new Map();
399
+ this._toolSessionFile = path.join(this.sessionsDir, 'tool-session.json');
395
400
  /* AJAN DM GRUPLARI: ajanların agent_dm ile kurduğu grup sohbetleri
396
401
  (id → {id,title,members,titles,createdAt,closed,closedAt}) */
397
402
  this._agentGroups = new Map();
@@ -2002,7 +2007,7 @@ class Engine {
2002
2007
  '- Grafikte gezinme/ölçek: computer_act ile timeframe, scroll, zoom (arka planda çalışır — kullanıcının faresini çalmaz).\n' +
2003
2008
  '- 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' +
2004
2009
  '- 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' +
2005
- '- 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 (doğrulanınca tool__<ad> olarak ANINDA çağrılır); küçük aracı skill("tool-yazma") prosedürüyle kendin de yazabilirsin.\n' +
2010
+ '- 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' +
2006
2011
  'VERİ AKIŞI (her değerlendirmede): mt5_account + mt5_positions + mt5_market çağrılarını AYNI turda PARALEL ver; gerekiyorsa mt5_history ile son işlemleri gör.\n' +
2007
2012
  'PARALEL + KOORDİNASYON: uzun araştırma/işleri run_background ile paralel finance işçisine devret (parent finance olduğu için işçi mt5 okuma araçlarını görür); koşan ajanlarla konuşmak için agent_dm (to: ajan başlığındaki anahtar kelime, örn "GOLD"; ortak karar için group: "İSİM" ile grup sohbeti kur — mesaj tüm üyelere düşer). Görevin bitince DM/grup sohbetleri otomatik KAPANIR (geçmiş panelde kalır).\n' +
2008
2013
  (symbols ? `İZLEME LİSTESİ: ${symbols}\n` : '') +
@@ -2121,7 +2126,7 @@ class Engine {
2121
2126
  'Kullanıcı bir tarihte/saatte hatırlatılmasını isterse set_reminder kullan; when değerini ORTAMdaki bugüne göre hesapla (yerel saat). "Her sabah/gün/hafta" gibi tekrarlı isteklerde repeat alanını da ver (daily/weekly/monthly/weekdays veya cron).',
2122
2127
  'Kullanıcı kalıcı bir arka plan takibi isterse (fiyat eşiği, pil seviyesi, sayfa değişikliği) watcher_add ile izleyici kur; kurduktan sonra watcher_list ile doğrula ve kullanıcıya koşulu + kontrol sıklığını kısaca bildir.',
2123
2128
  'Anlık olay takipleri için (yeni mail, fiyat eşiği, dosya değişimi, webhook) event_subscribe kullan — cron/polling gerekmez; listeyi event_list ile göster, vazgeçirirse event_unsubscribe.',
2124
- 'ARAÇ EKSİKSE ÇEKİNME (CEPHANE): ihtiyacın olan bir araç yoksa/bozuksa tool_request ile TOOL botuna yazdır — tool yazımı onun TEK işidir; task alanına araç adı + ne yapacağı + girdi/çıktı sözleşmesini, context alanına örnek veri/yol/endpoint yaz. Araç doğrulanınca tool__<ad> olarak ANINDA çağrılabilir. Küçük kişisel araçları skill("tool-yazma") prosedürüyle kendin de yazabilirsin — yazdığını run_command ile MUTLAKA doğrula.',
2129
+ 'ARAÇ EKSİKSE ÇEKİNME (CEPHANE): ihtiyacın olan bir araç yoksa/bozuksa tool_request ile TOOL botuna yazdır — tool yazımı onun TEK işidir; task alanına araç adı + ne yapacağı + girdi/çıktı sözleşmesini, context alanına örnek veri/yol/endpoint yaz. ASENKRON: istek anında kabul edilir, Tool botu kendi oturumunda arka planda yazar; sen BEKLEME, işine devam et. Araç doğrulanınca tool__<ad> olarak ANINDA çağrılabilir; rapor bitince sohbete otomatik düşer. Küçük kişisel araçları skill("tool-yazma") prosedürüyle kendin de yazabilirsin — yazdığını run_command ile MUTLAKA doğrula.',
2125
2130
  'LOG ZEKASI: "hata var mı / ne oldu / neden çalışmadı" sorularında ya da bir iş beklenmedik bittiğinde/hata verdiğini fark ettiğinde log_analyze ile logları tara — top desenleri okuyup en olası KÖK NEDENİ tek cümlede söyle, somut çözüm öner; aynı desen 3+ tekrarlıysa bunu vurgula. Sürekli log gözetimi istenirse watcher_add ile kind:"logs" kur (örn "hata artarsa bağır" → level:"error", windowMin:10, op:"gt", value:2) ve koşulu kısaca bildir.',
2126
2131
  'Kullanıcı "artık hep böyle yap / bunu unutma" tarzı kalıcı talimat verirse kural olarak kaydet: sohbette /rule <metin> kullanmasını söyle VEYA kullanıcı isterse event_subscribe ile olaya bağlan (mail/fiyat/dosya/webhook).',
2127
2132
  'Kullanıcının mesajında 2+ ayrı iş/hedef varsa (örn "X yap ve sonra Y\u2019i kontrol et") KODLAMAYA/İŞE BAŞLAMADAN önce todo_write ile plan çıkar ve sırayla yürüt; her adımı tamamlarken güncelle. LİSTE DİSİPLİNİ: her adım bittiği AN status:"done" yap; son cevabını vermeden önce tüm maddeler done olmalı — yapılmayacaksa listeden düş. Listeyi yarım bırakma.',
@@ -3705,7 +3710,7 @@ class Engine {
3705
3710
  `DOSYA KURALI: dosya işlemlerinde özel araçları kullan — VAR OLAN dosyayı edit_file ile düzenle, yeniyi write_file ile yaz, okuma/arama read_file/grep/glob; run_command terminal işlerindir (build, git, kurulum). Bir dosyayı BİR KEZ oku — içerik bağlamda kalır, tekrar okuma.\n` +
3706
3711
  (proj ? `PROJE TALİMATLARI (workspace AGENTS/CLAUDE/CONTEXT — daima uy):\n${proj}\n` : '') +
3707
3712
  `HIZ KURALLARI:\n` +
3708
- `- TOOL İSTEĞİ (CEPHANE): ihtiyacın olan araç yoksa/bozuksa tool_request ile TOOL botuna yazdır (araç doğrulanınca tool__<ad> olarak anında çağrılır); küçük aracı skill("tool-yazma") ile kendin de yaz ve run_command ile doğrula.\n` +
3713
+ `- TOOL İSTEĞİ (CEPHANE): ihtiyacın olan araç yoksa/bozuksa tool_request ile TOOL botuna yazdır (asenkron: istek anında döner, Tool botu arka planda yazar; araç doğrulanınca tool__<ad> olarak anında çağrılır, rapor sohbete düşer); küçük aracı skill("tool-yazma") ile kendin de yaz ve run_command ile doğrula.\n` +
3709
3714
  `- Döngülü işleri (çok URL/dosya/sayfa, tekrarlı parse-hesap) TEK python_run betiğinde topluca bitir.\n` +
3710
3715
  `- Web için web_search kullan (zincir dahili tarayıcıyla başlar — gerçek Chromium ile Google); tek aramada bulunamazsa veya çok kaynaklı derin araştırma gerekiyorsa deep_search kullan (çoklu sorgu paralel + gizli tarayıcıda tam sayfa okuma). Sayfa açma/göstermenin VARSAYILANI DAHİLİ tarayıcıdır: browser_open → browser_snapshot → browser_click/type/read. Kullanıcı açıkça dış tarayıcı (chrome/firefox/başka/normal/kendi tarayıcım) istediyse run_command ile \`start "" <url>\` çalıştır. Görseli göremiyorsan metni ocr_read ile oku (source:"browser").\n` +
3711
3716
  `- Bağımsız araç çağrılarını aynı turda PARALEL ver.\n` +
@@ -4400,6 +4405,8 @@ class Engine {
4400
4405
  }
4401
4406
  } finally {
4402
4407
  this.ctrls.delete(sid);
4408
+ /* Tool botu turu bittiyse bekleyen tool isteklerinin raporu dağıtılır */
4409
+ try { this._toolRequestFinished(sid); } catch {}
4403
4410
  emit({ type: 'status', status: 'idle' });
4404
4411
  /* bekleyen paralel-ajan raporları HER bitiş yolunda boşaltılır —
4405
4412
  hata/durdurma/tur-limiti sonrası bile sonuç raporu kullanıcıya ulaşır.
@@ -4769,8 +4776,10 @@ const skills = require('./skills');
4769
4776
  }
4770
4777
 
4771
4778
  /* TOOL İSTEĞİ (cephane): her oturum/bot eksik aracı TOOL botuna yazdırır.
4772
- Admin şartı YOK — amaç tüm ajanların tool üretebilmesi; tool botunun
4773
- kendisi ve DM oturumları hariç (döngü koruması). */
4779
+ Admin şartı YOK. ASENKRON akış: istek Tool botunun KENDİ oturumunda
4780
+ arka planda koşar (timeout yok), AJAN DM paneline düşer; rapor bitince
4781
+ isteyen oturuma otomatik iletilir. İstek anında döner — isteyen ajan
4782
+ beklemeden işine devam eder, araç hazır olunca tool__<ad> çağrılır. */
4774
4783
  async _toolRequest(args, sessionId, signal) {
4775
4784
  const bots = require('./bots');
4776
4785
  const task = String((args && args.task) || '').slice(0, 4000);
@@ -4789,32 +4798,144 @@ const skills = require('./skills');
4789
4798
  return (b && b.name) || (session && session.bgTitle) || 'Beast';
4790
4799
  } catch { return 'Beast'; }
4791
4800
  })();
4792
- const message =
4793
- `TOOL İSTEĞİ (gönderen: ${who}):\n` + task + '\n' +
4801
+ const requestId = 'tr' + Date.now().toString(36) + Math.random().toString(36).slice(2, 6);
4802
+ /* TOOL BOTUNUN KENDİ OTURUMU: yoksa açılır — botta kalıcı oturum oluşur */
4803
+ const toolSid = this._ensureToolBotSession(target);
4804
+ const text =
4805
+ `[TOOL İSTEĞİ — ${requestId} — gönderen: ${who}]\n` + task + '\n' +
4794
4806
  (context ? `\nBAĞLAM (kod/yol/örnek veri/endpoint):\n` + context + '\n' : '') +
4795
4807
  `\nHatırlatma: skill("tool-yazma") oku; %APPDATA%\\beast\\tools\\<slug>\\ içine tool.json + run.js yaz; run_command ile TEST DÖNGÜSÜNÜ işlet (çıktı {ok:true} olana kadar hata oku → edit_file ile düzelt → yeniden test; en fazla 5 deneme). Ancak test geçince yayınla; geçmeyen aracı yayınlama. Raporunda adımları yaz: yazıldı → test sonucu → (varsa) düzeltmeler → YAYINDA/BAŞARISIZ + tek satır çağrı örneği.`;
4796
- const r = await this._botConverse(senderBotId, target, message, signal, 240000);
4797
- /* RAPOR: tool yazım/doğrulama adımları bağlı entegrasyonlara (WA/TG/Discord) düşer */
4798
- const notifyIntegrations = (text) => {
4799
- try { if (typeof this.integrationNotify === 'function') this.integrationNotify(text); } catch {}
4808
+ /* AJAN DM paneline istek kaydı — kullanıcı Tool botu ile konuşmayı canlı görür */
4809
+ const dm = {
4810
+ at: new Date().toISOString(),
4811
+ from: String(sessionId || 'beast'),
4812
+ fromTitle: who,
4813
+ to: toolSid,
4814
+ toTitle: target.name || 'Tool botu',
4815
+ topic: 'tool isteği',
4816
+ text: task,
4800
4817
  };
4801
- if (!r || !r.ok) {
4802
- notifyIntegrations('🛠️ Tool botu BAŞARISIZ — isteyen: ' + who + '\nİstenen: ' + task.slice(0, 140) + '\nSebep: ' + String((r && r.error) || 'yanıt yok'));
4803
- return r || { ok: false, error: 'Tool botu yanıt vermedi' };
4804
- }
4805
- notifyIntegrations(
4806
- '🛠️ Tool botu raporu — isteyen: ' + who + '\n' +
4807
- 'İstenen: ' + task.slice(0, 140) + '\n' +
4808
- String(r.reply || '').replace(/\s+/g, ' ').slice(0, 500)
4809
- );
4818
+ try {
4819
+ this._pushAgentDm(dm);
4820
+ this._persistAgentDms();
4821
+ emitSafe(this, toolSid, { type: 'agent-dm', ...dm });
4822
+ } catch {}
4823
+ const toolSess = this.cache.get(toolSid) || this._load(toolSid);
4824
+ const before = toolSess.messages.length;
4825
+ /* bekleyen kaydı send'DEN ÖNCE düş — tur senkron bitebilir (ör. model
4826
+ yok); _run finally anında raporu dağıtır, kayıt kaçmaz */
4827
+ const list = this._toolPending.get(toolSid) || [];
4828
+ list.push({
4829
+ id: requestId,
4830
+ requesterSid: String(sessionId || ''),
4831
+ requesterTitle: who,
4832
+ responderTitle: target.name || 'Tool botu',
4833
+ task: task.slice(0, 300),
4834
+ before,
4835
+ at: Date.now(),
4836
+ });
4837
+ this._toolPending.set(toolSid, list);
4838
+ const sent = this.send(toolSid, { text });
4839
+ if (!sent) {
4840
+ this._toolPending.set(toolSid, list.filter((x) => x.id !== requestId));
4841
+ return { ok: false, error: 'Tool botu oturumu başlatılamadı (durdurulmuş olabilir)' };
4842
+ }
4843
+ if (!this.ctrls.has(toolSid)) {
4844
+ let s2 = this.cache.get(toolSid) || this._load(toolSid);
4845
+ if (s2.messages.length === before) this._toolRequestFinished(toolSid);
4846
+ }
4810
4847
  return {
4811
4848
  ok: true,
4812
- tool_bot: r.from,
4813
- reply: r.reply,
4814
- note: 'Araç hazır olduğunda modele tool__<slug> olarak ANINDA açılır (doğrulama testini Tool botu yaptı; adımlar entegrasyonlara bildirildi).',
4849
+ status: 'istek iletildi',
4850
+ tool_bot: target.name || 'Tool botu',
4851
+ request_id: requestId,
4852
+ session_id: 'bot:' + String(target.id || 'tool'),
4853
+ note: 'Tool botu ARKA PLANDA yazıyor; sen beklemeden işine devam et. Araç hazır olunca tool__<ad> olarak ANINDA çağrılır; rapor bitince bu sohbete otomatik düşer. Aynı araç için tekrar istek atma.',
4815
4854
  };
4816
4855
  }
4817
4856
 
4857
+ /* Tool botunun KALICI kendi oturumu (yoksa oluşturur) — istekler burada
4858
+ birikir, kullanıcı Tool botu sohbetinden tüm geçmişi görebilir. */
4859
+ _ensureToolBotSession(target) {
4860
+ const want = String((target && target.id) || 'tool');
4861
+ try {
4862
+ const rec = JSON.parse(fs.readFileSync(this._toolSessionFile, 'utf8'));
4863
+ const sid = String((rec && rec.id) || '');
4864
+ if (sid && fs.existsSync(this._file(sid))) {
4865
+ const s = this._load(sid);
4866
+ if (s && !s.isBotDm) {
4867
+ if (String(s.botId || '') !== want) this.setSessionBot(sid, want);
4868
+ return sid;
4869
+ }
4870
+ }
4871
+ } catch {}
4872
+ const created = this.createSession();
4873
+ const sid = String(created.id);
4874
+ this.setSessionBot(sid, want);
4875
+ this.setSessionPerm(sid, target.perm || 'all');
4876
+ try {
4877
+ fs.writeFileSync(this._toolSessionFile, JSON.stringify({ id: sid, botId: want, at: nowIso() }));
4878
+ } catch {}
4879
+ return sid;
4880
+ }
4881
+
4882
+ /* Tool botunun turu bitti: bekleyen isteklerin raporunu AJAN DM paneline
4883
+ ve isteyen oturuma düşür. _run finally'den çağrılır (tüm bitiş yolları). */
4884
+ _toolRequestFinished(sid) {
4885
+ try {
4886
+ const key = String(sid || '');
4887
+ if (!this._toolPending || !this._toolPending.size) return;
4888
+ const list = this._toolPending.get(key);
4889
+ if (!list || !list.length) return;
4890
+ this._toolPending.delete(key);
4891
+ const s = this.cache.get(key) || this._load(key);
4892
+ const reply = (() => {
4893
+ for (let i = s.messages.length - 1; i >= 0; i--) {
4894
+ const m = s.messages[i];
4895
+ if (m && m.role === 'assistant' && m.content && !(Array.isArray(m.tool_calls) && m.tool_calls.length)) {
4896
+ const txt = typeof m.content === 'string' ? m.content : '';
4897
+ if (txt.trim()) return stripAiDashes(txt.trim());
4898
+ }
4899
+ }
4900
+ return '';
4901
+ })();
4902
+ for (const req of list) {
4903
+ const body = reply
4904
+ ? `[TOOL BOTU RAPORU — ${req.id}]\n${reply}`
4905
+ : `[TOOL BOTU] ${req.id} numaralı istek tamamlanamadı (tur yarıda kesildi ya da metin rapor üretilemedi). Tool botu sohbetinden ayrıntıya bakabilirsin.`;
4906
+ const dm = {
4907
+ at: new Date().toISOString(),
4908
+ from: key,
4909
+ fromTitle: req.responderTitle || 'Tool botu',
4910
+ to: req.requesterSid || '',
4911
+ toTitle: req.requesterTitle || 'Beast',
4912
+ topic: 'tool isteği',
4913
+ text: body,
4914
+ };
4915
+ try {
4916
+ this._pushAgentDm(dm);
4917
+ this._persistAgentDms();
4918
+ emitSafe(this, req.requesterSid || key, { type: 'agent-dm', ...dm });
4919
+ } catch {}
4920
+ if (req.requesterSid) {
4921
+ try {
4922
+ if (this.ctrls.has(String(req.requesterSid))) this.send(String(req.requesterSid), { text: body });
4923
+ else this.injectAssistant(String(req.requesterSid), body);
4924
+ } catch {}
4925
+ }
4926
+ try {
4927
+ if (typeof this.integrationNotify === 'function') {
4928
+ this.integrationNotify(
4929
+ '🛠️ Tool botu raporu — isteyen: ' + (req.requesterTitle || 'Beast') + '\n' +
4930
+ 'İstenen: ' + String(req.task || '').slice(0, 140) + '\n' +
4931
+ String(reply || 'tamamlanamadı').replace(/\s+/g, ' ').slice(0, 500)
4932
+ );
4933
+ }
4934
+ } catch {}
4935
+ }
4936
+ } catch {}
4937
+ }
4938
+
4818
4939
  /* ADMIN İZLEME: tüm botlar arası DM oturumlarının listesi */
4819
4940
  listBotDmSessions() {
4820
4941
  const bots = require('./bots');
@@ -5826,7 +5947,7 @@ const TOOL_REQUEST_DEF = {
5826
5947
  function: {
5827
5948
  name: 'tool_request',
5828
5949
  description:
5829
- 'İhtiyaç duyduğun bir araç eksikse ya da bozuksa TOOL botuna yazdırır ve doğrulanmış aracın raporunu döndürür. Tool yazımı Tool botunun TEK işidir — sen tool yazmaya çalışma. task: araç adı + ne yapacak + girdi/çıktı sözleşmesi; context: örnek veri, dosya yolu, endpoint veya hata çıktısı. Araç hazır olunca tool__<ad> olarak ANINDA çağrılabilir.',
5950
+ 'İhtiyaç duyduğun bir araç eksikse ya da bozuksa TOOL botuna yazdırır. ASENKRON çalışır: istek anında kabul edilir, Tool botu KENDİ oturumunda arka planda aracı yazar ve test eder; sen BEKLEME, işine devam et. Araç hazır olunca tool__<ad> olarak ANINDA çağrılır; Tool botunun raporu bitince bu sohbete otomatik düşer (AJAN DM panelinde de görünür). task: araç adı + ne yapacak + girdi/çıktı sözleşmesi; context: örnek veri, dosya yolu, endpoint veya hata çıktısı. Aynı araç için tekrar istek atma.',
5830
5951
  parameters: {
5831
5952
  type: 'object',
5832
5953
  properties: {