beast-agent 0.24.5 → 0.25.1
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 +68 -96
- package/src/agent/tools.js +1 -1
- package/src/main.js +226 -60
- package/src/preload.js +1 -1
- package/src/renderer/i18n.js +2 -4
- package/src/renderer/index.html +45 -9
- package/src/renderer/renderer.js +351 -143
- package/src/renderer/style.css +195 -30
package/package.json
CHANGED
package/src/agent/engine.js
CHANGED
|
@@ -333,41 +333,6 @@ class Engine {
|
|
|
333
333
|
else this.sessionTools.delete(id);
|
|
334
334
|
}
|
|
335
335
|
|
|
336
|
-
/* ANA SOHBETE DAVETLİ BOTLAR: oturuma guest bot ekle/çıkar (persist) */
|
|
337
|
-
setSessionGuests(sessionId, guests) {
|
|
338
|
-
const s = this._load(String(sessionId || ''));
|
|
339
|
-
if (!s) return false;
|
|
340
|
-
const items = (Array.isArray(guests) ? guests : [])
|
|
341
|
-
.slice(0, 4)
|
|
342
|
-
.map((g) => ({ id: String((g && g.id) || ''), code: String((g && g.code) || ''), name: String((g && g.name) || '').slice(0, 40) }))
|
|
343
|
-
.filter((g) => g.id && g.code);
|
|
344
|
-
s.guests = items;
|
|
345
|
-
try {
|
|
346
|
-
const file = this._file(s.id);
|
|
347
|
-
const lines = fs.readFileSync(file, 'utf8').split('\n').filter((l) => l.trim());
|
|
348
|
-
const kept = lines.filter((l) => {
|
|
349
|
-
try { return JSON.parse(l).t !== 'guests'; } catch { return true; }
|
|
350
|
-
});
|
|
351
|
-
const out = kept.join('\n') + (items.length ? '\n' + JSON.stringify({ t: 'guests', items }) : '') + '\n';
|
|
352
|
-
const tmp = file + '.tmp';
|
|
353
|
-
fs.writeFileSync(tmp, out);
|
|
354
|
-
fs.renameSync(tmp, file);
|
|
355
|
-
} catch {}
|
|
356
|
-
return true;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
/* Davetli botlar system prompt bloğu — ajan bot_dm ile onlara danışır */
|
|
360
|
-
_guestsBlock(session) {
|
|
361
|
-
const g = Array.isArray(session && session.guests) ? session.guests : [];
|
|
362
|
-
if (!g.length) return '';
|
|
363
|
-
const lines = g.map((x) => `- ${x.name} (kod: ${x.code})`).join('\n');
|
|
364
|
-
return (
|
|
365
|
-
`# DAVETLİ BOTLAR\n` +
|
|
366
|
-
`Bu sohbete şu botlar davet edildi. Kullanıcı onlara hitap ederse veya uzmanlıkları gereken bir konu olursa ` +
|
|
367
|
-
`bot_dm aracıyla (to=5 haneli kod) onlara yaz; aldığın cevabı [BotAdı] etiketiyle kullanıcıya aktar:\n${lines}`
|
|
368
|
-
);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
336
|
/* Oturumun bağlı olduğu MÜŞTERİ botu (admin/seasız → null → global hafıza) */
|
|
372
337
|
_sessionBotCtx(session) {
|
|
373
338
|
if (!session || !session.botId || typeof this.resolveBot !== 'function') return null;
|
|
@@ -947,9 +912,6 @@ class Engine {
|
|
|
947
912
|
session.isBotDm = true;
|
|
948
913
|
session.dmA = String(rec.a || '');
|
|
949
914
|
session.dmB = String(rec.b || '');
|
|
950
|
-
} else if (rec.t === 'guests') {
|
|
951
|
-
/* ana sohbete davetli botlar */
|
|
952
|
-
session.guests = Array.isArray(rec.items) ? rec.items : [];
|
|
953
915
|
} else if (rec.t === 'msg') {
|
|
954
916
|
delete rec.t;
|
|
955
917
|
session.messages.push(rec);
|
|
@@ -1086,7 +1048,6 @@ class Engine {
|
|
|
1086
1048
|
count: s.messages.length,
|
|
1087
1049
|
isBg,
|
|
1088
1050
|
isBotDm: !!s.isBotDm,
|
|
1089
|
-
guests: Array.isArray(s.guests) ? s.guests : [],
|
|
1090
1051
|
bgStatus: isBg ? (job ? job.status : null) : null,
|
|
1091
1052
|
};
|
|
1092
1053
|
}
|
|
@@ -1330,11 +1291,11 @@ class Engine {
|
|
|
1330
1291
|
: 'Bağımsız alt-işleri delegate_task ile devret; kendi başına halledebileceğin işleri devretme.',
|
|
1331
1292
|
'Güncel/dış bilgi gerekiyorsa web_search kullan (zincir DAHİLİ tarayıcıyla başlar — gerçek Chromium ile Google); hızlı ham metin okuması için http_fetch kullan.',
|
|
1332
1293
|
'ARAMA-DİSİPLİN: bir bilgiyi 2-3 denemede bulamazsan TAKILMA — farklı bir açıya/sorguya geç, yine yoksa bulabildiğin kısmi bilgiyle cevap ver ve neyi bulamadığını açıkça söyle. Kapalı/gizli içerik (private profil, login arkası veri) peşinde KOŞMA — bulunamayacağı belliyse hemen vazgeç.',
|
|
1333
|
-
'TARAYICI VARSAYILANI (ZORUNLU): kullanıcı "şu siteyi aç", "bunu ara / google\u2019da ara", "şu sayfaya git" gibi bir web isteği verdiğinde HEP DAHİLİ TARAYICIYI KULLAN (browser_open ile aç →
|
|
1294
|
+
'TARAYICI VARSAYILANI (ZORUNLU): kullanıcı "şu siteyi aç", "bunu ara / google\u2019da ara", "şu sayfaya git" gibi bir web isteği verdiğinde HEP DAHİLİ TARAYICIYI KULLAN (browser_open ile aç → açılış yanıtında hazır snapshot gelir → ref numaralarıyla browser_click/browser_type/browser_select ile hareket et; HER eylem yanıtında taze snapshot döner — ayrıca browser_snapshot çağırma, yanıttaki refleri kullan; browser_read ile metin oku; sadece görsel yerleşim/grafik gerekiyorsa browser_screenshot çek). Tarih/saat alanlarını (type=date/time) browser_type ile DÜZ METİN yaz ("15.03.2026", "2026-03-15") — takvimden tıklamaya çalışma, alan programatik ayarlanır. Panel ekranın sağında açılır ve kullanıcı da sayfayı anında görür; JS/login/SPA/dinamik içerik için idealdir. Bu kural TÜM oturumları kapsar — masaüstü sohbeti ve çok kullanıcılı botlar (WhatsApp vb.) dahil.' +
|
|
1334
1295
|
' DIŞ TARAYICI İSTİSNASI: kullanıcı AÇIKÇA "chrome\u2019da aç", "firefox\u2019ta aç", "başka tarayıcıda aç", "normal tarayıcıda aç", "kendi tarayıcımda aç" derse O ZAMAN run_command ile `start "" <url>` çalıştır — sistem varsayılan (dış) tarayıcısında açılır. Kullanıcı dış tarayıcı istemedikçe ASLA dış tarayıcı açma.' +
|
|
1335
1296
|
' Görselleri GÖREMEMİYORSAN (metin-model) görüntüdeki metni okumak için ocr_read kullan: source:"browser" ile tarayıcı sayfasını, "screen" ile masaüstünü OCR\u2019la okursun (captcha/canvas/görsel metin dahil).' +
|
|
1336
1297
|
(this.ceoMode ? ' (CEO: bu araçları KENDİN ÇAĞIRMA — içinde tarayıcı geçen işi run_background ile paralel ajana devret.)' : ''),
|
|
1337
|
-
'Tarayıcı eylemlerinin yanıtındaki recent günlüğü ve navigated bilgisini takip et;
|
|
1298
|
+
'Tarayıcı eylemlerinin yanıtındaki recent günlüğü ve navigated bilgisini takip et; eylem yanıtları zaten taze snapshot içerir — refler tutarsız görünürse yeni snapshot al.',
|
|
1338
1299
|
'CONUŞMA ODAĞI SENDE KALSIN: kullanıcı seninle konuşurken iş çıkmışsa — uzun da olsa UFACIK da (tek komutluk dizin listesi, tek dosya okuma, tek arama…) — run_background ile PARALEL ajana devret; ana sohbet hiçbir işi beklemez; bittiğinde özet otomatik düşer.',
|
|
1339
1300
|
'Python işleri için python_run kullan: küçük betikler inline code ile; tekrarlayan işler %APPDATA%\\beast\\scripts klasöründeki dosyalarla (ör. news.py = RSS haber toplayıcı: args ["--limit","8","--json"]). Python kurulu olmasa bile ilk çağrıda taşınabilir gömülü runtime otomatik iner.',
|
|
1340
1301
|
'PYTHON DURUMU: makinede sistem Python\'u görünmese bile ŞAŞIRMA ve "python yok" DEME — python_run aracı kendi taşınabilir runtime\'ını (%APPDATA%\\beast\\py\\python.exe) otomatik indirir/kullanır ve bu klasör run_command PATH\'inde önceliklidir; yani run_command içinde de `python` çalışır. Ham Google/Bing scrape yerine önce web_search aracını kullan (zaten Python çoklu-motor + Exa destekli), script gerektiğinde python_run yaz.',
|
|
@@ -1540,6 +1501,10 @@ class Engine {
|
|
|
1540
1501
|
/* #6 bağlam sıkıştırma: öze dönüşen eski mesajlar bellekten VE diskten
|
|
1541
1502
|
düşer (compacted işaretiyle); notlar + son pencere her zaman kalır.
|
|
1542
1503
|
Böylece notesAt=0'dan yeniden başlar, uzun sohbette şişme olmaz. */
|
|
1504
|
+
/* YARIŞ KORUMASI: bu bakım artık done SONRASI arka planda koşuyor —
|
|
1505
|
+
yeni tur başladıysa dosya sıkıştırmayı ERTENELE (not satırı append ile
|
|
1506
|
+
zaten kayıtlı; sıkıştırma sonraki bakımda yapılır, append kaybı olmaz) */
|
|
1507
|
+
if (this.ctrls.has(session.id)) return { ok: true, deferred: true };
|
|
1543
1508
|
this._compactToNotes(session, cut);
|
|
1544
1509
|
/* bellek kopyasını da eşele: özetlenen bölge [0..cut) atılır */
|
|
1545
1510
|
session.messages = session.messages.slice(cut);
|
|
@@ -1550,6 +1515,29 @@ class Engine {
|
|
|
1550
1515
|
}
|
|
1551
1516
|
}
|
|
1552
1517
|
|
|
1518
|
+
/* Cevap done SONRASI arka planda koşan ev işleri (kullanıcıyı BEKLETMEZ,
|
|
1519
|
+
DURUM BALONUNU DA MEŞGUL ETMEZ — tamamen sessizdir):
|
|
1520
|
+
oturum notları → otomatik memory → skill yansıtma → kişilik kalibrasyonu.
|
|
1521
|
+
Aynı oturum için per-session zincirle sıralanır. */
|
|
1522
|
+
_postRunHousekeeping(session, prevSignal) {
|
|
1523
|
+
const sid = session.id;
|
|
1524
|
+
if (session.bgJob || session.bcCode || session.isBotDm) return;
|
|
1525
|
+
if (prevSignal && prevSignal.aborted) return;
|
|
1526
|
+
if (!this._housekeepingTail) this._housekeepingTail = new Map();
|
|
1527
|
+
const job = this._housekeepingTail.get(sid) || Promise.resolve();
|
|
1528
|
+
const next = job.catch(() => {}).then(async () => {
|
|
1529
|
+
const ctl = new AbortController();
|
|
1530
|
+
try { await this._updateSessionNotes(session, ctl.signal); } catch {}
|
|
1531
|
+
if (ctl.signal.aborted || this.ctrls.has(sid)) return;
|
|
1532
|
+
try { await this._autoMemory(session, ctl.signal); } catch {}
|
|
1533
|
+
if (this.reflection.enabled && !ctl.signal.aborted && !this.ctrls.has(sid)) {
|
|
1534
|
+
try { await this._maybeReflectSkill(session); } catch {}
|
|
1535
|
+
}
|
|
1536
|
+
try { memory.calibratePersona(); } catch {}
|
|
1537
|
+
});
|
|
1538
|
+
this._housekeepingTail.set(sid, next);
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1553
1541
|
/* ---------- agent loop ---------- */
|
|
1554
1542
|
|
|
1555
1543
|
send(sessionId, payload) {
|
|
@@ -2220,8 +2208,6 @@ class Engine {
|
|
|
2220
2208
|
/* bot kimliği: bota bağlı oturumlarda kişilik + izolasyon kuralları */
|
|
2221
2209
|
const botBlock = this._botSystemBlock(session);
|
|
2222
2210
|
if (botBlock) system += '\n\n' + botBlock;
|
|
2223
|
-
const guestBlock = this._guestsBlock(session);
|
|
2224
|
-
if (guestBlock) system += '\n\n' + guestBlock;
|
|
2225
2211
|
if (session.notes) {
|
|
2226
2212
|
system +=
|
|
2227
2213
|
`\n\n# OTURUM NOTLARI (oturum ${session.code || '?'} — bu oturumun önceki konuşma özeti; birebir geçmişi buradan hatırla)\n` +
|
|
@@ -2316,43 +2302,14 @@ class Engine {
|
|
|
2316
2302
|
emit({ type: 'message', message: assistant });
|
|
2317
2303
|
|
|
2318
2304
|
if (!res.toolCalls || !res.toolCalls.length) {
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
if (!session.bgJob && !session.bcCode && !session.isBotDm) {
|
|
2324
|
-
const r = await this._updateSessionNotes(session, ctrl.signal);
|
|
2325
|
-
if (r && r.ok) {
|
|
2326
|
-
emitSafe(this, sid, { type: 'status', status: `oturum notları güncellendi (${session.code || ''})` });
|
|
2327
|
-
} else if (r && r.reason && !/^bekleme/.test(r.reason)) {
|
|
2328
|
-
emitSafe(this, sid, { type: 'status', status: `oturum notu YAZILAMADI: ${r.reason}` });
|
|
2329
|
-
}
|
|
2330
|
-
}
|
|
2331
|
-
/* otomatik memory döngüsü: kalıcı değerli bilgiyi MEMORY.md'ye düşür */
|
|
2332
|
-
if (!ctrl.signal.aborted && !session.bgJob && !session.bcCode && !session.isBotDm) {
|
|
2333
|
-
try {
|
|
2334
|
-
await this._autoMemory(session, ctrl.signal);
|
|
2335
|
-
} catch {}
|
|
2336
|
-
}
|
|
2337
|
-
/* deneyimden skill doğurma (#2): 5+ yeni araç çağrısı biriktiyse yansıt */
|
|
2338
|
-
if (this.reflection.enabled && !ctrl.signal.aborted && !session.bgJob && !session.bcCode && !session.isBotDm) {
|
|
2339
|
-
try {
|
|
2340
|
-
const made = await this._maybeReflectSkill(session);
|
|
2341
|
-
if (made) emitSafe(this, sid, { type: 'status', status: `skill taslağı doğdu: ${made}` });
|
|
2342
|
-
} catch {}
|
|
2343
|
-
}
|
|
2344
|
-
this._clearCrash(); // temiz bitiş — çökme kaydını sil
|
|
2345
|
-
this._maybeCompact(sid); // oturum dosyası şiştiyse sıkıştır
|
|
2305
|
+
/* cevap tamam → done HEMEN: kullanıcı beklemeden yeni iş yazabilsin.
|
|
2306
|
+
Not/memory/skill bakımı artık arka planda (_postRunHousekeeping). */
|
|
2307
|
+
this._clearCrash();
|
|
2308
|
+
this._maybeCompact(sid);
|
|
2346
2309
|
emit({ type: 'done', usage: res.usage || null, meta: res.meta || null });
|
|
2347
2310
|
this._bgFinish(sid, 'done');
|
|
2348
|
-
this.flushPendingReports(sid);
|
|
2349
|
-
|
|
2350
|
-
try {
|
|
2351
|
-
const cal = memory.calibratePersona();
|
|
2352
|
-
if (cal.ok && cal.traits && cal.traits.length) {
|
|
2353
|
-
emitSafe(this, sid, { type: 'status', status: 'kişilik kalibre edildi' });
|
|
2354
|
-
}
|
|
2355
|
-
} catch {}
|
|
2311
|
+
this.flushPendingReports(sid);
|
|
2312
|
+
this._postRunHousekeeping(session, ctrl.signal);
|
|
2356
2313
|
return;
|
|
2357
2314
|
}
|
|
2358
2315
|
|
|
@@ -2400,8 +2357,7 @@ class Engine {
|
|
|
2400
2357
|
);
|
|
2401
2358
|
}
|
|
2402
2359
|
emit({ type: 'done', usage: null });
|
|
2403
|
-
this._bgFinish(sid, 'error', 'tur limiti doldu (MAX_TURNS)');
|
|
2404
|
-
} catch (e) {
|
|
2360
|
+
this._bgFinish(sid, 'error', 'tur limiti doldu (MAX_TURNS)'); } catch (e) {
|
|
2405
2361
|
const aborted = e && (e.name === 'AbortError' || ctrl.signal.aborted);
|
|
2406
2362
|
if (aborted) {
|
|
2407
2363
|
this._clearCrash(); // kullanıcı durdurdu — kurtarma yok
|
|
@@ -3112,23 +3068,38 @@ class Engine {
|
|
|
3112
3068
|
return JSON.stringify(r);
|
|
3113
3069
|
}
|
|
3114
3070
|
if (name === 'web_search') {
|
|
3115
|
-
/* SIRA:
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3071
|
+
/* SIRA: 1) dahili tarayıcı (DİREK GOOGLE — ücretsiz + AI cevabı)
|
|
3072
|
+
2) TinyFish (tarayıcı sorun çıkarsa HEMEN devreye girer — anahtar girildiyse)
|
|
3073
|
+
3) python çoklu-motor (ddgs / DDG+Bing+Mojeek)
|
|
3074
|
+
4) Exa (anahtar girildiyse, son çare)
|
|
3075
|
+
Tarayıcıda CAPTCHA/"olağandışı trafik"/boş sonuç algılanırsa 10 dk boyunca
|
|
3076
|
+
tarayıcı ATLANIR — her arama TinyFish'ten başlar, süre dolunca tarayıcı geri döner. */
|
|
3077
|
+
const q = String((args && args.query) || '');
|
|
3078
|
+
const n = Number((args && args.max_results) || 8);
|
|
3119
3079
|
let r = null;
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3080
|
+
let banned = false;
|
|
3081
|
+
const browserUsable = this.browser && typeof this.browser.search === 'function';
|
|
3082
|
+
if (Date.now() < (this._webSearchBrowserBanUntil || 0)) banned = true;
|
|
3083
|
+
if (browserUsable && !banned) {
|
|
3084
|
+
try { r = await this.browser.search(q, signal); } catch {}
|
|
3085
|
+
if (!r || !r.ok || !(r.results || []).length) {
|
|
3086
|
+
/* tarayıcı sorunlu — 10 dk atla, alternatif zincir hemen devrede */
|
|
3087
|
+
this._webSearchBrowserBanUntil = Date.now() + 10 * 60 * 1000;
|
|
3088
|
+
r = null;
|
|
3089
|
+
banned = true;
|
|
3124
3090
|
}
|
|
3125
3091
|
}
|
|
3092
|
+
if (!r || !r.ok || !(r.results || []).length) {
|
|
3093
|
+
try { r = await tools.tinyfishSearch(q, n, signal); } catch {}
|
|
3094
|
+
}
|
|
3126
3095
|
if (!r || !r.ok || !(r.results || []).length) {
|
|
3127
3096
|
try {
|
|
3128
3097
|
r = JSON.parse(await tools.exec('web_search', args, { cwd: this._sessionWorkspace(sessionId), signal }));
|
|
3129
3098
|
} catch {}
|
|
3130
3099
|
}
|
|
3131
|
-
|
|
3100
|
+
const out = r || { ok: false, error: 'web arama başarısız — tüm motorlar boş döndü' };
|
|
3101
|
+
if (out && out.ok && banned) out.note = 'tarayıcı araması 10 dk askıda (CAPTCHA/trafik) — TinyFish/alternatif zincir kullanıldı';
|
|
3102
|
+
return JSON.stringify(out);
|
|
3132
3103
|
}
|
|
3133
3104
|
if (name === 'ocr_read') {
|
|
3134
3105
|
return JSON.stringify(await this._ocrRead(args || {}, signal));
|
|
@@ -3676,7 +3647,7 @@ const TOOLS = [
|
|
|
3676
3647
|
function: {
|
|
3677
3648
|
name: 'browser_open',
|
|
3678
3649
|
description:
|
|
3679
|
-
'Open a URL in the built-in visible browser panel (JS-rendered pages work). This is the DEFAULT for every "open this site / search this / go to page" request — the user watches the page live in the side panel; ideal for login, SPA and dynamic content.
|
|
3650
|
+
'Open a URL in the built-in visible browser panel (JS-rendered pages work). This is the DEFAULT for every "open this site / search this / go to page" request — the user watches the page live in the side panel; ideal for login, SPA and dynamic content. The response ALREADY includes a fresh snapshot with numbered refs — act directly with browser_click/browser_type/browser_select; no separate browser_snapshot needed. Open the OS default (external) browser ONLY when the user explicitly asks for chrome/firefox/another/normal/my-own browser — in that case use run_command with `start "" <url>` instead of this tool.',
|
|
3680
3651
|
parameters: {
|
|
3681
3652
|
type: 'object',
|
|
3682
3653
|
properties: {
|
|
@@ -3709,7 +3680,7 @@ const TOOLS = [
|
|
|
3709
3680
|
function: {
|
|
3710
3681
|
name: 'browser_snapshot',
|
|
3711
3682
|
description:
|
|
3712
|
-
'List all interactive elements of the built-in browser page as numbered refs: [3] <button> "Gönder".
|
|
3683
|
+
'List all interactive elements of the built-in browser page as numbered refs: [3] <button> "Gönder". NOTE: every browser action response already includes a fresh snapshot — call this separately only when refs seem stale or you need a re-scan (e.g. after an action whose response had no snapshot). Open popups/calendars/datepickers are listed FIRST. Much more reliable than CSS selectors.',
|
|
3713
3684
|
parameters: { type: 'object', properties: {}, required: [] },
|
|
3714
3685
|
},
|
|
3715
3686
|
},
|
|
@@ -3733,7 +3704,7 @@ const TOOLS = [
|
|
|
3733
3704
|
function: {
|
|
3734
3705
|
name: 'browser_click',
|
|
3735
3706
|
description:
|
|
3736
|
-
'Click an element in the built-in browser. Prefer ref from
|
|
3707
|
+
'Click an element in the built-in browser. Prefer ref from the latest snapshot (e.g. {"ref":3}); CSS selector or text=X also accepted. The response includes a FRESH snapshot with new refs — continue with those directly instead of calling browser_snapshot again.',
|
|
3737
3708
|
parameters: {
|
|
3738
3709
|
type: 'object',
|
|
3739
3710
|
properties: {
|
|
@@ -3748,7 +3719,7 @@ const TOOLS = [
|
|
|
3748
3719
|
function: {
|
|
3749
3720
|
name: 'browser_type',
|
|
3750
3721
|
description:
|
|
3751
|
-
'Type text into an input/textarea/contenteditable in the built-in browser (prefer ref). Set submit=true to press Enter afterwards.',
|
|
3722
|
+
'Type text into an input/textarea/contenteditable in the built-in browser (prefer ref). Set submit=true to press Enter afterwards. Date/time fields (input type=date/time/month/datetime-local) are set PROGRAMMATICALLY — just send the date as text in any common format ("2026-03-15", "15.03.2026", "15 Mart 2026"); do NOT click the calendar popup. The response includes a FRESH snapshot with new refs.',
|
|
3752
3723
|
parameters: {
|
|
3753
3724
|
type: 'object',
|
|
3754
3725
|
properties: {
|
|
@@ -3766,7 +3737,7 @@ const TOOLS = [
|
|
|
3766
3737
|
function: {
|
|
3767
3738
|
name: 'browser_press',
|
|
3768
3739
|
description:
|
|
3769
|
-
'Press a key (Enter, Tab, Escape, ArrowDown…) on the focused element in the built-in browser; optionally focus a ref first.',
|
|
3740
|
+
'Press a key (Enter, Tab, Escape, ArrowDown…) on the focused element in the built-in browser; optionally focus a ref first. The response includes a FRESH snapshot with new refs.',
|
|
3770
3741
|
parameters: {
|
|
3771
3742
|
type: 'object',
|
|
3772
3743
|
properties: {
|
|
@@ -3781,7 +3752,8 @@ const TOOLS = [
|
|
|
3781
3752
|
type: 'function',
|
|
3782
3753
|
function: {
|
|
3783
3754
|
name: 'browser_scroll',
|
|
3784
|
-
description:
|
|
3755
|
+
description:
|
|
3756
|
+
'Scroll the built-in browser page. direction: up | down. The response includes a FRESH snapshot with newly visible refs.',
|
|
3785
3757
|
parameters: {
|
|
3786
3758
|
type: 'object',
|
|
3787
3759
|
properties: {
|
|
@@ -3797,7 +3769,7 @@ const TOOLS = [
|
|
|
3797
3769
|
function: {
|
|
3798
3770
|
name: 'browser_select',
|
|
3799
3771
|
description:
|
|
3800
|
-
'Pick an <option> of a dropdown (<select>) in the built-in browser by value/text (prefer ref).',
|
|
3772
|
+
'Pick an <option> of a dropdown (<select>) in the built-in browser by value/text (prefer ref). The response includes a FRESH snapshot with new refs. For CUSTOM (JS) dropdowns that are not <select>, click the trigger, then click the [role=option] ref from the snapshot (popups are listed first).',
|
|
3801
3773
|
parameters: {
|
|
3802
3774
|
type: 'object',
|
|
3803
3775
|
properties: {
|
package/src/agent/tools.js
CHANGED
|
@@ -620,7 +620,7 @@ const definitions = [
|
|
|
620
620
|
function: {
|
|
621
621
|
name: 'web_search',
|
|
622
622
|
description:
|
|
623
|
-
'FAST web search with an automatic chain: built-in browser first (real Chromium searching GOOGLE directly with AI Mode — no bot protection; the response may include an `ai` field holding Google\'s own AI answer, ideal for "who/what is X" questions), then Python multi-engine (ddgs / DuckDuckGo+Bing+Mojeek parallel), then Exa API as last resort if a key is configured (Ayarlar → Web Arama). Returns {ai?, results[{title,url,snippet}]}. Use when fresh or external info is needed; skip for things you already know.',
|
|
623
|
+
'FAST web search with an automatic chain: built-in browser first (real Chromium searching GOOGLE directly with AI Mode — no bot protection; the response may include an `ai` field holding Google\'s own AI answer, ideal for "who/what is X" questions), then TinyFish API (if a key is configured, used IMMEDIATELY whenever the browser hits CAPTCHA/unusual traffic — the browser is then skipped for 10 minutes), then Python multi-engine (ddgs / DuckDuckGo+Bing+Mojeek parallel), then Exa API as last resort if a key is configured (Ayarlar → Web Arama). Returns {ai?, results[{title,url,snippet}]}. Use when fresh or external info is needed; skip for things you already know.',
|
|
624
624
|
parameters: {
|
|
625
625
|
type: 'object',
|
|
626
626
|
properties: {
|