beast-agent 0.25.7 → 0.25.8

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": "0.25.7",
4
+ "version": "0.25.8",
5
5
  "description": "Ultra-fast local agent shell for Windows.",
6
6
  "author": "algokodcom (AlgoKod)",
7
7
  "license": "MIT",
package/src/main.js CHANGED
@@ -3723,7 +3723,13 @@ ipcMain.handle('agent:send', (_e, { sessionId, text }) => {
3723
3723
  if (!sess) {
3724
3724
  try { sess = engine._load(sid); } catch {}
3725
3725
  }
3726
- if (sess && !sess.botId) engine.setSessionBot(sid, actBot.id);
3726
+ if (sess && !sess.botId) {
3727
+ engine.setSessionBot(sid, actBot.id);
3728
+ /* tam bağlama: izin + araç seti + botun kendi modeli (sessions:create ile aynı) */
3729
+ engine.setSessionPerm(sid, actBot.perm || 'all');
3730
+ engine.setSessionTools(sid, botToolSet(actBot));
3731
+ engine.setSessionModel(sid, actBot.model || null);
3732
+ }
3727
3733
  }
3728
3734
  } catch {}
3729
3735
  if (t === '/stop' || t === '/start') {
@@ -4315,9 +4321,21 @@ async function netCheck() {
4315
4321
  }
4316
4322
 
4317
4323
  ipcMain.handle('model:set', (_e, sel) => {
4318
- settings.modelOverride = sel;
4319
- saveSettings();
4320
- engine.setModelOverride(sel);
4324
+ /* MÜŞTERİ botu aktifken picker seçimi O BOTUN modelini değiştirir;
4325
+ Beast (admin) aktifken global seçim değişir. */
4326
+ const act = settings.activeBotId ? bots.get(settings.activeBotId) : null;
4327
+ if (act && !act.admin) {
4328
+ try { bots.update(act.id, { model: String(sel || '') }); } catch {}
4329
+ try {
4330
+ for (const v of engine.listSessions()) {
4331
+ if (v.botId === act.id) engine.setSessionModel(v.id, sel || null);
4332
+ }
4333
+ } catch {}
4334
+ } else {
4335
+ settings.modelOverride = sel;
4336
+ saveSettings();
4337
+ engine.setModelOverride(sel);
4338
+ }
4321
4339
  return engine.publicState();
4322
4340
  });
4323
4341
 
@@ -471,16 +471,21 @@ async function renderSessions(list) {
471
471
  tgSet = new Set(await beast.tgListSessions());
472
472
  } catch {}
473
473
  els.sessList.innerHTML = '';
474
- /* aktif botun oturumları — botlar arası geçişte liste de o bota göre değişir */
474
+ /* aktif botun oturumları — botlar arası geçişte liste de o bota göre değişir.
475
+ BOT BAĞLAMA MİGRASYONU: bot kaydı olmayan (eski) oturumlar HER botun
476
+ listesinde de görünür — kullanıcı botunda açıp ilk mesajı yazınca
477
+ oturum KALICI olarak o bota bağlanır (agent:send auto-bind; notlar dahil).
478
+ Başka bir bota AÇIKÇA bağlı olanlar yalnız o botun listesinde. */
475
479
  for (const s of list) {
476
- if ((s.botId || 'beast') !== activeBotId) continue;
480
+ if (s.botId && s.botId !== activeBotId) continue;
481
+ const unbound = !s.botId && activeBotId !== 'beast';
477
482
  const row = document.createElement('div');
478
483
  row.className = 'sess' + (s.id === activeId ? ' active' : '');
479
484
  row.innerHTML =
480
485
  (waSet.has(s.id) ? '<span class="sess-wa" title="WhatsApp">W</span>' : '') +
481
486
  (tgSet.has(s.id) ? '<span class="sess-tg" title="Telegram">T</span>' : '') +
482
487
  `<span class="sess-title">${escapeHtml(s.title || 'Yeni Sohbet')}</span>` +
483
- `<span class="sess-code" title="Oturum kodu">${escapeHtml(s.code || '')}</span>` +
488
+ `<span class="sess-code" title="${unbound ? 'bağlantı bekliyor — ilk mesajda bu bota bağlanır' : 'Oturum kodu'}">${escapeHtml(s.code || '')}${unbound ? ' ·?' : ''}</span>` +
484
489
  `<button class="sess-del" title="Sil">×</button>`;
485
490
  row.addEventListener('click', () => openSession(s.id));
486
491
  row.querySelector('.sess-del').addEventListener('click', async (e) => {
@@ -815,7 +820,7 @@ async function renderProviderPane() {
815
820
 
816
821
  for (const m of state.models || []) {
817
822
  const row = document.createElement('div');
818
- row.className = 'prov-row' + (state.activeModel && state.activeModel.sel === m.sel ? ' active' : '');
823
+ row.className = 'prov-row' + (effectiveModelSel() === m.sel ? ' active' : '');
819
824
  row.innerHTML =
820
825
  `<span class="prov-name">${escapeHtml(m.providerName)}</span>` +
821
826
  `<span class="prov-model">${escapeHtml(m.model)}</span>` +
@@ -823,6 +828,7 @@ async function renderProviderPane() {
823
828
  `<button class="prov-del" title="${_t('p_del_title')}">✕</button>`;
824
829
  row.addEventListener('click', async () => {
825
830
  state = await beast.setModel(m.sel);
831
+ await refreshBots().catch(() => {});
826
832
  applyState();
827
833
  renderProviderPane();
828
834
  toast(_t('p_model_toast') + m.providerName + ' · ' + m.model);
@@ -2719,6 +2725,8 @@ async function refreshBots() {
2719
2725
  /* BOT PICKER SENKRONU: liste her yenilendiğinde üstteki rozet de aktif bota
2720
2726
  ayarlanır — startup yarışında (liste boşken çizilen) eski rozet düzelir */
2721
2727
  updateBotChip();
2728
+ /* model picker da aktif botun kendi modelini göstersin */
2729
+ if (state) applyState();
2722
2730
  if (!$('#botOverlay').hidden) renderBotPage();
2723
2731
  }
2724
2732
 
@@ -2776,12 +2784,15 @@ async function switchBot(id) {
2776
2784
  }
2777
2785
  } catch {}
2778
2786
  try { localStorage.setItem('beast.activeBot', id); } catch {}
2779
- /* o botun en son oturumuna geç; hiç yoksa o bot için yeni sohbet aç */
2787
+ /* o botun en son oturumuna geç; hiç yoksa o bot için yeni sohbet aç.
2788
+ (bot kaydı olmayan eski oturumlar da sayılır — ilk mesajda bağlanır) */
2780
2789
  try {
2781
- const list = (await beast.listSessions()).filter((s) => (s.botId || 'beast') === id);
2790
+ const list = (await beast.listSessions()).filter((s) => !s.botId || s.botId === id);
2782
2791
  if (list.length) await openSession(list[0].id);
2783
2792
  else { const v = await beast.createSession(); await openSession(v.id); }
2784
2793
  } catch {}
2794
+ /* picker, aktif botun kendi modelini göstersin */
2795
+ applyState();
2785
2796
  toast((b.icon || '🤖') + ' ' + b.name + (b.admin ? '' : ' — ' + _t('bot_switched')));
2786
2797
  }
2787
2798
 
@@ -2883,7 +2894,7 @@ async function renderBotNotes(pane, b) {
2883
2894
  pane.innerHTML = `<h2>${_t('notes_h2')}</h2><div class="sub">${_t('notes_sub')}</div>`;
2884
2895
  let all = [];
2885
2896
  try { all = await beast.listNotes(); } catch {}
2886
- const list = (b.admin ? all : all.filter((n) => (n.botId || 'beast') === b.id))
2897
+ const list = (b.admin ? all : all.filter((n) => !n.botId || n.botId === b.id))
2887
2898
  .slice()
2888
2899
  .sort((x, y) => String(y.updatedAt).localeCompare(String(x.updatedAt)));
2889
2900
  if (!list.length) {
@@ -2944,7 +2955,8 @@ async function renderBotChats(b) {
2944
2955
  const sessions = [];
2945
2956
  try {
2946
2957
  for (const s of await beast.listSessions()) {
2947
- if ((s.botId || 'beast') === b.id) sessions.push(s);
2958
+ /* bot kaydı olmayan (eski) oturumlar da gösterilir — ilk mesajda bu bota bağlanır */
2959
+ if (!s.botId || s.botId === b.id) sessions.push(s);
2948
2960
  }
2949
2961
  } catch {}
2950
2962
  sessions.sort((x, y) => String(y.updatedAt).localeCompare(String(x.updatedAt)));
@@ -3180,7 +3192,7 @@ async function renderBotWatcher(pane, b) {
3180
3192
  try { items = (await beast.watchersList()) || []; } catch {}
3181
3193
  let botSessions = new Set();
3182
3194
  try {
3183
- for (const s of await beast.listSessions()) if ((s.botId || 'beast') === b.id) botSessions.add(s.id);
3195
+ for (const s of await beast.listSessions()) if (!s.botId || s.botId === b.id) botSessions.add(s.id);
3184
3196
  } catch {}
3185
3197
  const mine = items.filter((w) => botSessions.has(w.sessionId));
3186
3198
  if (!mine.length) {
@@ -4023,15 +4035,26 @@ async function openCronModal() {
4023
4035
 
4024
4036
  /* ---------------- state / controls ---------------- */
4025
4037
 
4038
+ /* AKTİF BOTUN etkili model seçimi: müşteri botun kendi modeli varsa o,
4039
+ yoksa (ve admin bot daysa) global picker seçimi. */
4040
+ function effectiveModelSel() {
4041
+ const b = botsCache.find((x) => x.id === activeBotId);
4042
+ return b && !b.admin && b.model ? b.model : (state.activeModel && state.activeModel.sel) || '';
4043
+ }
4044
+
4026
4045
  function applyState() {
4027
4046
  if (!state) return;
4028
- els.modelBtnLabel.textContent = state.activeModel
4029
- ? `${state.activeModel.providerName} · ${state.activeModel.model}`
4030
- : 'Model seçilmedi';
4047
+ const botSel = activeBotId && botsCache.length ? effectiveModelSel() : (state.activeModel && state.activeModel.sel);
4048
+ const bm = botSel ? (state.models || []).find((x) => x.sel === botSel) : null;
4049
+ els.modelBtnLabel.textContent = bm
4050
+ ? `${bm.providerName} · ${bm.model}`
4051
+ : state.activeModel
4052
+ ? `${state.activeModel.providerName} · ${state.activeModel.model}`
4053
+ : 'Model seçilmedi';
4031
4054
  els.thinkBtnLabel.innerHTML =
4032
- '<svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 2A2.5 2.5 0 0 0 7 4.5v.55A3.5 3.5 0 0 0 4.5 8.5c0 .74.23 1.43.62 2A3.5 3.5 0 0 0 4 13.5 3.5 3.5 0 0 0 7 16.95v.55A2.5 2.5 0 0 0 9.5 20a2.5 2.5 0 0 0 2.5-2.5v-13A2.5 2.5 0 0 0 9.5 2z"/><path d="M14.5 2A2.5 2.5 0 0 1 17 4.5v.55a3.5 3.5 0 0 1 2.5 3.45c0 .74-.23 1.43-.62 2a3.5 3.5 0 0 1 1.12 3 3.5 3.5 0 0 1-3 3.45v.55A2.5 2.5 0 0 1 14.5 20 2.5 2.5 0 0 1 12 17.5v-13A2.5 2.5 0 0 1 14.5 2z"/></svg>';
4055
+ '<svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 2A2.5 2.5 0 0 0 7 4.5v.55A3.5 3.5 0 0 0 4.5 8.5c0 .74.23 1.43.62 2A3.5 3.5 0 0 0 4 13.5 3.5 3.5 0 0 0 7 16.95v.55A2.5 2.5 0 0 0 9.5 20a2.5 2.5 0 0 0 2.5-2.5v-13A2.5 2.5 0 0 0 9.5 2z"/><path d="M14.5 2A2.5 2.5 0 0 1 17 4.5v.55a3.5 3.5 0 0 1 2.5 3.45c0 .74-.23 1.43-.62 2a3.5 3.5 0 0 1-1.12 3 3.5 3.5 0 0 1-3 3.45v.55A2.5 2.5 0 0 1 14.5 20 2.5 2.5 0 0 1 12 17.5v-13A2.5 2.5 0 0 1 14.5 2z"/></svg>';
4033
4056
  renderModelMenu();
4034
- }
4057
+ }
4035
4058
 
4036
4059
  /* düşünme (reasoning) seviyesi picker — gerçek API değerleri */
4037
4060
  const THINK_UI_LEVELS = [
@@ -4088,7 +4111,7 @@ function renderModelMenu() {
4088
4111
  els.modelList.innerHTML = '';
4089
4112
  for (const m of list) {
4090
4113
  const item = document.createElement('div');
4091
- item.className = 'dd-item' + (state.activeModel && state.activeModel.sel === m.sel ? ' active' : '');
4114
+ item.className = 'dd-item' + (effectiveModelSel() && effectiveModelSel() === m.sel ? ' active' : '');
4092
4115
  item.innerHTML =
4093
4116
  `<span class="dn">${escapeHtml(m.providerName)}</span>` +
4094
4117
  `<span class="dm">${escapeHtml(m.model)}</span>` +
@@ -4096,6 +4119,7 @@ function renderModelMenu() {
4096
4119
  item.addEventListener('click', async () => {
4097
4120
  state = await beast.setModel(m.sel);
4098
4121
  closeModelMenu();
4122
+ await refreshBots().catch(() => {}); // bot modeli değiştiyse botsCache tazelensin
4099
4123
  applyState();
4100
4124
  });
4101
4125
  els.modelList.appendChild(item);
@@ -4750,7 +4774,7 @@ async function init() {
4750
4774
  if ($('#botOverviewBack')) $('#botOverviewBack').addEventListener('click', () => openBotPage(null));
4751
4775
  if ($('#botChip')) $('#botChip').addEventListener('click', () => openBotPage(activeBotId));
4752
4776
  /* kalıcı aktif bot: restart sonrası aynı botun UI'ı açılır */
4753
- beast.botsActiveGet().then((r) => { activeBotId = (r && r.id) || 'beast'; updateBotChip(); renderBotCards(); }).catch(() => {});
4777
+ beast.botsActiveGet().then((r) => { activeBotId = (r && r.id) || 'beast'; updateBotChip(); renderBotCards(); applyState(); }).catch(() => {});
4754
4778
  document.querySelectorAll('.btab').forEach((b) =>
4755
4779
  b.addEventListener('click', () => {
4756
4780
  document.querySelectorAll('.btab').forEach((x) => x.classList.remove('active'));