beast-agent 2.30.2 → 2.30.3
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 +48 -25
- package/src/main.js +19 -0
- package/src/renderer/index.html +1 -1
- package/src/renderer/renderer.js +21 -14
- package/src/renderer/style.css +0 -19
package/package.json
CHANGED
package/src/agent/engine.js
CHANGED
|
@@ -6372,34 +6372,37 @@ Engine.prototype._agentDmSend = function (fromSid, args) {
|
|
|
6372
6372
|
groupName verilmemişse ama iki taraf da AYNI AÇIK grubun üyesiyse mesaj
|
|
6373
6373
|
YİNE GRUBA düşer — üye üyeye 1:1 thread'lere ayrı ayrı dağılmaz; ekibin
|
|
6374
6374
|
tüm iç trafiği TEK grup sohbetinde canlı toplanır. */
|
|
6375
|
-
|
|
6375
|
+
/* TEK İŞ = TEK GRUP: taraflar AÇIK bir ekip/grup üyesiyse mesaj HER ZAMAN o
|
|
6376
|
+
gruba düşer — group: verilse bile yeni grup AÇILMAZ. Ayrıca group adı
|
|
6377
|
+
mevcut bir grubun başlığıyla eşleşiyorsa (ör. "Beast Finance EKİP" →
|
|
6378
|
+
team:finance) o grup kullanılır; aynı iş için ikinci grup oluşmaz. */
|
|
6379
|
+
const shared = target ? this._agentDmSharedGroup(fromSid, target) : null;
|
|
6376
6380
|
let gid = '';
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
.
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
if (!g) {
|
|
6394
|
-
if (!target) return { ok: false, error: 'yeni grup için to ile en az bir ajan belirt' };
|
|
6395
|
-
g = { id: gid, title: groupName, members: [], titles: {}, createdAt: at, closed: false };
|
|
6396
|
-
this._agentGroups.set(gid, g);
|
|
6381
|
+
let g = null;
|
|
6382
|
+
if (shared) {
|
|
6383
|
+
g = shared;
|
|
6384
|
+
gid = String(g.id || '');
|
|
6385
|
+
} else if (groupName) {
|
|
6386
|
+
gid = 'grp:' + this._agentGroupKey(groupName);
|
|
6387
|
+
g = this._agentGroups.get(gid) || null;
|
|
6388
|
+
if (!g) {
|
|
6389
|
+
const want = this._agentGroupKey(groupName);
|
|
6390
|
+
for (const [, cand] of this._agentGroups || new Map()) {
|
|
6391
|
+
if (!cand || cand.closed) continue;
|
|
6392
|
+
if (this._agentGroupKey(cand.title) === want) {
|
|
6393
|
+
g = cand;
|
|
6394
|
+
gid = String(cand.id || '');
|
|
6395
|
+
break;
|
|
6396
|
+
}
|
|
6397
6397
|
}
|
|
6398
|
-
} else {
|
|
6399
|
-
g = shared;
|
|
6400
|
-
gid = String(g.id || '');
|
|
6401
6398
|
}
|
|
6402
|
-
|
|
6399
|
+
if (!g) {
|
|
6400
|
+
if (!target) return { ok: false, error: 'yeni grup için to ile en az bir ajan belirt' };
|
|
6401
|
+
g = { id: gid, title: groupName, members: [], titles: {}, createdAt: at, closed: false };
|
|
6402
|
+
this._agentGroups.set(gid, g);
|
|
6403
|
+
}
|
|
6404
|
+
}
|
|
6405
|
+
if (g) { g.titles = g.titles || {};
|
|
6403
6406
|
const addMember = (sid, title) => {
|
|
6404
6407
|
sid = String(sid);
|
|
6405
6408
|
if (!g.members.includes(sid)) g.members.push(sid);
|
|
@@ -6478,6 +6481,20 @@ Engine.prototype._agentDmSharedGroup = function (a, b) {
|
|
|
6478
6481
|
return null;
|
|
6479
6482
|
};
|
|
6480
6483
|
|
|
6484
|
+
/* Grup adı anahtarı: Türkçe-kararsız normalize — ALTIN/Altın/altın aynı gruba
|
|
6485
|
+
iner; başlık eşleştirmede de kullanılır (ör. "Beast Finance EKİP"). */
|
|
6486
|
+
Engine.prototype._agentGroupKey = function (name) {
|
|
6487
|
+
return String(name || '')
|
|
6488
|
+
.toLowerCase()
|
|
6489
|
+
.replace(/\u0307/g, '')
|
|
6490
|
+
.replace(/ı/g, 'i')
|
|
6491
|
+
.replace(/ğ/g, 'g')
|
|
6492
|
+
.replace(/ü/g, 'u')
|
|
6493
|
+
.replace(/ş/g, 's')
|
|
6494
|
+
.replace(/ö/g, 'o')
|
|
6495
|
+
.replace(/ç/g, 'c');
|
|
6496
|
+
};
|
|
6497
|
+
|
|
6481
6498
|
Engine.prototype._pushAgentDm = function (dm) {
|
|
6482
6499
|
this._agentDms = this._agentDms || [];
|
|
6483
6500
|
this._agentDms.push(dm);
|
|
@@ -6517,6 +6534,12 @@ Engine.prototype._agentTeamJoin = function (job) {
|
|
|
6517
6534
|
g.closed = false;
|
|
6518
6535
|
delete g.closedAt;
|
|
6519
6536
|
g.titles = g.titles || {};
|
|
6537
|
+
/* durdurulmuş eski üyeler aktif kadrodan düşer — yeniden başlayan ekipte
|
|
6538
|
+
kapanmış ajanlar üye listesinde görünmez (geçmiş mesajlar korunur) */
|
|
6539
|
+
g.members = (g.members || []).filter((m) => {
|
|
6540
|
+
const j = this._bgJobs && this._bgJobs.get(String(m));
|
|
6541
|
+
return !j || j.status === 'running';
|
|
6542
|
+
});
|
|
6520
6543
|
const add = (id, title) => {
|
|
6521
6544
|
id = String(id);
|
|
6522
6545
|
if (!g.members.includes(id)) g.members.push(id);
|
package/src/main.js
CHANGED
|
@@ -8609,6 +8609,9 @@ function finAgentStop(sid, reason) {
|
|
|
8609
8609
|
engine._bgEmit();
|
|
8610
8610
|
}
|
|
8611
8611
|
} catch {}
|
|
8612
|
+
/* AJAN DM: duran ajanın birebir sohbetleri kapanır; grupta KOŞAN üye
|
|
8613
|
+
kalmadıysa ekip sohbeti de GEÇMİŞE düşer (aktif listede kalmaz) */
|
|
8614
|
+
try { if (engine && engine._agentDmClose) engine._agentDmClose(sid); } catch {}
|
|
8612
8615
|
finPush('trader', { state: 'idle', rounds: financeState.traderRounds });
|
|
8613
8616
|
return true;
|
|
8614
8617
|
}
|
|
@@ -8856,8 +8859,24 @@ ipcMain.handle('finance:settings', async (_e, patch) => {
|
|
|
8856
8859
|
}
|
|
8857
8860
|
f.symbolHistory = hist.slice(-40);
|
|
8858
8861
|
f.symbols = next;
|
|
8862
|
+
/* KOŞAN ajanlar DURDURULMADAN yeni listeyi alır: ana trader + analiz ekibi
|
|
8863
|
+
sonraki turda güncel sembollere odaklanır (sembol işçileri kendi
|
|
8864
|
+
sembolünde kalır — onlar tek sembole özeldir). */
|
|
8865
|
+
for (const [, a] of financeState.agents) {
|
|
8866
|
+
if (a && (a.main || a.role)) a.symbols = next.slice(0, 20);
|
|
8867
|
+
}
|
|
8859
8868
|
}
|
|
8860
8869
|
if (p.intervalSec !== undefined) f.intervalSec = Math.max(30, Math.min(3600, Math.round(Number(p.intervalSec) || 120)));
|
|
8870
|
+
/* TUR ARALIĞI CANLI: bekleyen zamanlayıcılar yeni aralıkla yeniden kurulur —
|
|
8871
|
+
koşan tur bitince zaten finFlushOnDone yeni aralığı okur. */
|
|
8872
|
+
if (p.intervalSec !== undefined && financeState.agents) {
|
|
8873
|
+
const iv = Math.max(30, Math.round(Number(f.intervalSec) || 120)) * 1000;
|
|
8874
|
+
for (const [sid, a] of financeState.agents) {
|
|
8875
|
+
if (!a || !engine || engine.isBusy(sid)) continue;
|
|
8876
|
+
clearTimeout(a.timer);
|
|
8877
|
+
a.timer = setTimeout(() => { try { finAgentRound(String(sid)); } catch {} }, iv);
|
|
8878
|
+
}
|
|
8879
|
+
}
|
|
8861
8880
|
if (p.maxLot !== undefined) f.maxLot = Math.max(0.01, Math.min(100, Number(p.maxLot) || 0.1));
|
|
8862
8881
|
if (p.maxPositions !== undefined) f.maxPositions = Math.max(1, Math.min(20, Math.round(Number(p.maxPositions) || 3)));
|
|
8863
8882
|
/* allowTrading artık AYARLANMAZ — daima true (finCfg zorlar) */
|
package/src/renderer/index.html
CHANGED
|
@@ -167,7 +167,7 @@
|
|
|
167
167
|
<span>Model</span>
|
|
168
168
|
<select id="finTraderModel" title="Trader ajanının modeli — farklı API/model seçilebilir"></select>
|
|
169
169
|
</div>
|
|
170
|
-
<div class="fin-grid2">
|
|
170
|
+
<div class="fin-grid2" title="Değişiklik anında kaydedilir — ajanı DURDURMADAN sonraki tura uygulanır">
|
|
171
171
|
<div class="fin-field">
|
|
172
172
|
<span>Tur (sn)</span>
|
|
173
173
|
<input id="finInterval" type="number" min="30" max="3600" step="10" />
|
package/src/renderer/renderer.js
CHANGED
|
@@ -8949,17 +8949,7 @@ function finRenderSymbols(list) {
|
|
|
8949
8949
|
row.innerHTML =
|
|
8950
8950
|
'<span class="fs-name">' + (s.symbol || '?') + '</span>' +
|
|
8951
8951
|
'<span class="fs-price ' + cls + '">' + bid.toFixed(digits) + '</span>' +
|
|
8952
|
-
'<span class="fs-spread">sp ' + (s.spread != null ? s.spread : '—') + '</span>'
|
|
8953
|
-
'<button class="fs-agent" title="' + escapeHtml(s.symbol || '') + ' için AYRI finance ajanı başlat (paralel koşar)">▶︎</button>';
|
|
8954
|
-
const spawnBtn = row.querySelector('.fs-agent');
|
|
8955
|
-
if (spawnBtn) {
|
|
8956
|
-
spawnBtn.addEventListener('click', async (e) => {
|
|
8957
|
-
e.stopPropagation();
|
|
8958
|
-
const r = await beast.financeAgentSpawn(s.symbol).catch((err) => ({ ok: false, error: String((err && err.message) || err) }));
|
|
8959
|
-
if (r && r.ok) toast(s.symbol + ' için ajan başladı — Paralel Ajanlar panelinde izle');
|
|
8960
|
-
else toast((r && r.error) || 'Ajan başlatılamadı');
|
|
8961
|
-
});
|
|
8962
|
-
}
|
|
8952
|
+
'<span class="fs-spread">sp ' + (s.spread != null ? s.spread : '—') + '</span>';
|
|
8963
8953
|
els.finSymList.appendChild(row);
|
|
8964
8954
|
}
|
|
8965
8955
|
}
|
|
@@ -9210,8 +9200,18 @@ function finSaveCfg(patch) {
|
|
|
9210
9200
|
beast.financeSettings(patch).then(() => { finWatchDirty = false; }).catch(() => { finWatchDirty = false; });
|
|
9211
9201
|
}, 400);
|
|
9212
9202
|
}
|
|
9213
|
-
if (els.finInterval) els.finInterval.addEventListener('change', () =>
|
|
9214
|
-
|
|
9203
|
+
if (els.finInterval) els.finInterval.addEventListener('change', () => {
|
|
9204
|
+
const v = Math.max(30, Math.min(3600, Math.round(Number(els.finInterval.value) || 120)));
|
|
9205
|
+
els.finInterval.value = v;
|
|
9206
|
+
finSaveCfg({ intervalSec: v });
|
|
9207
|
+
toast('Tur aralığı: ' + v + ' sn — durdurmadan sonraki tura uygulanır');
|
|
9208
|
+
});
|
|
9209
|
+
if (els.finMaxLot) els.finMaxLot.addEventListener('change', () => {
|
|
9210
|
+
const v = Math.max(0.01, Math.min(100, Number(els.finMaxLot.value) || 0.1));
|
|
9211
|
+
els.finMaxLot.value = v;
|
|
9212
|
+
finSaveCfg({ maxLot: v });
|
|
9213
|
+
toast('Max lot: ' + v + ' — sonraki turdan itibaren geçerli');
|
|
9214
|
+
});
|
|
9215
9215
|
if (els.finSymBtn) els.finSymBtn.addEventListener('click', finSymPickerOpen);
|
|
9216
9216
|
/* OTOMATİK İŞLEM onay kutusu KALDIRILDI — trade ajanı daima işlem açabilir */
|
|
9217
9217
|
if (els.finTraderModel) {
|
|
@@ -9256,11 +9256,18 @@ function finToggleWatch(sym) {
|
|
|
9256
9256
|
const i = finWatch.indexOf(s);
|
|
9257
9257
|
if (i >= 0) finWatch.splice(i, 1);
|
|
9258
9258
|
else finWatch.push(s);
|
|
9259
|
+
const added = i < 0; /* true = eklendi */
|
|
9259
9260
|
finSaveCfg({ symbols: [...finWatch] });
|
|
9260
9261
|
finSymBtnUpdate(); /* TRADE AJANI düğmesi anında güncellensin */
|
|
9261
9262
|
clearTimeout(finSymRefreshTimer);
|
|
9262
9263
|
finSymRefreshTimer = setTimeout(() => finSnapshot(), 700); /* PİYASA kartı tazelensin */
|
|
9263
|
-
|
|
9264
|
+
/* canlı geri bildirim: değişiklik koşan ajanı DURDURMADAN sonraki tura girer */
|
|
9265
|
+
toast(
|
|
9266
|
+
added
|
|
9267
|
+
? s + ' izleme listesine eklendi — koşan ajan sonraki turda kullanır'
|
|
9268
|
+
: s + ' izleme listesinden çıkarıldı — koşan ajan sonraki turda görmez'
|
|
9269
|
+
);
|
|
9270
|
+
return added;
|
|
9264
9271
|
}
|
|
9265
9272
|
|
|
9266
9273
|
function finRenderPickRows(rows, q) {
|
package/src/renderer/style.css
CHANGED
|
@@ -2290,25 +2290,6 @@ body.browser-open #settingsDialog { width: min(70vw, calc(100vw - var(--bw, 480p
|
|
|
2290
2290
|
letter-spacing: 0.4px;
|
|
2291
2291
|
}
|
|
2292
2292
|
|
|
2293
|
-
/* PİYASA satırındaki ▶ ajan butonu */
|
|
2294
|
-
.fin-sym { position: relative; }
|
|
2295
|
-
.fin-sym .fs-agent {
|
|
2296
|
-
position: absolute;
|
|
2297
|
-
right: 4px;
|
|
2298
|
-
top: 50%;
|
|
2299
|
-
transform: translateY(-50%);
|
|
2300
|
-
border: none;
|
|
2301
|
-
background: none;
|
|
2302
|
-
color: var(--muted);
|
|
2303
|
-
cursor: pointer;
|
|
2304
|
-
font-size: 11px;
|
|
2305
|
-
padding: 2px 4px;
|
|
2306
|
-
border-radius: 4px;
|
|
2307
|
-
visibility: hidden;
|
|
2308
|
-
}
|
|
2309
|
-
.fin-sym:hover .fs-agent { visibility: visible; color: var(--accent); }
|
|
2310
|
-
.fin-sym .fs-agent:hover { background: var(--accent-dim); }
|
|
2311
|
-
|
|
2312
2293
|
/* sembol seçicide bölüm başlıkları (geçmiş / tüm semboller) */
|
|
2313
2294
|
.fin-sym-sec {
|
|
2314
2295
|
font-size: 10px;
|