beast-agent 2.8.0 → 2.8.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/llm.js +20 -0
- package/src/main.js +20 -5
package/package.json
CHANGED
package/src/agent/llm.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
prompt_cache_key) 400'den otomatik öğrenir → model-caps.json'a kalıcı. */
|
|
11
11
|
|
|
12
12
|
const fs = require('fs');
|
|
13
|
+
const crypto = require('crypto');
|
|
13
14
|
|
|
14
15
|
const RETRYABLE_STATUS = new Set([408, 409, 425, 429, 500, 502, 503, 504]);
|
|
15
16
|
const MAX_RETRIES = 3; /* sağlayıcı geçici HTTP hataları */
|
|
@@ -328,6 +329,24 @@ async function withRetries(fn, { signal, onRetry } = {}) {
|
|
|
328
329
|
}
|
|
329
330
|
}
|
|
330
331
|
|
|
332
|
+
/* x-opencode-session: konuşma-başına sabit oturum kimliği — TÜM sağlayıcılara
|
|
333
|
+
standart gönderilir (opencode bununla isteği optimize eder; 09/06'dan
|
|
334
|
+
itibaren headersız istek hata dönebilir). Gerçek sohbetlerde cacheKey =
|
|
335
|
+
session.id; cacheKey'siz yardımcı isteklerde süreç-başına sabit yedek. */
|
|
336
|
+
let _sessionFallback = null;
|
|
337
|
+
function sessionHeaderId(body) {
|
|
338
|
+
const ck = String((body && body.cacheKey) || '').trim();
|
|
339
|
+
if (ck) return ck;
|
|
340
|
+
if (!_sessionFallback) {
|
|
341
|
+
try {
|
|
342
|
+
_sessionFallback = crypto.randomUUID();
|
|
343
|
+
} catch {
|
|
344
|
+
_sessionFallback = 'beast-' + Date.now().toString(36) + Math.random().toString(36).slice(2, 10);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return _sessionFallback;
|
|
348
|
+
}
|
|
349
|
+
|
|
331
350
|
async function openChat(sel, body, { stream, signal, drops } = {}) {
|
|
332
351
|
const d = drops || {};
|
|
333
352
|
const payload = {
|
|
@@ -357,6 +376,7 @@ async function openChat(sel, body, { stream, signal, drops } = {}) {
|
|
|
357
376
|
Authorization: `Bearer ${sel.key}`,
|
|
358
377
|
'HTTP-Referer': 'https://localhost/beast',
|
|
359
378
|
'X-Title': 'Beast Agent',
|
|
379
|
+
'x-opencode-session': sessionHeaderId(body),
|
|
360
380
|
},
|
|
361
381
|
body: JSON.stringify(payload),
|
|
362
382
|
});
|
package/src/main.js
CHANGED
|
@@ -6,6 +6,10 @@ const fs = require('fs');
|
|
|
6
6
|
const http = require('http');
|
|
7
7
|
const dns = require('dns');
|
|
8
8
|
const crypto = require('crypto');
|
|
9
|
+
/* x-opencode-session: opencode (Zen/Go) isteklerinde beklenen oturum kimliği —
|
|
10
|
+
kurulum/probe/model-liste istekleri için süreç-başına sabit değer; sohbet
|
|
11
|
+
isteklerindeki konuşma-başına kimlik agent/llm.js'te üretilir */
|
|
12
|
+
const OPENCODE_SESSION = 'beast-' + crypto.randomUUID();
|
|
9
13
|
const { spawn } = require('child_process');
|
|
10
14
|
const { Engine, OBSERVE_MARK } = require('./agent/engine');
|
|
11
15
|
const { loadBeastConfig, parseEnvFile, beastDir } = require('./agent/config');
|
|
@@ -8387,7 +8391,7 @@ async function refreshModelsAll() {
|
|
|
8387
8391
|
try {
|
|
8388
8392
|
const b = String(p.baseUrl).trim().replace(/\/+$/, '');
|
|
8389
8393
|
const url = /\/v\d+$/.test(b) ? b + '/models' : b + '/v1/models';
|
|
8390
|
-
const h = { Authorization: 'Bearer ' + p.key };
|
|
8394
|
+
const h = { Authorization: 'Bearer ' + p.key, 'x-opencode-session': OPENCODE_SESSION };
|
|
8391
8395
|
try {
|
|
8392
8396
|
if (new URL(url).hostname === 'api.anthropic.com') {
|
|
8393
8397
|
h['x-api-key'] = p.key;
|
|
@@ -8484,7 +8488,10 @@ function findZenToken() {
|
|
|
8484
8488
|
|
|
8485
8489
|
async function fetchZenFreeModels() {
|
|
8486
8490
|
try {
|
|
8487
|
-
const res = await fetch(ZEN_BASE + '/models', {
|
|
8491
|
+
const res = await fetch(ZEN_BASE + '/models', {
|
|
8492
|
+
headers: { 'x-opencode-session': OPENCODE_SESSION },
|
|
8493
|
+
signal: AbortSignal.timeout(15000),
|
|
8494
|
+
});
|
|
8488
8495
|
if (res.ok) {
|
|
8489
8496
|
const j = await res.json();
|
|
8490
8497
|
const ids = (j.data || []).map((m) => (typeof m === 'string' ? m : m.id)).filter(Boolean);
|
|
@@ -8584,7 +8591,11 @@ async function testZenModel(key, model) {
|
|
|
8584
8591
|
try {
|
|
8585
8592
|
const res = await fetch(ZEN_BASE + '/chat/completions', {
|
|
8586
8593
|
method: 'POST',
|
|
8587
|
-
headers: {
|
|
8594
|
+
headers: {
|
|
8595
|
+
'Content-Type': 'application/json',
|
|
8596
|
+
Authorization: 'Bearer ' + key,
|
|
8597
|
+
'x-opencode-session': OPENCODE_SESSION,
|
|
8598
|
+
},
|
|
8588
8599
|
body: JSON.stringify({
|
|
8589
8600
|
model,
|
|
8590
8601
|
messages: [{ role: 'user', content: 'ping' }],
|
|
@@ -8623,7 +8634,11 @@ async function testZenReasoning(key, model) {
|
|
|
8623
8634
|
try {
|
|
8624
8635
|
const res = await fetch(ZEN_BASE + '/chat/completions', {
|
|
8625
8636
|
method: 'POST',
|
|
8626
|
-
headers: {
|
|
8637
|
+
headers: {
|
|
8638
|
+
'Content-Type': 'application/json',
|
|
8639
|
+
Authorization: 'Bearer ' + key,
|
|
8640
|
+
'x-opencode-session': OPENCODE_SESSION,
|
|
8641
|
+
},
|
|
8627
8642
|
body: JSON.stringify({
|
|
8628
8643
|
model,
|
|
8629
8644
|
messages: [{ role: 'user', content: 'ping' }],
|
|
@@ -8731,7 +8746,7 @@ ipcMain.handle('custom:fetchModels', async (_e, { baseUrl, key }) => {
|
|
|
8731
8746
|
let b = String(baseUrl || '').trim().replace(/\/+$/, '');
|
|
8732
8747
|
if (!/^https?:\/\//i.test(b)) return { ok: false, error: 'URL http(s) ile başlamalı' };
|
|
8733
8748
|
const url = /\/v\d+$/.test(b) ? b + '/models' : b + '/v1/models';
|
|
8734
|
-
const headers = key ? { Authorization: 'Bearer ' + key } : {};
|
|
8749
|
+
const headers = { 'x-opencode-session': OPENCODE_SESSION, ...(key ? { Authorization: 'Bearer ' + key } : {}) };
|
|
8735
8750
|
/* Anthropic: /v1/models yerel API — x-api-key + versiyon başlığı ister */
|
|
8736
8751
|
try {
|
|
8737
8752
|
if (new URL(url).hostname === 'api.anthropic.com') {
|