beast-agent 0.23.8 → 0.23.9
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/engine.js +45 -7
- package/src/agent/skills.js +28 -0
- package/src/main.js +13 -0
- package/src/preload.js +2 -0
- package/src/renderer/i18n.js +2 -0
- package/src/renderer/renderer.js +10 -0
package/package.json
CHANGED
package/src/agent/engine.js
CHANGED
|
@@ -220,7 +220,10 @@ class Engine {
|
|
|
220
220
|
this.tokRatio = 1; // gerçek prompt_tokens ile kalibre edilir
|
|
221
221
|
this._codeIndex = new Map(); // kısa oturum kodu -> session id
|
|
222
222
|
/* yansıma: oturumda 5+ yeni araç çağrısında skill taslağı denenir */
|
|
223
|
-
this.reflection = { enabled: opts.reflection !== false, minTools:
|
|
223
|
+
this.reflection = { enabled: opts.reflection !== false, minTools: 3 };
|
|
224
|
+
/* OTOMATİK SKİLL SİSTEMİ: öğrenilen prosedür taslak onayı beklemeden
|
|
225
|
+
kurulu skill olur; mevcut skillin daha iyisi bulunursa üzerine günceller */
|
|
226
|
+
this.autoSkills = opts.autoSkills !== false;
|
|
224
227
|
this.historyTokenBudget = Number(opts.historyTokenBudget) || HISTORY_TOKEN_BUDGET;
|
|
225
228
|
this.browser = opts.browser || null; // dahili tarayıcı kancaları
|
|
226
229
|
this.fileSend = opts.fileSend || null; // #26 dosya gönderim köprüsü (chat/WA)
|
|
@@ -2479,12 +2482,25 @@ class Engine {
|
|
|
2479
2482
|
);
|
|
2480
2483
|
if (transcript.length < 400) return null; // çok kısa deneyim değmez
|
|
2481
2484
|
|
|
2485
|
+
/* OTOMATİK SKİLL SİSTEMİ: kurulu skill listesi de prompta girer —
|
|
2486
|
+
ajan "eski skillden daha kolay/better yol buldum" diyebilmesin, KARAR VERİP
|
|
2487
|
+
skilli GÜNCELLESİN. action: create (yeni) | update (mevcutu iyileştir) | none */
|
|
2488
|
+
const skills = require('./skills');
|
|
2489
|
+
const existing = skills
|
|
2490
|
+
.scan()
|
|
2491
|
+
.map((s) => `- ${s.name}: ${(s.description || '').slice(0, 100)}`)
|
|
2492
|
+
.join('\n');
|
|
2493
|
+
|
|
2482
2494
|
const prompt =
|
|
2483
|
-
'Aşağıdaki agent oturumunda TEKRARLANABİLİR, yeniden kullanılabilir bir prosedür/bilgi ' +
|
|
2484
|
-
'
|
|
2495
|
+
'Aşağıdaki agent oturumunda TEKRARLANABİLİR, yeniden kullanılabilir bir prosedür/bilgi birikti mi?\n' +
|
|
2496
|
+
'Bir kurulu skill, bu oturumda öğrenilen DAHA KOLAY/DAHA İYİ yöntemle güncellenmeyi hak ediyor mu?\n' +
|
|
2497
|
+
'Kullanıcıya özel geçici detaylar (tarih, şehir, numara gibi) skill\u2019e YAZILMAZ — genel yöntem yazılır.\n\n' +
|
|
2498
|
+
'# KURULU SKİLLER\n' + (existing || '(yok)') + '\n\n' +
|
|
2485
2499
|
'SADECE şu JSON formatında cevap ver, başka metin yok:\n' +
|
|
2486
|
-
'{"
|
|
2487
|
-
'
|
|
2500
|
+
'{"action": "none" | "create" | "update", "name": "kisa-kebab-ad", "description": "tek cümle ne işe yarar", "body": "# Başlık\\n\\nmaddeler halinde adım adım prosedür"}\n\n' +
|
|
2501
|
+
'action=create → yeni skill (body: baştan sona tam prosedür)\n' +
|
|
2502
|
+
'action=update → "name" MEVCUT skillin adı; body o skillin GÜNCELLENMİŞ TAM HALI (eskiden iyi olan adımları koru, yeni kolaylığı işle)\n' +
|
|
2503
|
+
'action=none → değerlenecek bir şey yok\n\n' +
|
|
2488
2504
|
'# OTURUM ÖZETİ\n' + transcript.slice(0, 6000);
|
|
2489
2505
|
|
|
2490
2506
|
const res = await chatOnce(
|
|
@@ -2493,8 +2509,30 @@ class Engine {
|
|
|
2493
2509
|
{}
|
|
2494
2510
|
);
|
|
2495
2511
|
const draft = parseReflectionJson(res.content || '');
|
|
2496
|
-
if (!draft || !draft.
|
|
2497
|
-
|
|
2512
|
+
if (!draft || !draft.name || !draft.body) return null;
|
|
2513
|
+
|
|
2514
|
+
const action = String(draft.action || (draft.create ? 'create' : 'none')).toLowerCase();
|
|
2515
|
+
if (action !== 'create' && action !== 'update') return null;
|
|
2516
|
+
|
|
2517
|
+
if (action === 'update') {
|
|
2518
|
+
/* mevcut skillin GÜNCELLENMİŞ hali — doğrudan üzerine (eski hali .bak) */
|
|
2519
|
+
const r = skills.upsertSkill({
|
|
2520
|
+
name: String(draft.name),
|
|
2521
|
+
description: String(draft.description || ''),
|
|
2522
|
+
body: String(draft.body),
|
|
2523
|
+
});
|
|
2524
|
+
return r.ok ? skills.slugify(draft.name) + ' (güncellendi)' : null;
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2527
|
+
/* create: otomatik skill modu AÇIKSA taslak beklemeden direkt kur */
|
|
2528
|
+
if (this.autoSkills) {
|
|
2529
|
+
const r = skills.upsertSkill({
|
|
2530
|
+
name: String(draft.name),
|
|
2531
|
+
description: String(draft.description || ''),
|
|
2532
|
+
body: String(draft.body),
|
|
2533
|
+
});
|
|
2534
|
+
return r.ok ? skills.slugify(draft.name) : null;
|
|
2535
|
+
}
|
|
2498
2536
|
const r = skills.addDraft({
|
|
2499
2537
|
name: String(draft.name),
|
|
2500
2538
|
description: String(draft.description || ''),
|
package/src/agent/skills.js
CHANGED
|
@@ -487,6 +487,33 @@ function dropDraft(id) {
|
|
|
487
487
|
}
|
|
488
488
|
}
|
|
489
489
|
|
|
490
|
+
/* OTOMATIK SKILL SİSTEMİ: yansımadan doğan prosedürü DOĞRUDAN kurulu skill olarak
|
|
491
|
+
yazar (taslak onayı beklemeden). Aynı isimde skill varsa GÜNCELLENİR:
|
|
492
|
+
eski içerik .bak'a alınır, created korunur, updated damgası vurulur. */
|
|
493
|
+
function upsertSkill({ name, description, body }) {
|
|
494
|
+
try {
|
|
495
|
+
const nm = String(name || '').trim() || 'yetenek';
|
|
496
|
+
const folder = slugify(nm);
|
|
497
|
+
const d = path.join(dir(), folder);
|
|
498
|
+
const file = path.join(d, 'SKILL.md');
|
|
499
|
+
fs.mkdirSync(d, { recursive: true });
|
|
500
|
+
let fm = `---\nname: ${nm}\ndescription: ${String(description || '').trim().slice(0, 160)}\n`;
|
|
501
|
+
let updated = false;
|
|
502
|
+
if (fs.existsSync(file)) {
|
|
503
|
+
const old = fs.readFileSync(file, 'utf8');
|
|
504
|
+
const oldFm = parseFrontmatter(old);
|
|
505
|
+
fm += `created: ${oldFm.created || oldFm.generatedAt || new Date().toISOString()}\n`;
|
|
506
|
+
fs.writeFileSync(file + '.bak', old);
|
|
507
|
+
updated = true;
|
|
508
|
+
}
|
|
509
|
+
fm += `updated: ${new Date().toISOString()}\n---\n\n`;
|
|
510
|
+
fs.writeFileSync(file, fm + String(body || '').trim() + '\n');
|
|
511
|
+
return { ok: true, folder, file, updated };
|
|
512
|
+
} catch (e) {
|
|
513
|
+
return { ok: false, error: String((e && e.message) || e) };
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
490
517
|
/* Kurulu bir skill'e madde ekler (#3 kural hattı): "## Kurallar" altına yazılır. */
|
|
491
518
|
function appendRuleToSkill(nameOrFolder, ruleText) {
|
|
492
519
|
try {
|
|
@@ -520,4 +547,5 @@ module.exports = {
|
|
|
520
547
|
acceptDraft,
|
|
521
548
|
dropDraft,
|
|
522
549
|
appendRuleToSkill,
|
|
550
|
+
upsertSkill,
|
|
523
551
|
};
|
package/src/main.js
CHANGED
|
@@ -2071,6 +2071,9 @@ function reloadBackend() {
|
|
|
2071
2071
|
thinkLevel: settings.thinkLevel || 0,
|
|
2072
2072
|
fallout: settings.fallout || null,
|
|
2073
2073
|
limits: settings.limits || null,
|
|
2074
|
+
/* OTOMATİK SKİLL SİSTEMİ: ayarlardan kapatılmadıysa öğrenilen prosedürler
|
|
2075
|
+
otomatik skill olur, mevcutların daha iyisi bulunursa güncellenir */
|
|
2076
|
+
autoSkills: settings.autoSkills !== false,
|
|
2074
2077
|
approvals: settings.security && settings.security.approvals ? approvalsBridge : null,
|
|
2075
2078
|
alwaysAllowTools: (settings.security && settings.security.alwaysAllow) || [],
|
|
2076
2079
|
crashFile: FALLOUT_CRASH_FILE,
|
|
@@ -3828,6 +3831,16 @@ ipcMain.handle('memory:save', (_e, { file, content }) => memory.save(file, conte
|
|
|
3828
3831
|
|
|
3829
3832
|
ipcMain.handle('skills:list', () => skillsMod.scan());
|
|
3830
3833
|
|
|
3834
|
+
/* OTOMATİK SKİLL SİSTEMİ: açıkken öğrenilen prosedürler direkt kurulur,
|
|
3835
|
+
mevcut skillin daha iyisi bulunursa güncellenir */
|
|
3836
|
+
ipcMain.handle('skills:auto:get', () => settings.autoSkills !== false);
|
|
3837
|
+
ipcMain.handle('skills:auto:set', (_e, v) => {
|
|
3838
|
+
settings.autoSkills = !!v;
|
|
3839
|
+
saveSettings();
|
|
3840
|
+
if (engine) engine.autoSkills = !!v;
|
|
3841
|
+
return settings.autoSkills;
|
|
3842
|
+
});
|
|
3843
|
+
|
|
3831
3844
|
/* taslak skill'ler (#2 yansıma ürünleri) */
|
|
3832
3845
|
ipcMain.handle('skills:drafts:list', () => skillsMod.listDrafts());
|
|
3833
3846
|
ipcMain.handle('skills:drafts:accept', (_e, id) => {
|
package/src/preload.js
CHANGED
|
@@ -25,6 +25,8 @@ contextBridge.exposeInMainWorld('beast', {
|
|
|
25
25
|
clearNotes: (id) => ipcRenderer.invoke('notes:clear', id),
|
|
26
26
|
saveMemory: (file, content) => ipcRenderer.invoke('memory:save', { file, content }),
|
|
27
27
|
listSkills: () => ipcRenderer.invoke('skills:list'),
|
|
28
|
+
skillsGetAuto: () => ipcRenderer.invoke('skills:auto:get'),
|
|
29
|
+
skillsSetAuto: (v) => ipcRenderer.invoke('skills:auto:set', v),
|
|
28
30
|
openSkillsFolder: () => ipcRenderer.invoke('skills:openFolder'),
|
|
29
31
|
draftsList: () => ipcRenderer.invoke('skills:drafts:list'),
|
|
30
32
|
draftAccept: (id) => ipcRenderer.invoke('skills:drafts:accept', id),
|
package/src/renderer/i18n.js
CHANGED
|
@@ -164,6 +164,7 @@
|
|
|
164
164
|
mem_saved: 'Memory kaydedildi — SOUL.md dahil',
|
|
165
165
|
sk_h2: 'Skills',
|
|
166
166
|
sk_sub: 'SKILL.md indeksi — tam metin model tarafından okunur',
|
|
167
|
+
sk_auto: 'Otomatik skill: ajan öğrendiği yeni yöntemleri taslak onayı beklemeden kurar; bir skillin daha kolay/daha iyi yolunu bulursa mevcut skilli kendisi günceller',
|
|
167
168
|
sk_rules_h2: 'Kalıcı Kurallar',
|
|
168
169
|
sk_rules_sub: 'Agent\u2019ın her sohbette uyduğu talimatlar — WA\u2019dan /rule ile de eklenir',
|
|
169
170
|
sk_no_rule: 'Henüz kural yok.',
|
|
@@ -678,6 +679,7 @@
|
|
|
678
679
|
mem_saved: 'Memory saved — including SOUL.md',
|
|
679
680
|
sk_h2: 'Skills',
|
|
680
681
|
sk_sub: 'SKILL.md index — full text is read by the model',
|
|
682
|
+
sk_auto: 'Auto skills: the agent installs learned procedures without draft approval and updates existing skills when it finds an easier or better way',
|
|
681
683
|
sk_rules_h2: 'Persistent Rules',
|
|
682
684
|
sk_rules_sub: 'Instructions the agent follows in every chat — also addable via /rule on WA',
|
|
683
685
|
sk_no_rule: 'No rules yet.',
|
package/src/renderer/renderer.js
CHANGED
|
@@ -1255,6 +1255,16 @@ async function renderFalloutPane() {
|
|
|
1255
1255
|
async function renderSkillsPane() {
|
|
1256
1256
|
const pane = $('#tab-skills');
|
|
1257
1257
|
pane.innerHTML = '<h2>' + _t('sk_h2') + '</h2><div class="sub">' + _t('sk_sub') + '</div>';
|
|
1258
|
+
/* OTOMATİK SKİLL SİSTEMİ: öğrenilen prosedürler otomatik kurulur/güncellenir */
|
|
1259
|
+
const auto = await beast.skillsGetAuto().catch(() => true);
|
|
1260
|
+
pane.insertAdjacentHTML(
|
|
1261
|
+
'afterbegin',
|
|
1262
|
+
`<div class="fo-toggles" style="margin-bottom:12px"><label class="lock-row"><input type="checkbox" id="autoSkillsOn" ${auto ? 'checked' : ''}/><span>${_t('sk_auto')}</span></label></div>`
|
|
1263
|
+
);
|
|
1264
|
+
pane.querySelector('#autoSkillsOn').addEventListener('change', async (e) => {
|
|
1265
|
+
await beast.skillsSetAuto(e.target.checked);
|
|
1266
|
+
toast((e.target.checked ? 'Otomatik skill: AÇIK' : 'Otomatik skill: KAPALI'));
|
|
1267
|
+
});
|
|
1258
1268
|
const list = await beast.listSkills();
|
|
1259
1269
|
for (const s of list) {
|
|
1260
1270
|
const row = document.createElement('div');
|