beast-agent 2.63.9 → 2.64.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/browseragent.js +477 -0
- package/src/agent/computeragent.js +366 -0
- package/src/agent/engine.js +121 -6
- package/src/agent/typesafe.js +85 -35
- package/src/agent/watext.js +2 -0
- package/src/main.js +296 -22
- package/src/renderer/i18n.js +4 -0
- package/src/renderer/renderer.js +20 -4
package/src/agent/typesafe.js
CHANGED
|
@@ -28,9 +28,19 @@ function cfg() {
|
|
|
28
28
|
return {
|
|
29
29
|
apiKey: String(c.apiKey || '').trim(),
|
|
30
30
|
model: String(c.model || '').trim() || DEFAULT_MODEL,
|
|
31
|
+
enabled: c.enabled !== false,
|
|
31
32
|
};
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
/* Ayar kapısı: anahtar yoksa ya da anahtar Ayarlar → TypeSafe'te KAPALIYSA
|
|
36
|
+
hiçbir TypeSafe çağrısı yapılmaz. Boş dönüş = hazır; dolu dönüş = hata metni. */
|
|
37
|
+
function unavailable() {
|
|
38
|
+
const c = cfg();
|
|
39
|
+
if (!c.apiKey) return 'TypeSafe API anahtarı yok — Ayarlar → TypeSafe sekmesinden gir';
|
|
40
|
+
if (!c.enabled) return 'TypeSafe kapalı — Ayarlar → TypeSafe sekmesinden aç';
|
|
41
|
+
return '';
|
|
42
|
+
}
|
|
43
|
+
|
|
34
44
|
function errorForStatus(status, bodyText) {
|
|
35
45
|
const detail = String(bodyText || '').slice(0, 240);
|
|
36
46
|
if (status === 401 || status === 403) return 'TypeSafe API anahtarı geçersiz (Ayarlar → TypeSafe sekmesinden kontrol et)' + (detail ? ' — ' + detail : '');
|
|
@@ -77,46 +87,87 @@ function normalizeQuestions(questions) {
|
|
|
77
87
|
return out;
|
|
78
88
|
}
|
|
79
89
|
|
|
80
|
-
/* systemOne çağrısı: state + questions → answers
|
|
90
|
+
/* systemOne çağrısı: state + questions → answers.
|
|
91
|
+
Geçici hatalarda (429/5xx/ağ/zaman aşımı) kısa backoff ile 2 kez yeniden
|
|
92
|
+
denenir — tek dalgalı hata tüm Jev döngüsünü düşürmesin. */
|
|
93
|
+
const RETRY_DELAYS_MS = [400, 1000];
|
|
94
|
+
|
|
95
|
+
function sleep(ms, signal) {
|
|
96
|
+
return new Promise((resolve, reject) => {
|
|
97
|
+
if (signal && signal.aborted) return reject(new Error('TypeSafe çağrısı iptal edildi'));
|
|
98
|
+
const t = setTimeout(() => {
|
|
99
|
+
if (signal && typeof signal.removeEventListener === 'function') signal.removeEventListener('abort', onAbort);
|
|
100
|
+
resolve();
|
|
101
|
+
}, ms);
|
|
102
|
+
function onAbort() {
|
|
103
|
+
clearTimeout(t);
|
|
104
|
+
reject(new Error('TypeSafe çağrısı iptal edildi'));
|
|
105
|
+
}
|
|
106
|
+
if (signal && typeof signal.addEventListener === 'function') signal.addEventListener('abort', onAbort, { once: true });
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
81
110
|
async function systemOne({ state, questions, model, timeoutMs, signal } = {}) {
|
|
82
111
|
const c = cfg();
|
|
83
|
-
|
|
112
|
+
const gate = unavailable();
|
|
113
|
+
if (gate) throw new Error(gate);
|
|
84
114
|
if (state == null || (typeof state === 'string' && !state.trim())) {
|
|
85
115
|
throw new Error('state boş — değerlendirilecek içerik gerekli (metin ya da JSON nesne/dizi)');
|
|
86
116
|
}
|
|
87
117
|
const qs = normalizeQuestions(questions);
|
|
88
118
|
const body = { state, model: String(model || '').trim() || c.model, questions: qs };
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
119
|
+
const perTry = Number(timeoutMs) > 0 ? Number(timeoutMs) : DEFAULT_TIMEOUT_MS;
|
|
120
|
+
let lastError = null;
|
|
121
|
+
for (let attempt = 0; attempt <= RETRY_DELAYS_MS.length; attempt++) {
|
|
122
|
+
if (signal && signal.aborted) throw new Error('TypeSafe çağrısı iptal edildi');
|
|
123
|
+
const ctrl = new AbortController();
|
|
124
|
+
const timer = setTimeout(() => ctrl.abort(), perTry);
|
|
125
|
+
const onAbort = () => ctrl.abort();
|
|
126
|
+
if (signal && typeof signal.addEventListener === 'function') signal.addEventListener('abort', onAbort, { once: true });
|
|
127
|
+
try {
|
|
128
|
+
const res = await fetch(BASE_URL + '/v1/systemone', {
|
|
129
|
+
method: 'POST',
|
|
130
|
+
headers: { 'content-type': 'application/json', authorization: 'Bearer ' + c.apiKey },
|
|
131
|
+
body: JSON.stringify(body),
|
|
132
|
+
signal: ctrl.signal,
|
|
133
|
+
});
|
|
134
|
+
if (!res.ok) {
|
|
135
|
+
const txt = await res.text().catch(() => '');
|
|
136
|
+
const err = new Error(errorForStatus(res.status, txt));
|
|
137
|
+
err.status = res.status;
|
|
138
|
+
throw err;
|
|
139
|
+
}
|
|
140
|
+
const data = await res.json();
|
|
141
|
+
return {
|
|
142
|
+
model: String((data && data.model) || body.model),
|
|
143
|
+
answers: (data && data.answers) || {},
|
|
144
|
+
usage: (data && data.usage) || null,
|
|
145
|
+
};
|
|
146
|
+
} catch (e) {
|
|
147
|
+
const abortedByUser = !!(signal && signal.aborted);
|
|
148
|
+
if (abortedByUser) throw new Error('TypeSafe çağrısı iptal edildi');
|
|
149
|
+
const timedOut = !!(e && (e.name === 'AbortError' || e.name === 'TimeoutError'));
|
|
150
|
+
const network = e instanceof TypeError;
|
|
151
|
+
const retryable = timedOut || network || e.status === 429 || (Number(e.status) >= 500 && Number(e.status) <= 599);
|
|
152
|
+
lastError = e;
|
|
153
|
+
if (retryable && attempt < RETRY_DELAYS_MS.length) {
|
|
154
|
+
try {
|
|
155
|
+
await sleep(RETRY_DELAYS_MS[attempt], signal);
|
|
156
|
+
} catch (abortErr) {
|
|
157
|
+
throw new Error('TypeSafe çağrısı iptal edildi');
|
|
158
|
+
}
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (timedOut) {
|
|
162
|
+
throw new Error('TypeSafe zaman aşımı — istek ' + Math.round(perTry / 1000) + ' sn içinde yanıtlanmadı');
|
|
163
|
+
}
|
|
164
|
+
throw e;
|
|
165
|
+
} finally {
|
|
166
|
+
clearTimeout(timer);
|
|
167
|
+
if (signal && typeof signal.removeEventListener === 'function') signal.removeEventListener('abort', onAbort);
|
|
114
168
|
}
|
|
115
|
-
throw e;
|
|
116
|
-
} finally {
|
|
117
|
-
clearTimeout(timer);
|
|
118
|
-
if (signal && typeof signal.removeEventListener === 'function') signal.removeEventListener('abort', onAbort);
|
|
119
169
|
}
|
|
170
|
+
throw lastError || new Error('TypeSafe çağrısı başarısız');
|
|
120
171
|
}
|
|
121
172
|
|
|
122
173
|
/* Anahtar testi: tek soruluk ucuz systemOne çağrısı (bağlantı + auth doğrular) */
|
|
@@ -222,10 +273,8 @@ function summarize(answers) {
|
|
|
222
273
|
|
|
223
274
|
async function handler(args, ctx) {
|
|
224
275
|
const a = args && typeof args === 'object' ? args : {};
|
|
225
|
-
const
|
|
226
|
-
if (
|
|
227
|
-
return { ok: false, error: 'TypeSafe API anahtarı yok — Ayarlar → TypeSafe sekmesinden gir (kullanıcıya bunu söyle)' };
|
|
228
|
-
}
|
|
276
|
+
const gate = unavailable();
|
|
277
|
+
if (gate) return { ok: false, error: gate + ' (kullanıcıya bunu söyle)' };
|
|
229
278
|
let state = a.state;
|
|
230
279
|
if (typeof state === 'string') {
|
|
231
280
|
const s = state.trim();
|
|
@@ -272,6 +321,7 @@ module.exports = {
|
|
|
272
321
|
probe,
|
|
273
322
|
setConfig,
|
|
274
323
|
cfg,
|
|
324
|
+
unavailable,
|
|
275
325
|
normalizeQuestions,
|
|
276
326
|
BASE_URL,
|
|
277
327
|
DEFAULT_MODEL,
|
package/src/agent/watext.js
CHANGED
|
@@ -42,6 +42,8 @@ const TOOL_LABELS = {
|
|
|
42
42
|
},
|
|
43
43
|
http_fetch: (a) => `Sayfa: ${a.url || ''}`,
|
|
44
44
|
browser_open: (a) => `Tarayıcı aç: ${a.url || ''}`,
|
|
45
|
+
browser_agent: (a) => `T3SFast ajan: ${String(a.goal || a.task || '').slice(0, 80)}`,
|
|
46
|
+
computer_agent: (a) => `T3SFast PC: ${String(a.goal || a.task || '').slice(0, 80)}`,
|
|
45
47
|
browser_click: (a) => `Tıkla: ${a.ref ?? ''}`,
|
|
46
48
|
browser_type: (a) => `Yaz: ${String(a.text || '').slice(0, 60)}`,
|
|
47
49
|
browser_select: (a) => `Seç: ${a.ref ?? ''}`,
|