dsh-telegram-multiagent 1.5.1 → 1.5.2
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 +23 -0
- package/package.json +1 -1
- package/src/index.js +27 -3
- package/test/stend-prichiny-otkaza.mjs +42 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
## 1.5.2
|
|
2
|
+
|
|
3
|
+
**Разбор брошенного — по ДВУМ ОСЯМ.** Три места (`Измеритель отказал`, `обход событий отказал`,
|
|
4
|
+
`llm.resolveModelInfo отказал`) собирали причину как `String(e?.message ?? e)`.
|
|
5
|
+
|
|
6
|
+
ось 1 — пустое исключение -> строка НЕ пуста было 6 из 10
|
|
7
|
+
ось 2 — брошенный ПРИМИТИВ -> текст СОХРАНЁН было 4 из 5
|
|
8
|
+
стало: ось 1 — 10 из 10, ось 2 — 4 из 5 (не хуже)
|
|
9
|
+
|
|
10
|
+
🔴 Первая предложенная редакция закрывала ось 1 и ЛОМАЛА ось 2: `throw 'сессия не открыта'`
|
|
11
|
+
давала «string: (без пояснения)». Пустоту закрыли, потерю открыли рядом. Нашлось это не чтением
|
|
12
|
+
кода, а второй осью — пробы одной оси слепы к дефекту другой, сколько бы их ни было.
|
|
13
|
+
|
|
14
|
+
`code` добавлен сверх присланного замысла: у нас ДОКАЗАНО замером, что при пустом `message`
|
|
15
|
+
причина живёт именно в нём (`ECONNRESET`, `ENOTFOUND` у fetch). Без него три случая из пяти
|
|
16
|
+
дают «(без пояснения)» там, где код известен.
|
|
17
|
+
|
|
18
|
+
⚠️ Остаток названный: `throw null` и `{}` текста не несут вовсе — там «(без пояснения)» честно,
|
|
19
|
+
а не потеря.
|
|
20
|
+
|
|
21
|
+
Две порчи, каждая ломает СВОЮ ось: первая редакция роняет ось 2, прежнее выражение — ось 1.
|
|
22
|
+
Стенд 8 из 8.
|
|
23
|
+
|
|
1
24
|
## 1.5.1
|
|
2
25
|
|
|
3
26
|
🔴 **`errDetail` печатал пустоту после слова «причина».** Собирал причину через `??`, а нулевое
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-telegram-multiagent",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "Канал Telegram для DeepSeek Harness: один модуль на машину обслуживает несколько агентов, у каждого свой бот, свой файл токена и свой список разрешённых. Метка отправителя неподделываема, память владельца и координатора слита в одну, режим доставки переключается файлом вне кода, цели управляются из канала.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
package/src/index.js
CHANGED
|
@@ -1372,6 +1372,30 @@ export function apply(ctx, config = {}) {
|
|
|
1372
1372
|
// двоеточия. Хуже отсутствия поля: «причина:» с пустотой читается как «причину
|
|
1373
1373
|
// узнали, она пустая», а её просто не достали.
|
|
1374
1374
|
// Воспроизведено: errDetail(cause с message='') -> '', errDetail(AggregateError) -> ''.
|
|
1375
|
+
// 🔴 РАЗБОР БРОШЕННОГО. Замысел соавтора от 04.09 плюс `code` — и то, и другое
|
|
1376
|
+
// по замеру, а не по вкусу.
|
|
1377
|
+
//
|
|
1378
|
+
// ДВЕ ОСИ ПРИЁМКИ, и вторая нашла дефект, к которому первая слепа по построению:
|
|
1379
|
+
// ось 1 — пустое исключение -> строка НЕ пуста
|
|
1380
|
+
// ось 2 — брошенный ПРИМИТИВ -> текст СОХРАНЁН
|
|
1381
|
+
// Прежнее `String(e?.message ?? e)` держало ось 2 (4 из 5) и проваливало ось 1
|
|
1382
|
+
// (6 из 10): у Error с пустым message и у AggregateError печаталась пустота.
|
|
1383
|
+
// Первая присланная редакция закрывала ось 1 и ЛОМАЛА ось 2: `throw 'сессия не
|
|
1384
|
+
// открыта'` давала «string: (без пояснения)» — пустоту закрыли, потерю открыли рядом.
|
|
1385
|
+
//
|
|
1386
|
+
// Здесь: ось 1 — 10 из 10, ось 2 — 4 из 5 (не хуже прежнего).
|
|
1387
|
+
// `code` добавлен сверх замысла соавтора, потому что у нас ДОКАЗАНО замером: при
|
|
1388
|
+
// пустом message причина живёт именно в нём (ECONNRESET, ENOTFOUND у fetch). Без
|
|
1389
|
+
// него три случая из пяти дают «(без пояснения)» там, где код известен.
|
|
1390
|
+
// Остаток названный, а не замазанный: `throw null` и `{}` текста не несут вовсе —
|
|
1391
|
+
// терять там нечего, и «(без пояснения)» тут ЧЕСТНО, а не потеря.
|
|
1392
|
+
function prichina(e) {
|
|
1393
|
+
const tekst = String(e?.message ?? (typeof e === 'object' ? '' : (e ?? ''))).trim();
|
|
1394
|
+
const kod = e?.code ? String(e.code) : '';
|
|
1395
|
+
const hvost = [kod, tekst].filter(Boolean).join(' ') || '(без пояснения)';
|
|
1396
|
+
return ((e?.name ?? typeof e) + ': ' + hvost).slice(0, 90);
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1375
1399
|
function errDetail(e) {
|
|
1376
1400
|
const c = e?.cause;
|
|
1377
1401
|
if (!c) return 'не указана';
|
|
@@ -1495,7 +1519,7 @@ export function apply(ctx, config = {}) {
|
|
|
1495
1519
|
if (!sess) return { kind: 'error', text: 'Сессия недоступна.' };
|
|
1496
1520
|
let m;
|
|
1497
1521
|
try { m = schetchik.measure(sess); }
|
|
1498
|
-
catch (e) { return { kind: 'error', text: `Измеритель отказал: ${
|
|
1522
|
+
catch (e) { return { kind: 'error', text: `Измеритель отказал: ${prichina(e)}` }; }
|
|
1499
1523
|
// 🔴 СВЕЖЕСТЬ ОПОРЫ. baseline.kind различает ПРОИСХОЖДЕНИЕ опоры и НЕ различает
|
|
1500
1524
|
// её СВЕЖЕСТЬ: при surface-replace (compaction/summary|prune) поверхность
|
|
1501
1525
|
// пересчитывается, а якорь остаётся прежним и тащит свой kind='usage'
|
|
@@ -1536,7 +1560,7 @@ export function apply(ctx, config = {}) {
|
|
|
1536
1560
|
return { kind: 'ne-znayu', pochemu: 'у сессии нет ни events, ни eventAt+seq' };
|
|
1537
1561
|
}
|
|
1538
1562
|
} catch (e) {
|
|
1539
|
-
return { kind: 'ne-znayu', pochemu: `обход событий отказал: ${
|
|
1563
|
+
return { kind: 'ne-znayu', pochemu: `обход событий отказал: ${prichina(e)}` };
|
|
1540
1564
|
}
|
|
1541
1565
|
if (poslednijKompakt < 0) return { kind: 'svezhaya', kompaktov: 0 };
|
|
1542
1566
|
if (poslednijYakor > poslednijKompakt) return { kind: 'svezhaya', kompaktov: 1 };
|
|
@@ -1597,7 +1621,7 @@ export function apply(ctx, config = {}) {
|
|
|
1597
1621
|
okno = undefined;
|
|
1598
1622
|
}
|
|
1599
1623
|
} catch (e) {
|
|
1600
|
-
pochemuNet = `llm.resolveModelInfo отказал: ${
|
|
1624
|
+
pochemuNet = `llm.resolveModelInfo отказал: ${prichina(e)}`;
|
|
1601
1625
|
}
|
|
1602
1626
|
}
|
|
1603
1627
|
}
|
|
@@ -69,5 +69,47 @@ t('cause без единого поля → сказано, что описан
|
|
|
69
69
|
nePusto(r, 'пустой объект')
|
|
70
70
|
})
|
|
71
71
|
|
|
72
|
+
// ── ДВЕ ОСИ ПРИЁМКИ ДЛЯ prichina(). ────────────────────────────────────────
|
|
73
|
+
// 🔴 ОСИ, А НЕ «ЕЩЁ ПРОБЫ». Ось — это другой ВОПРОС к тому же предмету, и пробы одной
|
|
74
|
+
// оси слепы к дефекту другой, сколько бы их ни было.
|
|
75
|
+
// ось 1 — пустое исключение -> строка НЕ пуста
|
|
76
|
+
// ось 2 — брошенный ПРИМИТИВ -> текст СОХРАНЁН
|
|
77
|
+
// Первая присланная редакция закрывала ось 1 и ломала ось 2 (`throw 'текст'` давала
|
|
78
|
+
// «string: (без пояснения)»): пустоту закрыли, потерю открыли рядом. Нашлось это не
|
|
79
|
+
// чтением кода, а второй осью.
|
|
80
|
+
const mP = text.match(/function prichina\(e\) \{[\s\S]*?\n \}/)
|
|
81
|
+
if (!mP) { console.log('СЛЕПОТА: функция prichina в предмете не найдена'); process.exit(2) }
|
|
82
|
+
let prichina
|
|
83
|
+
try { prichina = new Function(mP[0] + '; return prichina;')() }
|
|
84
|
+
catch (e) { console.log(`СЛЕПОТА: prichina не собирается: ${e?.message ?? e}`); process.exit(2) }
|
|
85
|
+
|
|
86
|
+
t('ОСЬ 1: пустые исключения дают НЕпустую строку', () => {
|
|
87
|
+
const bed = []
|
|
88
|
+
for (const [imya, v] of [['Error с пустым message', new Error('')],
|
|
89
|
+
['AggregateError пустой', new AggregateError([], '')],
|
|
90
|
+
['throw null', null], ['throw undefined', undefined],
|
|
91
|
+
['объект пустой', {}]]) {
|
|
92
|
+
const r = prichina(v)
|
|
93
|
+
if (typeof r !== 'string' || r.trim() === '' || /^(undefined|null):?\s*$/.test(r.trim()))
|
|
94
|
+
bed.push(`${imya}: «${r}»`)
|
|
95
|
+
}
|
|
96
|
+
if (bed.length) throw new Error(bed.join(' | '))
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
t('ОСЬ 2: брошенный примитив — текст СОХРАНЁН, не заменён пояснением', () => {
|
|
100
|
+
const bed = []
|
|
101
|
+
for (const [v, chto] of [['сессия не открыта', 'сессия не открыта'], [42, '42'],
|
|
102
|
+
[{ message: 'своё' }, 'своё'], [new Error('сеть'), 'сеть']]) {
|
|
103
|
+
const r = prichina(v)
|
|
104
|
+
if (!r.includes(chto)) bed.push(`потерян текст «${chto}»: «${r}»`)
|
|
105
|
+
}
|
|
106
|
+
if (bed.length) throw new Error(bed.join(' | '))
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
t('код ошибки попадает в причину, когда message пуст', () => {
|
|
110
|
+
const r = prichina(Object.assign(new Error(''), { code: 'ECONNRESET' }))
|
|
111
|
+
if (!/ECONNRESET/.test(r)) throw new Error(`код потерян: «${r}»`)
|
|
112
|
+
})
|
|
113
|
+
|
|
72
114
|
console.log(`итог: ${ok} из ${ok + bed}`)
|
|
73
115
|
process.exit(bed === 0 ? 0 : 1)
|