beast-agent 2.63.4 → 2.63.6
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 +33 -16
- package/src/agent/financetools.js +44 -17
- package/src/agent/seeds/typesafe-ai/SKILL.md +60 -0
- package/src/agent/tools.js +5 -2
- package/src/agent/typesafe.js +278 -0
- package/src/main.js +766 -77
- package/src/preload.js +4 -0
- package/src/renderer/i18n.js +38 -0
- package/src/renderer/index.html +3 -1
- package/src/renderer/renderer.js +165 -23
package/package.json
CHANGED
package/src/agent/engine.js
CHANGED
|
@@ -19,6 +19,7 @@ const agentdefs = require('./agentdefs');
|
|
|
19
19
|
const memory = require('./memory');
|
|
20
20
|
const mem0 = require('./mem0');
|
|
21
21
|
const supermemory = require('./supermemory');
|
|
22
|
+
const typesafe = require('./typesafe');
|
|
22
23
|
const nightref = require('./nightref');
|
|
23
24
|
const skills = require('./skills');
|
|
24
25
|
const mcp = require('./mcp');
|
|
@@ -1995,28 +1996,42 @@ class Engine {
|
|
|
1995
1996
|
visual:
|
|
1996
1997
|
'ROL: GÖRSEL ANALİZ AJANI 👁 — grafik/ekran görüntüsü uzmanısın, İşlem AÇMAZSIN (mt5_trade/mt5_pending KULLANMA — yeni işlem AÇMAZSIN; açık pozisyonda kısmi kapatma (mt5_close percent) ve SL/TP güncelleme (mt5_modify) SERBEST). MT5 grafiği için ÖNCE tool__mt5_shot kullan (BeastFinance EA "shot": gerçek grafik PNG + görsel SONRAKİ TURDA gözüne gelir; symbol/timeframe vererek başka sembol/periyot çekebilirsin; dönen path send_file ile gönderilebilir); gerekirse EA panosuna mt5_ea action:"note" ile plan/seviye yaz. ÇOKLU SEMBOL: symbols:["GOLD","EURUSD","BTCUSD"] ile izleme listesindeki tüm semboller TEK çağrıda çekilip etiketli TEK PNG\'de birleştirilir — ayrı ayrı 3 DM atmak yerine bu birleşik görseli gönder. web grafiklerinde browser_open + browser_screenshot; bilgisayar ekranı için computer_look; görsel göremeyen metin-model isen ocr_read (source:"screen"/"browser") kullan. Gördüğün yapıyı yorumla: trend, formasyon, mum yapısı, destek-direnç ve SL/TP çizgileri; sembol başına GÖRSEL TEYİT + AL/SAT/BEKLE notu üret. Önemli bulguyu GÖRSELİYLE paylaş: agent_dm image:true (son ekran görüntün) ya da image:"<mt5_shot path>" ile ANA TRADER\'a/ekibe gönder — karşı ajan görüntüyü GERÇEKTEN görür, AJAN DM panelinde açılır. NOT: image:true DAİMA oturumdaki EN SON görseli yollar — her sembolün fotoğrafını ayrı göndermen gerekirse dönen path\'leri kullan (image:"<path>").',
|
|
1997
1998
|
})[String((session && session.financeRole) || '')] || '';
|
|
1998
|
-
/* ROL → SKILL eşleştirmesi (ayarlar modalı): rol başına
|
|
1999
|
-
|
|
2000
|
-
Seçili SKILL.md'
|
|
1999
|
+
/* ROL → SKILL eşleştirmesi (ayarlar modalı): rol başına EN FAZLA 2 skill;
|
|
2000
|
+
ANA TRADER için ayrıca PLAYBOOK skill'leri (roleSkills.trader).
|
|
2001
|
+
Seçili SKILL.md'lerin TAM GÖVDESİ prompta gömülür — ajan skill aracını
|
|
2001
2002
|
çağırmayı atlasa bile prosedür KESİN uygulanır. */
|
|
2002
2003
|
const roleSkills = Array.isArray(session && session.financeRoleSkills)
|
|
2003
|
-
? session.financeRoleSkills.map((s) => String(s || '').trim()).filter(Boolean).slice(0,
|
|
2004
|
+
? session.financeRoleSkills.map((s) => String(s || '').trim()).filter(Boolean).slice(0, 2)
|
|
2004
2005
|
: [];
|
|
2005
2006
|
let roleSkillBlock = '';
|
|
2006
2007
|
if (roleSkills.length) {
|
|
2007
|
-
const roleSkillName = roleSkills[0];
|
|
2008
|
-
const sb = this._skillBody({ name: roleSkillName });
|
|
2009
2008
|
const what = roleBlock
|
|
2010
2009
|
? 'Bu rolün ZORUNLU skill\'i'
|
|
2011
2010
|
: session && session.financePlaybook
|
|
2012
2011
|
? 'TRADER PLAYBOOK\'un (ZORUNLU skill)'
|
|
2013
2012
|
: 'BU OTURUMUN ZORUNLU skill\'i';
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2013
|
+
for (const roleSkillName of roleSkills) {
|
|
2014
|
+
const sb = this._skillBody({ name: roleSkillName });
|
|
2015
|
+
roleSkillBlock +=
|
|
2016
|
+
` ${what}: skill("${roleSkillName}")` +
|
|
2017
|
+
(sb && sb.ok && sb.content
|
|
2018
|
+
? ' — aşağıda TAM prosedürü verilmiştir; HER TURDA birebir uygula (ayrıca okumana gerek yok):\n\n' +
|
|
2019
|
+
`===== SKILL: ${roleSkillName} =====\n${sb.content}\n===== /SKILL =====`
|
|
2020
|
+
: ' — ilk turda bu skill\'i mutlaka oku ve prosedürüne birebir uy.') +
|
|
2021
|
+
'\n';
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
/* TYPESAFE ENTEGRASYONU: roleSkills'te "typesafe-ai" seçiliyse ajan tipli
|
|
2025
|
+
kararlarını chat modeline yazdırmak yerine typesafe_decision aracıyla
|
|
2026
|
+
TypeSafe System One'dan (Jev) alır — anahtar yoksa uyarır. */
|
|
2027
|
+
const finTypeSkill = roleSkills.find((s) => s.toLowerCase() === 'typesafe-ai');
|
|
2028
|
+
if (finTypeSkill) {
|
|
2029
|
+
let tsReady = false;
|
|
2030
|
+
try { tsReady = !!typesafe.cfg().apiKey; } catch {}
|
|
2031
|
+
roleSkillBlock +=
|
|
2032
|
+
tsReady
|
|
2033
|
+
? ' TYPESAFE (typesafe-ai skill) ZORUNLU: semantik/olasılıklı yargılarını (haber-makro etkisi, setup kalitesi, yön/aksiyon seçimi, tez doğrulama) chat modeline metin yazdırıp yorumlamak yerine typesafe_decision aracıyla TypeSafe System One\'a (Jev) sor: state içine tüm somut bağlamı (sembol, fiyat/seviye, haber metni, pozisyon) koy; aynı state üzerindeki bağımsız soruları TEK çağrıda birlikte sor (noul: evet olasılığı, choice: seçenek+dağılım, score: ağırlıklı puan+dağılım). Dönen olasılıkları eşikle yorumla (ör. >0.65 güçlü kanaat, 0.35-0.65 belirsiz → temkinli davran/teyit ara) ve kararının gerekçesine sayısal değerleri yaz. TypeSafe yargısı SENİN yerine karar vermez — nihai karar ve risk yönetimi sende.\n'
|
|
2034
|
+
: ' TYPESAFE (typesafe-ai skill) SEÇİLİ ama API anahtarı ayarlı DEĞİL: kullanıcıya Ayarlar → TypeSafe sekmesinden anahtar girmesini söyle; o zamana kadar bu turda kendi analizinle devam et ve typesafe_decision aracını kullanma.\n';
|
|
2020
2035
|
}
|
|
2021
2036
|
const roleBlockFull = roleBlock + roleSkillBlock;
|
|
2022
2037
|
/* FİNANS EKİBİ: tüm finance ajanları tek DM grubundadır — sohbet grup
|
|
@@ -2032,7 +2047,7 @@ class Engine {
|
|
|
2032
2047
|
modeBlock2 + '\n' +
|
|
2033
2048
|
(roleBlockFull ? roleBlockFull + '\n' : '') +
|
|
2034
2049
|
(teamLine || '') +
|
|
2035
|
-
'MT5 ARAÇLARI: mt5_status (bağlantı), mt5_account (hesap), mt5_market (canlı fiyat), mt5_positions (açık pozisyonlar), mt5_orders (bekleyen emirler), mt5_history (kapanan işlemler), mt5_alerts (fiyat alarmı: kur/listele/sil — modu SEN seçersin: once/repeat), mt5_ogrenme (SEMBOL BAZLI ÖĞRENME: işlem istatistiği + dersler —
|
|
2050
|
+
'MT5 ARAÇLARI: mt5_status (bağlantı), mt5_account (hesap), mt5_market (canlı fiyat), mt5_positions (açık pozisyonlar), mt5_orders (bekleyen emirler), mt5_history (kapanan işlemler), mt5_alerts (fiyat alarmı: kur/listele/sil — modu SEN seçersin: once/repeat), mt5_ogrenme (SEMBOL + PERİYOT BAZLI ÖĞRENME: işlem istatistiği + periyot kırılımı + son hatalar + dersler — zarar/stop sonrası kind:"mistake" dersini ZORUNLU yaz, karar öncesi stats/list ile oku), mt5_limits (lot/pozisyon limitlerini gör/GÜNCELLE — yalnız trader; symbol ile SEMBOL BAZLI min/max lot — sembolün karakterine göre karar senin), mt5_ea (BeastFinance grafik panosu: status/ping/chart/note), mt5_trade (⚡PİYASA EMRİ: side:"buy"|"sell" ile ANLIK gir — bekleyen emir ZORUNLU DEĞİL; timeframe ver (M1..MN1, SEN seçersin — öğrenme o periyoda işlenir); lot için volume yerine riskPct+sl ver, sistem hesaplar; limit/stop tipleri de kabul eder), mt5_close (TAM ya da KISMİ kapat: percent ile kısmi TP & kısmi stop — karar ajanın), mt5_modify (SL/TP), mt5_pending (BEKLEYEN emir: limit/stop + price + timeframe — fiyatın seviyeye gelmesini beklemek için; anlık giriş için mt5_trade kullan), mt5_cancel (emir iptal).\n' +
|
|
2036
2051
|
'EMİR TİPLERİ (6 tip — HEPSİ AÇIK): buy_market/sell_market = anlık piyasa emri (fiyat beklenmez), buy_limit/sell_limit = bekleyen limit (price zorunlu), buy_stop/sell_stop = bekleyen stop (price zorunlu). mt5_trade ve mt5_pending İKİSİ DE 6 tipi kabul eder; emir tipini net söyle (ör. type:"sell_limit").\n' +
|
|
2037
2052
|
'⚡HIZLI AKSİYON (ZORUNLU ZİHNİYET): piyasa emri (market buy/sell) HER ZAMAN elinde ve bekleyen emir vermek ZORUNDA DEĞİLSİN. Fırsat anıksa / teyitli kırılım, momentum, haber veya seviye reddi anında mt5_trade {symbol, side:"buy"|"sell", sl, tp, riskPct ya da volume, reason} ile ANINDA market gir — type bile yazmana gerek yok. Bekleyen emir YALNIZ fiyatın seviyeye gelmesini beklemek gerçekten mantıklıysa kurulur (ör. geri çekilme limiti); "emir" diye her şeyi bekleyen emirle yapma. Hızlı girişte tek çağrı yeter: volume yerine riskPct+sl ver → lot otomatik hesaplanır.\n' +
|
|
2038
2053
|
'ALARM KARARI SENDE: mt5_alerts ile alarm kurarken mode ZORUNLU — "once" (tek seferlik; ilk tetiklemede kapanır) ya da "repeat" (tekrarlı; alarm açık kalır, koşul sürdükçe cooldownMin dakikada bir tekrar uyarır + seni uyandırır; cooldownMin varsayılan 5). Tekrarlı mı tek seferlik mi olacağını sen seç, varsayılana bırakma; seviyenin önemine göre cooldownMin belirle (ör. 5/15/60).\n' +
|
|
@@ -2082,8 +2097,9 @@ class Engine {
|
|
|
2082
2097
|
'- Martingale/kademeli lot artışı YASAK; kaybı geri kovalama (revenge trade) YASAK.\n' +
|
|
2083
2098
|
'- Emin olmadığında İŞLEM YOK — "BEKLE: <sebep>" yaz. Sık işlem tek başına iyi işlem değil; ama onaylı fırsatta HIZLI gir, kârı hızlı topla.\n' +
|
|
2084
2099
|
'- LOT KORKUSU YOK — önemli olan LOT DEĞİL, STOP YERİ ve risktir: SL yakın ve setup netse yüksek lot NORMALDİR (boyut zaten risk % + SL mesafesinden hesaplanır; sembol tavanı trader kararıdır). Tek işlemde serbest marjın tamamını riske atma; sık işlem için lotu değil, TUR RİTMİNİ (mt5_limits intervalSec) ve kısmi kâr alımını kullan.\n' +
|
|
2085
|
-
(
|
|
2086
|
-
|
|
2100
|
+
'ZAMAN DİLİMİ SENİN KARARIN (BOT KARARI): işlemi hangi periyodun analizine dayandırdıysan mt5_trade/mt5_pending çağrısında timeframe ver (M1|M5|M15|M30|H1|H4|D1|W1|MN1). Kapanış otomatik o periyoda işlenir; aynı sembolde hangi periyot kazandırıyorsa onu kullan, NEGATİF periyotta riski düşür ya da teyit bekle. Hiçbir sabit periyoda bağlı kalma — istatistik neyi söylüyorsa onu seç.\n' +
|
|
2101
|
+
(session && session.financeLearn ? `SEMBOL BAZLI ÖĞRENME HAFIZAN (otomatik istatistik + periyot kırılımı + son hatalar + kendi derslerin — kararlarında kullan):\n${session.financeLearn}\n` : '') +
|
|
2102
|
+
'ÖĞRENME DÖNGÜSÜ (ZORUNLU KISIM: zarardan ders): ZARAR/STOP ile kapanan her işlemden sonra mt5_ogrenme {action:"add", symbol, timeframe, kind:"mistake", text:"yanlış neydi + bundan sonra kaçınma kuralı"} ile hatayı MUTLAKA yaz — bu ders bir sonraki turların karar girdisine girer (tek kısa cümle, sebep-sonuç; ör. "M5 destek kırılımında teyitsiz girdim; kapanış teyidi beklemeliydim"). İşe yarayan deseni ise kind:"pattern" ile yaz (her kapanışa ders değil; günde en fazla 2-3). YASAK: günlük/rapor tarzı uzun metin ("bugün şunu yaptım"), genel laf ("dikkatli olmalıyım"), aynı dersin tekrarı. Karar öncesi mt5_ogrenme {action:"stats"|"list", symbol, timeframe?} ile periyot istatistiğini ve son hataları oku; TEKRAR EDEN HATA uyarısı varsa o periyotta riski düşür/teyit ara; aynı hatayı tekrarlama, işleyen deseni kullan. Hafıza kendini sadeleştirir: eski dersler otomatik özetlenir ve süresi geçenler unutulur; gerekirse mt5_ogrenme {action:"compact", symbol} ile hemen özetlet, geçersiz dersi remove/clear ile sil.\n' +
|
|
2087
2103
|
(session && session.financeStrategy ? `SAHİBİNİN STRATEJİ NOTU (önceliklidir):\n${session.financeStrategy}\n` : '') +
|
|
2088
2104
|
(session && session.financeShadow ? 'SHADOW MOD AKTİF: mt5_trade/mt5_pending emir GÖNDERMEZ — kararını teziyle raporla; gerçek işlem açılmaz (karar günlüğe yazılır).\n' : '') +
|
|
2089
2105
|
(session && session.financeDigest ? `İŞLEM PERFORMANS GEÇMİŞİN (kendi kayıtların — kararlarında ders çıkar):\n${session.financeDigest}\n` : '') +
|
|
@@ -5976,7 +5992,8 @@ const skills = require('./skills');
|
|
|
5976
5992
|
if (
|
|
5977
5993
|
!(name === 'run_command' || name === 'read_file' || name === 'write_file' || name === 'edit_file' ||
|
|
5978
5994
|
name === 'list_dir' || name === 'grep' || name === 'glob' ||
|
|
5979
|
-
name === 'web_search' || name === 'http_fetch' || name === 'webfetch' || name === 'python_run'
|
|
5995
|
+
name === 'web_search' || name === 'http_fetch' || name === 'webfetch' || name === 'python_run' ||
|
|
5996
|
+
name === 'typesafe_decision') &&
|
|
5980
5997
|
!FINANCE_TOOL_SET.has(name)
|
|
5981
5998
|
) {
|
|
5982
5999
|
return JSON.stringify({ ok: false, error: `unknown tool ${name}` });
|
|
@@ -101,6 +101,18 @@ function tickPrice(row, side) {
|
|
|
101
101
|
return Number(row && row.bid) || Number(row && row.ask) || 0;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
/* ZAMAN DİLİMİ: ajanın seçtiği periyot — işlem yorumuna yazılır ("Beast M15"),
|
|
105
|
+
watchdog pozisyondan okur ve kapanışta periyot bazlı öğrenmeye işler. */
|
|
106
|
+
const TF_VALID = new Set(['M1', 'M5', 'M15', 'M30', 'H1', 'H4', 'D1', 'W1', 'MN1']);
|
|
107
|
+
function normTimeframe(v) {
|
|
108
|
+
const s = String(v || '').trim().toUpperCase();
|
|
109
|
+
if (!s) return '';
|
|
110
|
+
const m = s.match(/^(M|H|D|W|MN)\s*(\d+)$/);
|
|
111
|
+
if (!m) return '';
|
|
112
|
+
const key = m[1] === 'MN' ? 'MN1' : m[1] + m[2];
|
|
113
|
+
return TF_VALID.has(key) ? key : '';
|
|
114
|
+
}
|
|
115
|
+
|
|
104
116
|
/* SEMBOL BAZLI LOT ARALIĞI (trader mt5_limits ile koyar): sembol limiti
|
|
105
117
|
varsa genel aralığın yerine geçer — yoksa genel minLot/maxLot kullanılır.
|
|
106
118
|
İki değer de broker normalizasyonuna girer (adım/min/max sembolden gelir). */
|
|
@@ -293,14 +305,15 @@ const definitions = NAMES.map((name) => {
|
|
|
293
305
|
},
|
|
294
306
|
mt5_ogrenme: {
|
|
295
307
|
description:
|
|
296
|
-
'SEMBOL BAZLI ÖĞRENME HAFIZASI — Beast Finance sürekli öğrenir: mt5_ogrenme {action:"list"|"add"|"remove"|"clear"|"stats"|"compact"|"forget", symbol?, text?, kind?, tags?, id?, ids?, all?, limit?}. Her sembolün KENDİ istatistiği (işlem/kazanç/kayıp, net, kâr yakalama, kâr geri verme) OTOMATİK birikir;
|
|
308
|
+
'SEMBOL + ZAMAN DİLİMİ BAZLI ÖĞRENME HAFIZASI — Beast Finance sürekli öğrenir: mt5_ogrenme {action:"list"|"add"|"remove"|"clear"|"stats"|"compact"|"forget", symbol?, timeframe?, text?, kind?, tags?, id?, ids?, all?, limit?}. Her sembolün KENDİ istatistiği (işlem/kazanç/kayıp, net, kâr yakalama, kâr geri verme) OTOMATİK birikir; timeframe verilirse PERİYOT kırılımı da tutulur (M5/M15/H1… hangi periyot kazandırıyor) ve yanlışlar hata kaydı olur. ZAMAN DİLİMİ SENİN KARARIN: işlemi mt5_trade/mt5_pending timeframe ile açarsan kapanış otomatik o periyoda işlenir; istatistikler periyot bazlıdır. DERS KURALLARI (SEÇİCİ): (1) Her kapanışa ders YAZMA — yalnız gerçekten öğrenilmiş, tekrar kullanılabilir, kanıtlı içgörüyü TEK KISA cümleyle kaydet (en fazla ~20 kelime / 200 karakter); ör. "XAUUSD M5 EMA50 üstü Londra açılışı momentumu 3/4 işledi". ZARAR/STOP olan her kapanışta İSE hata dersini SEN yazmalısın: kind:"mistake", text "yanlış neydi + bundan sonra kaçınma kuralı" (ör. "M5 destek kırılımında erken girdim; kapanış teyidi beklemeliydim"). YASAK: günlük/rapor tarzı uzun metin ("bugün şunu yaptım"), genel laf ("dikkatli olmalıyım"), tekrar. (2) Yeni işlem kararından ÖNCE ilgili sembolün stats (kompakt: istatistik + periyot kırılımı + kalıcı özet + son 3 ders + son hatalar) ya da list (son 8 ders; limit ile artır) çıktısını oku; aynı hatayı tekrarlama, işleyen deseni kullan, NEGATİF periyotta riski düşür. (3) Yanlış çıkan/genel geçersiz dersi remove/clear ile sil. Aynı ders tekrar yazılamaz; sembol başına 24 saatte en fazla 3 ders kabul edilir (kalite kapısı: çok kısa/uzun, günlük tarzı ve genel tavsiye metinleri reddedilir). HAFIZA KENDİNİ SADELEŞTİRİR (opencode tarzı compaction): ham dersler birikince (24+) ESKİ dersler OTOMATİK olarak modele özetlettirilir ve tek KALICI ÖZETE sıkıştırılır — ham yalnız son dersler kalır; 30 günden eski dersler, 90 günden eski işlem kayıtları ve 120 gün hareketsiz semboller otomatik unutulur. Gerekirse compact {symbol} ile hemen özetlet, forget ile süresi geçenleri temizle. action:"list" symbol verilmezse tüm sembollerin özetini döner (periyot kırılımı + kalıcı özet dahil).',
|
|
297
309
|
parameters: {
|
|
298
310
|
type: 'object',
|
|
299
311
|
properties: {
|
|
300
312
|
action: { type: 'string', enum: ['list', 'add', 'remove', 'clear', 'stats', 'compact', 'forget'] },
|
|
301
313
|
symbol: { type: 'string', description: 'Sembol (ör. XAUUSD) — öğrenme sembol bazlıdır' },
|
|
302
|
-
|
|
303
|
-
|
|
314
|
+
timeframe: { type: 'string', description: 'Zaman dilimi (M1|M5|M15|M30|H1|H4|D1|W1|MN1) — add: dersin periyodu; list/stats: yalnız o periyodu filtrele (boş = tümü)' },
|
|
315
|
+
text: { type: 'string', description: 'add: öğrenilen ders — TEK kısa cümle (en fazla ~20 kelime/200 karakter), somut ve tekrar kullanılabilir; zarar sonrası kind:"mistake" ile "yanlış + kaçınma kuralı" yaz' },
|
|
316
|
+
kind: { type: 'string', enum: ['pattern', 'mistake', 'rule', 'observation'], description: 'add: kayıt türü (zarar/stop sonrası hata dersi → mistake)' },
|
|
304
317
|
tags: { type: 'array', items: { type: 'string' }, description: 'add: etiketler (ör. ["scalp","london"])' },
|
|
305
318
|
id: { type: 'string', description: 'remove: kayıt id' },
|
|
306
319
|
ids: { type: 'array', items: { type: 'string' }, description: 'clear: silinecek kayıt id listesi' },
|
|
@@ -335,7 +348,7 @@ const definitions = NAMES.map((name) => {
|
|
|
335
348
|
},
|
|
336
349
|
mt5_trade: {
|
|
337
350
|
description:
|
|
338
|
-
'ANLIK PİYASA EMRİ AÇAR — ⚡HIZLI AKSİYON; bekleyen emir vermek ZORUNLU DEĞİL: mt5_trade {symbol, side:"buy"|"sell", volume?|riskPct?, sl?, tp?, type?, comment?, reason?}. Fırsat anıksa / teyitli kırılım-momentum-haber anında market buy/sell ile HEMEN gir — side:"buy"|"sell" yeter (type gerekmez; type:"market"|"buy_market"|"sell_market" de anlıktır). BEKLEYEN emir yalnız fiyatın bir seviyeye gelmesini beklemek gerçekten mantıklıysa kurulur: type:"buy_limit"|"sell_limit"|"buy_stop"|"sell_stop" + price (bu tipler otomatik mt5_pending hattına gider). LOT: volume ver ya da volume yerine riskPct + sl ver — sistem SL mesafesinden lotu hesaplar (tek çağrıda giriş; ayardaki işlem riski % varsayılan). Lot limiti, max pozisyon, marj ve yoğunluk sistemce zorlanır. SL vermek ŞİDDETLİ önerilir. reason: kararın tek cümlelik tezi (günlüğe yazılır).',
|
|
351
|
+
'ANLIK PİYASA EMRİ AÇAR — ⚡HIZLI AKSİYON; bekleyen emir vermek ZORUNLU DEĞİL: mt5_trade {symbol, side:"buy"|"sell", volume?|riskPct?, sl?, tp?, timeframe?, type?, comment?, reason?}. Fırsat anıksa / teyitli kırılım-momentum-haber anında market buy/sell ile HEMEN gir — side:"buy"|"sell" yeter (type gerekmez; type:"market"|"buy_market"|"sell_market" de anlıktır). BEKLEYEN emir yalnız fiyatın bir seviyeye gelmesini beklemek gerçekten mantıklıysa kurulur: type:"buy_limit"|"sell_limit"|"buy_stop"|"sell_stop" + price (bu tipler otomatik mt5_pending hattına gider). ZAMAN DİLİMİ SENİN KARARIN: işlemi hangi periyodun (M5/M15/H1…) analizine dayandırdıysan timeframe ile ver — öğrenme bu periyoda yazılır; aynı sembolde en iyi istatistik gösteren periyodu tercih et, negatif periyotta riski düşür. LOT: volume ver ya da volume yerine riskPct + sl ver — sistem SL mesafesinden lotu hesaplar (tek çağrıda giriş; ayardaki işlem riski % varsayılan). Lot limiti, max pozisyon, marj ve yoğunluk sistemce zorlanır. SL vermek ŞİDDETLİ önerilir. reason: kararın tek cümlelik tezi (günlüğe yazılır).',
|
|
339
352
|
parameters: {
|
|
340
353
|
type: 'object',
|
|
341
354
|
properties: {
|
|
@@ -346,6 +359,7 @@ const definitions = NAMES.map((name) => {
|
|
|
346
359
|
enum: ['market', 'buy_market', 'sell_market', 'buy_limit', 'sell_limit', 'buy_stop', 'sell_stop'],
|
|
347
360
|
description: 'Emir tipi. Boş/side verilirse piyasa (anlık); limit/stop verilirse bekleyen emir (price zorunlu olur).',
|
|
348
361
|
},
|
|
362
|
+
timeframe: { type: 'string', description: 'İşlemin dayandığı periyot (M1|M5|M15|M30|H1|H4|D1|W1|MN1) — SEN seçersin; öğrenme/istatistik bu periyoda yazılır (boş = belirsiz)' },
|
|
349
363
|
volume: { type: 'number', description: 'Lot (min/max lot sınırına tabi) — boşsa riskPct + sl ile OTOMATİK hesaplanır' },
|
|
350
364
|
riskPct: { type: 'number', description: 'İşlem riski % (ör. 0.5-2) — volume yerine ver: SL mesafesinden lot hesaplanır (sl zorunlu)' },
|
|
351
365
|
price: { type: 'number', description: 'Limit/stop emirlerinde tetik fiyatı (piyasa emrinde gerekmez)' },
|
|
@@ -386,7 +400,7 @@ const definitions = NAMES.map((name) => {
|
|
|
386
400
|
},
|
|
387
401
|
mt5_pending: {
|
|
388
402
|
description:
|
|
389
|
-
'BEKLEYEN EMİR (limit/stop) AÇAR: mt5_pending {symbol, type:"buy_limit"|"sell_limit"|"buy_stop"|"sell_stop", volume, price, sl?, tp?, reason?}. Fiyatın seviyeye gelmesini beklemek için kullanılır. ⚡ANLIK giriş (hızlı aksiyon) için bunu kullanma — mt5_trade {symbol, side} ile market gir (buy_market/sell_market tipleri burada da kabul edilir ve anlık emre yönlenir). Otomatik işlem anahtarına tabidir. reason: kararın tezi (günlüğe yazılır).',
|
|
403
|
+
'BEKLEYEN EMİR (limit/stop) AÇAR: mt5_pending {symbol, type:"buy_limit"|"sell_limit"|"buy_stop"|"sell_stop", volume, price, sl?, tp?, timeframe?, reason?}. Fiyatın seviyeye gelmesini beklemek için kullanılır. ⚡ANLIK giriş (hızlı aksiyon) için bunu kullanma — mt5_trade {symbol, side} ile market gir (buy_market/sell_market tipleri burada da kabul edilir ve anlık emre yönlenir). ZAMAN DİLİMİ SENİN KARARIN: timeframe ile işlemin dayandığı periyodu ver — öğrenme o periyoda yazılır. Otomatik işlem anahtarına tabidir. reason: kararın tezi (günlüğe yazılır).',
|
|
390
404
|
parameters: {
|
|
391
405
|
type: 'object',
|
|
392
406
|
properties: {
|
|
@@ -396,6 +410,7 @@ const definitions = NAMES.map((name) => {
|
|
|
396
410
|
enum: ['buy_limit', 'sell_limit', 'buy_stop', 'sell_stop', 'buy_market', 'sell_market'],
|
|
397
411
|
description: 'Limit/stop = bekleyen (price zorunlu); buy_market/sell_market = anlık piyasa emri',
|
|
398
412
|
},
|
|
413
|
+
timeframe: { type: 'string', description: 'İşlemin dayandığı periyot (M1|M5|M15|M30|H1|H4|D1|W1|MN1) — SEN seçersin; öğrenme bu periyoda yazılır' },
|
|
399
414
|
volume: { type: 'number' },
|
|
400
415
|
price: { type: 'number', description: 'Tetik fiyatı — limit/stop için zorunlu, market tiplerinde gerekmez' },
|
|
401
416
|
sl: { type: 'number' },
|
|
@@ -599,13 +614,14 @@ const handlers = {
|
|
|
599
614
|
async mt5_ogrenme(args, ctx) {
|
|
600
615
|
const action = String(args.action || 'list').toLowerCase();
|
|
601
616
|
const symbol = String(args.symbol || '').trim().toUpperCase();
|
|
617
|
+
const timeframe = normTimeframe(args.timeframe);
|
|
602
618
|
if (action === 'list') {
|
|
603
619
|
/* kompakt okuma: varsayılan son 8 ders (limit ile artırılır, max 25) —
|
|
604
620
|
hafızanın tamamı ajana gönderilmez */
|
|
605
621
|
const limit = Math.round(Number(args.limit) || 0);
|
|
606
|
-
return learningApi.list({ symbol, limit: limit > 0 ? limit : 8 });
|
|
622
|
+
return learningApi.list({ symbol, timeframe, limit: limit > 0 ? limit : 8 });
|
|
607
623
|
}
|
|
608
|
-
if (action === 'stats') return learningApi.stats({ symbol });
|
|
624
|
+
if (action === 'stats') return learningApi.stats({ symbol, timeframe });
|
|
609
625
|
if (action === 'add') {
|
|
610
626
|
const text = String(args.text || '').replace(/\s+/g, ' ').trim();
|
|
611
627
|
if (!symbol) return { ok: false, error: 'symbol gerekli — öğrenme sembol bazlıdır' };
|
|
@@ -615,9 +631,9 @@ const handlers = {
|
|
|
615
631
|
const tags = Array.isArray(args.tags) ? args.tags.map((t) => String(t || '').trim()).filter(Boolean).slice(0, 6) : [];
|
|
616
632
|
/* metin AYNEN geçer: kalite kapısı (kısa+somut) main tarafında çalışır —
|
|
617
633
|
uzun/günlük metin sessizce kırpılmaz, ajan net hata alıp kısaltır */
|
|
618
|
-
const res = learningApi.add({ symbol, text, kind, tags, sid: (ctx && ctx.sessionId) || '' });
|
|
634
|
+
const res = learningApi.add({ symbol, text, kind, tags, timeframe, sid: (ctx && ctx.sessionId) || '' });
|
|
619
635
|
if (res && res.ok) {
|
|
620
|
-
noteTrade('learn', { symbol, text: text.slice(0, 200), kind }, ctx || {});
|
|
636
|
+
noteTrade('learn', { symbol, text: text.slice(0, 200), kind, timeframe }, ctx || {});
|
|
621
637
|
}
|
|
622
638
|
return res;
|
|
623
639
|
}
|
|
@@ -752,6 +768,11 @@ const handlers = {
|
|
|
752
768
|
const side = t.side;
|
|
753
769
|
const symbol = String(args.symbol || '').trim().toUpperCase();
|
|
754
770
|
if (!symbol) return { ok: false, error: 'symbol gerekli' };
|
|
771
|
+
/* ZAMAN DİLİMİ (bot kararı): emir yorumuna yazılır — watchdog pozisyondan
|
|
772
|
+
okur, kapanışta periyot bazlı öğrenmeye işler */
|
|
773
|
+
const timeframe = normTimeframe(args.timeframe);
|
|
774
|
+
const baseComment = String(args.comment || '').trim();
|
|
775
|
+
const orderComment = (timeframe ? `Beast ${timeframe}${baseComment ? ' ' + baseComment : ''}` : baseComment || 'Beast').slice(0, 26);
|
|
755
776
|
const range = lotRange(cfg, symbol);
|
|
756
777
|
const sl = Number(args.sl) || 0;
|
|
757
778
|
const tp = Number(args.tp) || 0;
|
|
@@ -796,13 +817,14 @@ const handlers = {
|
|
|
796
817
|
volume: vol,
|
|
797
818
|
sl,
|
|
798
819
|
tp,
|
|
820
|
+
timeframe,
|
|
799
821
|
reason: String(args.reason || '').slice(0, 500),
|
|
800
822
|
risk: riskInfo,
|
|
801
823
|
}, ctx);
|
|
802
824
|
return {
|
|
803
825
|
ok: true,
|
|
804
826
|
shadow: true,
|
|
805
|
-
planned: { symbol, side, volume: vol, sl, tp },
|
|
827
|
+
planned: { symbol, side, volume: vol, sl, tp, timeframe: timeframe || null },
|
|
806
828
|
risk: riskInfo,
|
|
807
829
|
note: 'SHADOW MOD: emir GÖNDERİLMEDİ, karar günlüğe yazıldı. Gerçek işlem için TRADE AJANI ayarlarından shadow modu kapat.',
|
|
808
830
|
};
|
|
@@ -814,10 +836,10 @@ const handlers = {
|
|
|
814
836
|
sl,
|
|
815
837
|
tp,
|
|
816
838
|
deviation: 20,
|
|
817
|
-
comment:
|
|
839
|
+
comment: orderComment,
|
|
818
840
|
}, 20000);
|
|
819
|
-
noteTrade('trade', { symbol, side, volume: vol, sl, tp, risk: riskInfo, comment: String(args.comment || ''), reason: String(args.reason || '').slice(0, 500), result: data && data.result }, ctx);
|
|
820
|
-
return { ok: true, opened: { symbol, side, volume: vol, sl, tp }, risk: riskInfo, result: data && data.result };
|
|
841
|
+
noteTrade('trade', { symbol, side, volume: vol, sl, tp, timeframe, risk: riskInfo, comment: String(args.comment || ''), reason: String(args.reason || '').slice(0, 500), result: data && data.result }, ctx);
|
|
842
|
+
return { ok: true, opened: { symbol, side, volume: vol, sl, tp, timeframe: timeframe || null }, risk: riskInfo, result: data && data.result };
|
|
821
843
|
},
|
|
822
844
|
async mt5_close(args, ctx) {
|
|
823
845
|
if (!mt5.running) return notConnected();
|
|
@@ -890,6 +912,11 @@ const handlers = {
|
|
|
890
912
|
if (!mt5.running) return notConnected();
|
|
891
913
|
const symbol = String(args.symbol || '').trim().toUpperCase();
|
|
892
914
|
if (!symbol) return { ok: false, error: 'symbol gerekli' };
|
|
915
|
+
/* ZAMAN DİLİMİ (bot kararı): yorumla birlikte saklanır; pozisyon aktifleşip
|
|
916
|
+
kapandığında öğrenme bu periyoda yazılır */
|
|
917
|
+
const timeframe = normTimeframe(args.timeframe);
|
|
918
|
+
const baseComment = String(args.comment || '').trim();
|
|
919
|
+
const orderComment = (timeframe ? `Beast ${timeframe}${baseComment ? ' ' + baseComment : ''}` : baseComment || 'Beast').slice(0, 26);
|
|
893
920
|
const info = await symInfoRow(symbol);
|
|
894
921
|
if (!info) return { ok: false, error: 'sembol bulunamadı: ' + symbol + ' (MT5 Market Watch?)' };
|
|
895
922
|
const range = lotRange(cfg, symbol);
|
|
@@ -907,7 +934,7 @@ const handlers = {
|
|
|
907
934
|
if (discErr) return { ok: false, error: discErr };
|
|
908
935
|
/* SHADOW MOD: bekleyen emir de GÖNDERİLMEZ — tez günlüğe düşer */
|
|
909
936
|
if (cfg.shadowMode) {
|
|
910
|
-
noteTrade('shadow', { symbol, type: ptype, side: pside, volume: vol, price: Number(args.price) || 0, sl: Number(args.sl) || 0, tp: Number(args.tp) || 0, reason: String(args.reason || '').slice(0, 500) }, ctx);
|
|
937
|
+
noteTrade('shadow', { symbol, type: ptype, side: pside, volume: vol, price: Number(args.price) || 0, sl: Number(args.sl) || 0, tp: Number(args.tp) || 0, timeframe, reason: String(args.reason || '').slice(0, 500) }, ctx);
|
|
911
938
|
return { ok: true, shadow: true, note: 'SHADOW MOD: bekleyen emir GÖNDERİLMEDİ, karar günlüğe yazıldı.' };
|
|
912
939
|
}
|
|
913
940
|
const data = await bcall('pending', {
|
|
@@ -917,10 +944,10 @@ const handlers = {
|
|
|
917
944
|
price: Number(args.price) || 0,
|
|
918
945
|
sl: Number(args.sl) || 0,
|
|
919
946
|
tp: Number(args.tp) || 0,
|
|
920
|
-
comment:
|
|
947
|
+
comment: orderComment,
|
|
921
948
|
}, 20000);
|
|
922
|
-
noteTrade('pending', { symbol, type: ptype, volume: vol, reason: String(args.reason || '').slice(0, 500) }, ctx);
|
|
923
|
-
return { ok: true, result: data && data.result };
|
|
949
|
+
noteTrade('pending', { symbol, type: ptype, volume: vol, timeframe, reason: String(args.reason || '').slice(0, 500) }, ctx);
|
|
950
|
+
return { ok: true, result: data && data.result, timeframe: timeframe || null };
|
|
924
951
|
},
|
|
925
952
|
async mt5_cancel(args, ctx) {
|
|
926
953
|
if (!mt5.running) return notConnected();
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: typesafe-ai
|
|
3
|
+
description: TypeSafe System One (Jev) ile TİPLİ KARAR rehberi — semantik/olasılıklı yargıları (haber-makro etkisi, setup kalitesi, yön/aksiyon seçimi, tez doğrulama, sınıflandırma, yeniden sıralama) chat modeline metin yazdırıp JSON ayrıştırmak yerine typesafe_decision aracıyla kalibre olasılıklı yanıt olarak al. Olasılık eşikleri, soru tasarımı (noul/choice/score), tek çağrıda çoklu soru ve hata yönetimi burada. Bir karar "evet/hayır", "hangisi" ya da "ne kadar" sorusuna indirgenebiliyorsa ÖNCE bu skill'i oku.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# TypeSafe (System One · Jev) — Tipli Karar Rehberi
|
|
8
|
+
|
|
9
|
+
## NE ZAMAN KULLANILIR
|
|
10
|
+
|
|
11
|
+
Karar zaten bir soruya indirgenebiliyorsa ve cevap SAYIYLA (olasılık/puan) işe yarayacaksa `typesafe_decision` kullan. Chat modeli cevap metni yazar; sen metni tekrar yorumlarsın. TypeSafe metin üretmez — doğrudan `noul` (0-1 evet), `choice` (seçenek + dağılım), `score` (ağırlıklı puan + dağılım) döner. Bu daha hızlı, daha ucuz ve kalibrelidir.
|
|
12
|
+
|
|
13
|
+
KULLANMA: yaratıcı metin, uzun analiz yazısı, kod yazma, çok adımlı akıl yürütme (bunlar chat modelinin işi). TypeSafe tek, dar, bağımsız yargılar içindir.
|
|
14
|
+
|
|
15
|
+
## ARAÇ ÇAĞRISI
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
typesafe_decision {
|
|
19
|
+
state: <tüm somut bağlam — haber metni, fiyat/seviye, pozisyon, geçmiş, politika>,
|
|
20
|
+
questions: {
|
|
21
|
+
<id>: { type: "noul", instructions: "Bu haber X'i yukarı iter mi?", criteria: { true: "...", false: "..." } },
|
|
22
|
+
<id>: { type: "choice", instructions: "Bu setup için doğru aksiyon?", criteria: { al: "...", bekle: "...", pas: "..." } },
|
|
23
|
+
<id>: { type: "score", instructions: "Setup kalitesi?", criteria: ["Çöp", "Zayıf", "Orta", "İyi", "A sınıfı"] }
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- `state`: model YALNIZ bunu görür. Eksik bağlam = kötü karar. Sembol, fiyat, seviyeler, haber metninin kendisi, pozisyon ve risk bilgisini koy. Nesne/dizi de verebilirsin (ör. `{ sembol, fiyat, mtfYapi, haber, pozisyon }`).
|
|
29
|
+
- Soru id'leri kod içindir; modele gitmez — anlamı `instructions` içinde tam yaz.
|
|
30
|
+
- `criteria`: choice → `{seçenek: açıklama|null}` (en az 2), score → sıralı `["seviye1", ...]` (en az 2), noul → `{true, false}` açıklamaları (opsiyonel ama önerilir).
|
|
31
|
+
- BAĞIMSIZ soruları TEK çağrıda birlikte sor: her soru ayrı token/gecikme demektir; toplu soru aynı state'i bir kez okur.
|
|
32
|
+
|
|
33
|
+
## SORU TASARIMI
|
|
34
|
+
|
|
35
|
+
- Soru BAŞINA tek yargı: "hem yön hem zamanlama" sorma; iki soru yap. Bağımsız boyutları ayır, ilişkiyi bozma.
|
|
36
|
+
- Bir sonraki soru önceki cevaba bağlıysa ikinci çağrı yap (önce yön: noul → sonra giriş bölgesi: choice).
|
|
37
|
+
- "Yok/eşleşme yok" ihtimali gerçekse choice'a `yok` seçeneği ekle.
|
|
38
|
+
- Spekülatif soruları da sor: aynı state üzerinde "şu senaryo gerçekleşirse..." yargısı bedava gelir, kod yalnız gerekenini kullanır.
|
|
39
|
+
|
|
40
|
+
## OLASILIKLARI YORUMLAMA
|
|
41
|
+
|
|
42
|
+
- noul: 0.5 = bilgi yok denecek kadar belirsiz (yoğunluk değil). >0.65 güçlü kanaat, <0.35 karşı yön güçlü, 0.35-0.65 → temkinli davran / ek teyit ara / küçük risk.
|
|
43
|
+
- choice/score `confidence`: dağılımın yoğunluğu — workfloun doğruluğu DEĞİL, aksiyon izni DEĞİL. Düşük confidence'ta kesin konuşma, olasılıkları raporla.
|
|
44
|
+
- Eşikleri işlemin/kararın SONUCUNA göre seç: geri dönüşü kolay kararda 0.55 yeter; para/risk kararında 0.7+ ve teyit ara.
|
|
45
|
+
- Sayıları kararına YAZ: "javAX: noul=0.78, yön yukarı; kalite score=3.4/5" gibi. Gerekçesiz "TypeSafe öyle dedi" yasak — birincil veriyle (fiyat/yapı/haber) çapraz kontrol et.
|
|
46
|
+
|
|
47
|
+
## BEAST FINANCE ÖRNEKLERİ
|
|
48
|
+
|
|
49
|
+
- Haber etkisi: `noul` — "Bu haber X'i kısa vadede yukarı iter mi?" state: haber metni + sembol + mevcut yapı.
|
|
50
|
+
- Aksiyon seçimi: `choice` — `{gir, bekle_geri_cek, pas}` state: setup + risk limitleri + açık pozisyonlar.
|
|
51
|
+
- Setup kalitesi: `score` — levels: `["Çöp","Zayıf","Orta","İyi","A sınıfı"]`; >3.5 değilse riski düşür.
|
|
52
|
+
- Tez doğrulama: `noul` — "Fiyat yapısı bu LONG tezini destekliyor mu?" state: tez + son mumlar/OHLC özeti.
|
|
53
|
+
- Haber-tekrar filtresi: `noul` — "Bu haber son 24 saatte fiyatlanmış mı?" state: manşet + fiyat değişimi.
|
|
54
|
+
|
|
55
|
+
## HATA YÖNETİMİ
|
|
56
|
+
|
|
57
|
+
- "API anahtarı yok" → kullanıcıya Ayarlar → TypeSafe'ten anahtar girmesini söyle; o turda kendi analizinle devam et, aracı zorlama.
|
|
58
|
+
- 401/403 → anahtar geçersiz; 429/529 → bekle, kritik değilse atla (tekrar denemeyi turu kilitlemeden yap).
|
|
59
|
+
- 422 → questions/state biçimini düzelt (choice criteria nesne, score dizi olmalı).
|
|
60
|
+
- Anahtarını asla rapor/log/skill metnine YAZMA — Ayarlar → TypeSafe girer.
|
package/src/agent/tools.js
CHANGED
|
@@ -13,6 +13,7 @@ const searxng = require('./searxng');
|
|
|
13
13
|
const gittools = require('./gittools');
|
|
14
14
|
const repomap = require('./repomap');
|
|
15
15
|
const xlsxtools = require('./xlsxtools');
|
|
16
|
+
const typesafe = require('./typesafe');
|
|
16
17
|
let financetools = null;
|
|
17
18
|
try { financetools = require('./financetools'); } catch {}
|
|
18
19
|
|
|
@@ -1793,11 +1794,12 @@ function readCacheDrop(abs) {
|
|
|
1793
1794
|
}
|
|
1794
1795
|
|
|
1795
1796
|
const definitions = [
|
|
1796
|
-
/* yerleşik modül araçları: git, repo haritası, excel, finance (MT5) */
|
|
1797
|
+
/* yerleşik modül araçları: git, repo haritası, excel, finance (MT5), TypeSafe */
|
|
1797
1798
|
...gittools.definitions,
|
|
1798
1799
|
...repomap.definitions,
|
|
1799
1800
|
...xlsxtools.definitions,
|
|
1800
1801
|
...(financetools ? financetools.definitions : []),
|
|
1802
|
+
...typesafe.definitions,
|
|
1801
1803
|
{
|
|
1802
1804
|
type: 'function',
|
|
1803
1805
|
function: {
|
|
@@ -2080,11 +2082,12 @@ const definitions = [
|
|
|
2080
2082
|
|
|
2081
2083
|
async function exec(name, args, ctx) {
|
|
2082
2084
|
const cwd = ctx.cwd;
|
|
2083
|
-
/* modül araçları: gittools / repomap / xlsxtools / financetools — kendi handler'larında */
|
|
2085
|
+
/* modül araçları: gittools / repomap / xlsxtools / financetools / typesafe — kendi handler'larında */
|
|
2084
2086
|
const modHandler =
|
|
2085
2087
|
gittools.handlers[name] ||
|
|
2086
2088
|
repomap.handlers[name] ||
|
|
2087
2089
|
xlsxtools.handlers[name] ||
|
|
2090
|
+
typesafe.handlers[name] ||
|
|
2088
2091
|
(financetools && financetools.handlers[name]);
|
|
2089
2092
|
if (modHandler) {
|
|
2090
2093
|
try {
|