wormclaude 1.0.114 → 1.0.116
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/cli.js +17 -6
- package/dist/theme.js +1 -1
- package/dist/tui.js +40 -5
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -746,6 +746,7 @@ function App() {
|
|
|
746
746
|
let lastToolSig = '';
|
|
747
747
|
let sameToolCount = 0;
|
|
748
748
|
let consecFailTurns = 0; // üst üste TÜM araçların başarısız olduğu tur sayısı (devre-kesici)
|
|
749
|
+
let totalFails = 0; // görev boyunca toplam başarısız komut (karışık başarı/başarısızlık döngüsü)
|
|
749
750
|
let taskIn = 0, taskOut = 0, taskCache = 0; // bu görevin GERÇEK token toplamı (tüm turlar; API usage'dan)
|
|
750
751
|
while (iter < MAX_TURNS) {
|
|
751
752
|
if (ac.signal.aborted) {
|
|
@@ -778,8 +779,12 @@ function App() {
|
|
|
778
779
|
const TAIL_CHARS = 4000;
|
|
779
780
|
let lastUi = 0;
|
|
780
781
|
const paintStream = () => {
|
|
781
|
-
|
|
782
|
-
|
|
782
|
+
// Canlı akışta da gömülü tool-call JSON'unu gizle: model uzun çok-adımlı mesaj yazarken
|
|
783
|
+
// ham {"name":"Bash",...} görünmesin. (stripInlineToolCalls "name" yoksa hemen döner →
|
|
784
|
+
// düz metinde maliyet yok.) Tamamlanmamış son blok doğal olarak kalır, sonra temizlenir.
|
|
785
|
+
const cleaned = stripInlineToolCalls(cleanModelText(assistantText));
|
|
786
|
+
const tail = cleaned.length > TAIL_CHARS ? cleaned.slice(-TAIL_CHARS) : cleaned;
|
|
787
|
+
setStreaming(tail);
|
|
783
788
|
setTokens(Math.round(assistantText.length / 4));
|
|
784
789
|
};
|
|
785
790
|
for await (const ev of streamChat(historyRef.current, allToolSchemas(), config, ac.signal)) {
|
|
@@ -915,17 +920,23 @@ function App() {
|
|
|
915
920
|
// Devre-kesici: bu turda TÜM araçlar başarısız olduysa say. Üst üste 2 tur olursa
|
|
916
921
|
// modele "DUR ve özetle" dedir — yoksa model olmayan araç/Unix sözdizimini (grep, hydra)
|
|
917
922
|
// deneyip döngüye girip token yakıyor ve hiç bitirmiyor.
|
|
918
|
-
|
|
923
|
+
// Devre-kesici 2: KÜMÜLATIF başarısızlık — curl başarılı + grep başarısız KARIŞSA bile
|
|
924
|
+
// (olmayan aracı/Unix sözdizimini tekrar tekrar deniyorsa "hepsi fail" tetiklenmez ama
|
|
925
|
+
// başarısızlıklar birikir) toplam eşiği aşınca dur+özetle.
|
|
926
|
+
const _failed = results.filter((r) => !r.ok).length;
|
|
927
|
+
totalFails += _failed;
|
|
928
|
+
const _allFailed = results.length > 0 && _failed === results.length;
|
|
919
929
|
consecFailTurns = _allFailed ? consecFailTurns + 1 : 0;
|
|
920
|
-
if (consecFailTurns >= 2) {
|
|
930
|
+
if (consecFailTurns >= 2 || totalFails >= 4) {
|
|
921
931
|
historyRef.current = [...historyRef.current, {
|
|
922
932
|
role: 'user',
|
|
923
933
|
content: getLang() === 'en'
|
|
924
|
-
? '
|
|
925
|
-
: 'Komutlar
|
|
934
|
+
? '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, in the user\'s language. Do NOT call any more tools, and do NOT use grep/sed/awk.'
|
|
935
|
+
: '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 ve şu ana kadarki bulguları KISA bir özetle ver. Başka araç çağırma, grep/sed/awk kullanma.',
|
|
926
936
|
}];
|
|
927
937
|
push({ kind: 'note', text: getLang() === 'en' ? 'Commands kept failing — wrapping up with a summary.' : 'Komutlar başarısız oldu — özetle bitiriliyor.' });
|
|
928
938
|
consecFailTurns = 0;
|
|
939
|
+
totalFails = 0;
|
|
929
940
|
}
|
|
930
941
|
}
|
|
931
942
|
if (!done)
|
package/dist/theme.js
CHANGED
package/dist/tui.js
CHANGED
|
@@ -11,8 +11,9 @@ 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';
|
|
@@ -20,6 +21,22 @@ import { loadMemoryContext, shouldExtract, triggerMemory } from './memory.js';
|
|
|
20
21
|
import { shouldAutoCompact, runCompact } 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,14 @@ 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
|
|
271
291
|
try {
|
|
272
292
|
for (let iter = 0; iter < 25; iter++) {
|
|
273
293
|
streamChars = 0;
|
|
@@ -305,7 +325,9 @@ export async function runTui() {
|
|
|
305
325
|
}
|
|
306
326
|
if (cut <= committed)
|
|
307
327
|
return;
|
|
308
|
-
|
|
328
|
+
// Gömülü araç-çağrısı JSON'unu (```json {"name":...}```) stdout'a YAZMADAN gizle —
|
|
329
|
+
// stdout append-only, sonradan silinemez. Kesimler fence-güvenli → tam blok burada.
|
|
330
|
+
const chunk = stripInlineToolCalls(cleanModelText(answer.slice(committed, cut))).replace(/\n+$/, '');
|
|
309
331
|
committed = cut;
|
|
310
332
|
if (!chunk && !final)
|
|
311
333
|
return;
|
|
@@ -333,7 +355,7 @@ export async function runTui() {
|
|
|
333
355
|
}
|
|
334
356
|
}
|
|
335
357
|
flushStream(true); // kalan yarım satırı bas
|
|
336
|
-
answer = cleanModelText(answer).trim();
|
|
358
|
+
answer = stripInlineToolCalls(cleanModelText(answer)).trim();
|
|
337
359
|
const am = { role: 'assistant', content: answer || '' };
|
|
338
360
|
if (toolCalls.length)
|
|
339
361
|
am.tool_calls = toolCalls.map((t) => ({ id: t.id, type: 'function', function: { name: t.name, arguments: t.args || '{}' } }));
|
|
@@ -366,7 +388,20 @@ export async function runTui() {
|
|
|
366
388
|
usedWeb = true; printItem({ kind: 'tool', label: toolLabel(c.name, res.args), result: sanitizeOutput(res.output), ok: res.ok }); },
|
|
367
389
|
});
|
|
368
390
|
for (let i = 0; i < toolCalls.length; i++)
|
|
369
|
-
history.push({ role: 'tool', tool_call_id: toolCalls[i].id, content: (results[i].output || '')
|
|
391
|
+
history.push({ role: 'tool', tool_call_id: toolCalls[i].id, content: capToolOut(toolCalls[i].name, results[i].output || '') });
|
|
392
|
+
// Devre-kesici: olmayan araç/Unix sözdizimini (grep/openssl/hydra) tekrar deneyip
|
|
393
|
+
// döngüye girmesin. Üst üste hepsi fail (2 tur) VEYA toplam 4 başarısız → dur+özetle.
|
|
394
|
+
const _failed = results.filter((r) => !r.ok).length;
|
|
395
|
+
totalFails += _failed;
|
|
396
|
+
consecFail = (results.length > 0 && _failed === results.length) ? consecFail + 1 : 0;
|
|
397
|
+
if (consecFail >= 2 || totalFails >= 4) {
|
|
398
|
+
history.push({ role: 'user', content: getLang() === 'en'
|
|
399
|
+
? '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.'
|
|
400
|
+
: '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.' });
|
|
401
|
+
printItem({ kind: 'note', text: getLang() === 'en' ? 'Commands kept failing — wrapping up.' : 'Komutlar başarısız oldu — özetle bitiriliyor.' });
|
|
402
|
+
consecFail = 0;
|
|
403
|
+
totalFails = 0;
|
|
404
|
+
}
|
|
370
405
|
}
|
|
371
406
|
}
|
|
372
407
|
catch (e) {
|