beast-agent 0.30.0 → 1.0.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 +6 -3
- package/src/agent/engine.js +463 -21
- package/src/agent/llm.js +52 -3
- package/src/agent/obscura.js +26 -10
- package/src/agent/skills.js +2 -2
- package/src/agent/tools.js +519 -7
- package/src/main.js +28 -13
- package/src/renderer/i18n.js +7 -7
- package/src/renderer/index.html +5 -2
- package/src/renderer/renderer.js +154 -5
- package/src/renderer/style.css +45 -4
- package/.env.example +0 -8
- package/config.example.yaml +0 -39
- package/eng.traineddata +0 -0
- package/scripts/fix-electron.js +0 -126
- package/scripts/release.js +0 -121
- package/scripts/swap-electron.js +0 -40
- package/store/skills.json +0 -5
- package/tests/approval.test.js +0 -56
- package/tests/bg-jobs.test.js +0 -424
- package/tests/bots-name.test.js +0 -42
- package/tests/bus.test.js +0 -46
- package/tests/computeruse-context.test.js +0 -69
- package/tests/cron.test.js +0 -95
- package/tests/engine.test.js +0 -203
- package/tests/eval.test.js +0 -91
- package/tests/fallout.test.js +0 -188
- package/tests/llm.test.js +0 -205
- package/tests/memory.test.js +0 -33
- package/tests/memoryloop.test.js +0 -26
- package/tests/notegen.test.js +0 -63
- package/tests/obscura.test.js +0 -124
- package/tests/owner.test.js +0 -32
- package/tests/python.test.js +0 -76
- package/tests/research.test.js +0 -116
- package/tests/scenarios.json +0 -81
- package/tests/sessioncode.test.js +0 -50
- package/tests/setup.js +0 -9
- package/tests/tokens.test.js +0 -42
- package/tests/tools.test.js +0 -84
- package/tests/usage.test.js +0 -44
- package/tests/v11.test.js +0 -76
- package/tests/watchers.test.js +0 -206
- package/tests/watext.test.js +0 -53
- package/tests/whatsapp.test.js +0 -103
- package/tests/wherewasi.test.js +0 -40
package/src/agent/llm.js
CHANGED
|
@@ -70,6 +70,38 @@ function friendlyError(status, statusText, detail) {
|
|
|
70
70
|
return msg;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
/* opencode cache disiplini (provider/transform.ts:1262-1276 port): destekleyen
|
|
74
|
+
sağlayıcılara oturum-sabit önbellek anahtarı gönderilir — aynı önek tekrar
|
|
75
|
+
kullanıldığında girdi tokenleri cache'ten okunur (~%90 ucuz + hızlı TTFT) */
|
|
76
|
+
const CACHE_KEY_PROVIDER_RE = /openai|azure|xai|deepseek|cerebras|deepinfra|mistral|venice/i;
|
|
77
|
+
const CACHE_KEY_MODEL_RE = /openai|gpt-|^o[134]|xai|grok|deepseek|cerebras|deepinfra|mistral|venice/i;
|
|
78
|
+
function wantsCacheKey(sel) {
|
|
79
|
+
if (!sel) return false;
|
|
80
|
+
return (
|
|
81
|
+
CACHE_KEY_PROVIDER_RE.test(String(sel.providerId || '')) ||
|
|
82
|
+
CACHE_KEY_MODEL_RE.test(String(sel.model || ''))
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* Retry-After başlığı: saniye ("2"), milisaniye ("120ms" / retry-after-ms)
|
|
87
|
+
ya da HTTP-tarih olabilir (opencode session/retry.ts port) */
|
|
88
|
+
function parseRetryAfter(v) {
|
|
89
|
+
if (v == null) return null;
|
|
90
|
+
const s = String(v).trim();
|
|
91
|
+
if (!s) return null;
|
|
92
|
+
const ms = /^(\d+)\s*ms$/i.exec(s);
|
|
93
|
+
if (ms) return Number(ms[1]);
|
|
94
|
+
if (/^\d+(\.\d+)?$/.test(s)) return Number(s) * 1000;
|
|
95
|
+
const d = Date.parse(s);
|
|
96
|
+
if (!Number.isNaN(d)) return Math.max(0, d - Date.now());
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const RETRY_AFTER_CAP_MS = 30000; /* opencode retry.ts:39 — headersız bekleme tavanı */
|
|
101
|
+
function clampMs(v) {
|
|
102
|
+
return Math.min(RETRY_AFTER_CAP_MS, Math.max(0, Number(v) || 0));
|
|
103
|
+
}
|
|
104
|
+
|
|
73
105
|
function sleep(ms, signal) {
|
|
74
106
|
return new Promise((resolve, reject) => {
|
|
75
107
|
const t = setTimeout(resolve, ms);
|
|
@@ -112,9 +144,14 @@ async function withRetries(fn, { signal, onRetry } = {}) {
|
|
|
112
144
|
try {
|
|
113
145
|
onRetry && onRetry(attempt, status);
|
|
114
146
|
} catch {}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
147
|
+
/* sağlayıcı retry-after dediye: backoff yerine ona uy (30 sn tavan);
|
|
148
|
+
opencode session/retry.ts:26-31 ile aynı politika */
|
|
149
|
+
let wait;
|
|
150
|
+
if (e.retryAfterMs) wait = clampMs(e.retryAfterMs);
|
|
151
|
+
else
|
|
152
|
+
wait = netErr
|
|
153
|
+
? NET_BACKOFF[Math.min(attempt - 1, NET_BACKOFF.length - 1)]
|
|
154
|
+
: 800 * Math.pow(2, attempt - 1);
|
|
118
155
|
await sleep(wait, signal);
|
|
119
156
|
}
|
|
120
157
|
}
|
|
@@ -133,6 +170,10 @@ async function openChat(sel, body, { stream, signal, omitReasoning } = {}) {
|
|
|
133
170
|
if (body.reasoningEffort && !omitReasoning) {
|
|
134
171
|
payload.reasoning_effort = String(body.reasoningEffort);
|
|
135
172
|
}
|
|
173
|
+
/* prompt cache anahtarı: oturum başına sabit → sağlayıcı önek önbelleği tutar */
|
|
174
|
+
if (body.cacheKey && wantsCacheKey(sel)) {
|
|
175
|
+
payload.prompt_cache_key = String(body.cacheKey);
|
|
176
|
+
}
|
|
136
177
|
return fetch(sel.url, {
|
|
137
178
|
method: 'POST',
|
|
138
179
|
signal,
|
|
@@ -180,6 +221,9 @@ async function streamOnce(sel, body, { signal, onDelta, onRetry } = {}, omitReas
|
|
|
180
221
|
} catch {}
|
|
181
222
|
const err = new Error(friendlyError(r.status, r.statusText, detail));
|
|
182
223
|
err.status = r.status;
|
|
224
|
+
err.retryAfterMs = parseRetryAfter(
|
|
225
|
+
r.headers && (r.headers.get('retry-after-ms') || r.headers.get('retry-after'))
|
|
226
|
+
);
|
|
183
227
|
throw err;
|
|
184
228
|
}
|
|
185
229
|
return r;
|
|
@@ -317,6 +361,9 @@ async function chatOnce(sel, body, { signal, onRetry } = {}) {
|
|
|
317
361
|
} catch {}
|
|
318
362
|
const err = new Error(friendlyError(r.status, r.statusText, detail));
|
|
319
363
|
err.status = r.status;
|
|
364
|
+
err.retryAfterMs = parseRetryAfter(
|
|
365
|
+
r.headers && (r.headers.get('retry-after-ms') || r.headers.get('retry-after'))
|
|
366
|
+
);
|
|
320
367
|
throw err;
|
|
321
368
|
}
|
|
322
369
|
return r;
|
|
@@ -343,4 +390,6 @@ module.exports = {
|
|
|
343
390
|
sumUsage,
|
|
344
391
|
setNetProbe,
|
|
345
392
|
isNetworkError,
|
|
393
|
+
wantsCacheKey,
|
|
394
|
+
parseRetryAfter,
|
|
346
395
|
};
|
package/src/agent/obscura.js
CHANGED
|
@@ -23,6 +23,12 @@ const FETCH_TIMEOUT_MS = 25000;
|
|
|
23
23
|
/* content-length gelmezse yüzde tahmini için yaklaşık boyut (stealth zip ≈74 MB) */
|
|
24
24
|
const EST_ZIP_BYTES = 74 * 1024 * 1024;
|
|
25
25
|
|
|
26
|
+
/* Beast Agent PAKETİNE gömülü zip (vendor/) — varsa HİÇ indirme yapılmaz */
|
|
27
|
+
function bundledZip() {
|
|
28
|
+
const p = path.join(__dirname, '..', '..', 'vendor', 'obscura.zip');
|
|
29
|
+
try { return fs.existsSync(p) ? p : null; } catch { return null; }
|
|
30
|
+
}
|
|
31
|
+
|
|
26
32
|
function obscuraDir() {
|
|
27
33
|
const base = process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming');
|
|
28
34
|
return path.join(base, 'beast', 'obscura');
|
|
@@ -130,8 +136,8 @@ function psExpand(zipPath, destDir) {
|
|
|
130
136
|
});
|
|
131
137
|
}
|
|
132
138
|
|
|
133
|
-
/* Obscura'yı kur / güncelle
|
|
134
|
-
|
|
139
|
+
/* Obscura'yı kur / güncelle. SIRA: pakete gömülü vendor zip'i (network YOK,
|
|
140
|
+
anında) → yoksa GitHub'dan indir. onProgress({pct, phase}). */
|
|
135
141
|
async function installObscura(signal, onProgress) {
|
|
136
142
|
const tick = (pct, phase) => {
|
|
137
143
|
if (typeof onProgress === 'function') {
|
|
@@ -142,14 +148,23 @@ async function installObscura(signal, onProgress) {
|
|
|
142
148
|
tick(0, 'hazırlanıyor');
|
|
143
149
|
const dest = obscuraDir();
|
|
144
150
|
fs.mkdirSync(dest, { recursive: true });
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
const bundled = bundledZip();
|
|
152
|
+
let ok = false;
|
|
153
|
+
if (bundled) {
|
|
154
|
+
/* PAKET İÇİ kurulum — indirme yok, saniyeler sürer */
|
|
155
|
+
tick(30, 'kuruluyor');
|
|
156
|
+
ok = await psExpand(bundled, dest);
|
|
157
|
+
tick(97, 'doğrulanıyor');
|
|
158
|
+
} else {
|
|
159
|
+
const zipPath = path.join(os.tmpdir(), 'beast-obscura.zip');
|
|
160
|
+
const buf = await httpsDownload(RELEASE_BASE + WINDOWS_ZIP, 5, signal, onProgress);
|
|
161
|
+
tick(89, 'kuruluyor');
|
|
162
|
+
fs.writeFileSync(zipPath, buf);
|
|
163
|
+
tick(90, 'kuruluyor');
|
|
164
|
+
ok = await psExpand(zipPath, dest);
|
|
165
|
+
try { fs.unlinkSync(zipPath); } catch {}
|
|
166
|
+
tick(97, 'doğrulanıyor');
|
|
167
|
+
}
|
|
153
168
|
if (!ok || !obscuraInstalled()) {
|
|
154
169
|
return { ok: false, error: 'obscura kurulumu başarısız (zip açılamadı)' };
|
|
155
170
|
}
|
|
@@ -265,6 +280,7 @@ module.exports = {
|
|
|
265
280
|
ENGINE: 'obscura',
|
|
266
281
|
RELEASE_BASE,
|
|
267
282
|
WINDOWS_ZIP,
|
|
283
|
+
bundledZip,
|
|
268
284
|
obscuraDir,
|
|
269
285
|
obscuraExe,
|
|
270
286
|
obscuraInstalled,
|
package/src/agent/skills.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
'use strict';
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
/* Beast skills: %APPDATA%\beast\skills\**\SKILL.md
|
|
4
4
|
Only name+description go into the system prompt (few tokens).
|
|
@@ -236,7 +236,7 @@ Gerçek Chromium olduğu için Google'a bot koruması uygulamaz. Arama aep=1 ile
|
|
|
236
236
|
|
|
237
237
|
## 2. Obscura (stealth headless — DuckDuckGo)
|
|
238
238
|
|
|
239
|
-
Rust tabanlı gizli tarayıcı: anti-detect parmak izi + V8 JS.
|
|
239
|
+
Rust tabanlı gizli tarayıcı: anti-detect parmak izi + V8 JS. Beast Agent PAKETİNDE hazır gelir — ilk açılışta %APPDATA%\\beast\\obscura'ya açılır (indirme yok). Varsayılan AKTİF — tarayıcı engellenirse bot korumasını aşarak DuckDuckGo'dan sonuç getirir.
|
|
240
240
|
|
|
241
241
|
## 3. TinyFish API (anahtar varsa)
|
|
242
242
|
|