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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "beast-agent",
3
3
  "productName": "Beast Agent",
4
- "version": "2.8.0",
4
+ "version": "2.8.1",
5
5
  "description": "Ultra-fast local agent shell for Windows.",
6
6
  "author": "algokodcom (AlgoKod)",
7
7
  "license": "MIT",
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', { signal: AbortSignal.timeout(15000) });
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: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + key },
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: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + key },
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') {