beast-agent 2.67.0 → 2.69.0

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.67.0",
4
+ "version": "2.69.0",
5
5
  "description": "Ultra-fast local agent shell for Windows.",
6
6
  "author": "algokodcom (AlgoKod)",
7
7
  "license": "MIT",
package/src/main.js CHANGED
@@ -3632,12 +3632,12 @@ function reloadBackend() {
3632
3632
  try {
3633
3633
  let txt = '';
3634
3634
  if (ev.type === 'error') {
3635
- txt = '⚠️ [cron: ' + String((cjob && cjob.name) || 'görev') + ']\nHata: ' + String(ev.error || '').slice(0, 200);
3635
+ txt = '⚠️ [cronjob ' + String((cjob && cjob.id) || '?') + ']\nHata: ' + String(ev.error || '').slice(0, 200);
3636
3636
  } else {
3637
3637
  const s = engine.openSession(ev.sessionId);
3638
3638
  const lastA = [...s.messages].reverse().find((m) => m.role === 'assistant' && m.content);
3639
3639
  txt = typeof (lastA && lastA.content) === 'string' ? lastA.content : '';
3640
- if (txt.trim()) txt = '⏰ [cron: ' + String((cjob && cjob.name) || 'görev') + ']\n' + txt;
3640
+ if (txt.trim()) txt = '⏰ [cronjob ' + String((cjob && cjob.id) || '?') + ']\n' + txt;
3641
3641
  }
3642
3642
  if (!txt.trim()) return;
3643
3643
  for (const m of cronMirrorTargets(String(ev.sessionId))) {
@@ -8265,7 +8265,7 @@ function cronPump() {
8265
8265
  let sent = false;
8266
8266
  try {
8267
8267
  sent = engine.send(sid, {
8268
- text: `[cron: ${job.name}]\n${job.prompt}`,
8268
+ text: `[cronjob ${job.id}]\n${job.prompt}`,
8269
8269
  });
8270
8270
  } catch {}
8271
8271
  if (!sent) {
@@ -8278,7 +8278,7 @@ function cronPump() {
8278
8278
  return;
8279
8279
  }
8280
8280
  toastNotify(
8281
- `Cron: ${job.name}`,
8281
+ `cronjob ${job.id}`,
8282
8282
  isReminderJob(job) ? 'Hatırlatma zamanı geldi' : String(job.prompt || '').slice(0, 160),
8283
8283
  'cron'
8284
8284
  );
@@ -10146,17 +10146,12 @@ function finHoursPause(reason) {
10146
10146
  /* Duraklatılan tek ajanı geri aç (ekip rolü ya da sembol işçisi). */
10147
10147
  function finHoursSpawn(role, symbol) {
10148
10148
  if (!engine) return false;
10149
- const f = finCfg();
10150
10149
  try {
10151
10150
  const created = role ? finAgentCreate([], false, role) : finAgentCreate([symbol], false);
10152
- try { engine.setSessionModel(created.s.id, f.traderSel || null); } catch {}
10153
- const ok = engine.send(created.s.id, finTraderBrief(created.agent), { userAction: true });
10154
- if (!ok) {
10155
- finAgentStop(String(created.s.id), 'saat açılışı — oturum meşgul');
10156
- return false;
10157
- }
10151
+ /* JEV-ONLY: LLM turu YOK — TypeSafe turu hemen kuyruğa girer */
10152
+ finTypeSafeKick(String(created.s.id), created.agent);
10158
10153
  const roleDef = role ? finRoleDef(role) : null;
10159
- financeLog('[saat] ' + (roleDef ? roleDef.label : symbol) + ' geri başlatıldı');
10154
+ financeLog('[saat] ' + (roleDef ? roleDef.label : symbol) + ' geri başlatıldı (JEV)');
10160
10155
  return true;
10161
10156
  } catch {
10162
10157
  return false;
@@ -11156,8 +11151,8 @@ function finWakeAgentDm(sid, text) {
11156
11151
  finTradeHoursBlockedLog('olay uyandırması');
11157
11152
  return false;
11158
11153
  }
11159
- /* TYPESAFE-ONLY: LLM turu BAŞLATILMAZ — olay TS turunu öne çeker; prompt/
11160
- pendingReports hattı (engine.send) bu modda hiç kullanılmaz */
11154
+ /* JEV-ONLY: LLM turu BAŞLATILMAZ — olay TS turunu öne çeker; prompt/
11155
+ pendingReports hattı (engine.send) finance ajanlarında hiç kullanılmaz */
11161
11156
  if (finTsAgentMode(agent)) {
11162
11157
  if (!agent.tsBusy) finTypeSafeKick(id, agent);
11163
11158
  return true;
@@ -11201,6 +11196,13 @@ function finWakeAgents(text, meta) {
11201
11196
  engine._agentTeamPost('team:finance', 'finance', 'Beast Finance', body);
11202
11197
  }
11203
11198
  } catch {}
11199
+ /* JEV TURU OLAYI GÖRSÜN: uyanan TypeSafe turunun state'ine (ekip_yanitlari)
11200
+ olay metni de girer — ajan "neden uyandım" bağlamını kaybetmez */
11201
+ try {
11202
+ financeState.tsFeed = Array.isArray(financeState.tsFeed) ? financeState.tsFeed : [];
11203
+ financeState.tsFeed.push({ at: Date.now(), sid: 'finance', who: 'Beast Finance', text: body });
11204
+ while (financeState.tsFeed.length > 30) financeState.tsFeed.shift();
11205
+ } catch {}
11204
11206
  if (!financeState.agents.size) {
11205
11207
  financeLog('[olay] koşan finance ajanı yok — uyarı yalnız günlük/bildirimde' + (meta && meta.kind ? ' (' + meta.kind + ')' : ''));
11206
11208
  return 0;
@@ -11654,18 +11656,9 @@ async function finWeeklyReport(manual) {
11654
11656
  capture: mfeSumMfe > 0 ? Math.round((mfeSumNet / mfeSumMfe) * 100) : null,
11655
11657
  avgMaeLoss: mfeLoss.length ? Math.round((mfeLoss.reduce((a, e) => a + Math.abs(Number(e.mae)), 0) / mfeLoss.length) * 100) / 100 : null,
11656
11658
  } : null;
11657
- let review = '';
11658
- if (engine) {
11659
- try {
11660
- const task =
11661
- 'Beast Finance haftalık performans değerlendirmesi: aşağıdaki istatistik ve işlem günlüğünü ELEŞTİREL yorumla. ' +
11662
- 'Ne iyi gitti, hangi hatalar tekrarlandı, gelecek hafta ne değişmeli? En fazla 12 satır, madde madde, Türkçe.';
11663
- const ctx = JSON.stringify({ stats, drawdown, journal: journal.slice(-20) }).slice(0, 12000);
11664
- const signal = typeof AbortSignal !== 'undefined' && AbortSignal.timeout ? AbortSignal.timeout(120000) : undefined;
11665
- const res = await engine._subagent(task, ctx, signal, null, '');
11666
- review = String(res || '').trim().slice(0, 4000);
11667
- } catch {}
11668
- }
11659
+ /* JEV-ONLY: haftalık yorum LLM'e YAZDIRILMAZ — rapor tamamen kod
11660
+ istatistiklerinden (finstats) üretilir. */
11661
+ const review = '';
11669
11662
  const md = finstats.buildWeeklyReport({ stats, drawdown, equity, journal, account, positions, fromTs, toTs: now, review, mfe });
11670
11663
  const day = finstats.dayKey(now);
11671
11664
  const file = path.join(financeDir(), 'reports', 'weekly-' + day + '.md');
@@ -12270,6 +12263,8 @@ function finLearnSummaryPrompt(sym, e, oldNotes) {
12270
12263
  /* Bir sembolü özetle: snapshot'taki ESKİ dersleri modele özetlet, onları düş,
12271
12264
  yerine kalıcı özet yaz. Model çalışırken gelen YENİ dersler ham kalır. */
12272
12265
  async function finLearnCompactSymbol(symbol, force) {
12266
+ /* JEV-ONLY: finance hafıza özetlemesi LLM İLE YAPILMAZ (kapı) */
12267
+ return { ok: false, error: 'LLM özetleme JEV-ONLY modunda kapalı' };
12273
12268
  const sym = String(symbol || '').trim().toUpperCase();
12274
12269
  if (!sym) return { ok: false, error: 'symbol gerekli' };
12275
12270
  if (finLearnCompacting.has(sym)) return { ok: false, error: 'bu sembol şu an özetleniyor' };
@@ -12321,9 +12316,10 @@ async function finLearnCompactSymbol(symbol, force) {
12321
12316
  }
12322
12317
  }
12323
12318
 
12324
- /* Arka plan tetikleyici: ajanı BEKLETMEDEN özetler (notlar birikince) */
12319
+ /* Arka plan tetikleyici: Beast Finance = JEV-ONLY olduğu için LLM özetleme
12320
+ KAPALI; ham dersler tavan (60) + TTL (30 gün) ile kendiliğinden sadeleşir. */
12325
12321
  function finLearnCompactAuto(sym) {
12326
- try { finLearnCompactSymbol(sym, false).catch(() => {}); } catch {}
12322
+ void sym;
12327
12323
  }
12328
12324
 
12329
12325
  function finLearnSym(symbol) {
@@ -12667,12 +12663,12 @@ function finLearnApi() {
12667
12663
  if (r.notes || r.trades || r.symbols) finLearnSave();
12668
12664
  return { ok: true, ...r };
12669
12665
  },
12670
- compact: ({ symbol } = {}) => {
12671
- /* OPENCODE TARZI ÖZETLEME (elle): eski dersleri modele özetlet,
12672
- ham yalnız son dersler kalsın */
12673
- const sym = norm(symbol);
12674
- if (!sym) return Promise.resolve({ ok: false, error: 'compact için symbol gerekli' });
12675
- return finLearnCompactSymbol(sym, true);
12666
+ compact: () => {
12667
+ /* JEV-ONLY: LLM özetleme KAPATILDI — dersler tavan + TTL ile sadeleşir */
12668
+ return Promise.resolve({
12669
+ ok: false,
12670
+ error: 'LLM özetleme JEV-ONLY modunda kapalı — dersler tavan (60) + 30 gün TTL ile otomatik sadeleşir',
12671
+ });
12676
12672
  },
12677
12673
  };
12678
12674
  }
@@ -13446,16 +13442,19 @@ function finDailyRoutine(mode) {
13446
13442
  const agent = financeState.agents.get(mainSid);
13447
13443
  const s = engine.cache.get(mainSid);
13448
13444
  if (s) finApplyTraderFields(s, agent.symbols, agent.role, true);
13449
- if (engine.isBusy(mainSid)) {
13450
- financeLog('[rutin] trader meşgul — günlük ' + mode + ' atlandı');
13451
- return;
13452
- }
13453
- const digest = finBuildDigest();
13454
- const text = mode === 'plan'
13455
- ? 'GÜNLÜK PLAN (açılış rutini): Bugün için net bir plan yap — izleme listesini ve piyasa koşullarını tara; sembol başına yön eğilimi, izlenecek seviyeler ve risk planı (kaç işlem, hangi setup/kurulum, günlük kayıp sınırı) yaz. Zorunlu işlem yok. Planı mt5_note ile günlüğe kaydet.\n\nİŞLEM GEÇMİŞİN:\n' + digest
13456
- : 'GÜNLÜK REVIEW (kapanış rutini): Bugünün işlemlerini ve performans geçmişini değerlendir — hangi kararlar işledi, hangileri hata; kâr yakalama (MFE) ve MAE verisine bak; açık pozisyonların SL/TP\'lerini kontrol et, korumasız bırakma; yarın için 2-3 somut ders çıkar ve mt5_note ile kaydet.\n\nİŞLEM GEÇMİŞİN:\n' + digest;
13457
- const ok = engine.send(mainSid, text, { userAction: true });
13458
- financeLog('[rutin] günlük ' + mode + (ok ? ' gönderildi' : ' gönderilemedi (meşgul)'));
13445
+ /* JEV-ONLY: günlük plan/review de LLM'SİZ koşar — trader'ın TypeSafe turu
13446
+ hemen tetiklenir (işlem geçmişi/öğrenme digest'i tur state'ine zaten
13447
+ gömülür); AJAN DM'e rutin notu düşer. */
13448
+ try { finTypeSafeKick(mainSid, agent); } catch {}
13449
+ finTsPost(
13450
+ mainSid,
13451
+ agent,
13452
+ mode === 'plan'
13453
+ ? '📅 GÜNLÜK PLAN rutini tetiklendi — TypeSafe turu koşuyor (LLM yok)'
13454
+ : '🧾 GÜNLÜK REVIEW rutini tetiklendi — TypeSafe turu koşuyor (LLM yok)',
13455
+ 'rutin'
13456
+ );
13457
+ financeLog('[rutin] günlük ' + mode + ' TypeSafe turu tetiklendi');
13459
13458
  } catch {}
13460
13459
  }
13461
13460
 
@@ -13484,6 +13483,8 @@ function finSyncScheduleJobs() {
13484
13483
  (_subagent) hesap/pozisyon/strateji bağlamıyla kısa işlem planı üretir.
13485
13484
  Plan, tur mesajına [ANA AJAN PLANI] bloğu olarak eklenir. */
13486
13485
  async function finConsultPlan(f, agent, sid) {
13486
+ /* JEV-ONLY: finance ajanları için LLM danışma planı ÜRETİLMEZ (kapı) */
13487
+ return '';
13487
13488
  if (!engine) return '';
13488
13489
  let account = null;
13489
13490
  let positions = [];
@@ -13581,13 +13582,14 @@ function finTeamWaitTick(sid) {
13581
13582
  finAgentRound(sid, { noTeamWait: true });
13582
13583
  }
13583
13584
 
13584
- /* ---------- TYPESAFE-ONLY FİNANS MODU (LLM'SİZ) ----------
13585
- Rol→Skill eşleştirmesinde "typesafe-ai" seçiliyse ajan LLM HİÇ kullanmaz:
13586
- tur verisi (fiyat/gösterge/pozisyon/öğrenme geçmişi/ekip yanıtları) YALNIZ
13587
- TypeSafe System One'a gider; yanıtlar olasılık olarak döner, kararı KOD
13588
- uygular. Yanıtlar AJAN DM ekip grubuna yazılır — tüm ajanlar birbirinin
13589
- cevabını görür (son yanıtlar sonraki turların state'ine de girer) ve emirler
13590
- YALNIZ market buy/sell olarak açılır (bekleyen emir YOK). */
13585
+ /* ---------- JEV-ONLY FİNANS AJAN MODU (LLM'SİZ, SABİT) ----------
13586
+ TÜM finance ajanları (Trader + analiz ekibi + sembol işçileri) LLM HİÇ
13587
+ kullanmaz: tur verisi (fiyat/gösterge/pozisyon/öğrenme geçmişi/ekip
13588
+ yanıtları) YALNIZ TypeSafe System One'a gider; yanıtlar olasılık olarak
13589
+ döner, kararı KOD uygular. Yanıtlar AJAN DM ekip grubuna yazılır — tüm
13590
+ ajanlar birbirinin cevabını görür (son yanıtlar sonraki turların state'ine
13591
+ de girer) ve emirler YALNIZ market buy/sell olarak açılır (bekleyen emir
13592
+ YOK). LLM yalnız finance SOHBET yardımcısında serbesttir. */
13591
13593
  const FIN_TS_MARGIN_P = 0.12; /* birinci ile ikinci seçenek arası min fark */
13592
13594
  const FIN_TS_CONFIRM_P = 0.55; /* noul teyit eşiği */
13593
13595
  const FIN_TS_EXIT_P = 0.62; /* pozisyon kapatma eşiği */
@@ -13617,15 +13619,11 @@ const FIN_TS_ROLE_CRIT = {
13617
13619
  };
13618
13620
 
13619
13621
  function finTsAgentMode(agent) {
13620
- try {
13621
- const f = finCfg();
13622
- const key = agent && agent.main ? 'trader' : String((agent && agent.role) || '');
13623
- if (!key) return false;
13624
- const list = f.roleSkills && Array.isArray(f.roleSkills[key]) ? f.roleSkills[key] : [];
13625
- return list.some((s) => String(s || '').toLowerCase() === 'typesafe-ai');
13626
- } catch {
13627
- return false;
13628
- }
13622
+ /* BEAST FINANCE = JEV-ONLY (sabit kural): Trader + analiz ekibi + sembol
13623
+ işçileri LLM ASLA kullanmaz — her tur deterministik TypeSafe System One
13624
+ hattıyla koşar (veri koda toplanır, karar Jev'den gelir, emir koda
13625
+ uygulanır). LLM yalnız finance SOHBET yardımcısında serbesttir. */
13626
+ return !!agent;
13629
13627
  }
13630
13628
 
13631
13629
  function finTsWho(agent, extra) {
@@ -13757,15 +13755,21 @@ async function finTypeSafeRound(sid, agent) {
13757
13755
  if (!agent || !engine || agent.tsBusy) return;
13758
13756
  agent.tsBusy = true;
13759
13757
  const sidS = String(sid);
13760
- const isTrader = !!agent.main;
13758
+ /* SEMBOL İŞÇİSİ (rolü olmayan ajan) da otonom işlem açabilir — trader
13759
+ karar hattını kullanır; rol ajanları yalnız analiz üretir. */
13760
+ const isTrader = !!agent.main || !String(agent.role || '');
13761
13761
  const role = String(agent.role || '');
13762
- const roleLabel = isTrader ? 'TRADER (ana karar verici)' : ((finRoleDef(role) || {}).label || role || 'finans');
13762
+ const roleLabel = agent.main
13763
+ ? 'TRADER (ana karar verici)'
13764
+ : isTrader
13765
+ ? 'SEMBOL İŞÇİSİ (otonom)'
13766
+ : ((finRoleDef(role) || {}).label || role || 'finans');
13763
13767
  try {
13764
13768
  if (!typesafeMod.cfg().apiKey) {
13765
13769
  const now = Date.now();
13766
13770
  if (!agent.tsNoKeyAt || now - agent.tsNoKeyAt > 10 * 60 * 1000) {
13767
13771
  agent.tsNoKeyAt = now;
13768
- finTsPost(sidS, agent, '⚠ TypeSafe API anahtarı yok — bu rol typesafe-ai modunda ve LLM KULLANILMIYOR; tur atlanıyor. Sahibe söyle: Ayarlar → TypeSafe sekmesinden anahtar girilmeli.', 'anahtar');
13772
+ finTsPost(sidS, agent, '⚠ TypeSafe API anahtarı yok — finance ajanları JEV-ONLY çalışır ve LLM KULLANILMIYOR; tur atlanıyor. Sahibe söyle: Ayarlar → TypeSafe sekmesinden anahtar girilmeli.', 'anahtar');
13769
13773
  }
13770
13774
  return;
13771
13775
  }
@@ -13789,7 +13793,7 @@ async function finTypeSafeRound(sid, agent) {
13789
13793
  return;
13790
13794
  }
13791
13795
  agent.round = (Number(agent.round) || 0) + 1;
13792
- if (isTrader) {
13796
+ if (agent.main) {
13793
13797
  financeState.traderRounds = agent.round;
13794
13798
  finPush('trader', { state: 'running', round: agent.round, mode: 'typesafe' });
13795
13799
  }
@@ -14056,7 +14060,7 @@ async function finTypeSafeRound(sid, agent) {
14056
14060
  } finally {
14057
14061
  agent.tsBusy = false;
14058
14062
  finTsSchedule(sidS, agent, finPaceSec());
14059
- if (isTrader && financeState.agents.has(sidS)) finPush('trader', { state: 'idle', round: agent.round, mode: 'typesafe' });
14063
+ if (agent.main && financeState.agents.has(sidS)) finPush('trader', { state: 'idle', round: agent.round, mode: 'typesafe' });
14060
14064
  }
14061
14065
  }
14062
14066
 
@@ -14077,9 +14081,9 @@ function finAgentRound(sid, opts) {
14077
14081
  /* hâlâ çalışıyor — done eventinde tekrar planlanır */
14078
14082
  return;
14079
14083
  }
14080
- /* TYPESAFE-ONLY MODU: roleSkills'te typesafe-ai varsa LLM HİÇ kullanılmaz —
14081
- tur deterministik TypeSafe hattıyla koşar (girdi yalnız TypeSafe'e gider,
14082
- cevaplar AJAN DM'e düşer, emirler yalnız market buy/sell) */
14084
+ /* JEV-ONLY (SABİT): finance ajanları LLM HİÇ kullanmaz — tur deterministik
14085
+ TypeSafe hattıyla koşar (girdi yalnız TypeSafe'e gider, cevaplar AJAN
14086
+ DM'e düşer, emirler yalnız market buy/sell) */
14083
14087
  if (finTsAgentMode(agent)) {
14084
14088
  finTypeSafeRound(String(sid), agent).catch(() => {});
14085
14089
  return;
@@ -14578,7 +14582,9 @@ async function financeTraderStart() {
14578
14582
  const th = f.tradeHours || {};
14579
14583
  return { ok: false, error: `trade saatleri dışı (${th.start || '09:00'}-${th.end || '22:00'} yerel) — pencere açılınca ajanlar otomatik başlar` };
14580
14584
  }
14581
- if (!engine.publicState().hasModel && !f.traderSel) return { ok: false, error: 'model yok — Ayarlar → Provider' };
14585
+ /* JEV-ONLY: LLM modeli GEREKMEZ — anahtar kapısı TypeSafe'tir */
14586
+ const tsGate = typesafeMod.unavailable();
14587
+ if (tsGate) return { ok: false, error: tsGate };
14582
14588
  try { finSyncScheduleJobs(); } catch {} /* plan/review saatleri trader açılışında garantiye alınır */
14583
14589
  /* ANA trader: varsa aynen sürdür, yoksa yeni sürekli ajan aç */
14584
14590
  let mainSid = '';
@@ -14600,27 +14606,15 @@ async function financeTraderStart() {
14600
14606
  mainSid = String(created.s.id);
14601
14607
  mainAgent = created.agent;
14602
14608
  }
14603
- try { engine.setSessionModel(mainSid, f.traderSel || null); } catch {}
14604
14609
  financeState.traderOn = true;
14605
14610
  try { engine.clearStop(); } catch {}
14606
- /* TYPESAFE-ONLY: roleSkills.trader'da typesafe-ai varsa LLM'e HİÇ gidilmez */
14607
- if (finTsAgentMode(mainAgent)) {
14608
- financeState.lastRoundAt = Date.now();
14609
- financeLog('[trader] başlatıldı (TYPESAFE-ONLY — LLM kullanılmıyor, girdi yalnız TypeSafe)');
14610
- finPush('trader', { state: 'running', round: mainAgent.round, mode: 'typesafe' });
14611
- finTypeSafeKick(mainSid, mainAgent);
14612
- finTeamStart(f);
14613
- return { ok: true, sid: mainSid };
14614
- }
14615
- const ok = engine.send(mainSid, finTraderBrief(mainAgent), { userAction: true });
14616
- if (!ok) {
14617
- financeState.traderOn = false;
14618
- return { ok: false, error: 'trader oturumu meşgul — birkaç saniye sonra tekrar dene' };
14619
- }
14611
+ /* JEV-ONLY (SABİT): Trader HER ZAMAN TypeSafe turuyla koşar — LLM'e HİÇ
14612
+ gidilmez (girdi koda toplanır, karar Jev'den gelir, emir koda uygulanır). */
14620
14613
  financeState.lastRoundAt = Date.now();
14621
- financeLog('[trader] başlatıldı (model: ' + (f.traderSel || 'genel aktif model') + ')');
14622
- finPush('trader', { state: 'running', round: mainAgent.round });
14623
- /* ANALİZ EKİBİ: seçili roller için ayrı sürekli ajanlar (koşmıyorsa) */
14614
+ financeLog('[trader] başlatıldı (JEV-ONLY — LLM kullanılmıyor, girdi yalnız TypeSafe)');
14615
+ finPush('trader', { state: 'running', round: mainAgent.round, mode: 'typesafe' });
14616
+ finTypeSafeKick(mainSid, mainAgent);
14617
+ /* ANALİZ EKİBİ: seçili roller için ayrı sürekli Jev ajanları (koşmıyorsa) */
14624
14618
  finTeamStart(f);
14625
14619
  return { ok: true, sid: mainSid };
14626
14620
  }
@@ -14643,20 +14637,10 @@ function finTeamStart(f) {
14643
14637
  const roleDef = finRoleDef(roleId);
14644
14638
  try {
14645
14639
  const created = finAgentCreate([], false, roleId);
14646
- try { engine.setSessionModel(created.s.id, f.traderSel || null); } catch {}
14647
- /* TYPESAFE-ONLY: bu rolün skill eşleştirmesinde typesafe-ai varsa LLM yok */
14648
- if (finTsAgentMode(created.agent)) {
14649
- financeLog('[ekip] ' + roleDef.label + ' başladı (TYPESAFE-ONLY — LLM kullanılmıyor)');
14650
- finTypeSafeKick(String(created.s.id), created.agent);
14651
- continue;
14652
- }
14653
- const ok = engine.send(created.s.id, finTraderBrief(created.agent), { userAction: true });
14654
- if (!ok) {
14655
- finAgentStop(String(created.s.id), 'oturum meşgul — ekip ajanı başlatılamadı');
14656
- financeLog('[ekip] ' + roleDef.label + ' başlatılamadı: oturum meşgul');
14657
- } else {
14658
- financeLog('[ekip] ' + roleDef.label + ' başladı — analiz turu koşuyor (İşlem AÇMAZ)');
14659
- }
14640
+ /* JEV-ONLY: ekibin HER rolü LLM'SİZ TypeSafe turuyla koşar (analiz
14641
+ üretir, işlem AÇMAZ) */
14642
+ financeLog('[ekip] ' + roleDef.label + ' başladı (JEV — LLM yok)');
14643
+ finTypeSafeKick(String(created.s.id), created.agent);
14660
14644
  } catch (e) {
14661
14645
  financeLog('[ekip] ' + roleDef.label + ' hatası: ' + String((e && e.message) || e));
14662
14646
  }
@@ -14697,7 +14681,9 @@ ipcMain.handle('finance:agent:spawn', async (_e, payload) => {
14697
14681
  const th = f.tradeHours || {};
14698
14682
  return { ok: false, error: `trade saatleri dışı (${th.start || '09:00'}-${th.end || '22:00'} yerel) — pencere açılınca ajanlar otomatik başlar` };
14699
14683
  }
14700
- if (!engine.publicState().hasModel && !f.traderSel) return { ok: false, error: 'model yok — Ayarlar → Provider' };
14684
+ /* JEV-ONLY: LLM modeli GEREKMEZ — anahtar kapısı TypeSafe'tir */
14685
+ const tsGate = typesafeMod.unavailable();
14686
+ if (tsGate) return { ok: false, error: tsGate };
14701
14687
  const symbol = String((payload && payload.symbol) || '').trim().toUpperCase();
14702
14688
  if (!symbol) return { ok: false, error: 'sembol gerekli' };
14703
14689
  for (const [, a] of financeState.agents) {
@@ -14706,13 +14692,9 @@ ipcMain.handle('finance:agent:spawn', async (_e, payload) => {
14706
14692
  }
14707
14693
  }
14708
14694
  const created = finAgentCreate([symbol], false);
14709
- try { engine.setSessionModel(created.s.id, f.traderSel || null); } catch {}
14710
- const ok = engine.send(created.s.id, finTraderBrief(created.agent), { userAction: true });
14711
- if (!ok) {
14712
- finAgentStop(String(created.s.id), 'oturum meşgul — ajan başlatılamadı');
14713
- return { ok: false, error: 'ajan oturumu meşgul — birkaç saniye sonra tekrar dene' };
14714
- }
14715
- financeLog('[ajan] ' + symbol + ' işçisi başlatıldı');
14695
+ /* JEV-ONLY: sembol işçisi LLM'SİZ TypeSafe turuyla otonom çalışır */
14696
+ finTypeSafeKick(String(created.s.id), created.agent);
14697
+ financeLog('[ajan] ' + symbol + ' işçisi başlatıldı (JEV — LLM yok)');
14716
14698
  return { ok: true, sid: created.s.id, title: created.s.bgTitle };
14717
14699
  });
14718
14700
 
@@ -217,13 +217,13 @@
217
217
  p_role_sub: 'Vision, Terminal, Coding ve Subagent için ayrı model; boş bırakırsan ana model kullanılır',
218
218
  p_role_main: '— Ana model —',
219
219
  p_custom_h2: 'Özel Provider',
220
- p_custom_sub: 'API adres + key ver, modeller otomatik çekilir',
220
+ p_custom_sub: 'API adres + key ver, modeller otomatik çekilir; olmayanları elle ekle',
221
221
  p_custom_del: 'Sil',
222
222
  p_name_opt: 'Ad (opsiyonel)',
223
223
  p_api_url: 'API adresi',
224
224
  p_api_key: 'API Key',
225
225
  p_fetch: 'Modelleri Çek',
226
- p_models_manual: 'Modelleri elle gir (her satıra bir model adı)',
226
+ p_models_manual: 'Ek modeller — elle ekle (her satıra bir ad; çekilenlere eklenir)',
227
227
  p_save: 'Kaydet',
228
228
  p_model_toast: 'Model: ',
229
229
  p_del_toast: 'Silindi: ',
@@ -755,7 +755,7 @@
755
755
  mail_need_to: 'Alıcı adresi gerekli',
756
756
  /* TypeSafe (System One / Jev) */
757
757
  ts_h2: 'TypeSafe (System One · Jev)',
758
- ts_sub: 'Tipli karar motoru: metin üretmeden olasılıklı yanıt (noul/choice/score). Anahtar girilince ajanlar typesafe_decision aracını kullanır; Beast Finance rol→skill eşleştirmesinde "typesafe-ai" seçilirse roller bu kararları kullanır.',
758
+ ts_sub: 'Tipli karar motoru: metin üretmeden olasılıklı yanıt (noul/choice/score). Beast Finance ajanları (Trader + analiz ekibi + sembol işçileri) JEV-ONLY çalışır — kararları YALNIZ buradan alır, LLM kullanılmaz; anahtar yoksa finans ajanları tur atmaz. Diğer ajanlar ve sohbet etkilenmez.',
759
759
  ts_key_label: 'TypeSafe API anahtarı (typesafe.ai)',
760
760
  ts_model_label: 'Model (varsayılan: jev-latest)',
761
761
  ts_enabled_label: 'TypeSafe açık (browser_agent/T3SFast + typesafe_decision kullanılabilir)',
@@ -772,7 +772,7 @@
772
772
  ts_saved_toast: 'TypeSafe anahtarı kaydedildi',
773
773
  ts_cleared_toast: 'TypeSafe anahtarı silindi',
774
774
  ts_fail_toast: 'TypeSafe kaydedilemedi',
775
- ts_hint: 'İpucu: Rol→Skill eşleştirmesinde "typesafe-ai" seçilen roller (ve ana trader playbook) kararlarını typesafe_decision ile alır; anahtar yoksa diğer ajanlar chat modeliyle devam eder.',
775
+ ts_hint: 'İpucu: Beast Finance ajanları JEV-ONLY koşar (LLM yok) — Ayarlar → TypeSafe anahtarı zorunludur. Finance SOHBET yardımcısı ve diğer ajanlar chat modelini kullanmaya devam eder.',
776
776
  },
777
777
  en: {
778
778
  newChat: '+ New Chat',
@@ -979,13 +979,13 @@
979
979
  p_role_sub: 'Separate model for Vision, Terminal, Coding and Subagent; leave empty to use the main model',
980
980
  p_role_main: '— Main model —',
981
981
  p_custom_h2: 'Custom Provider',
982
- p_custom_sub: 'Provide API URL + key, models are fetched automatically',
982
+ p_custom_sub: 'Provide API URL + key, models are fetched automatically; add extra ones manually',
983
983
  p_custom_del: 'Delete',
984
984
  p_name_opt: 'Name (optional)',
985
985
  p_api_url: 'API URL',
986
986
  p_api_key: 'API Key',
987
987
  p_fetch: 'Fetch Models',
988
- p_models_manual: 'Enter models manually (one per line)',
988
+ p_models_manual: 'Extra models — add manually (one per line; added to fetched list)',
989
989
  p_save: 'Save',
990
990
  p_model_toast: 'Model: ',
991
991
  p_del_toast: 'Deleted: ',
@@ -1512,7 +1512,7 @@
1512
1512
  store_login_note: 'Your Beast ID is anonymous; your real Beast Code is never shared.',
1513
1513
  /* TypeSafe (System One / Jev) */
1514
1514
  ts_h2: 'TypeSafe (System One · Jev)',
1515
- ts_sub: 'Typed decision engine: probabilistic answers without text generation (noul/choice/score). Once a key is set, agents can use the typesafe_decision tool; when "typesafe-ai" is picked in Beast Finance role→skill matching, those roles use it.',
1515
+ ts_sub: 'Typed decision engine: probabilistic answers without text generation (noul/choice/score). Beast Finance agents (Trader + analysis team + symbol workers) are JEV-ONLY — they take decisions solely from here, no LLM; without a key finance agents do not run. Other agents and the chat are unaffected.',
1516
1516
  ts_key_label: 'TypeSafe API key (typesafe.ai)',
1517
1517
  ts_model_label: 'Model (default: jev-latest)',
1518
1518
  ts_enabled_label: 'TypeSafe ON (enables browser_agent/T3SFast + typesafe_decision)',
@@ -1529,7 +1529,7 @@
1529
1529
  ts_saved_toast: 'TypeSafe key saved',
1530
1530
  ts_cleared_toast: 'TypeSafe key deleted',
1531
1531
  ts_fail_toast: 'Could not save TypeSafe key',
1532
- ts_hint: 'Tip: roles (and the main trader playbook) matched to "typesafe-ai" use typesafe_decision for their judgments; without a key other agents keep using the chat model.',
1532
+ ts_hint: 'Tip: Beast Finance agents run JEV-ONLY (no LLM) — a TypeSafe key in Settings is required. The finance chat copilot and other agents keep using the chat model.',
1533
1533
  },
1534
1534
  };
1535
1535
 
@@ -856,7 +856,7 @@
856
856
  </div>
857
857
  <div class="mini-body">
858
858
  <div id="finSkillsList" class="mini-list"></div>
859
- <div class="fin-sym-hint">Her rol için EN FAZLA 2 skill seçilir (ör. price-action + typesafe-ai). Seçili skill'i satırın sağ üstündeki çöp ikonuyla kaldırabilirsin; boş bırakırsan ajan skill'i göreve göre SKILLS kataloğundan kendi seçer. Seçim, koşan ajanlar dahil sonraki turdan itibaren geçerli olur.<br><b>typesafe-ai seçilirse:</b> o ajan LLM KULLANMAZ — tur verisi yalnız TypeSafe System One'a gider (tipli kararlar), cevaplar AJAN DM'de tüm ekibe görünür ve ajanlar birbirinin yanıtını görür; emirler YALNIZ market buy/sell olarak açılır (bekleyen emir yok). Ayarlar → TypeSafe'ten API anahtarı gerekir.</div>
859
+ <div class="fin-sym-hint"><b>BEAST FINANCE AJANLARI ARTIK HER ZAMAN JEV (TypeSafe System One) İLE ÇALIŞIR — LLM KULLANILMAZ.</b> Trader + analiz ekibi + sembol işçileri tur verisini koda toplar, kararı Jev'den (tipli olasılıklar) alır, emri kod uygular; cevaplar AJAN DM'de tüm ekibe görünür. Ayarlar → TypeSafe'ten API anahtarı zorunludur; anahtar yoksa ajanlar tur atmaz.<br>Buradaki skill seçimi (en fazla 2) yalnız finance SOHBET yardımcısının (LLM) playbook'u içindir; ajanların karar hattını değiştirmez. Seçili skill'i çöp ikonuyla kaldırabilirsin.</div>
860
860
  </div>
861
861
  </div>
862
862
  </div>
@@ -1683,8 +1683,8 @@ async function renderWebSearchPane() {
1683
1683
  }
1684
1684
 
1685
1685
  /* TypeSafe sekmesi (System One / Jev): API anahtarı + model + bağlantı testi.
1686
- Anahtar kayıtlıysa ajanlar typesafe_decision aracıyla tipli kararlar alır;
1687
- Beast Finance rol→skill eşleştirmesinde "typesafe-ai" seçilirse kullanılır. */
1686
+ Beast Finance ajanları JEV-ONLY çalışır (anahtar zorunlu); diğer ajanlar
1687
+ anahtar kayıtlıysa typesafe_decision aracıyla tipli kararlar alır. */
1688
1688
  async function renderTypesafePane() {
1689
1689
  const pane = $('#tab-typesafe');
1690
1690
  if (!pane) return;
@@ -1920,11 +1920,11 @@ async function renderProviderPane() {
1920
1920
  `</div>` +
1921
1921
  `<button id="cpFetch" class="btn ghost">${_t('p_fetch')}</button>` +
1922
1922
  `<div id="cpPicks" class="model-picks" hidden></div>` +
1923
- `<div id="cpManualWrap" hidden>` +
1923
+ `<div id="cpManualWrap">` +
1924
1924
  `<label class="mem-label">${_t('p_models_manual')}</label>` +
1925
- `<textarea id="cpManual" class="mem-area" rows="4" placeholder="model-adi-1&#10;model-adi-2"></textarea>` +
1925
+ `<textarea id="cpManual" class="mem-area" rows="3" placeholder="model-adi-1&#10;model-adi-2"></textarea>` +
1926
1926
  `</div>` +
1927
- `<button id="cpSave" class="btn" hidden>${_t('p_save')}</button>`;
1927
+ `<button id="cpSave" class="btn">${_t('p_save')}</button>`;
1928
1928
  pane.appendChild(form);
1929
1929
 
1930
1930
  let discovered = [];
@@ -1981,11 +1981,11 @@ async function renderProviderPane() {
1981
1981
 
1982
1982
  const collectedModels = () => {
1983
1983
  const picked = [...document.querySelectorAll('#cpPicks input:checked')].map((c) => c.value);
1984
- if (picked.length) return picked;
1985
- return ($('#cpManual').value || '')
1984
+ const manual = ($('#cpManual').value || '')
1986
1985
  .split(/[\n,]+/)
1987
1986
  .map((s) => s.trim())
1988
1987
  .filter(Boolean);
1988
+ return [...new Set([...picked, ...manual])];
1989
1989
  };
1990
1990
 
1991
1991
  $('#cpFetch').addEventListener('click', async () => {
@@ -2005,24 +2005,20 @@ async function renderProviderPane() {
2005
2005
  discovered = res.ok ? res.models : [];
2006
2006
  const picks = $('#cpPicks');
2007
2007
  if (discovered.length) {
2008
- $('#cpManualWrap').hidden = true;
2009
2008
  picks.hidden = false;
2010
2009
  picks.innerHTML = discovered
2011
2010
  .map((m) => `<label><input type="checkbox" value="${escapeHtml(m)}" checked> ${escapeHtml(m)}</label>`)
2012
2011
  .join('');
2013
- $('#cpSave').hidden = false;
2014
- toast(discovered.length + ' model bulundu');
2012
+ toast(discovered.length + ' model bulundu — listeden seç ya da elle ekle');
2015
2013
  } else {
2016
2014
  picks.hidden = true;
2017
2015
  picks.innerHTML = '';
2018
- $('#cpManualWrap').hidden = false;
2019
- $('#cpSave').hidden = false;
2020
2016
  toast('Model çekilemedi (' + (res.error || 'boş') + ') — elle girebilirsin');
2021
2017
  }
2022
2018
  });
2023
2019
 
2024
2020
  $('#cpSave').addEventListener('click', async () => {
2025
- const models = [...new Set(collectedModels())];
2021
+ const models = collectedModels();
2026
2022
  const url = $('#cpUrl').value.trim();
2027
2023
  if (!/^https?:\/\//i.test(url)) { toast('Geçerli API adresi gir'); return; }
2028
2024
  if (!models.length) { toast('En az bir model gir ya da seç'); return; }
@@ -7037,7 +7033,7 @@ async function renderCronModal(force) {
7037
7033
  row.innerHTML =
7038
7034
  `<span class="mr-dot"></span>` +
7039
7035
  `<div class="mr-main">` +
7040
- `<div class="mr-name">${escapeHtml(j.name || j.id)}</div>` +
7036
+ `<div class="mr-name">${escapeHtml(j.name || 'görev')} <span style="opacity:.55">#${escapeHtml(j.id)}</span></div>` +
7041
7037
  `<div class="mr-meta"><b>${escapeHtml(j.schedule)}</b> · ${escapeHtml(String(j.prompt || '').slice(0, 70))}${live}</div>` +
7042
7038
  `</div>`;
7043
7039
  const btns = document.createElement('div');
@@ -7411,7 +7407,8 @@ function renderCronList(jobs) {
7411
7407
  infoDiv.className = 'cj-info';
7412
7408
  const name = document.createElement('div');
7413
7409
  name.className = 'cj-name';
7414
- name.textContent = j.name;
7410
+ /* mesajlarda isim yerine JOB ID görünür — eşleştirme için listede de id */
7411
+ name.textContent = j.name + ' · #' + j.id;
7415
7412
  const meta = document.createElement('div');
7416
7413
  meta.className = 'cj-meta';
7417
7414
  const code = document.createElement('code');
@@ -7499,7 +7496,7 @@ async function renderAgendaPane() {
7499
7496
  if (!j.enabled) continue;
7500
7497
  const t = j.nextRunAt ? new Date(j.nextRunAt).getTime() : 0;
7501
7498
  if (!t) continue;
7502
- items.push({ type: isReminderLike(j) ? 'rem' : 'cron', name: j.name || j.id, at: t, meta: j.schedule, id: j.id });
7499
+ items.push({ type: isReminderLike(j) ? 'rem' : 'cron', name: (j.name || 'görev') + ' #' + j.id, at: t, meta: j.schedule, id: j.id });
7503
7500
  }
7504
7501
  for (const w of ws) {
7505
7502
  if (!w.enabled) continue;
@@ -11030,10 +11027,10 @@ function finSymPickerClose() {
11030
11027
  }
11031
11028
 
11032
11029
  /* ---------- ROL → SKILL eşleştirme modalı ----------
11033
- Roller sunucudan (snapshot.roles), skill listesi KURULU katalogdan gelir —
11034
- yeni skill eklendiğinde modalda otomatik görünür. Rol başına EN FAZLA 2
11035
- skill seçilir; seçim finance ayarına (roleSkills) yazılır; rol ajanı her
11036
- turda o skill'leri okumakla yükümlüdür (ör. price-action + typesafe-ai). */
11030
+ Roller sunucudan (snapshot.roles), skill listesi KURULU katalogdan gelir.
11031
+ Rol başına EN FAZLA 2 skill seçilir ve finance ayarına (roleSkills) yazılır.
11032
+ NOT: Finance AJANLARI artık JEV-ONLY (LLM yok) — bu seçim yalnız finance
11033
+ SOHBET yardımcısının (LLM) playbook'unu etkiler. */
11037
11034
  let finSkillNames = [];
11038
11035
 
11039
11036
  async function finSkillsOpen() {
@@ -11289,8 +11286,10 @@ function finLearnSymEl(row) {
11289
11286
  const noteCount = document.createElement('span');
11290
11287
  noteCount.className = 'fin-learn-sym-notes';
11291
11288
  noteCount.textContent = (Number(row.notes) || 0) + ' ders' + (row.hasSummary ? ' · özet' : '');
11292
- /* ÖZETLE (opencode tarzı compaction): eski dersler modele özetlettirilir */
11289
+ /* ÖZETLE: Beast Finance JEV-ONLY olduğu için LLM özetleme kapalı —
11290
+ düğme gizli (dersler tavan + TTL ile kendiliğinden sadeleşir) */
11293
11291
  const sum = document.createElement('button');
11292
+ sum.hidden = true;
11294
11293
  sum.type = 'button';
11295
11294
  sum.className = 'fin-learn-sum-btn';
11296
11295
  sum.title = 'Eski dersleri modele özetlet — hafıza sadeleşir (24+ ders birikince otomatik de çalışır)';