@7n/llm-lib 2.9.1 → 2.9.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 +6 -0
- package/lib/agent-fix.mjs +28 -6
- package/lib/docs/agent-fix.md +22 -6
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
package/lib/agent-fix.mjs
CHANGED
|
@@ -106,10 +106,11 @@ function astUnavailable() {
|
|
|
106
106
|
* джерелом правди — тут лише рання й точніша петля всередині рунга.
|
|
107
107
|
* @param {{ session: object, verify: (args: { touchedFiles: string[] }) => Promise<{ ok: boolean, output?: string }> | { ok: boolean, output?: string },
|
|
108
108
|
* verifyMax: number, timeoutMs: number, startedAt: number, clock: () => number,
|
|
109
|
-
* guard: { touchedFiles: () => string[] }, fixPrompt: string
|
|
109
|
+
* guard: { touchedFiles: () => string[] }, fixPrompt: string,
|
|
110
|
+
* getTransportError: () => string|null }} args контекст петлі.
|
|
110
111
|
* @returns {Promise<{ verifyAttempts: Array<{ ok: boolean, infra?: boolean }>, error: string|null }>} результат петлі.
|
|
111
112
|
*/
|
|
112
|
-
async function runVerifyLoop({ session, verify, verifyMax, timeoutMs, startedAt, clock, guard, fixPrompt }) {
|
|
113
|
+
async function runVerifyLoop({ session, verify, verifyMax, timeoutMs, startedAt, clock, guard, fixPrompt, getTransportError }) {
|
|
113
114
|
const verifyAttempts = []
|
|
114
115
|
for (let attempt = 0; ; attempt++) {
|
|
115
116
|
let evidence
|
|
@@ -137,6 +138,8 @@ async function runVerifyLoop({ session, verify, verifyMax, timeoutMs, startedAt,
|
|
|
137
138
|
failOnMemoryGuard(promptError.message, fixPrompt)
|
|
138
139
|
return { verifyAttempts, error: promptError.message }
|
|
139
140
|
}
|
|
141
|
+
const transportError = getTransportError()
|
|
142
|
+
if (transportError) return { verifyAttempts, error: transportError }
|
|
140
143
|
}
|
|
141
144
|
}
|
|
142
145
|
|
|
@@ -414,6 +417,7 @@ export async function runAgentFix(ruleId, violation, cwd, opts = {}) {
|
|
|
414
417
|
let turnCount = 0
|
|
415
418
|
let toolCallCount = 0
|
|
416
419
|
let backstopHit = false
|
|
420
|
+
let transportError = null
|
|
417
421
|
session.subscribe(event => {
|
|
418
422
|
switch (event.type) {
|
|
419
423
|
case 'turn_start': {
|
|
@@ -435,9 +439,16 @@ export async function runAgentFix(ruleId, violation, cwd, opts = {}) {
|
|
|
435
439
|
}
|
|
436
440
|
case 'message_end': {
|
|
437
441
|
const t = turns.at(-1)
|
|
438
|
-
if (t
|
|
439
|
-
t.usage = event.message
|
|
440
|
-
t.finish = event.message
|
|
442
|
+
if (t) {
|
|
443
|
+
t.usage = event.message?.usage ?? null
|
|
444
|
+
t.finish = event.message?.stopReason ?? null
|
|
445
|
+
}
|
|
446
|
+
if (event.message?.stopReason === 'error') {
|
|
447
|
+
const messageError = event.message.errorMessage
|
|
448
|
+
transportError ??=
|
|
449
|
+
typeof messageError === 'string' && messageError.trim()
|
|
450
|
+
? messageError
|
|
451
|
+
: 'LLM transport завершився з помилкою без повідомлення'
|
|
441
452
|
}
|
|
442
453
|
break
|
|
443
454
|
}
|
|
@@ -466,11 +477,22 @@ export async function runAgentFix(ruleId, violation, cwd, opts = {}) {
|
|
|
466
477
|
error = promptError.message
|
|
467
478
|
failOnMemoryGuard(error, fixPrompt)
|
|
468
479
|
}
|
|
480
|
+
if (!error && transportError) error = transportError
|
|
469
481
|
|
|
470
482
|
// Evidence-гейт: verify → (не ok) → фідбек у ТУ САМУ сесію (див. runVerifyLoop).
|
|
471
483
|
let verifyAttempts = []
|
|
472
484
|
if (verify && !error) {
|
|
473
|
-
const loop = await runVerifyLoop({
|
|
485
|
+
const loop = await runVerifyLoop({
|
|
486
|
+
session,
|
|
487
|
+
verify,
|
|
488
|
+
verifyMax,
|
|
489
|
+
timeoutMs,
|
|
490
|
+
startedAt,
|
|
491
|
+
clock,
|
|
492
|
+
guard,
|
|
493
|
+
fixPrompt,
|
|
494
|
+
getTransportError: () => transportError
|
|
495
|
+
})
|
|
474
496
|
verifyAttempts = loop.verifyAttempts
|
|
475
497
|
error = loop.error
|
|
476
498
|
}
|
package/lib/docs/agent-fix.md
CHANGED
|
@@ -3,25 +3,41 @@ type: JS Module
|
|
|
3
3
|
title: agent-fix.mjs
|
|
4
4
|
resource: llm-lib/lib/agent-fix.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: 73c7797b
|
|
7
7
|
model: openai-codex/gpt-5.4-mini
|
|
8
8
|
tier: cloud-min
|
|
9
|
-
score:
|
|
10
|
-
issues:
|
|
9
|
+
score: 90
|
|
10
|
+
issues: internal-name:runVerifyLoop,judge-refine:kept-original,judge:inaccurate:0.98
|
|
11
|
+
judgeModel: openai-codex/gpt-5.4-mini
|
|
11
12
|
---
|
|
12
13
|
|
|
14
|
+
## Огляд
|
|
15
|
+
|
|
16
|
+
`buildVerifyFeedbackPrompt`, `buildFixPrompt` і `runAgentFix` описують локальний agent-fix цикл: перші дві функції формують промпти для перевірки та виправлення, а `runAgentFix` запускає саму спробу правки. Це потрібно, щоб тримати зміни в межах заданого `violation` і пов’язаного контексту та віддавати керований результат для подальшого кроку.
|
|
17
|
+
|
|
18
|
+
Усі публічні точки входу працюють fail-safe: помилки перехоплюються всередині, назовні винятки не виходять.
|
|
19
|
+
|
|
20
|
+
## Поведінка
|
|
21
|
+
|
|
22
|
+
Поточний `violation` стає джерелом правди для стартового fix-пrompt, а `ruleText`, `feedback`, `targetFiles`, `sourceFiles` і `editMode` лише уточнюють межі та контекст правки. `buildFixPrompt` формує жорстко обмежений запит на механічні зміни, щоб агент не розмивав помилку семантичними “виправленнями” поза дозволеними файлами; далі цей prompt передається в ту саму сесію, де виконуються правки, і після цього запускається внутрішня verify-петля.
|
|
23
|
+
|
|
24
|
+
`runAgentFix` оркеструє один рунг від старту до завершення: створює сесію, дає їй prompt для правки, збирає результати редагування, а потім передає контроль у verify-loop. Якщо перевірка повертає порушення, `buildVerifyFeedbackPrompt` перетворює їх на фідбек для тієї ж сесії, щоб ітерація була локальною і не втрачала вже зроблені зміни.
|
|
25
|
+
|
|
26
|
+
`runVerifyLoop` зупиняється лише коли перевірка стає ok, вичерпується ліміт спроб або закінчується спільний time budget рунга; він не заводить нові таймери й не маскує помилки самої перевірки. Якщо перевірка падає як інфраструктура, це повертається як помилка без спалювання ітерацій. Фінальний результат `runAgentFix` завжди fail-safe: або застосована правка з переліком touched files і telemetry, або контрольована помилка з можливістю rollback.
|
|
27
|
+
|
|
13
28
|
## Публічний API
|
|
14
29
|
|
|
15
30
|
- buildVerifyFeedbackPrompt — Будує фідбек-prompt verify-ітерації: точний вивід canonical-перевірки + нагадування
|
|
16
|
-
обмежень (той самий semantic-collateral guard, що й у buildFixPrompt).
|
|
31
|
+
обмежень (той самий semantic-collateral guard, що й у buildFixPrompt).
|
|
17
32
|
- buildFixPrompt — Будує fix-промпт для рунга: правило + порушення + (опц.) target-файли + (опц.) feedback
|
|
18
|
-
попереднього провалу + жорсткий блок обмежень (лише механічні зміни) + інструкція
|
|
19
|
-
«ast_facts перед edit, self_check після».
|
|
33
|
+
попереднього провалу + жорсткий блок обмежень (лише механічні зміни) + інструкція
|
|
34
|
+
«ast_facts перед edit, self_check після».
|
|
20
35
|
|
|
21
36
|
Блок обмежень — перший шар semantic-collateral guard (спека pi-migration §12,
|
|
22
37
|
addendum 2026-07-05): слабкі локальні моделі схильні «виправляти» правило семантичною
|
|
23
38
|
правкою (хардкод значення, симуляція поведінки) — промпт явно це забороняє, а
|
|
24
39
|
verdict-veto consumer-а (re-check) відхиляє такі правки поза target-файлами.
|
|
40
|
+
|
|
25
41
|
- runAgentFix — Проводить ОДНУ агентну fix-спробу (рунг) для правила.
|
|
26
42
|
|
|
27
43
|
## Гарантії поведінки
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@7n/llm-lib",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.2",
|
|
4
4
|
"description": "Тонкий шар роботи з LLM (локальні omlx + хмарні провайдери) поверх pi: model tiers, one-shot, agentic-раннери, write-guard, trace, telemetry, prompt-budget",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nitra",
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
"access": "public"
|
|
56
56
|
},
|
|
57
57
|
"optionalDependencies": {
|
|
58
|
-
"@7n/llm-lib-darwin-arm64": "2.9.
|
|
59
|
-
"@7n/llm-lib-linux-x64": "2.9.
|
|
58
|
+
"@7n/llm-lib-darwin-arm64": "2.9.2",
|
|
59
|
+
"@7n/llm-lib-linux-x64": "2.9.2"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
62
|
"@earendil-works/pi-ai": "~0.80.10",
|