beast-agent 2.60.0 → 2.61.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 +1 -1
- package/src/main.js +119 -3
- package/src/renderer/renderer.js +1 -0
package/package.json
CHANGED
package/src/main.js
CHANGED
|
@@ -11446,6 +11446,9 @@ function finAgentStop(sid, reason) {
|
|
|
11446
11446
|
const agent = financeState.agents.get(sid);
|
|
11447
11447
|
if (!agent) return false;
|
|
11448
11448
|
clearTimeout(agent.timer);
|
|
11449
|
+
if (agent.waitPoll) { clearTimeout(agent.waitPoll); agent.waitPoll = null; }
|
|
11450
|
+
agent.waitingTeam = false;
|
|
11451
|
+
agent.consultPromise = null;
|
|
11449
11452
|
financeState.agents.delete(sid);
|
|
11450
11453
|
if (sid === String(financeState.traderSid || '')) financeState.traderSid = null;
|
|
11451
11454
|
try {
|
|
@@ -11465,6 +11468,22 @@ function finAgentStop(sid, reason) {
|
|
|
11465
11468
|
/* AJAN DM: duran ajanın birebir sohbetleri kapanır; grupta KOŞAN üye
|
|
11466
11469
|
kalmadıysa ekip sohbeti de GEÇMİŞE düşer (aktif listede kalmaz) */
|
|
11467
11470
|
try { if (engine && engine._agentDmClose) engine._agentDmClose(sid); } catch {}
|
|
11471
|
+
/* EKİP AJANI DURDU: bekleyen trader varsa hemen değerlendir (deadlock yok) */
|
|
11472
|
+
if (agent.role) {
|
|
11473
|
+
for (const [msid, ma] of financeState.agents) {
|
|
11474
|
+
if (ma && ma.main && ma.waitingTeam) { try { finTeamWaitTick(msid); } catch {} break; }
|
|
11475
|
+
}
|
|
11476
|
+
}
|
|
11477
|
+
/* ANA TRADER DURDU: ekip cycle'sız kaldı — kendi timer'ıyla dönmeye devam etsin */
|
|
11478
|
+
if (agent.main) {
|
|
11479
|
+
const iv = Math.max(30, Number(finCfg().intervalSec) || 120) * 1000;
|
|
11480
|
+
for (const [tsid, ta] of financeState.agents) {
|
|
11481
|
+
if (!ta || !ta.role) continue;
|
|
11482
|
+
if (engine && engine.isBusy(tsid)) continue;
|
|
11483
|
+
clearTimeout(ta.timer);
|
|
11484
|
+
ta.timer = setTimeout(() => { try { finAgentRound(String(tsid)); } catch {} }, iv);
|
|
11485
|
+
}
|
|
11486
|
+
}
|
|
11468
11487
|
finPush('trader', { state: 'idle', rounds: financeState.traderRounds });
|
|
11469
11488
|
return true;
|
|
11470
11489
|
}
|
|
@@ -11604,8 +11623,57 @@ async function finConsultPlan(f, agent, sid) {
|
|
|
11604
11623
|
}
|
|
11605
11624
|
}
|
|
11606
11625
|
|
|
11626
|
+
/* ---------- CYCLE ORKESTRASYONU: trader turu ekip raporlarını BEKLER ----------
|
|
11627
|
+
Ana trader kendi turuna başlamadan önce koşan analiz ekibi ajanlarını
|
|
11628
|
+
(teknik/risk/macro/visual) tura sokar ve O ANKİ turları bitene kadar bekler —
|
|
11629
|
+
böylece finTeamDigest her zaman TAZE rapor taşır. Sembol işçileri beklenmez.
|
|
11630
|
+
Ekip ajanları ana trader koşarken kendi başına tur planlamaz
|
|
11631
|
+
(finFlushOnDone); sıradaki turlarını cycle başlatır. */
|
|
11632
|
+
function finTeamAgents() {
|
|
11633
|
+
const out = [];
|
|
11634
|
+
try {
|
|
11635
|
+
for (const [sid, a] of financeState.agents) {
|
|
11636
|
+
if (a && a.role) out.push({ sid: String(sid), agent: a, def: finRoleDef(a.role) });
|
|
11637
|
+
}
|
|
11638
|
+
} catch {}
|
|
11639
|
+
return out;
|
|
11640
|
+
}
|
|
11641
|
+
|
|
11642
|
+
function finTeamHasMain() {
|
|
11643
|
+
try {
|
|
11644
|
+
for (const [, a] of financeState.agents) if (a && a.main) return true;
|
|
11645
|
+
} catch {}
|
|
11646
|
+
return false;
|
|
11647
|
+
}
|
|
11648
|
+
|
|
11649
|
+
/* Takılma valfi: ekip turu bu süreyi aşarsa trader eski raporla başlar */
|
|
11650
|
+
function finTeamWaitMaxMs() {
|
|
11651
|
+
const iSec = Math.max(30, Number(finCfg().intervalSec) || 120);
|
|
11652
|
+
return Math.max(60, Math.min(300, iSec)) * 1000;
|
|
11653
|
+
}
|
|
11654
|
+
|
|
11655
|
+
/* Ekip ajanı bittiğinde/durduğunda ya da 2 sn'lik yoklamada çağrılır:
|
|
11656
|
+
bekleyen trader'ın turunu açar (rapor taze) ya da beklemeye devam eder. */
|
|
11657
|
+
function finTeamWaitTick(sid) {
|
|
11658
|
+
const agent = financeState.agents.get(String(sid));
|
|
11659
|
+
if (!agent || !agent.main || !agent.waitingTeam) return;
|
|
11660
|
+
if (agent.waitPoll) { clearTimeout(agent.waitPoll); agent.waitPoll = null; }
|
|
11661
|
+
const busy = finTeamAgents().filter((t) => engine && engine.isBusy(t.sid));
|
|
11662
|
+
const expired = Date.now() >= Number(agent.waitDeadline || 0);
|
|
11663
|
+
if (busy.length && !expired) {
|
|
11664
|
+
agent.waitPoll = setTimeout(() => { try { finTeamWaitTick(sid); } catch {} }, 2000);
|
|
11665
|
+
return;
|
|
11666
|
+
}
|
|
11667
|
+
agent.waitingTeam = false;
|
|
11668
|
+
/* MAKS BEKLEME AŞILDI: geç kalanlar rapor prefix'ine açıkça notlanır */
|
|
11669
|
+
agent.waitLateNames = expired && busy.length
|
|
11670
|
+
? busy.map((t) => (t.def ? t.def.label : t.agent.role || t.sid))
|
|
11671
|
+
: [];
|
|
11672
|
+
finAgentRound(sid, { noTeamWait: true });
|
|
11673
|
+
}
|
|
11674
|
+
|
|
11607
11675
|
/* Bir ajanın TEK turu: (opsiyonel) ana ajan planı + tur emri */
|
|
11608
|
-
function finAgentRound(sid) {
|
|
11676
|
+
function finAgentRound(sid, opts) {
|
|
11609
11677
|
const agent = financeState.agents.get(String(sid));
|
|
11610
11678
|
if (!agent || !engine) return;
|
|
11611
11679
|
/* TRADE SAATLERİ KAPISI: aralık dışında YENİ TUR BAŞLATILMAZ — ajan askıya
|
|
@@ -11621,9 +11689,36 @@ function finAgentRound(sid) {
|
|
|
11621
11689
|
/* hâlâ çalışıyor — done eventinde tekrar planlanır */
|
|
11622
11690
|
return;
|
|
11623
11691
|
}
|
|
11692
|
+
const f = finCfg();
|
|
11693
|
+
/* EKİP BEKLEMESİ SÜRÜYOR: DM uyandırması vb. turu erkene çekemez — tick açar */
|
|
11694
|
+
if (agent.main && agent.waitingTeam && !(opts && opts.noTeamWait)) return;
|
|
11695
|
+
/* CYCLE KAPISI: karar turundan ÖNCE ekip ajanlarını tura sok, O ANKİ
|
|
11696
|
+
turları bitmeden trader'ı başlatma (rapor tazeliği garantisi). */
|
|
11697
|
+
if (agent.main && !(opts && opts.noTeamWait)) {
|
|
11698
|
+
const team = finTeamAgents();
|
|
11699
|
+
if (team.length) {
|
|
11700
|
+
for (const t of team) {
|
|
11701
|
+
if (engine.isBusy(t.sid)) continue;
|
|
11702
|
+
clearTimeout(t.agent.timer);
|
|
11703
|
+
t.agent.timer = null;
|
|
11704
|
+
try { finAgentRound(t.sid); } catch {}
|
|
11705
|
+
}
|
|
11706
|
+
const busy = team.filter((t) => engine.isBusy(t.sid));
|
|
11707
|
+
if (busy.length) {
|
|
11708
|
+
agent.waitingTeam = true;
|
|
11709
|
+
agent.waitDeadline = Date.now() + finTeamWaitMaxMs();
|
|
11710
|
+
/* danışma planı bekleme SIRASINDA üretilir — tur gecikmesi gizlenir */
|
|
11711
|
+
if (!agent.consultPromise && f.consultChat !== false) {
|
|
11712
|
+
agent.consultPromise = finConsultPlan(f, agent, String(sid)).catch(() => '');
|
|
11713
|
+
}
|
|
11714
|
+
finPush('trader', { state: 'team', round: (Number(agent.round) || 0) + 1, waiting: busy.length, maxSec: Math.round(finTeamWaitMaxMs() / 1000) });
|
|
11715
|
+
agent.waitPoll = setTimeout(() => { try { finTeamWaitTick(sid); } catch {} }, 2000);
|
|
11716
|
+
return;
|
|
11717
|
+
}
|
|
11718
|
+
}
|
|
11719
|
+
}
|
|
11624
11720
|
agent.round += 1;
|
|
11625
11721
|
if (agent.main) financeState.traderRounds = agent.round;
|
|
11626
|
-
const f = finCfg();
|
|
11627
11722
|
const roleDef = finRoleDef(agent.role);
|
|
11628
11723
|
let shadow = false;
|
|
11629
11724
|
try {
|
|
@@ -11660,14 +11755,23 @@ function finAgentRound(sid) {
|
|
|
11660
11755
|
if (agent.main) {
|
|
11661
11756
|
const team = finTeamDigest();
|
|
11662
11757
|
if (team) teamPrefix = '[EKİP RAPORLARI — koşan uzman ajanların son raporları; kararında dikkate al]\n' + team + '\n\n';
|
|
11758
|
+
/* MAKS BEKLEME AŞILDI: geç kalan ajanlar açıkça işaretlenir */
|
|
11759
|
+
const late = Array.isArray(agent.waitLateNames) ? agent.waitLateNames.filter(Boolean) : [];
|
|
11760
|
+
if (late.length) {
|
|
11761
|
+
teamPrefix = `[EKİP NOTU] Şu ajanlar hâlâ analizde — raporları BİR ÖNCEKİ turdan: ${late.join(', ')}. Gecikmeyi kararında dikkate al.\n\n` + teamPrefix;
|
|
11762
|
+
agent.waitLateNames = [];
|
|
11763
|
+
}
|
|
11663
11764
|
}
|
|
11664
11765
|
if (f.consultChat === false || roleDef) {
|
|
11665
11766
|
/* danışma kapalı ya da rol ajanı (plan trader'a yöneliktir): tur doğrudan başlar */
|
|
11666
11767
|
launch(teamPrefix);
|
|
11667
11768
|
return;
|
|
11668
11769
|
}
|
|
11770
|
+
/* Danışma planı ekip beklemesi SIRASINDA üretildiyse hazır olanı kullan */
|
|
11771
|
+
const consult = agent.consultPromise || finConsultPlan(f, agent, String(sid));
|
|
11772
|
+
agent.consultPromise = null;
|
|
11669
11773
|
if (agent.main) finPush('trader', { state: 'consult', round: agent.round });
|
|
11670
|
-
|
|
11774
|
+
consult
|
|
11671
11775
|
.then((plan) => launch(teamPrefix + (plan ? `[ANA AJAN PLANI — bu turun varsayılan stratejisi; strateji notuyla çelişirse not önceliklidir]\n${plan}\n\n` : '')))
|
|
11672
11776
|
.catch(() => launch(teamPrefix));
|
|
11673
11777
|
}
|
|
@@ -11706,6 +11810,12 @@ function finFlushOnDone(ev) {
|
|
|
11706
11810
|
finAgentStop(sid, String(ev.reason || 'kullanıcı durdurdu'));
|
|
11707
11811
|
return;
|
|
11708
11812
|
}
|
|
11813
|
+
/* EKİP TURU BİTTİ: bekleyen trader varsa ANINDA değerlendir (rapor taze) */
|
|
11814
|
+
if (agent.role) {
|
|
11815
|
+
for (const [msid, ma] of financeState.agents) {
|
|
11816
|
+
if (ma && ma.main && ma.waitingTeam) { try { finTeamWaitTick(msid); } catch {} break; }
|
|
11817
|
+
}
|
|
11818
|
+
}
|
|
11709
11819
|
clearTimeout(agent.timer);
|
|
11710
11820
|
/* TUR SIRASINDA GELEN OLAY/DM: tur bitti → interval BEKLENMEDEN yeni tur
|
|
11711
11821
|
(dmInbox'taki olay mesajı bu turda okunur) */
|
|
@@ -11715,6 +11825,10 @@ function finFlushOnDone(ev) {
|
|
|
11715
11825
|
agent.timer = setTimeout(() => { try { finAgentRound(sid); } catch {} }, 800);
|
|
11716
11826
|
return;
|
|
11717
11827
|
}
|
|
11828
|
+
/* CYCLE MODU: ana trader koşarken ekip ajanı KENDİ turunu planlamaz —
|
|
11829
|
+
sıradaki turu trader'ın cycle'ı başlatır (rapor tazeliği). Trader yoksa
|
|
11830
|
+
ekip kendi timer'ıyla dönmeye devam eder. */
|
|
11831
|
+
if (agent.role && finTeamHasMain()) return;
|
|
11718
11832
|
const f = finCfg();
|
|
11719
11833
|
const iv = Math.max(30, Number(f.intervalSec) || 120) * 1000;
|
|
11720
11834
|
financeState.lastRoundAt = Date.now();
|
|
@@ -11884,8 +11998,10 @@ ipcMain.handle('finance:settings', async (_e, patch) => {
|
|
|
11884
11998
|
koşan tur bitince zaten finFlushOnDone yeni aralığı okur. */
|
|
11885
11999
|
if (p.intervalSec !== undefined && financeState.agents) {
|
|
11886
12000
|
const iv = Math.max(30, Math.round(Number(f.intervalSec) || 120)) * 1000;
|
|
12001
|
+
const hasMain = finTeamHasMain();
|
|
11887
12002
|
for (const [sid, a] of financeState.agents) {
|
|
11888
12003
|
if (!a || !engine || engine.isBusy(sid)) continue;
|
|
12004
|
+
if (a.role && hasMain) continue; /* cycle modu: ekip turunu trader başlatır */
|
|
11889
12005
|
clearTimeout(a.timer);
|
|
11890
12006
|
a.timer = setTimeout(() => { try { finAgentRound(String(sid)); } catch {} }, iv);
|
|
11891
12007
|
}
|
package/src/renderer/renderer.js
CHANGED
|
@@ -10162,6 +10162,7 @@ function finOnEvent(ev) {
|
|
|
10162
10162
|
finSetDot(ev.connected ? true : 'busy', { error: ev.error });
|
|
10163
10163
|
} else if (ev.fn === 'trader') {
|
|
10164
10164
|
if (ev.state === 'running') finLogLine('[trader] tur #' + (ev.round || 0) + ' başladı');
|
|
10165
|
+
else if (ev.state === 'team') finLogLine('[trader] ekip raporları bekleniyor — ' + (ev.waiting || 0) + ' ajan turunu bitirsin (max ' + (ev.maxSec || '?') + ' sn)');
|
|
10165
10166
|
else if (ev.state === 'idle') finLogLine('[trader] tur #' + (ev.round || 0) + ' bitti — sıradaki tur ~' + (ev.nextInSec || '?') + ' sn');
|
|
10166
10167
|
else if (ev.state === 'hours') finLogLine('[trader] trade saatleri dışı — ajan askıda (kontrol ~' + (ev.nextInSec || 60) + ' sn)');
|
|
10167
10168
|
else if (ev.state === 'stopped') finLogLine('[trader] durduruldu');
|