@operatingtag/dsh-unclesam 1.3.3 → 1.3.4
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/CHANGELOG.md +32 -0
- package/README.ar.md +1 -1
- package/README.az.md +1 -1
- package/README.bg.md +1 -1
- package/README.bn.md +1 -1
- package/README.cs.md +1 -1
- package/README.da.md +1 -1
- package/README.de.md +1 -1
- package/README.el.md +1 -1
- package/README.es.md +1 -1
- package/README.fa.md +1 -1
- package/README.fi.md +1 -1
- package/README.fr.md +1 -1
- package/README.he.md +1 -1
- package/README.hi.md +1 -1
- package/README.hr.md +1 -1
- package/README.hu.md +1 -1
- package/README.id.md +1 -1
- package/README.it.md +1 -1
- package/README.ja.md +1 -1
- package/README.ka.md +1 -1
- package/README.kk.md +1 -1
- package/README.km.md +1 -1
- package/README.ko.md +1 -1
- package/README.lt.md +1 -1
- package/README.md +1 -1
- package/README.mr.md +1 -1
- package/README.ms.md +1 -1
- package/README.my.md +1 -1
- package/README.ne.md +1 -1
- package/README.nl.md +1 -1
- package/README.no.md +1 -1
- package/README.pl.md +1 -1
- package/README.pt.md +1 -1
- package/README.ro.md +1 -1
- package/README.ru.md +1 -1
- package/README.si.md +1 -1
- package/README.sk.md +1 -1
- package/README.sl.md +1 -1
- package/README.sr.md +1 -1
- package/README.sv.md +1 -1
- package/README.sw.md +1 -1
- package/README.ta.md +1 -1
- package/README.te.md +1 -1
- package/README.th.md +1 -1
- package/README.tl.md +1 -1
- package/README.tr.md +1 -1
- package/README.uk.md +1 -1
- package/README.ur.md +1 -1
- package/README.uz.md +1 -1
- package/README.vi.md +1 -1
- package/README.zh.md +1 -1
- package/index.js +31 -8
- package/lib/prompt.mjs +168 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,38 @@ fixes the patch.
|
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
+
## 1.3.4
|
|
12
|
+
|
|
13
|
+
**A tool call is now written `name({...})` instead of a JSON envelope, so the answer can stream.**
|
|
14
|
+
|
|
15
|
+
MEASURED: a reply that is nothing but `{"tool":…}` cannot be shown while it is written — `streamSafeCut`
|
|
16
|
+
returns 0 for the whole generation — so the harness sits empty for the entire turn and looks stuck. And a
|
|
17
|
+
brace is the commonest punctuation in technical prose, so `{` is a poor delimiter: it both blocks streaming
|
|
18
|
+
and invites false positives.
|
|
19
|
+
|
|
20
|
+
`replace_note({"text":"…"})` needs no instruction, because it is the shape models already produce, and it is
|
|
21
|
+
unambiguous once anchored on a tool name the model was actually offered. Prose streams until a known name
|
|
22
|
+
opens a parenthesis, instead of stopping at the first brace anywhere.
|
|
23
|
+
|
|
24
|
+
- **`parseToolCall` walks characters, not a regex**, so an argument may contain a parenthesis, a brace, an
|
|
25
|
+
escaped quote or a newline. `read()` parses as empty arguments; `see figure(2)` does not parse at all,
|
|
26
|
+
because `figure` was never offered.
|
|
27
|
+
- **The JSON envelope is still accepted**, fenced or bare, as a fallback — a model may emit it unprompted
|
|
28
|
+
and refusing it would throw away a working call.
|
|
29
|
+
- **`stripToolCall` removes whichever shape was used**, so neither reaches the transcript.
|
|
30
|
+
- **`streamSafeCut` holds from a known name plus `(`, or from a trailing fragment of a known name of three
|
|
31
|
+
characters or more.** The first version held any fragment, so a sentence ending in `r` stalled one
|
|
32
|
+
character back — `r` prefixes `read`. Found by a test, fixed before shipping.
|
|
33
|
+
- **`dev/test-call-form.mjs`** pins ten shapes that are calls, five that are not, and the stripping and
|
|
34
|
+
streaming behaviour. Two of its own assertions were written from guesswork and failed; they now measure.
|
|
35
|
+
- **`dev/test-web-tool-write.mjs` asserts the shape**, not just the outcome: the raw reply is captured through
|
|
36
|
+
`UNCLE_SAM_RAW_REPLY` and must start with `name(`. Measured live: the page replied
|
|
37
|
+
`replace_note({"text":"…"})` and the file changed, **4,062 ms**.
|
|
38
|
+
|
|
39
|
+
The raw capture is off unless that variable names a file, so nothing is written during ordinary use.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
11
43
|
## 1.3.3
|
|
12
44
|
|
|
13
45
|
**The tool names were not enough: a call with the wrong argument name cannot be executed.**
|
package/README.ar.md
CHANGED
|
@@ -250,7 +250,7 @@ Copyright (c) 2026 Darren T. Weldon، منشور تحت اسم Operating Tag.
|
|
|
250
250
|
Uncle Sam إضافة مستقلة. غير مرتبطة بـ DeepSeek، ولا تحظى بتأييدهم أو دعمهم.
|
|
251
251
|
|
|
252
252
|
```
|
|
253
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
253
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
254
254
|
المؤلف Operating Tag
|
|
255
255
|
الترخيص CC BY-NC-ND 4.0 — مجاني للاستخدام، لا للتغيير أو المشاركة أو البيع
|
|
256
256
|
```
|
package/README.az.md
CHANGED
|
@@ -256,7 +256,7 @@ soruşun — aydın cavab və aydın qiymət alacaqsınız.
|
|
|
256
256
|
Uncle Sam müstəqil plagindir. DeepSeek ilə bağlı deyil, onlar tərəfindən təsdiqlənməyib və dəstəklənmir.
|
|
257
257
|
|
|
258
258
|
```
|
|
259
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
259
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
260
260
|
Müəllif Operating Tag
|
|
261
261
|
Lisenziya CC BY-NC-ND 4.0 — istifadə üçün pulsuz, dəyişdirmək, paylaşmaq və ya satmaq üçün deyil
|
|
262
262
|
```
|
package/README.bg.md
CHANGED
|
@@ -259,7 +259,7 @@ Copyright (c) 2026 Darren T. Weldon, публикувано под името Op
|
|
|
259
259
|
Uncle Sam е независима приставка. Не е свързана с DeepSeek, не е одобрена или поддържана от тях.
|
|
260
260
|
|
|
261
261
|
```
|
|
262
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
262
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
263
263
|
Автор Operating Tag
|
|
264
264
|
Лиценз CC BY-NC-ND 4.0 — свободно за използване, не за промяна, споделяне или продажба
|
|
265
265
|
```
|
package/README.bn.md
CHANGED
|
@@ -254,7 +254,7 @@ Copyright (c) 2026 Darren T. Weldon, Operating Tag নামে প্রকা
|
|
|
254
254
|
Uncle Sam একটি স্বাধীন প্লাগইন। DeepSeek-এর সঙ্গে যুক্ত নয়, তাদের অনুমোদন বা সমর্থন নেই।
|
|
255
255
|
|
|
256
256
|
```
|
|
257
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
257
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
258
258
|
লেখক Operating Tag
|
|
259
259
|
লাইসেন্স CC BY-NC-ND 4.0 — ব্যবহারে বিনামূল্যে, পরিবর্তন, শেয়ার বা বিক্রিতে নয়
|
|
260
260
|
```
|
package/README.cs.md
CHANGED
|
@@ -256,7 +256,7 @@ Závazný je soubor [LICENSE](LICENSE) a začíná stejným shrnutím v jednoduc
|
|
|
256
256
|
Uncle Sam je nezávislý plugin. Není spojený s DeepSeek, není jimi schválený ani podporovaný.
|
|
257
257
|
|
|
258
258
|
```
|
|
259
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
259
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
260
260
|
Autor Operating Tag
|
|
261
261
|
Licence CC BY-NC-ND 4.0 — zdarma k použití, ne ke změně, sdílení nebo prodeji
|
|
262
262
|
```
|
package/README.da.md
CHANGED
|
@@ -257,7 +257,7 @@ Filen [LICENSE](LICENSE) er den gældende, og den begynder med samme resumé på
|
|
|
257
257
|
Uncle Sam er et uafhængigt plugin. Ikke knyttet til DeepSeek, ikke godkendt eller støttet af dem.
|
|
258
258
|
|
|
259
259
|
```
|
|
260
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
260
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
261
261
|
Forfatter Operating Tag
|
|
262
262
|
Licens CC BY-NC-ND 4.0 — frit at bruge, ikke at ændre, dele eller sælge
|
|
263
263
|
```
|
package/README.de.md
CHANGED
|
@@ -270,7 +270,7 @@ Englisch.
|
|
|
270
270
|
Uncle Sam ist ein unabhängiges Plugin. Nicht mit DeepSeek verbunden, von ihnen weder unterstützt noch gefördert.
|
|
271
271
|
|
|
272
272
|
```
|
|
273
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
273
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
274
274
|
Autor Operating Tag
|
|
275
275
|
Lizenz CC BY-NC-ND 4.0 — frei zur Nutzung, nicht zum Ändern, Weitergabe oder Verkauf
|
|
276
276
|
```
|
package/README.el.md
CHANGED
|
@@ -266,7 +266,7 @@ Copyright (c) 2026 Darren T. Weldon, δημοσιευμένο με το όνομ
|
|
|
266
266
|
Το Uncle Sam είναι ανεξάρτητο πρόσθετο. Δεν συνδέεται με τη DeepSeek, δεν εγκρίνεται ούτε υποστηρίζεται από αυτούς.
|
|
267
267
|
|
|
268
268
|
```
|
|
269
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
269
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
270
270
|
Δημιουργός Operating Tag
|
|
271
271
|
Άδεια CC BY-NC-ND 4.0 — ελεύθερο για χρήση, όχι για αλλαγή, κοινή χρήση ή πώληση
|
|
272
272
|
```
|
package/README.es.md
CHANGED
|
@@ -264,7 +264,7 @@ El archivo [LICENSE](LICENSE) es el que rige, y abre con el mismo resumen en ing
|
|
|
264
264
|
Uncle Sam es un plugin independiente. No está afiliado, respaldado ni soportado por DeepSeek.
|
|
265
265
|
|
|
266
266
|
```
|
|
267
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
267
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
268
268
|
Autor Operating Tag
|
|
269
269
|
Licencia CC BY-NC-ND 4.0 — gratis para usar, no para cambiar, compartir o vender
|
|
270
270
|
```
|
package/README.fa.md
CHANGED
|
@@ -256,7 +256,7 @@ Copyright (c) 2026 Darren T. Weldon، منتشرشده با نام Operating Tag
|
|
|
256
256
|
Uncle Sam یک افزونه مستقل است. وابسته به DeepSeek نیست، تأیید یا پشتیبانی نمیشود.
|
|
257
257
|
|
|
258
258
|
```
|
|
259
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
259
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
260
260
|
نویسنده Operating Tag
|
|
261
261
|
پروانه CC BY-NC-ND 4.0 — آزاد برای استفاده، نه برای تغییر، اشتراک یا فروش
|
|
262
262
|
```
|
package/README.fi.md
CHANGED
|
@@ -258,7 +258,7 @@ Tiedosto [LICENSE](LICENSE) on ratkaiseva, ja se alkaa samalla yhteenvedolla yks
|
|
|
258
258
|
Uncle Sam on itsenäinen lisäosa. Ei sidoksissa DeepSeekiin, ei heidän hyväksymänsä tai tukemansa.
|
|
259
259
|
|
|
260
260
|
```
|
|
261
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
261
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
262
262
|
Tekijä Operating Tag
|
|
263
263
|
Lisenssi CC BY-NC-ND 4.0 — vapaa käytettäväksi, ei muutettavaksi, jaettavaksi tai myytäväksi
|
|
264
264
|
```
|
package/README.fr.md
CHANGED
|
@@ -268,7 +268,7 @@ Le fichier [LICENSE](LICENSE) fait foi, et il s'ouvre sur le même résumé en a
|
|
|
268
268
|
Uncle Sam est un plugin indépendant. Non affilié à DeepSeek, ni approuvé ni soutenu par eux.
|
|
269
269
|
|
|
270
270
|
```
|
|
271
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
271
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
272
272
|
Auteur Operating Tag
|
|
273
273
|
Licence CC BY-NC-ND 4.0 — gratuit à l'usage, pas au changement, au partage ou à la vente
|
|
274
274
|
```
|
package/README.he.md
CHANGED
|
@@ -248,7 +248,7 @@ Copyright (c) 2026 Darren T. Weldon, פורסם תחת השם Operating Tag.
|
|
|
248
248
|
Uncle Sam הוא תוסף עצמאי. לא קשור ל‑DeepSeek, לא מאושר ולא נתמך על ידם.
|
|
249
249
|
|
|
250
250
|
```
|
|
251
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
251
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
252
252
|
יוצר Operating Tag
|
|
253
253
|
רישיון CC BY-NC-ND 4.0 — חופשי לשימוש, לא לשינוי, שיתוף או מכירה
|
|
254
254
|
```
|
package/README.hi.md
CHANGED
|
@@ -259,7 +259,7 @@ Copyright (c) 2026 Darren T. Weldon, Operating Tag नाम से प्रक
|
|
|
259
259
|
Uncle Sam एक स्वतंत्र प्लगइन है। DeepSeek से जुड़ा नहीं, उनका समर्थन या अनुमोदन नहीं।
|
|
260
260
|
|
|
261
261
|
```
|
|
262
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
262
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
263
263
|
लेखक Operating Tag
|
|
264
264
|
लाइसेंस CC BY-NC-ND 4.0 — इस्तेमाल मुफ़्त, बदलना, बाँटना या बेचना नहीं
|
|
265
265
|
```
|
package/README.hr.md
CHANGED
|
@@ -256,7 +256,7 @@ Datoteka [LICENSE](LICENSE) je obvezujuća i počinje istim sažetkom na jednost
|
|
|
256
256
|
Uncle Sam je neovisni dodatak. Nije povezan s DeepSeekom, nije odobren ni podržan od njih.
|
|
257
257
|
|
|
258
258
|
```
|
|
259
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
259
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
260
260
|
Autor Operating Tag
|
|
261
261
|
Licencija CC BY-NC-ND 4.0 — besplatno za korištenje, ne za izmjenu, dijeljenje ili prodaju
|
|
262
262
|
```
|
package/README.hu.md
CHANGED
|
@@ -260,7 +260,7 @@ A [LICENSE](LICENSE) fájl a mérvadó, és ugyanazzal az egyszerű angol össze
|
|
|
260
260
|
Az Uncle Sam független bővítmény. Nem kapcsolódik a DeepSeekhez, ő nem hagyja jóvá és nem támogatja.
|
|
261
261
|
|
|
262
262
|
```
|
|
263
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
263
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
264
264
|
Szerző Operating Tag
|
|
265
265
|
Licenc CC BY-NC-ND 4.0 — szabadon használható, nem módosítható, osztható meg vagy adható el
|
|
266
266
|
```
|
package/README.id.md
CHANGED
|
@@ -260,7 +260,7 @@ Berkas [LICENSE](LICENSE) yang mengikat, dan ia dibuka dengan ringkasan yang sam
|
|
|
260
260
|
Uncle Sam adalah plugin independen. Tidak berafiliasi dengan DeepSeek, tidak didukung maupun disponsori oleh mereka.
|
|
261
261
|
|
|
262
262
|
```
|
|
263
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
263
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
264
264
|
Penulis Operating Tag
|
|
265
265
|
Lisensi CC BY-NC-ND 4.0 — bebas dipakai, tidak untuk diubah, dibagikan, atau dijual
|
|
266
266
|
```
|
package/README.it.md
CHANGED
|
@@ -264,7 +264,7 @@ Il file [LICENSE](LICENSE) è quello che fa fede, e si apre con lo stesso riassu
|
|
|
264
264
|
Uncle Sam è un plugin indipendente. Non affiliato a DeepSeek, né approvato né supportato da loro.
|
|
265
265
|
|
|
266
266
|
```
|
|
267
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
267
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
268
268
|
Autore Operating Tag
|
|
269
269
|
Licenza CC BY-NC-ND 4.0 — libero da usare, non da modificare, condividere o vendere
|
|
270
270
|
```
|
package/README.ja.md
CHANGED
|
@@ -259,7 +259,7 @@ Copyright (c) 2026 Darren T. Weldon、Operating Tag 名義で公開。
|
|
|
259
259
|
Uncle Sam は独立したプラグインです。DeepSeek とは関係がなく、承認も支援も受けていません。
|
|
260
260
|
|
|
261
261
|
```
|
|
262
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
262
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
263
263
|
作者 Operating Tag
|
|
264
264
|
ライセンス CC BY-NC-ND 4.0 — 使用は自由、変更・共有・販売は不可
|
|
265
265
|
```
|
package/README.ka.md
CHANGED
|
@@ -257,7 +257,7 @@ Copyright (c) 2026 Darren T. Weldon, გამოქვეყნებული
|
|
|
257
257
|
Uncle Sam დამოუკიდებელი დანამატია. არ არის დაკავშირებული DeepSeek-თან, მათ მიერ არ არის დამტკიცებული ან მხარდაჭერილი.
|
|
258
258
|
|
|
259
259
|
```
|
|
260
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
260
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
261
261
|
ავტორი Operating Tag
|
|
262
262
|
ლიცენზია CC BY-NC-ND 4.0 — თავისუფალი გამოსაყენებლად, არა შესაცვლელად, გასაზიარებლად ან გასაყიდად
|
|
263
263
|
```
|
package/README.kk.md
CHANGED
|
@@ -258,7 +258,7 @@ Operating Tag-тан сұраңыз — нақты жауап және нақт
|
|
|
258
258
|
Uncle Sam — тәуелсіз плагин. DeepSeek-пен байланысты емес, олар мақұлдамаған немесе қолдамаған.
|
|
259
259
|
|
|
260
260
|
```
|
|
261
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
261
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
262
262
|
Авторы Operating Tag
|
|
263
263
|
Лицензия CC BY-NC-ND 4.0 — пайдалануға тегін, өзгертуге, бөлісуге немесе сатуға емес
|
|
264
264
|
```
|
package/README.km.md
CHANGED
|
@@ -253,7 +253,7 @@ Tag — អ្នកនឹងទទួលបានចម្លើយច្បា
|
|
|
253
253
|
Uncle Sam គឺជាកម្មវិធីបន្ថែមឯករាជ្យ។ មិនពាក់ព័ន្ធនឹង DeepSeek មិនត្រូវបានអនុម័ត ឬគាំទ្រដោយពួកគេ។
|
|
254
254
|
|
|
255
255
|
```
|
|
256
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
256
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
257
257
|
អ្នកនិពន្ធ Operating Tag
|
|
258
258
|
អាជ្ញាបណ្ណ CC BY-NC-ND 4.0 — ប្រើឥតគិតថ្លៃ មិនមែនសម្រាប់កែប្រែ ចែករំលែក ឬលក់
|
|
259
259
|
```
|
package/README.ko.md
CHANGED
|
@@ -254,7 +254,7 @@ Copyright (c) 2026 Darren T. Weldon, Operating Tag 이름으로 공개.
|
|
|
254
254
|
Uncle Sam은 독립적인 플러그인입니다. DeepSeek과 무관하며, 그들의 보증이나 지원을 받지 않습니다.
|
|
255
255
|
|
|
256
256
|
```
|
|
257
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
257
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
258
258
|
저자 Operating Tag
|
|
259
259
|
라이선스 CC BY-NC-ND 4.0 — 사용은 자유, 변경·공유·판매는 불가
|
|
260
260
|
```
|
package/README.lt.md
CHANGED
|
@@ -257,7 +257,7 @@ Failas [LICENSE](LICENSE) yra privalomas, ir jis prasideda ta pačia santrauka p
|
|
|
257
257
|
Uncle Sam yra nepriklausomas papildinys. Nesusijęs su DeepSeek, jų nepatvirtintas ir neremiamas.
|
|
258
258
|
|
|
259
259
|
```
|
|
260
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
260
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
261
261
|
Autorius Operating Tag
|
|
262
262
|
Licencija CC BY-NC-ND 4.0 — nemokama naudoti, ne keisti, bendrinti ar parduoti
|
|
263
263
|
```
|
package/README.md
CHANGED
|
@@ -257,7 +257,7 @@ The [LICENSE](LICENSE) file governs, and it opens with the same summary in plain
|
|
|
257
257
|
Uncle Sam is an independent plugin. Not affiliated with, endorsed by, or supported by DeepSeek.
|
|
258
258
|
|
|
259
259
|
```
|
|
260
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
260
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
261
261
|
Author Operating Tag
|
|
262
262
|
Licence CC BY-NC-ND 4.0 — free to use, not to change, share or sell
|
|
263
263
|
```
|
package/README.mr.md
CHANGED
|
@@ -254,7 +254,7 @@ Copyright (c) 2026 Darren T. Weldon, Operating Tag नावाने प्र
|
|
|
254
254
|
Uncle Sam एक स्वतंत्र प्लगइन आहे. DeepSeek शी संबंधित नाही, त्यांची मान्यता किंवा समर्थन नाही.
|
|
255
255
|
|
|
256
256
|
```
|
|
257
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
257
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
258
258
|
लेखक Operating Tag
|
|
259
259
|
परवाना CC BY-NC-ND 4.0 — वापरण्यास मोफत, बदलण्यास, सामायिक करण्यास किंवा विकण्यास नाही
|
|
260
260
|
```
|
package/README.ms.md
CHANGED
|
@@ -261,7 +261,7 @@ mudah.
|
|
|
261
261
|
Uncle Sam ialah pemalam bebas. Tidak berkaitan dengan DeepSeek, tidak disokong atau ditaja oleh mereka.
|
|
262
262
|
|
|
263
263
|
```
|
|
264
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
264
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
265
265
|
Penulis Operating Tag
|
|
266
266
|
Lesen CC BY-NC-ND 4.0 — bebas digunakan, bukan untuk diubah, dikongsi atau dijual
|
|
267
267
|
```
|
package/README.my.md
CHANGED
|
@@ -262,7 +262,7 @@ Copyright (c) 2026 Darren T. Weldon, Operating Tag အမည်ဖြင့်
|
|
|
262
262
|
Uncle Sam သည် သီးခြားလွတ်လပ်သော plugin ဖြစ်သည်။ DeepSeek နှင့် မသက်ဆိုင်ပါ၊ ၎င်းတို့က အတည်မပြု၊ မပံ့ပိုးပါ။
|
|
263
263
|
|
|
264
264
|
```
|
|
265
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
265
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
266
266
|
စာရေးသူ Operating Tag
|
|
267
267
|
လိုင်စင် CC BY-NC-ND 4.0 — အသုံးပြုရန် အခမဲ့၊ ပြောင်းလဲရန်၊ မျှဝေရန် သို့မဟုတ် ရောင်းရန် မဟုတ်
|
|
268
268
|
```
|
package/README.ne.md
CHANGED
|
@@ -254,7 +254,7 @@ Copyright (c) 2026 Darren T. Weldon, Operating Tag नाममा प्रक
|
|
|
254
254
|
Uncle Sam स्वतन्त्र प्लगइन हो। DeepSeek सँग सम्बन्धित छैन, उनीहरूको स्वीकृति वा समर्थन छैन।
|
|
255
255
|
|
|
256
256
|
```
|
|
257
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
257
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
258
258
|
लेखक Operating Tag
|
|
259
259
|
इजाजतपत्र CC BY-NC-ND 4.0 — प्रयोग गर्न निःशुल्क, परिवर्तन, बाँड्न वा बेच्न होइन
|
|
260
260
|
```
|
package/README.nl.md
CHANGED
|
@@ -262,7 +262,7 @@ Het bestand [LICENSE](LICENSE) is bindend, en het begint met dezelfde samenvatti
|
|
|
262
262
|
Uncle Sam is een onafhankelijke plugin. Niet verbonden met DeepSeek, door hen niet goedgekeurd of ondersteund.
|
|
263
263
|
|
|
264
264
|
```
|
|
265
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
265
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
266
266
|
Auteur Operating Tag
|
|
267
267
|
Licentie CC BY-NC-ND 4.0 — vrij om te gebruiken, niet om te wijzigen, delen of verkopen
|
|
268
268
|
```
|
package/README.no.md
CHANGED
|
@@ -257,7 +257,7 @@ Filen [LICENSE](LICENSE) er den gjeldende, og den begynner med det samme sammend
|
|
|
257
257
|
Uncle Sam er en uavhengig utvidelse. Ikke knyttet til DeepSeek, ikke godkjent eller støttet av dem.
|
|
258
258
|
|
|
259
259
|
```
|
|
260
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
260
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
261
261
|
Forfatter Operating Tag
|
|
262
262
|
Lisens CC BY-NC-ND 4.0 — fritt å bruke, ikke å endre, dele eller selge
|
|
263
263
|
```
|
package/README.pl.md
CHANGED
|
@@ -262,7 +262,7 @@ Wiążący jest plik [LICENSE](LICENSE), a otwiera się tym samym podsumowaniem
|
|
|
262
262
|
Uncle Sam to niezależna wtyczka. Niepowiązana z DeepSeek, nie firmowana ani nie wspierana przez nich.
|
|
263
263
|
|
|
264
264
|
```
|
|
265
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
265
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
266
266
|
Autor Operating Tag
|
|
267
267
|
Licencja CC BY-NC-ND 4.0 — wolno używać, nie wolno zmieniać, udostępniać ani sprzedawać
|
|
268
268
|
```
|
package/README.pt.md
CHANGED
|
@@ -261,7 +261,7 @@ O arquivo [LICENSE](LICENSE) é o que vale, e ele abre com o mesmo resumo em ing
|
|
|
261
261
|
O Uncle Sam é um plugin independente. Não afiliado ao DeepSeek, nem endossado nem apoiado por ele.
|
|
262
262
|
|
|
263
263
|
```
|
|
264
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
264
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
265
265
|
Autor Operating Tag
|
|
266
266
|
Licença CC BY-NC-ND 4.0 — livre para usar, não para alterar, compartilhar ou vender
|
|
267
267
|
```
|
package/README.ro.md
CHANGED
|
@@ -258,7 +258,7 @@ Fișierul [LICENSE](LICENSE) este cel care guvernează și începe cu același r
|
|
|
258
258
|
Uncle Sam este un plugin independent. Neafiliat cu DeepSeek, neaprobat și nesprijinit de ei.
|
|
259
259
|
|
|
260
260
|
```
|
|
261
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
261
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
262
262
|
Autor Operating Tag
|
|
263
263
|
Licență CC BY-NC-ND 4.0 — liber de folosit, nu de modificat, partajat sau vândut
|
|
264
264
|
```
|
package/README.ru.md
CHANGED
|
@@ -265,7 +265,7 @@ International. Copyright (c) 2026 Darren T. Weldon, опубликовано п
|
|
|
265
265
|
Uncle Sam — независимый плагин. Не связан с DeepSeek, не одобрен и не поддерживается им.
|
|
266
266
|
|
|
267
267
|
```
|
|
268
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
268
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
269
269
|
Автор Operating Tag
|
|
270
270
|
Лицензия CC BY-NC-ND 4.0 — бесплатно для использования, не для изменения, передачи или продажи
|
|
271
271
|
```
|
package/README.si.md
CHANGED
|
@@ -255,7 +255,7 @@ Copyright (c) 2026 Darren T. Weldon, Operating Tag නාමයෙන් ප්
|
|
|
255
255
|
Uncle Sam ස්වාධීන ප්ලගීනයකි. DeepSeek සමඟ සම්බන්ධ නැත, ඔවුන් අනුමත හෝ අනුග්රහය නොදක්වයි.
|
|
256
256
|
|
|
257
257
|
```
|
|
258
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
258
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
259
259
|
කතෘ Operating Tag
|
|
260
260
|
බලපත්රය CC BY-NC-ND 4.0 — භාවිතයට නොමිලේ, වෙනස් කිරීමට, බෙදා ගැනීමට හෝ විකිණීමට නොවේ
|
|
261
261
|
```
|
package/README.sk.md
CHANGED
|
@@ -257,7 +257,7 @@ Záväzný je súbor [LICENSE](LICENSE) a začína rovnakým zhrnutím v jednodu
|
|
|
257
257
|
Uncle Sam je nezávislý doplnok. Nie je spojený s DeepSeek, nie je nimi schválený ani podporovaný.
|
|
258
258
|
|
|
259
259
|
```
|
|
260
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
260
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
261
261
|
Autor Operating Tag
|
|
262
262
|
Licencia CC BY-NC-ND 4.0 — zadarmo na používanie, nie na zmenu, zdieľanie alebo predaj
|
|
263
263
|
```
|
package/README.sl.md
CHANGED
|
@@ -258,7 +258,7 @@ Zavezujoča je datoteka [LICENSE](LICENSE) in se začne z istim povzetkom v prep
|
|
|
258
258
|
Uncle Sam je neodvisen vtičnik. Ni povezan z DeepSeek, ni odobren ali podprt z njihove strani.
|
|
259
259
|
|
|
260
260
|
```
|
|
261
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
261
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
262
262
|
Avtor Operating Tag
|
|
263
263
|
Licenca CC BY-NC-ND 4.0 — brezplačno za uporabo, ne za spreminjanje, deljenje ali prodajo
|
|
264
264
|
```
|
package/README.sr.md
CHANGED
|
@@ -258,7 +258,7 @@ Copyright (c) 2026 Darren T. Weldon, објављено под именом Oper
|
|
|
258
258
|
Uncle Sam је независни додатак. Није повезан са DeepSeek, није одобрен ни подржан од њих.
|
|
259
259
|
|
|
260
260
|
```
|
|
261
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
261
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
262
262
|
Аутор Operating Tag
|
|
263
263
|
Лиценца CC BY-NC-ND 4.0 — бесплатно за употребу, не за измену, дељење или продају
|
|
264
264
|
```
|
package/README.sv.md
CHANGED
|
@@ -259,7 +259,7 @@ Filen [LICENSE](LICENSE) är den som gäller, och den börjar med samma sammanfa
|
|
|
259
259
|
Uncle Sam är ett fristående insticksprogram. Inte knutet till DeepSeek, inte godkänt eller stött av dem.
|
|
260
260
|
|
|
261
261
|
```
|
|
262
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
262
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
263
263
|
Författare Operating Tag
|
|
264
264
|
Licens CC BY-NC-ND 4.0 — fritt att använda, inte att ändra, dela eller sälja
|
|
265
265
|
```
|
package/README.sw.md
CHANGED
|
@@ -259,7 +259,7 @@ Faili [LICENSE](LICENSE) ndiyo inayotumika, na inaanza na muhtasari huo huo kwa
|
|
|
259
259
|
Uncle Sam ni programu-jalizi huru. Haijahusishwa na DeepSeek, haijaidhinishwa wala kuungwa mkono nao.
|
|
260
260
|
|
|
261
261
|
```
|
|
262
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
262
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
263
263
|
Mwandishi Operating Tag
|
|
264
264
|
Leseni CC BY-NC-ND 4.0 — huru kutumika, si kubadilisha, kushiriki au kuuza
|
|
265
265
|
```
|
package/README.ta.md
CHANGED
|
@@ -262,7 +262,7 @@ Tag ஐக் கேளுங்கள் — தெளிவான பதில
|
|
|
262
262
|
Uncle Sam ஒரு சுயாதீனச் செருகல். DeepSeek உடன் தொடர்பில்லை, அவர்களின் ஒப்புதல் அல்லது ஆதரவு இல்லை.
|
|
263
263
|
|
|
264
264
|
```
|
|
265
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
265
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
266
266
|
ஆசிரியர் Operating Tag
|
|
267
267
|
உரிமம் CC BY-NC-ND 4.0 — பயன்படுத்த இலவசம், மாற்ற, பகிர அல்லது விற்க அல்ல
|
|
268
268
|
```
|
package/README.te.md
CHANGED
|
@@ -256,7 +256,7 @@ Tag ను అడగండి — స్పష్టమైన సమాధాన
|
|
|
256
256
|
Uncle Sam స్వతంత్ర ప్లగిన్. DeepSeek తో సంబంధం లేదు, వారి ఆమోదం లేదా మద్దతు లేదు.
|
|
257
257
|
|
|
258
258
|
```
|
|
259
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
259
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
260
260
|
రచయిత Operating Tag
|
|
261
261
|
లైసెన్స్ CC BY-NC-ND 4.0 — వాడటానికి ఉచితం, మార్చడానికి, పంచుకోవడానికి లేదా అమ్మడానికి కాదు
|
|
262
262
|
```
|
package/README.th.md
CHANGED
|
@@ -252,7 +252,7 @@ Operating Tag แล้วคุณจะได้คำตอบที่ชั
|
|
|
252
252
|
Uncle Sam เป็นปลั๊กอินอิสระ ไม่เกี่ยวข้องกับ DeepSeek ไม่ได้รับการรับรองหรือสนับสนุนจากพวกเขา
|
|
253
253
|
|
|
254
254
|
```
|
|
255
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
255
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
256
256
|
ผู้เขียน Operating Tag
|
|
257
257
|
สัญญาอนุญาต CC BY-NC-ND 4.0 — ใช้ฟรี ไม่ใช่เพื่อดัดแปลง แบ่งปัน หรือขาย
|
|
258
258
|
```
|
package/README.tl.md
CHANGED
|
@@ -265,7 +265,7 @@ Ang file na [LICENSE](LICENSE) ang namamahala, at nagsisimula ito sa parehong bu
|
|
|
265
265
|
Ang Uncle Sam ay isang malayang plugin. Hindi kaanib sa DeepSeek, hindi inendorso o sinusuportahan nila.
|
|
266
266
|
|
|
267
267
|
```
|
|
268
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
268
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
269
269
|
May-akda Operating Tag
|
|
270
270
|
Lisensya CC BY-NC-ND 4.0 — libre gamitin, hindi para baguhin, ibahagi o ibenta
|
|
271
271
|
```
|
package/README.tr.md
CHANGED
|
@@ -261,7 +261,7 @@ Uncle Sam bağımsız bir eklentidir. DeepSeek ile bağlantılı değildir, onla
|
|
|
261
261
|
desteklenmemiştir.
|
|
262
262
|
|
|
263
263
|
```
|
|
264
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
264
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
265
265
|
Yazar Operating Tag
|
|
266
266
|
Lisans CC BY-NC-ND 4.0 — kullanması serbest, değiştirmesi, paylaşması veya satması değil
|
|
267
267
|
```
|
package/README.uk.md
CHANGED
|
@@ -261,7 +261,7 @@ International. Copyright (c) 2026 Darren T. Weldon, опубліковано п
|
|
|
261
261
|
Uncle Sam — незалежний плагін. Не пов'язаний із DeepSeek, не схвалений і не підтриманий ними.
|
|
262
262
|
|
|
263
263
|
```
|
|
264
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
264
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
265
265
|
Автор Operating Tag
|
|
266
266
|
Ліцензія CC BY-NC-ND 4.0 — вільно використовувати, не змінювати, передавати чи продавати
|
|
267
267
|
```
|
package/README.ur.md
CHANGED
|
@@ -257,7 +257,7 @@ Copyright (c) 2026 Darren T. Weldon، Operating Tag نام سے شائع شدہ
|
|
|
257
257
|
Uncle Sam ایک خودمختار پلگ ان ہے۔ DeepSeek سے وابستہ نہیں، ان کی توثیق یا معاونت حاصل نہیں۔
|
|
258
258
|
|
|
259
259
|
```
|
|
260
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
260
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
261
261
|
مصنف Operating Tag
|
|
262
262
|
لائسنس CC BY-NC-ND 4.0 — استعمال کے لیے مفت، تبدیلی، اشتراک یا فروخت کے لیے نہیں
|
|
263
263
|
```
|
package/README.uz.md
CHANGED
|
@@ -258,7 +258,7 @@ Tag dan so'rang — aniq javob va aniq narx olasiz.
|
|
|
258
258
|
Uncle Sam — mustaqil plagin. DeepSeek bilan bog'liq emas, ular tomonidan ma'qullanmagan yoki qo'llab-quvvatlanmagan.
|
|
259
259
|
|
|
260
260
|
```
|
|
261
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
261
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
262
262
|
Muallif Operating Tag
|
|
263
263
|
Litsenziya CC BY-NC-ND 4.0 — foydalanish uchun bepul, o'zgartirish, ulashish yoki sotish uchun emas
|
|
264
264
|
```
|
package/README.vi.md
CHANGED
|
@@ -259,7 +259,7 @@ Tệp [LICENSE](LICENSE) là văn bản có hiệu lực, và nó mở đầu b
|
|
|
259
259
|
Uncle Sam là một plugin độc lập. Không liên kết với DeepSeek, không được họ chứng thực hay hỗ trợ.
|
|
260
260
|
|
|
261
261
|
```
|
|
262
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
262
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
263
263
|
Tác giả Operating Tag
|
|
264
264
|
Giấy phép CC BY-NC-ND 4.0 — miễn phí để dùng, không được sửa, chia sẻ hay bán
|
|
265
265
|
```
|
package/README.zh.md
CHANGED
|
@@ -244,7 +244,7 @@ Copyright (c) 2026 Darren T. Weldon,以 Operating Tag 名义发布。
|
|
|
244
244
|
Uncle Sam 是一个独立插件。与 DeepSeek 无关联,未获其背书,也未获其支持。
|
|
245
245
|
|
|
246
246
|
```
|
|
247
|
-
@operatingtag/dsh-unclesam v1.3.
|
|
247
|
+
@operatingtag/dsh-unclesam v1.3.4
|
|
248
248
|
作者 Operating Tag
|
|
249
249
|
许可 CC BY-NC-ND 4.0 —— 可免费使用,不可修改、共享或出售
|
|
250
250
|
```
|
package/index.js
CHANGED
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
* prose instead of a call, and the harness sees no tool use that turn.
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
|
-
import {
|
|
31
|
-
import { buildPrompt, messageText, parseToolCall, stripToolCall, streamSafeCut } from './lib/prompt.mjs';
|
|
30
|
+
import { writeFileSync } from 'node:fs';
|
|
31
|
+
import { ChatSession, WebChatError } from './lib/engine.mjs';import { buildPrompt, messageText, parseToolCall, stripToolCall, streamSafeCut } from './lib/prompt.mjs';
|
|
32
32
|
import { SavingsMeter, estimateTokens as estimateTokensForSavings } from './lib/savings.mjs';
|
|
33
33
|
import { Locales } from './lib/i18n.mjs';
|
|
34
34
|
import { Prefs, prefsPath, profileDir } from './lib/prefs.mjs';
|
|
@@ -457,6 +457,13 @@ export function apply(ctx, config = {}) {
|
|
|
457
457
|
}
|
|
458
458
|
|
|
459
459
|
const wantTools = Array.isArray(options.tools) && options.tools.length > 0;
|
|
460
|
+
/*
|
|
461
|
+
* The names this turn offered, exactly as the page was told them.
|
|
462
|
+
*
|
|
463
|
+
* `name({...})` is only a call when `name` is one of these - that is what makes the form unambiguous.
|
|
464
|
+
* Without the list, prose like `see figure(2)` would look like a call.
|
|
465
|
+
*/
|
|
466
|
+
const toolNames = wantTools ? options.tools.map((t) => t?.name).filter(Boolean) : [];
|
|
460
467
|
const switches = switchesFor(model, settings);
|
|
461
468
|
// A search answer is delivered as two blocks: what was searched and where it looked, then the
|
|
462
469
|
// answer. That means the text cannot stream while search is on - the sources are only readable
|
|
@@ -556,6 +563,22 @@ export function apply(ctx, config = {}) {
|
|
|
556
563
|
if (chunk.done) {
|
|
557
564
|
assembled = chunk.text;
|
|
558
565
|
if (chunk.sources) sources = chunk.sources;
|
|
566
|
+
/*
|
|
567
|
+
* Optional raw capture, for tests that need to see the reply AS THE PAGE WROTE IT.
|
|
568
|
+
*
|
|
569
|
+
* A recovered call proves the parser worked, not which shape the model chose - and the shape is
|
|
570
|
+
* the thing being changed when the call format changes. Writing the raw reply to a path the test
|
|
571
|
+
* names turns "the call parsed" into "the model emitted this, character for character".
|
|
572
|
+
*
|
|
573
|
+
* Off unless UNCLE_SAM_RAW_REPLY names a file, so nothing is written during ordinary use.
|
|
574
|
+
*/
|
|
575
|
+
if (process.env.UNCLE_SAM_RAW_REPLY) {
|
|
576
|
+
try {
|
|
577
|
+
writeFileSync(process.env.UNCLE_SAM_RAW_REPLY, chunk.text ?? '', 'utf8');
|
|
578
|
+
} catch {
|
|
579
|
+
/* a diagnostic must never break the turn */
|
|
580
|
+
}
|
|
581
|
+
}
|
|
559
582
|
continue;
|
|
560
583
|
}
|
|
561
584
|
if (!chunk.text) continue;
|
|
@@ -573,7 +596,7 @@ export function apply(ctx, config = {}) {
|
|
|
573
596
|
* grow into {"tool":...}. Ordinary prose passes straight through, braces included, so the stream
|
|
574
597
|
* stays live; it simply stops one brace early when a call might be starting.
|
|
575
598
|
*/
|
|
576
|
-
const safe = streamSafeCut(assembled);
|
|
599
|
+
const safe = streamSafeCut(assembled, toolNames);
|
|
577
600
|
if (safe > shown) {
|
|
578
601
|
const out = assembled.slice(shown, safe);
|
|
579
602
|
shown = safe;
|
|
@@ -634,7 +657,7 @@ export function apply(ctx, config = {}) {
|
|
|
634
657
|
yield { type: 'text-delta', index: 0, text: summaryWithLabel };
|
|
635
658
|
yield { type: 'block-end', index: 0, block: { type: 'text', text: summaryWithLabel } };
|
|
636
659
|
|
|
637
|
-
const answerText = stripToolCall(assembled);
|
|
660
|
+
const answerText = stripToolCall(assembled, toolNames);
|
|
638
661
|
yield { type: 'block-start', index: 1, blockType: 'text' };
|
|
639
662
|
if (answerText) yield { type: 'text-delta', index: 1, text: answerText };
|
|
640
663
|
yield { type: 'block-end', index: 1, block: { type: 'text', text: answerText } };
|
|
@@ -645,7 +668,7 @@ export function apply(ctx, config = {}) {
|
|
|
645
668
|
* block is emitted after the answer, exactly as the plain path does.
|
|
646
669
|
*/
|
|
647
670
|
if (wantTools) {
|
|
648
|
-
const call = parseToolCall(assembled);
|
|
671
|
+
const call = parseToolCall(assembled, toolNames);
|
|
649
672
|
if (call) {
|
|
650
673
|
const callId = `webcall_${Date.now().toString(36)}`;
|
|
651
674
|
yield { type: 'block-start', index: 2, blockType: 'tool-call' };
|
|
@@ -689,7 +712,7 @@ export function apply(ctx, config = {}) {
|
|
|
689
712
|
}
|
|
690
713
|
|
|
691
714
|
if (wantTools) {
|
|
692
|
-
const call = parseToolCall(assembled);
|
|
715
|
+
const call = parseToolCall(assembled, toolNames);
|
|
693
716
|
if (call) {
|
|
694
717
|
// A tool call was made. Any prose the model wrapped around it belongs in the text block;
|
|
695
718
|
// the JSON itself must not reach the transcript.
|
|
@@ -732,7 +755,7 @@ export function apply(ctx, config = {}) {
|
|
|
732
755
|
emitted += WEB_LABEL;
|
|
733
756
|
yield { type: 'text-delta', index: 0, text: WEB_LABEL };
|
|
734
757
|
}
|
|
735
|
-
const tail = stripToolCall(assembled.slice(shown));
|
|
758
|
+
const tail = stripToolCall(assembled.slice(shown), toolNames);
|
|
736
759
|
if (tail) {
|
|
737
760
|
emitted += tail;
|
|
738
761
|
yield { type: 'text-delta', index: 0, text: tail };
|
|
@@ -774,7 +797,7 @@ export function apply(ctx, config = {}) {
|
|
|
774
797
|
* scanner stopped one brace short of any. Scrubbing the tail and appending it keeps the committed
|
|
775
798
|
* block equal to the deltas that were yielded, which the harness checks.
|
|
776
799
|
*/
|
|
777
|
-
const held = stripToolCall(assembled.slice(shown));
|
|
800
|
+
const held = stripToolCall(assembled.slice(shown), toolNames);
|
|
778
801
|
if (held) {
|
|
779
802
|
if (!emitted) {
|
|
780
803
|
emitted += WEB_LABEL;
|
package/lib/prompt.mjs
CHANGED
|
@@ -161,7 +161,7 @@ export function toolPreamble(tools) {
|
|
|
161
161
|
* emulation exists to work around.
|
|
162
162
|
*/
|
|
163
163
|
const HEAD = 'Tools: ';
|
|
164
|
-
const TAIL = ' · to call one reply only with {"
|
|
164
|
+
const TAIL = ' · to call one reply only with name({"arg":"value"})';
|
|
165
165
|
|
|
166
166
|
/**
|
|
167
167
|
* Room for the list.
|
|
@@ -393,10 +393,115 @@ function finish(text, expectsToolCall, continuing) {
|
|
|
393
393
|
* that merely CONTAINS the word tool but no valid object is treated as prose, because treating it as a
|
|
394
394
|
* malformed call would throw away a perfectly good answer.
|
|
395
395
|
*/
|
|
396
|
-
|
|
396
|
+
/**
|
|
397
|
+
* Find `name({...})` in a reply, where `name` is one of the tools that was offered.
|
|
398
|
+
*
|
|
399
|
+
* WHY THIS FORM IS PREFERRED OVER JSON
|
|
400
|
+
* MEASURED: a reply that is nothing but `{"tool":…}` cannot be shown while it is written, so the harness
|
|
401
|
+
* sits empty for the whole generation and looks stuck. And a brace is the commonest punctuation in
|
|
402
|
+
* technical prose, so `{` is a poor delimiter - it both blocks streaming and invites false positives.
|
|
403
|
+
*
|
|
404
|
+
* `read({"path":"x"})` needs no instruction, because it is the shape models already produce, and it is
|
|
405
|
+
* unambiguous once it is anchored on a tool name the model was actually given. `read(` when `read` is in
|
|
406
|
+
* the offered list is a far stronger signal than `{`.
|
|
407
|
+
*
|
|
408
|
+
* WHAT IT DOES NOT DO
|
|
409
|
+
* It does not JSON.parse inside strings or respect nesting by regex - it walks the characters, because an
|
|
410
|
+
* argument may contain a parenthesis or a brace inside a string and a regex would stop there.
|
|
411
|
+
*/
|
|
412
|
+
function findCallForm(text, names) {
|
|
413
|
+
const wanted = Array.isArray(names) && names.length ? names : null;
|
|
414
|
+
|
|
415
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
416
|
+
if (!/[A-Za-z_]/.test(text[i])) continue;
|
|
417
|
+
|
|
418
|
+
// Read the identifier at this position.
|
|
419
|
+
let j = i;
|
|
420
|
+
let word = '';
|
|
421
|
+
while (j < text.length && /[A-Za-z0-9_.-]/.test(text[j])) {
|
|
422
|
+
word += text[j];
|
|
423
|
+
j += 1;
|
|
424
|
+
}
|
|
425
|
+
if (!word) continue;
|
|
426
|
+
if (wanted && !wanted.includes(word)) {
|
|
427
|
+
i = j - 1;
|
|
428
|
+
continue;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Optional whitespace, then a parenthesis.
|
|
432
|
+
let k = j;
|
|
433
|
+
while (k < text.length && (text[k] === ' ' || text[k] === '\t' || text[k] === '\n')) k += 1;
|
|
434
|
+
if (text[k] !== '(') {
|
|
435
|
+
i = j - 1;
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Walk to the matching parenthesis, respecting strings and escapes.
|
|
440
|
+
let depth = 0;
|
|
441
|
+
let inString = false;
|
|
442
|
+
let escaped = false;
|
|
443
|
+
let end = -1;
|
|
444
|
+
for (let p = k; p < text.length; p += 1) {
|
|
445
|
+
const ch = text[p];
|
|
446
|
+
if (inString) {
|
|
447
|
+
if (escaped) escaped = false;
|
|
448
|
+
else if (ch === '\\') escaped = true;
|
|
449
|
+
else if (ch === '"') inString = false;
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
if (ch === '"') inString = true;
|
|
453
|
+
else if (ch === '(') depth += 1;
|
|
454
|
+
else if (ch === ')') {
|
|
455
|
+
depth -= 1;
|
|
456
|
+
if (depth === 0) {
|
|
457
|
+
end = p;
|
|
458
|
+
break;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
if (end === -1) return null; // still being written - no complete call yet
|
|
463
|
+
|
|
464
|
+
const inside = text.slice(k + 1, end).trim();
|
|
465
|
+
let args = {};
|
|
466
|
+
if (inside) {
|
|
467
|
+
try {
|
|
468
|
+
args = JSON.parse(inside);
|
|
469
|
+
} catch {
|
|
470
|
+
return null; // parentheses that are not a call, or arguments not yet valid
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
return {
|
|
475
|
+
name: word,
|
|
476
|
+
arguments: JSON.stringify(args),
|
|
477
|
+
start: i,
|
|
478
|
+
end: end + 1,
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
return null;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Recover a tool call from a plain-text reply, if the model made one.
|
|
487
|
+
*
|
|
488
|
+
* TWO SHAPES, IN ORDER
|
|
489
|
+
* 1 `name({...})` — preferred: no instruction needed, and it streams
|
|
490
|
+
* 2 `{"tool":"name","arguments":{…}}` — kept because models emit it unprompted, and because a fallback
|
|
491
|
+
* costs nothing when the primary misses
|
|
492
|
+
*
|
|
493
|
+
* Fenced blocks are searched last-first because a model that explains itself tends to put the final answer at
|
|
494
|
+
* the end. A reply that merely CONTAINS the word tool but no valid object is treated as prose, because
|
|
495
|
+
* treating it as a malformed call would throw away a perfectly good answer.
|
|
496
|
+
*/
|
|
497
|
+
export function parseToolCall(reply, names) {
|
|
397
498
|
const text = String(reply ?? '').trim();
|
|
398
499
|
if (!text) return null;
|
|
399
500
|
|
|
501
|
+
// Shape 1: name({...}).
|
|
502
|
+
const direct = findCallForm(text, names);
|
|
503
|
+
if (direct) return { name: direct.name, arguments: direct.arguments };
|
|
504
|
+
|
|
400
505
|
const candidates = [];
|
|
401
506
|
// fenced blocks first
|
|
402
507
|
const fence = /```(?:json)?\s*([\s\S]*?)```/gi;
|
|
@@ -464,9 +569,56 @@ export function parseToolCall(reply) {
|
|
|
464
569
|
* It does not decide whether a call exists - `parseToolCall` does that at the end. It only answers
|
|
465
570
|
* "how far can I safely show right now", which is the question a live stream needs.
|
|
466
571
|
*/
|
|
467
|
-
export function streamSafeCut(text) {
|
|
572
|
+
export function streamSafeCut(text, names) {
|
|
468
573
|
const s = String(text ?? '');
|
|
469
574
|
|
|
575
|
+
/**
|
|
576
|
+
* Hold from a known tool name that has opened, or is about to open, a parenthesis.
|
|
577
|
+
*
|
|
578
|
+
* This is the call-syntax half of the same question. `read(` is a call; `read` alone might be the first
|
|
579
|
+
* letters of `readable`, so it is not held - but a trailing fragment that could still become a known name
|
|
580
|
+
* (`repl` at the very end of the text) IS held, because the next characters may complete it.
|
|
581
|
+
*/
|
|
582
|
+
const wanted = Array.isArray(names) && names.length ? names : null;
|
|
583
|
+
if (wanted) {
|
|
584
|
+
for (let i = 0; i < s.length; i += 1) {
|
|
585
|
+
if (!/[A-Za-z_]/.test(s[i])) continue;
|
|
586
|
+
let j = i;
|
|
587
|
+
let word = '';
|
|
588
|
+
while (j < s.length && /[A-Za-z0-9_.-]/.test(s[j])) {
|
|
589
|
+
word += s[j];
|
|
590
|
+
j += 1;
|
|
591
|
+
}
|
|
592
|
+
if (wanted.includes(word)) {
|
|
593
|
+
let k = j;
|
|
594
|
+
while (k < s.length && /\s/.test(s[k])) k += 1;
|
|
595
|
+
// A complete `name (` is a call being written; nothing after it may stream.
|
|
596
|
+
if (k >= s.length || s[k] === '(') return i;
|
|
597
|
+
}
|
|
598
|
+
i = j - 1;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* A name that is still arriving.
|
|
603
|
+
*
|
|
604
|
+
* The reply may end mid-identifier — `… now call replace_not` — and one more character would make it a
|
|
605
|
+
* call. Holding the fragment costs a few visible characters and stops a call's opening words from
|
|
606
|
+
* appearing in the transcript before the call does.
|
|
607
|
+
*
|
|
608
|
+
* THREE CHARACTERS MINIMUM, measured. The first version held any trailing fragment that prefixed a known
|
|
609
|
+
* name, so an ordinary sentence ending in `r` stalled one character back - `r` prefixes `read` and
|
|
610
|
+
* `replace_note`. On screen that is a reply that appears to stop mid-word and then finishes a keystroke
|
|
611
|
+
* later. A three-letter fragment is worth holding; one letter is not.
|
|
612
|
+
*/
|
|
613
|
+
const tailStart = Math.max(0, s.length - 40);
|
|
614
|
+
for (let i = tailStart; i < s.length; i += 1) {
|
|
615
|
+
const fragment = s.slice(i);
|
|
616
|
+
if (fragment.length < 3) break;
|
|
617
|
+
if (!/^[A-Za-z_][A-Za-z0-9_.-]*$/.test(fragment)) continue;
|
|
618
|
+
if (wanted.some((n) => n.startsWith(fragment))) return i;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
470
622
|
/**
|
|
471
623
|
* Could the brace at `i` still turn out to be the start of a tool object?
|
|
472
624
|
*
|
|
@@ -497,9 +649,21 @@ export function streamSafeCut(text) {
|
|
|
497
649
|
return s.length;
|
|
498
650
|
}
|
|
499
651
|
|
|
500
|
-
export function stripToolCall(reply) {
|
|
652
|
+
export function stripToolCall(reply, names) {
|
|
501
653
|
let text = String(reply ?? '');
|
|
502
654
|
|
|
655
|
+
/**
|
|
656
|
+
* Shape 1: `name({...})`, wherever it appears, prose either side.
|
|
657
|
+
*
|
|
658
|
+
* Removed by the same character walk that found it, so a call whose arguments contain a parenthesis or a
|
|
659
|
+
* brace inside a string is removed whole rather than up to the first `)`.
|
|
660
|
+
*/
|
|
661
|
+
for (let guard = 0; guard < 20; guard += 1) {
|
|
662
|
+
const found = findCallForm(text, names);
|
|
663
|
+
if (!found) break;
|
|
664
|
+
text = text.slice(0, found.start) + ' ' + text.slice(found.end);
|
|
665
|
+
}
|
|
666
|
+
|
|
503
667
|
// Fenced calls first: the fence marks the whole block, so no brace counting is needed.
|
|
504
668
|
text = text.replace(/```(?:json)?\s*\{\s*"tool"[\s\S]*?\}\s*```/gi, '');
|
|
505
669
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@operatingtag/dsh-unclesam",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Uncle Sam — answers through chat.deepseek.com in a real browser tab instead of the metered API. Switch between the API and the web account from the composer; web replies are signed so you always know which route answered.",
|