wormclaude 1.0.160 → 1.0.161
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/api.js +22 -1
- package/dist/inlinetools.js +25 -3
- package/dist/theme.js +1 -1
- package/package.json +1 -1
package/dist/api.js
CHANGED
|
@@ -111,6 +111,26 @@ async function fetchWithRetry(url, init) {
|
|
|
111
111
|
}
|
|
112
112
|
throw lastErr ?? new Error('retry exhausted');
|
|
113
113
|
}
|
|
114
|
+
// Konuşmadaki EN SON URL/host'u bul (SecurityScan narration-recovery hedefi). Dosya adlarını
|
|
115
|
+
// (.js/.json/.html…) ELER ki "package.json" gibi şeyler hedef sanılmasın.
|
|
116
|
+
function _lastTargetFromMessages(messages) {
|
|
117
|
+
const urlRe = /https?:\/\/[^\s"'<>)\]]+/i;
|
|
118
|
+
const hostRe = /\b((?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,24})\b/i;
|
|
119
|
+
const badExt = /\.(?:js|ts|tsx|jsx|json|html?|css|png|jpe?g|gif|svg|md|txt|py|sh|yml|yaml|lock|map|ico|woff2?|mjs|cjs)$/i;
|
|
120
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
121
|
+
const c = messages[i]?.content;
|
|
122
|
+
const s = typeof c === 'string' ? c : Array.isArray(c) ? c.map((x) => x?.text || '').join(' ') : '';
|
|
123
|
+
if (!s)
|
|
124
|
+
continue;
|
|
125
|
+
const u = s.match(urlRe);
|
|
126
|
+
if (u)
|
|
127
|
+
return u[0];
|
|
128
|
+
const h = s.match(hostRe);
|
|
129
|
+
if (h && !badExt.test(h[1]) && !/\.(localhost)$/i.test(h[1]))
|
|
130
|
+
return h[1];
|
|
131
|
+
}
|
|
132
|
+
return '';
|
|
133
|
+
}
|
|
114
134
|
export async function* streamChat(messages, tools, config, signal) {
|
|
115
135
|
const body = {
|
|
116
136
|
model: config.model,
|
|
@@ -263,8 +283,9 @@ export async function* streamChat(messages, tools, config, signal) {
|
|
|
263
283
|
args: safeJsonStringify(c.args),
|
|
264
284
|
}));
|
|
265
285
|
// Yedek: upstream yapısal tool_call vermediyse modelin metne gömdüğü çağrıyı kurtar.
|
|
286
|
+
// scanTarget: SecurityScan'i "anlatıp" çağırmayan 32B için hedefi konuşmadan al (en son URL/host).
|
|
266
287
|
if (toolCalls.length === 0 && fullText) {
|
|
267
|
-
const recovered = recoverInlineToolCalls(fullText);
|
|
288
|
+
const recovered = recoverInlineToolCalls(fullText, { scanTarget: _lastTargetFromMessages(messages) });
|
|
268
289
|
if (recovered.length)
|
|
269
290
|
toolCalls = recovered;
|
|
270
291
|
}
|
package/dist/inlinetools.js
CHANGED
|
@@ -232,11 +232,19 @@ function extractTopLevelJsonObjects(text) {
|
|
|
232
232
|
}
|
|
233
233
|
/** Metindeki gömülü araç çağrılarını kurtarır. Gürültüden kaçınmak için yalnız açık sarmalları
|
|
234
234
|
* (<tool_call>, ```json) veya mesajın TAMAMI tek JSON çağrısıysa onu alır. */
|
|
235
|
-
|
|
235
|
+
// SecurityScan'i ÇAĞIRMAYIP "anlatan" 32B için: tarama-ismi + aksiyon-fiili + hedef → gerçek çağrı.
|
|
236
|
+
// (Model "Recon işlemini başlatıyorum:" deyip takılıyordu; kullanıcı 'başla' deyip duruyordu.)
|
|
237
|
+
// Stem eşleşmesi (Türkçe ekleri için sondaki \b yok): "tarayacağım/tarıyorum", "keşfederek".
|
|
238
|
+
// tara(?!f) → "taraf/tarafından" YANLIŞ yakalanmaz; "keşif" (isim) + "keşf" (keşfet fiili) ayrı.
|
|
239
|
+
const _SCAN_NOUN_RE = /\b(?:recon|keşif|keşf|kesif|tar[aı](?!f)|scan|securityscan|zafiyet|enjeksiyon|injection|sqli|xss)/i;
|
|
240
|
+
const _SCAN_ACT_RE = /(başl|basl|çalıştır|calistir|gerçekleştir|gerceklestir|kullan|aca[gğ]|ece[gğ]|acak|ecek|[ıiuü]yor|start|run\b|launch|initiat|perform)/i;
|
|
241
|
+
function _scanIntent(s) { return _SCAN_NOUN_RE.test(s) && _SCAN_ACT_RE.test(s); }
|
|
242
|
+
export function recoverInlineToolCalls(text, opts) {
|
|
236
243
|
const t = (text || '').trim();
|
|
237
|
-
|
|
244
|
+
const scanTarget = (opts?.scanTarget || '').trim();
|
|
245
|
+
// JSON/prose/ToolName{…}/ToolName(…)/SecurityScan-niyeti çağrısı yoksa erken çık.
|
|
238
246
|
// (Kod fence'i varsa çıkma — dosya-adı etiketli blok olabilir, adım 7 karar verir.)
|
|
239
|
-
if (!t || (!t.includes('"name"') && !t.includes('"tool"') && !t.includes('"function"') && !/AskUserQuestion/i.test(t) && !TOOL_PREFIX_RE.test(t) && !TOOL_PAREN_RE.test(t) && !t.includes('```')))
|
|
247
|
+
if (!t || (!t.includes('"name"') && !t.includes('"tool"') && !t.includes('"function"') && !/AskUserQuestion/i.test(t) && !TOOL_PREFIX_RE.test(t) && !TOOL_PAREN_RE.test(t) && !t.includes('```') && !(scanTarget && _scanIntent(t))))
|
|
240
248
|
return [];
|
|
241
249
|
const out = [];
|
|
242
250
|
const seen = new Set();
|
|
@@ -334,6 +342,20 @@ export function recoverInlineToolCalls(text) {
|
|
|
334
342
|
}
|
|
335
343
|
}
|
|
336
344
|
}
|
|
345
|
+
// 6.5) SecurityScan NARRASYON → gerçek çağrı. 32B "recon başlatıyorum / XSS taraması yapacağım /
|
|
346
|
+
// SecurityScan ile tarayacağız" diye NİYET yazıp aracı çağırmıyor → takılıyordu. Hedef
|
|
347
|
+
// (konuşmadan) + niyet varsa SecurityScan'i kendimiz emit ediyoruz. Araç metinden seçilir.
|
|
348
|
+
if (!out.length && scanTarget && _scanIntent(t)) {
|
|
349
|
+
const low = t.toLowerCase();
|
|
350
|
+
let tool = 'recon'; // varsayılan: genel "tara" → önce keşif
|
|
351
|
+
if (/\bxss\b/.test(low))
|
|
352
|
+
tool = 'xss';
|
|
353
|
+
else if (/sql/.test(low))
|
|
354
|
+
tool = 'sqli';
|
|
355
|
+
else if (/(recon|keşif|keşf|kesif)/.test(low))
|
|
356
|
+
tool = 'recon';
|
|
357
|
+
push({ name: 'SecurityScan', arguments: { tool, target: scanTarget } });
|
|
358
|
+
}
|
|
337
359
|
// 7) SON ÇARE: hiç çağrı kurtarılamadıysa, dosya-adı etiketli ```kod bloklarını
|
|
338
360
|
// Write'a çevir (model build'de Write yerine kod yapıştırınca dosya kaybolmasın).
|
|
339
361
|
// Adım 7, gerçek tool-call YOKKEN çalışır → "kod göster"i bozmaz (etiket gerekir).
|
package/dist/theme.js
CHANGED