wormclaude 1.0.115 → 1.0.117
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/dist/compact.js +3 -1
- package/dist/theme.js +1 -1
- package/dist/tools.js +4 -2
- package/dist/tui.js +57 -6
- package/package.json +1 -1
package/dist/compact.js
CHANGED
|
@@ -7,7 +7,9 @@ import { approxTokens } from './usage.js';
|
|
|
7
7
|
// Model tavanı değişirse bu değer de güncellenmeli (ya da WORMCLAUDE_CONTEXT_WINDOW ile override).
|
|
8
8
|
const CONTEXT_WINDOW = Number(process.env.WORMCLAUDE_CONTEXT_WINDOW) || 32768;
|
|
9
9
|
const SUMMARY_RESERVE = 4000; // özet çıktısı için rezerv (CC: ~20K büyük modellerde)
|
|
10
|
-
|
|
10
|
+
// Erken tetikle (~%69): geç tetiklenince tek bir turun büyük çıktısı (grep/curl) pencereyi
|
|
11
|
+
// taşırıp "token bitti → yazılmıyor"a sokuyordu. Erken tazeleme = kesilme yok.
|
|
12
|
+
const AUTOCOMPACT_BUFFER = 6000;
|
|
11
13
|
export function autoCompactThreshold() {
|
|
12
14
|
return CONTEXT_WINDOW - SUMMARY_RESERVE - AUTOCOMPACT_BUFFER;
|
|
13
15
|
}
|
package/dist/theme.js
CHANGED
package/dist/tools.js
CHANGED
|
@@ -1137,7 +1137,9 @@ export async function executeTool(name, args) {
|
|
|
1137
1137
|
const showLineNo = args['-n'] !== false; // content modunda varsayılan true
|
|
1138
1138
|
const after = Number(args['-A'] ?? args['-C'] ?? args.context ?? 0);
|
|
1139
1139
|
const before = Number(args['-B'] ?? args['-C'] ?? args.context ?? 0);
|
|
1140
|
-
|
|
1140
|
+
// Varsayılan 60 eşleşme: yüzlerce satırlık çıktı context'i şişirip modeli tekrar-döngüsüne
|
|
1141
|
+
// (sahte link üretimi) sokuyordu. Model gerekirse head_limit ile artırabilir.
|
|
1142
|
+
const headLimit = args.head_limit === 0 ? Infinity : Number(args.head_limit) || 60;
|
|
1141
1143
|
const offset = Number(args.offset) || 0;
|
|
1142
1144
|
const reset = () => { rx.lastIndex = 0; return rx; };
|
|
1143
1145
|
const entries = [];
|
|
@@ -1206,7 +1208,7 @@ export async function executeTool(name, args) {
|
|
|
1206
1208
|
if (!sliced.length)
|
|
1207
1209
|
return { ok: true, output: '(no matches)' };
|
|
1208
1210
|
const note = entries.length > sliced.length ? `\n(${entries.length - sliced.length} more, raise head_limit to see)` : '';
|
|
1209
|
-
return { ok: true, output: sliced.join('\n').slice(0,
|
|
1211
|
+
return { ok: true, output: sliced.join('\n').slice(0, 6000) + note + `\n\n[${fileCount} file(s) with matches]` };
|
|
1210
1212
|
}
|
|
1211
1213
|
if (name === 'WebFetch') {
|
|
1212
1214
|
let url = String(args.url);
|
package/dist/tui.js
CHANGED
|
@@ -11,15 +11,32 @@ import { sanitizeOutput } from './errorsan.js';
|
|
|
11
11
|
import { itemAnsi, markdownAnsi } from './ansi.js';
|
|
12
12
|
import { theme, VERSION } from './theme.js';
|
|
13
13
|
import { cleanModelText } from './textclean.js';
|
|
14
|
+
import { stripInlineToolCalls } from './inlinetools.js';
|
|
14
15
|
import { COMMANDS, runSlashCommand } from './commands.js';
|
|
15
|
-
import { cmdDesc, t, setLang, loadLang } from './i18n.js';
|
|
16
|
+
import { cmdDesc, t, setLang, loadLang, getLang } from './i18n.js';
|
|
16
17
|
import { getSkill, getSkills, buildSkillPrompt } from './skills.js';
|
|
17
18
|
import { getExtCommand, getExtCommands, buildExtCommandPrompt } from './extensions.js';
|
|
18
19
|
import { resolveAtMentions } from './atmention.js';
|
|
19
20
|
import { loadMemoryContext, shouldExtract, triggerMemory } from './memory.js';
|
|
20
|
-
import { shouldAutoCompact, runCompact } from './compact.js';
|
|
21
|
+
import { shouldAutoCompact, runCompact, isContextError } from './compact.js';
|
|
21
22
|
import { recordLearned } from './learn.js';
|
|
22
23
|
import { connectMcpServers } from './mcp.js';
|
|
24
|
+
// Komut çıktılarını context'e eklerken KIS: curl/scan gürültüsü (handshake, tüm header'lar)
|
|
25
|
+
// 32k pencereyi hızla doldurur → baş+son tut, ortayı at. Az token = uzun tarama. Read geniş kalır.
|
|
26
|
+
function fmtDur(ms) {
|
|
27
|
+
const s = Math.max(0, Math.floor(ms / 1000));
|
|
28
|
+
return s >= 60 ? `${Math.floor(s / 60)}m ${s % 60}s` : `${s}s`;
|
|
29
|
+
}
|
|
30
|
+
function capToolOut(name, out) {
|
|
31
|
+
const s = out || '';
|
|
32
|
+
const isCmd = name === 'Bash' || name === 'PowerShell';
|
|
33
|
+
const CAP = isCmd ? 2200 : 8000;
|
|
34
|
+
if (s.length <= CAP)
|
|
35
|
+
return s;
|
|
36
|
+
if (isCmd)
|
|
37
|
+
return s.slice(0, 1400) + `\n… [${s.length - 2000} karakter kısaltıldı] …\n` + s.slice(-600);
|
|
38
|
+
return s.slice(0, CAP) + `\n… [${s.length - CAP} karakter kısaltıldı]`;
|
|
39
|
+
}
|
|
23
40
|
const RESET = '\x1b[0m';
|
|
24
41
|
const hex = (h) => { const m = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(h); return m ? `\x1b[38;2;${parseInt(m[1], 16)};${parseInt(m[2], 16)};${parseInt(m[3], 16)}m` : ''; };
|
|
25
42
|
const paint = (s, c, bold = false) => `${bold ? '\x1b[1m' : ''}${c ? hex(c) : ''}${s}${RESET}`;
|
|
@@ -65,6 +82,7 @@ export async function runTui() {
|
|
|
65
82
|
];
|
|
66
83
|
const displayItems = [{ kind: 'banner' }];
|
|
67
84
|
let inputBuf = '', inputCur = 0, busy = false, streamChars = 0, spin = 0;
|
|
85
|
+
let taskStart = 0; // görev başlangıç zamanı (spinner'da geçen süre için)
|
|
68
86
|
// Canlı akış artık FOOTER'da DEĞİL — içerik akışına (mesajın altından aşağı) satır-satır basılır.
|
|
69
87
|
const SPIN = ['·', '✢', '✳', '✶', '✻', '✽', '✶', '✳', '✢'];
|
|
70
88
|
// Canlı bağlam ölçer: son isteğin prompt_tokens'ı = o anki kullanılan bağlam (footer'da gösterilir).
|
|
@@ -227,7 +245,7 @@ export async function runTui() {
|
|
|
227
245
|
else {
|
|
228
246
|
const g = ctxUsed ? paint(' ' + ctxGauge(), theme.greyDim) : '';
|
|
229
247
|
const status = busy
|
|
230
|
-
? paint(` ${SPIN[spin % SPIN.length]} ${t('tui.working')}${
|
|
248
|
+
? paint(` ${SPIN[spin % SPIN.length]} ${t('tui.working')}${taskStart ? ' · ' + fmtDur(Date.now() - taskStart) : ''}${streamChars ? ' · ' + Math.round(streamChars / 4) + ' tokens' : ''}`, theme.grey) + g
|
|
231
249
|
: paint(' ' + t('tui.footerHint'), theme.greyDim) + g;
|
|
232
250
|
body = [status, line, ...inputLines, line];
|
|
233
251
|
}
|
|
@@ -262,12 +280,15 @@ export async function runTui() {
|
|
|
262
280
|
async function runTurn(userText, displayText) {
|
|
263
281
|
busy = true;
|
|
264
282
|
streamChars = 0;
|
|
283
|
+
taskStart = Date.now();
|
|
265
284
|
if (displayText !== undefined)
|
|
266
285
|
printItem({ kind: 'user', text: displayText }); // skill/@mention: gösterim farklı
|
|
267
286
|
history.push({ role: 'user', content: userText });
|
|
268
287
|
const timer = setInterval(() => { spin++; if (busy && !perm && !ask)
|
|
269
288
|
refresh(); }, 120);
|
|
270
289
|
let lastSig = '', sameCount = 0, usedWeb = false, lastAnswer = '';
|
|
290
|
+
let consecFail = 0, totalFails = 0; // devre-kesici: olmayan araç/sözdizimi döngüsünü kır
|
|
291
|
+
let reactiveRetried = false; // bağlam taşmasında bir kez compact+retry
|
|
271
292
|
try {
|
|
272
293
|
for (let iter = 0; iter < 25; iter++) {
|
|
273
294
|
streamChars = 0;
|
|
@@ -305,7 +326,9 @@ export async function runTui() {
|
|
|
305
326
|
}
|
|
306
327
|
if (cut <= committed)
|
|
307
328
|
return;
|
|
308
|
-
|
|
329
|
+
// Gömülü araç-çağrısı JSON'unu (```json {"name":...}```) stdout'a YAZMADAN gizle —
|
|
330
|
+
// stdout append-only, sonradan silinemez. Kesimler fence-güvenli → tam blok burada.
|
|
331
|
+
const chunk = stripInlineToolCalls(cleanModelText(answer.slice(committed, cut))).replace(/\n+$/, '');
|
|
309
332
|
committed = cut;
|
|
310
333
|
if (!chunk && !final)
|
|
311
334
|
return;
|
|
@@ -315,6 +338,7 @@ export async function runTui() {
|
|
|
315
338
|
process.stdout.write(out); // imleç içerik bölgesinde → aşağı akar, taşınca scrollback'e
|
|
316
339
|
refresh(); // footer'ı dibe yeniden sabitle
|
|
317
340
|
};
|
|
341
|
+
let gotCtxErr = false;
|
|
318
342
|
for await (const ev of streamChat(history, allToolSchemas(), config)) {
|
|
319
343
|
if (ev.type === 'text') {
|
|
320
344
|
answer += ev.text;
|
|
@@ -328,12 +352,26 @@ export async function runTui() {
|
|
|
328
352
|
ctxUsed = u.input;
|
|
329
353
|
}
|
|
330
354
|
else if (ev.type === 'error') {
|
|
355
|
+
if (isContextError(ev.error))
|
|
356
|
+
gotCtxErr = true;
|
|
331
357
|
answer += `\n[hata: ${ev.error}]`;
|
|
332
358
|
flushStream(false);
|
|
333
359
|
}
|
|
334
360
|
}
|
|
335
361
|
flushStream(true); // kalan yarım satırı bas
|
|
336
|
-
|
|
362
|
+
// Reactive compact: bağlam taştıysa bir kez özetle ve turu tekrarla → "token bitti, yazılmıyor" olmaz.
|
|
363
|
+
if (gotCtxErr && !reactiveRetried) {
|
|
364
|
+
reactiveRetried = true;
|
|
365
|
+
printItem({ kind: 'note', text: t('tui.autoCompacted') });
|
|
366
|
+
try {
|
|
367
|
+
const { history: nh } = await runCompact(history, config);
|
|
368
|
+
history.length = 0;
|
|
369
|
+
history.push(...nh);
|
|
370
|
+
}
|
|
371
|
+
catch { }
|
|
372
|
+
continue; // tur sayılmaz, kaldığı yerden devam
|
|
373
|
+
}
|
|
374
|
+
answer = stripInlineToolCalls(cleanModelText(answer)).trim();
|
|
337
375
|
const am = { role: 'assistant', content: answer || '' };
|
|
338
376
|
if (toolCalls.length)
|
|
339
377
|
am.tool_calls = toolCalls.map((t) => ({ id: t.id, type: 'function', function: { name: t.name, arguments: t.args || '{}' } }));
|
|
@@ -366,7 +404,20 @@ export async function runTui() {
|
|
|
366
404
|
usedWeb = true; printItem({ kind: 'tool', label: toolLabel(c.name, res.args), result: sanitizeOutput(res.output), ok: res.ok }); },
|
|
367
405
|
});
|
|
368
406
|
for (let i = 0; i < toolCalls.length; i++)
|
|
369
|
-
history.push({ role: 'tool', tool_call_id: toolCalls[i].id, content: (results[i].output || '')
|
|
407
|
+
history.push({ role: 'tool', tool_call_id: toolCalls[i].id, content: capToolOut(toolCalls[i].name, results[i].output || '') });
|
|
408
|
+
// Devre-kesici: olmayan araç/Unix sözdizimini (grep/openssl/hydra) tekrar deneyip
|
|
409
|
+
// döngüye girmesin. Üst üste hepsi fail (2 tur) VEYA toplam 4 başarısız → dur+özetle.
|
|
410
|
+
const _failed = results.filter((r) => !r.ok).length;
|
|
411
|
+
totalFails += _failed;
|
|
412
|
+
consecFail = (results.length > 0 && _failed === results.length) ? consecFail + 1 : 0;
|
|
413
|
+
if (consecFail >= 2 || totalFails >= 4) {
|
|
414
|
+
history.push({ role: 'user', content: getLang() === 'en'
|
|
415
|
+
? 'Several commands failed — required tools/syntax are not available here (e.g. grep/openssl/hydra on Windows). STOP running commands now and give a SHORT summary of what you found so far. Do NOT call more tools, do NOT use grep/sed/awk.'
|
|
416
|
+
: 'Komutlar başarısız oldu — bu ortamda gerekli araç/sözdizim yok (Windows\'ta grep/openssl/hydra gibi). Komut çalıştırmayı ŞİMDİ BIRAK, şu ana kadarki bulguları KISA özetle. Başka araç çağırma, grep/sed/awk kullanma.' });
|
|
417
|
+
printItem({ kind: 'note', text: getLang() === 'en' ? 'Commands kept failing — wrapping up.' : 'Komutlar başarısız oldu — özetle bitiriliyor.' });
|
|
418
|
+
consecFail = 0;
|
|
419
|
+
totalFails = 0;
|
|
420
|
+
}
|
|
370
421
|
}
|
|
371
422
|
}
|
|
372
423
|
catch (e) {
|