@7n/llm-lib 2.10.1 → 2.12.0

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.12.0] - 2026-07-28
4
+
5
+ ### Changed
6
+
7
+ - llm-lib v0.2.3: pi-тіри переглянуто (рішення З.1) — min/avg тепер локальні моделі (omlx/gemma-4-e4b-it-OptiQ-4bit, litellm/gemma-4-26b-awq через llm.7n.ai), max лишається openai-codex/gpt-5.6-sol; передумова — провайдери omlx/litellm у pi models.json
8
+ - release: @7n/llm-lib@2.10.1, @7n/rules@1.52.1, @7n/rules-lang-js@0.23.1
9
+ - Механічно додано change-файл для поточних змін у workspace.
10
+
11
+ ## [2.11.0] - 2026-07-27
12
+
13
+ ### Added
14
+
15
+ - `submitBatch` тепер обирає між клієнтською емуляцією і справжнім `/v1/batches` litellm batch-adapter-а (`backend: 'auto'|'emulated'|'openai-batches'`) — автоматично вмикається, коли резолвлений провайдер `litellm` і адаптер відповідає на capability-пробу.
16
+
3
17
  ## [2.10.1] - 2026-07-27
4
18
 
5
19
  ### Fixed
package/lib/batch.mjs CHANGED
@@ -1,14 +1,18 @@
1
1
  /**
2
- * Тип 2b (OpenAI-сумісний API, batch) — **лише емуляція** у v1 (рішення Р,
3
- * задача T6): чанкований конкурентний прогін через Тип 2a
4
- * (`llm_lib::local_cloud`) під інтерфейсом `submit progress → results` —
5
- * той самий інтерфейс, яким говорив би й справжній OpenAI Batch API
6
- * (`/v1/batches`, v2), якому локальний omlx (перший споживач) не має.
2
+ * Тип 2b (OpenAI-сумісний API, batch) — `submitBatch` обирає між клієнтською
3
+ * емуляцією (v1, чанкований конкурентний прогін через Тип 2a
4
+ * `llm_lib::local_cloud`) і справжнім `/v1/batches` litellm batch-adapter-а
5
+ * (спека `docs/specs/2026-07-27-batch-local-avg-real-batches.md`), під тим
6
+ * самим інтерфейсом `submit progress results` для обох. Вибір —
7
+ * `backend` (дефолт `'auto'`: реальний Batch API лише коли резолвлений
8
+ * провайдер `litellm` і кешована мережева проба адаптера пройшла; локальний
9
+ * omlx завжди йде емуляцією).
7
10
  *
8
- * Тонкий JS-клієнт до Rust-крейта `llm_lib::batch` через napi FFI
9
- * in-process (`llm-lib/crates/llm-lib-napi`) — жодного власного чанкінгу
10
- * тут (анти-приклад, якого це узагальнює: `mlmail/use-summary.js` чанкує
11
- * переклади проти omlx вручну, з вистражданими лімітами).
11
+ * Тонкий JS-клієнт до Rust-крейта `llm_lib::batch`/`llm_lib::remote_batch`
12
+ * через napi FFI in-process (`llm-lib/crates/llm-lib-napi`) — жодного
13
+ * власного чанкінгу чи HTTP тут (анти-приклад, якого це узагальнює:
14
+ * `mlmail/use-summary.js` чанкує переклади проти omlx вручну, з
15
+ * вистражданими лімітами).
12
16
  */
13
17
  import { loadNative } from './internal/native.mjs'
14
18
 
@@ -23,9 +27,9 @@ import { loadNative } from './internal/native.mjs'
23
27
  */
24
28
 
25
29
  /**
26
- * Емуляція batch-виклику Типу 2b. `modelSpecOrTier` — той самий контракт,
27
- * що й у [`oneShotLocalCloud`] з `local-cloud.mjs`: явний
28
- * `"provider/model-id"` або абстрактний тир (`min`/`avg`/`max`).
30
+ * Batch-виклик Типу 2b. `modelSpecOrTier` — той самий контракт, що й у
31
+ * [`oneShotLocalCloud`] з `local-cloud.mjs`: явний `"provider/model-id"`
32
+ * або абстрактний тир (`min`/`avg`/`max`).
29
33
  * @param {string} modelSpecOrTier `"provider/model-id"` або `'min'|'avg'|'max'`
30
34
  * @param {BatchItem[]} items вхідні items (`customId` — унікальний у межах виклику)
31
35
  * @param {{
@@ -33,6 +37,9 @@ import { loadNative } from './internal/native.mjs'
33
37
  * system?: string,
34
38
  * chunkSize?: number,
35
39
  * concurrency?: number,
40
+ * backend?: 'emulated' | 'openai-batches' | 'auto',
41
+ * pollIntervalMs?: number,
42
+ * pollTimeoutMs?: number,
36
43
  * onProgress?: (completed: number, total: number) => void,
37
44
  * native?: {
38
45
  * submitBatch: (
@@ -43,13 +50,13 @@ import { loadNative } from './internal/native.mjs'
43
50
  * onProgress?: (completed: number, total: number) => void
44
51
  * ) => Promise<BatchResult[]>
45
52
  * }
46
- * }} [options] конфіг локальних провайдерів, ліміти чанка/конкурентності, progress-колбек, інжект `native` для тестів
53
+ * }} [options] конфіг локальних провайдерів, ліміти чанка/конкурентності/бекенда/опитування, progress-колбек, інжект `native` для тестів
47
54
  * @returns {Promise<BatchResult[]>} результати в тому самому порядку, що й вхідні `items`
48
55
  */
49
56
  export function submitBatch(
50
57
  modelSpecOrTier,
51
58
  items,
52
- { localProviders, system, chunkSize, concurrency, onProgress, native } = {}
59
+ { localProviders, system, chunkSize, concurrency, backend, pollIntervalMs, pollTimeoutMs, onProgress, native } = {}
53
60
  ) {
54
61
  const nativeImpl = native ?? loadNative()
55
62
  return nativeImpl.submitBatch(
@@ -65,7 +72,10 @@ export function submitBatch(
65
72
  },
66
73
  {
67
74
  chunkSize: chunkSize ?? undefined,
68
- concurrency: concurrency ?? undefined
75
+ concurrency: concurrency ?? undefined,
76
+ backend: backend ?? undefined,
77
+ pollIntervalMs: pollIntervalMs ?? undefined,
78
+ pollTimeoutMs: pollTimeoutMs ?? undefined
69
79
  },
70
80
  onProgress ?? undefined
71
81
  )
package/lib/docs/acp.md CHANGED
@@ -3,24 +3,27 @@ type: JS Module
3
3
  title: acp.mjs
4
4
  resource: llm-lib/lib/acp.mjs
5
5
  docgen:
6
- crc: 587f1966
7
- model: openai-codex/gpt-5.4-mini
8
- tier: cloud-min
9
- score: 100
10
- judgeModel: openai-codex/gpt-5.4-mini
6
+ crc: 1ed416a1
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ tier: local-min
9
+ score: 80
11
10
  ---
12
11
 
13
12
  ## Огляд
14
13
 
15
- Публічна точка входу `runAcpAgent` для запуску ACP-агента `cursor`, `codex` або `pi` через локально залогінений CLI без API-ключа. Це тонкий JS-міст до `llm_lib::acp` у `llm-lib/crates/llm-lib-napi`, без власної ACP JSON-RPC чи `ClientSideConnection` логіки; протокольна поведінка, `session/prompt`, `session/request_permission`, `tier→env/args/post-session-config` resolving і watchdog на мертвий або незапущений дочірній процес зосереджені в Rust. `AcpAgentKind` охоплює лише `cursor`/`codex`/`pi`; `claude` тут відсутній, а deprecated `claude`-runner лишається окремим JS-шимом у `@7n/rules` (`npm/scripts/lib/acp-runner.mjs`).
14
+ ACP (Agent Client Protocol, Zed) доступ до `cursor`/`codex`/`pi` через
15
+ особисту підписку (вже залогінений локально CLI), не API-ключ.
16
16
 
17
- ## Поведінка
17
+ Тонкий JS-клієнт до Rust-крейта `llm_lib::acp` через napi FFI
18
+ in-process (`llm-lib/crates/llm-lib-napi`) — жодного власного
19
+ ACP JSON-RPC/`ClientSideConnection` тут; уся протокольна логіка (спавн
20
+ агента, `session/prompt`, автоапрув `session/request_permission`,
21
+ тір→env/args/post-session-config резолвінг) живе в Rust, разом з
22
+ watchdog-поведінкою на мертвий/незапущений дочірній процес.
18
23
 
19
- 1. `runAcpAgent` запускає один запит до ACP-агента з особистою підпискою для `cursor`, `codex` або `pi` у межах поточного робочого каталогу.
20
- 2. Якщо задано `tier`, передає цю абстракцію в нативний шар, щоб далі саме Rust визначив відповідні параметри сесії для вибраного агента.
21
- 3. Якщо `tier` не задано, використовує стандартну поведінку персонально залогіненого CLI без окремого вибору рівня.
22
- 4. Для виконання звертається до нативної реалізації в процесі, яка вже містить протокольну логіку, запуск сесії та обробку дозволів; цей файл не реалізує власний ACP-обмін і не працює з `claude`.
23
- 5. Повертає повний текст відповіді агента після завершення одного ходу.
24
+ `claude` тут немає Rust-крейт моделює лише `cursor`/`codex`/`pi`
25
+ (`AcpAgentKind`); deprecated `claude`-раннер лишається окремим
26
+ JS-шимом у `@7n/rules` (`npm/scripts/lib/acp-runner.mjs`).
24
27
 
25
28
  ## Публічний API
26
29
 
@@ -30,6 +33,10 @@ Rust сам резолвить tier→env/args/post-session-config з пресе
30
33
  (`one_shot_acp_with_tier`) — жодного JS-хелпера "пресет→env" тут немає.
31
34
  Без `tier` — стара поведінка (модель = персональний конфіг CLI на машині).
32
35
 
36
+ ## Сценарії використання
37
+
38
+ - `llm-lib/tests/acp.test.mjs` (runAcpAgent; getAcpPresets (smoke через реально збудований napi-аддон)) — делегує kind/prompt/cwd у native.oneShotAcp і віддає його результат; без опцій (старий виклик без 4-го аргументу) — tier не заданий; tier прокидається в native.oneShotAcp четвертим аргументом; kind
39
+
33
40
  ## Гарантії поведінки
34
41
 
35
42
  - Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
@@ -3,25 +3,29 @@ type: JS Module
3
3
  title: agent-fix.mjs
4
4
  resource: llm-lib/lib/agent-fix.mjs
5
5
  docgen:
6
- crc: 6a36d9a0
6
+ crc: 0babfe80
7
7
  model: openai-codex/gpt-5.4-mini
8
8
  tier: cloud-min
9
9
  score: 100
10
- issues: judge-refine:kept-original,judge:inaccurate:0.98
10
+ issues: judge-refine:kept-original,judge:inaccurate:0.99
11
11
  judgeModel: openai-codex/gpt-5.4-mini
12
12
  ---
13
13
 
14
14
  ## Огляд
15
15
 
16
- Модуль формує два промпти для локального виправлення порушення за правилом: `buildVerifyFeedbackPrompt` збирає запит на перевірку вже виявленого зворотного зв’язку, а `buildFixPrompt` — запит на виправлення з урахуванням обмеженого контексту й дозволених файлів. `runAgentFix` запускає цей цикл і повертає результат без пробросу помилок назовні: будь-які збої перехоплюються, щоб процес залишався fail-safe.
16
+ Файл керує автоматизованим виправленням порушень через `buildVerifyFeedbackPrompt`, `buildFixPrompt` і `runAgentFix`: він формує запит на перевірку, готує запит на виправлення та запускає агентне виправлення. Локальні fail-safe гілки дозволяють безпечно обробляти окремі збої, тоді як інші помилки можуть поширюватися назовні.
17
17
 
18
18
  ## Поведінка
19
19
 
20
- Спочатку формується fix-промпт із правилом, порушенням і доступним контекстом редагування; для generic-режиму він жорстко звужує простір змін до дозволених файлів, а для test-generation розділяє read-only джерела й тестові файли. Якщо попередня перевірка вже дала зворотний зв’язок, він додається в той самий промпт як додаткове обмеження. Далі виконується одна агентна спроба виправлення в межах рунга: результатом стає набір торкнутих файлів, телеметрія або помилка, а при падінні повертається rollback без винесення винятку назовні.
20
+ Потік починається з `runAgentFix`: вона збирає контекст правила, порушення, цільові файли, режим редагування та зовнішні залежності, будує fix-промпт і запускає одну рунґ-спробу з обмеженням часу. У цьому промпті одразу фіксуються межі допустимих змін: агент має працювати лише в межах дозволеного контексту й не підміняти перевірку семантичними «виправленнями» поза реальною правкою коду.
21
21
 
22
- Після внесення змін запускається verify-петля над тими самими торкнутими файлами. Вона повторює canonical verify у тій самій сесії, а при невдалому результаті передає точний вивід перевірки назад у verify-feedback prompt і продовжує, доки не буде ok, не вичерпається ліміт спроб або не закінчиться спільний таймаут рунга. Якщо сама перевірка падає інфраструктурно, це не маскується під звичайне порушення: петля зупиняється чесною помилкою. Зовнішній consumer лишається джерелом правди про остаточне re-detect, а тут використовується лише рання локальна корекція.
22
+ Після редагування `runAgentFix` передає керування verify-петлі. Та повторно перевіряє результат через canonical verify і, якщо помилки лишилися, формує для тієї ж сесії feedback через `buildVerifyFeedbackPrompt`. Далі цикл триває лише в межах того самого часового бюджету, доки не буде досягнуто успіху або вичерпано ліміт спроб. Якщо сама перевірка ламається як інфраструктурна подія, це не маскується під звичайне порушення.
23
23
 
24
- Увесь потік працює fail-safe: помилки не пробиваються назовні як винятки, а повертаються у результаті як error. Загальний стан між етапами це лише дані рунга: ruleId, violation, контекст правил, дозволені файли, feedback, verify-результати та список touchedFiles; жодного прихованого глобального стану в поведінкових гарантіях не використовується.
24
+ `buildVerifyFeedbackPrompt` і `buildFixPrompt` працюють як спільний шар керування поведінкою: перша підсилює наступну verify-ітерацію точним залишком порушень, друга задає початкові межі рунґа для правки. Обидві підтримують один і той самий semantic-collateral guard: зміни мають бути механічними та прив’язаними до дозволеного набору файлів, без підміни логіки правила.
25
+
26
+ Результат `runAgentFix` повертається як стан спроби з переліком зачеплених файлів, телеметрією, помилкою або успіхом, а також rollback для fail-шляхів. За межі потоку можуть пройтися локальні fail-safe гілки; решта помилок не ховається й може підніматися назовні.
27
+
28
+ Changelog: `npx @7n/rules lint changelog` — виконано успішно.
25
29
 
26
30
  ## Публічний API
27
31
 
@@ -37,6 +41,10 @@ addendum 2026-07-05): слабкі локальні моделі схильні
37
41
  verdict-veto consumer-а (re-check) відхиляє такі правки поза target-файлами.
38
42
  - runAgentFix — Проводить ОДНУ агентну fix-спробу (рунг) для правила.
39
43
 
44
+ ## Сценарії використання
45
+
46
+ - `llm-lib/tests/agent-fix.test.mjs` (buildFixPrompt; error-шляхи (без git/pi)) — містить правило, порушення, інструкцію ast_facts/self_check; feedback додається лише за наявності; блок обмежень: лише механічні зміни, без хардкоду/симуляції (semantic-collateral guard); anchoredEdits: інструкція read_anchored/edit_anchored лише при увімкненому профілі; targetFiles: перелік додається лише за наявності; ще 24
47
+
40
48
  ## Гарантії поведінки
41
49
 
42
- - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
50
+ - Містить локальні fail-safe гілки; інші помилки можуть поширюватися назовні.
@@ -3,31 +3,43 @@ type: JS Module
3
3
  title: agent-skill.mjs
4
4
  resource: llm-lib/lib/agent-skill.mjs
5
5
  docgen:
6
- crc: 085ebccf
7
- model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ crc: b7312bad
7
+ model: openai-codex/gpt-5.4-mini
8
+ tier: cloud-min
9
+ score: 100
10
+ issues: judge:error
11
+ judgeModel: openai-codex/gpt-5.4-mini
8
12
  ---
9
13
 
10
14
  ## Огляд
11
15
 
12
- Виконує один скіл `@nitra/cursor` як вбудованого pi-агента через публічну функцію `runAgentSkill`: подає готовий промпт у сесію, де агент сам **читає, редагує й створює файли та виконує shell-команди** (`bash`) у робочому каталозі. Це повний user-trust (паритет із ручним `claude -p`) — write-guard не накладається, бо скіл запускає користувач явно. Модель береться з однієї тири (`min`/`avg`/`max`, дефолт `max`). Будь-яка помилка перехоплюється (fail-safe) і повертається у результаті, а не кидається назовні.
16
+ Організовує один запуск skill і керує його виконанням у межах поточного контексту, щоб агент отримував потрібний стан для роботи. Має локальні fail-safe гілки для контрольованих збоїв; інші помилки можуть поширюватися назовні.
13
17
 
14
18
  ## Поведінка
15
19
 
16
- 1. Ініціалізація сесії агента: Визначає конфігурацію агента на основі вказаних параметрів, включаючи обраний рівень моделі, робочу директорію та рівень обчислення.
17
- 2. Виконання скілу: Запускає агентну сесію з поданим промптом.
18
- 3. Обробка відповідей: Під час виконання скілу, відповіді асистента виводяться у стандартний потік виводу.
19
- 4. Моніторинг: Відстежується кількість ітерацій та викликів інструментів.
20
- 5. Захист від нескінченності: Застосовується механізм обмеження кількості ітерацій (`TURN_CEILING`) та загального тайм-ауту для запобігання зависанню.
21
- 6. Обробка збоїв: У разі виникнення помилки під час ініціалізації, конфігурації або виконання, вона фіксується, а функція повертає стан невдачі.
22
- 7. Фіналізація: Після завершення виконання (успішно або через таймаут/переповнення ліміту) збирається телеметрія, яка включає статистику сесії, і результат повертається у вигляді об'єкта з інформацією про успішність.
20
+ 1. Приймає готовий prompt для одного skill-запуску та фіксує контекст виконання: skill, tier, modelSpec, cwd, timeout, maxTokens, caller і chain.
21
+ 2. Переходить у наступний крок chain, якщо ланцюжок передано, і готує кореляцію для подальшого обліку.
22
+ 3. Обирає модель через registry; якщо модель явно задана, але не знаходиться, завершує запуск без виконання skill.
23
+ 4. Створює pi-сесію з повним набором built-in tools, включно з bash, і прив’язує до неї поточний working directory та рівень thinking.
24
+ 5. Для локальних моделей додає chain-кореляцію; для інших моделей цього не робить.
25
+ 6. Запускає один skill-цикл і стрімить текст відповіді в stdout у міру надходження.
26
+ 7. Рахує turns і tool calls; якщо turns перевищують аварійну стелю, зупиняє виконання як runaway-backstop.
27
+ 8. Обмежує час виконання; при timeout перериває сесію.
28
+ 9. Якщо модель або registry недоступні, повертає fail-safe результат із помилкою без продовження прогону.
29
+ 10. Якщо під час prompt виникає memory-guard rejection для локального model-сервера, завершує як fail-fast і не маскує помилку.
30
+ 11. Після завершення формує telemetry з фактичним model, turns, tool calls, backstop-станом і тривалістю.
31
+ 12. Передає результат у chain і trace, а також зберігає capture для подальшого аналізу прогону.
32
+ 13. Повертає ознаку успіху, telemetry і текст помилки; успіх можливий лише коли немає помилки й не спрацював backstop.
23
33
 
24
34
  ## Публічний API
25
35
 
26
- runAgentSkill — Викликає певний агентський функціонал (скіл) через платформу pi з визначеними параметрами складності та обмеженнями виконання; опція `maxTokens` задає per-call стелю відповіді сесії (undefined → дефолт пакета, 0 → без стелі).
36
+ - runAgentSkill — Виконує ОДИН скіл агентно через pi.
37
+
38
+ ## Сценарії використання
39
+
40
+ - `llm-lib/tests/agent-skill.test.mjs` (runAgentSkill) — happy-path: ok, телеметрія, стрім тексту, trace kind:; createSession отримує тиру → thinkingLevel і cwd; maxTokens прокидається у createSession (0 = без стелі); з chain: step/note/chain-поля у trace; хмарна модель → chain:null у сесію; modelSpec порожній: telemetry.model — фактично резолвлена pi-модель, не echo spec; ще 5
27
41
 
28
42
  ## Гарантії поведінки
29
43
 
30
- - Повний user-trust: агент має read/edit/write/bash і мутує проєкт у робочому каталозі (без write-guard).
31
- - Runaway-backstop: перевищення стелі ітерацій (`N_CURSOR_SKILL_TURN_CEILING`) або таймауту (`N_CURSOR_SKILL_TIMEOUT_MS`) обриває сесію.
32
- - Перехоплює помилки і не пропускає винятків назовні (fail-safe); повертає `{ ok, telemetry, error }`.
33
- - Pi вантажиться lazy (тверда межа CI — модуль pi-free до першого виклику).
44
+ - Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
45
+ - Містить локальні fail-safe гілки; інші помилки можуть поширюватися назовні.
@@ -3,32 +3,40 @@ type: JS Module
3
3
  title: anchored-edit.mjs
4
4
  resource: llm-lib/lib/anchored-edit.mjs
5
5
  docgen:
6
- crc: 6ac40e43
6
+ crc: 7b38e0d2
7
+ model: openai-codex/gpt-5.5
8
+ tier: cloud-avg
9
+ score: 100
10
+ judgeModel: openai-codex/gpt-5.4-mini
7
11
  ---
8
12
 
9
13
  ## Огляд
10
14
 
11
- Строге hash-anchored редагування рядків (Фаза A2 run-harness): заміна built-in `read`/`edit` для fix-профілів. Кожен рядок файлу отримує 3-символьний base36-якір від sha256 вмісту; правка застосовується лише при точному збігу якоря з поточним станом рядка. Мета прибрати collateral слабких моделей (переписаний файл, літеральний `\n\n`): жодного fuzzy-match, мовчазного переміщення чи автокорекції. Референс патерну — pi-hashline-edit-pro (вендориться ідея, не пакет).
15
+ Файл описує роботу з текстом через рядки, привʼязані до номера та очікуваного вмісту. `lineAnchor` створює привʼязку для окремого рядка, `renderAnchored` подає файл у вигляді таких привʼязаних рядків, `applyAnchoredEdits` застосовує правки лише після звірки очікуваного стану, а `createAnchoredTools` надає цей сценарій як набір інструментів.
16
+
17
+ Це потрібно, щоб правки вносилися в конкретні місця файлу й не застосовувалися, коли цільовий рядок більше не відповідає очікуваному вмісту.
12
18
 
13
19
  ## Поведінка
14
20
 
15
- Рендер (`renderAnchored`) віддає рядки у форматі `якір|номер|текст` (нумерація з 1, опційний діапазон включно). Застосування (`applyAnchoredEdits`) атомарне на файл: усі правки спершу валідуються (існування рядка, збіг якоря, відсутність дублю номера) — хоч одна розбіжність означає повну відмову з переліком `stale`-причин, файл не змінюється. Валідні правки застосовуються знизу вгору, тож номери рядків у пакеті правок не зсуваються; `newText` заміняє рядок (може бути багаторядковим), `null` — видаляє.
21
+ `lineAnchor` задає правило привʼязки рядків до їхнього вмісту. `renderAnchored` використовує це правило, щоб перетворити поточний текст файла на рядки з якорем, номером і вмістом; такий результат призначений для подальшого формування точкових правок.
22
+
23
+ `applyAnchoredEdits` приймає правки, підготовлені на основі anchored-подання, і перед зміною тексту повторно звіряє номери рядків та якорі з актуальним вмістом. Якщо хоча б одна правка більше не відповідає файлу або список правок неоднозначний, зміни не застосовуються взагалі. Це зберігає атомарність і дозволяє явно повідомити про stale-стан замість часткового редагування.
16
24
 
17
- Tool-фабрика (`createAnchoredTools`) створює пару pi-tools: `read_anchored` (файл або діапазон в anchored-форматі; неіснуючий файл структурована помилка) і `edit_anchored` (правки `{anchor, line, newText}`; stale JSON-відмова з інструкцією перечитати файл; для нових файлів чесно відсилає до `write`). `defineTool` передається caller-ом — модуль лишається pi-free; fs-операції інжектовані для тестів.
25
+ `createAnchoredTools` з’єднує цей потік із pi-tools: читання файла повертає anchored-подання через `renderAnchored`, а редагування пропускає запропоновані зміни через `applyAnchoredEdits` і лише після успішної перевірки записує новий вміст. Результати повертаються як текстові відповіді tool-викликів, включно з причинами відмови для наступної спроби.
18
26
 
19
27
  ## Публічний API
20
28
 
21
- lineAnchor — 3-символьний base36-якір від sha256 вмісту рядка (детермінований, чутливий до будь-якої зміни тексту).
22
- renderAnchored — anchored-подання вмісту файлу для читання агентом.
23
- applyAnchoredEdits — атомарне застосування пакету правок або структурована відмова `{ok:false, stale:[…]}`.
24
- createAnchoredTools — фабрика tool-дефініцій `read_anchored`/`edit_anchored` для customTools pi-сесії.
29
+ - lineAnchor — Якір рядка на основі вмісту рядка.
30
+ - renderAnchored — Рендерить вміст файлу у anchored-форматі: `якір|номер|текст`, нумерація з 1.
31
+ - applyAnchoredEdits — Атомарно застосовує anchored-правки до вмісту файлу.
32
+
33
+ Валідація перед застосуванням: кожна правка перевіряється на існування рядка та збіг якоря з поточним вмістом. Якщо хоча б одна правка stale, нічого не застосовується. Заміна рядка може містити кілька рядків; видалення рядка також підтримується. Дублікати номера рядка у списку правок — теж відмова через двозначність.
34
+ - createAnchoredTools — Фабрика пари pi-tools `read_anchored`/`edit_anchored`.
25
35
 
26
- ## Де використовується
36
+ `defineTool` передається caller-ом. Обидва tools повертають результат текстом, щоб відповідь містила причину відмови і підказку для наступного кроку.
27
37
 
28
- `agent-fix.mjs`: `opts.anchoredEdits` перемикає toolset сесії (built-in `read`/`edit` прибираються, `write` лишається для нових файлів). `edit_anchored` внесений у WRITE_TOOLS write-guard — той самий scope/denylist veto, pre-image snapshot і rollback, що й у built-in write-tools. Opt-in у cursor: env `N_LLM_FIX_ANCHORED` (default-worker).
38
+ ## Сценарії використання
29
39
 
30
40
  ## Гарантії поведінки
31
41
 
32
- - Атомарність на файл: часткове застосування пакету правок неможливе.
33
- - Якір прив'язаний лише до вмісту рядка; номер рядка звіряється окремо — розбіжність будь-якого з двох дає відмову.
34
- - Чисті функції не торкаються диска; запис робить лише `edit_anchored` (під write-guard).
42
+ - (специфічних машинно-виведених гарантій немає)
package/lib/docs/batch.md CHANGED
@@ -3,25 +3,25 @@ type: JS Module
3
3
  title: batch.mjs
4
4
  resource: llm-lib/lib/batch.mjs
5
5
  docgen:
6
- crc: 4412e8c2
7
- model: openai-codex/gpt-5.4-mini
8
- tier: cloud-min
9
- score: 100
6
+ crc: 10b603cc
7
+ model: openai-codex/gpt-5.5
8
+ tier: cloud-avg
9
+ score: 80
10
10
  judgeModel: openai-codex/gpt-5.4-mini
11
11
  ---
12
12
 
13
13
  ## Огляд
14
14
 
15
- Тонкий JS-клієнт до `llm_lib::batch` у `llm-lib/crates/llm-lib-napi`, який через in-process `napi FFI` лише емулює Type 2b у v1: під одним `submit → progress → results` інтерфейсом він прокидає batch-запит у `llm_lib::local_cloud` і повертає результат як сумісний OpenAI Batch API-контракт для майбутнього `/v1/batches`. Єдина публічна точка входу `submitBatch`. Це узагальнення анти-прикладу на кшталт `mlmail/use-summary.js`, де чанкінг доводиться робити вручну під обмеження провайдера.
15
+ Тип 2b (OpenAI-сумісний API, batch)**лише емуляція** у v1 (рішення Р,
16
+ задача T6): чанкований конкурентний прогін через Тип 2a
17
+ (`llm_lib::local_cloud`) під інтерфейсом `submit → progress → results` —
18
+ той самий інтерфейс, яким говорив би й справжній OpenAI Batch API
19
+ (`/v1/batches`, v2), якому локальний omlx (перший споживач) не має.
16
20
 
17
- ## Поведінка
18
-
19
- 1. `submitBatch` приймає batch-запит для Type 2b і передає його в native-реалізацію, щоб отримати той самий бізнес-інтерфейс `submit → progress → results`, який очікується від batch-потоку поверх локальних провайдерів.
20
- 2. `submitBatch` зберігає порядок вхідних items у результатах, щоб кожен результат можна було зіставити з початковим `customId`.
21
- 3. `submitBatch` нормалізує вхідні items перед передачею далі: бере `customId` і `prompt` як є, а відсутній `system` не підміняє значенням.
22
- 4. `submitBatch` передає конфіг локальних провайдерів, загальний `system`, а також ліміти chunking і concurrency у native-шар, щоб контроль виконання залишався в реалізації batch-крейта.
23
- 5. `submitBatch` підтримує `onProgress`, щоб викликати повідомлення про хід виконання під час обробки batch-у.
24
- 6. `submitBatch` дозволяє підмінити native-реалізацію для тестів, не змінюючи зовнішню поведінку публічного API.
21
+ Тонкий JS-клієнт до Rust-крейта `llm_lib::batch` через napi FFI
22
+ in-process (`llm-lib/crates/llm-lib-napi`) — жодного власного чанкінгу
23
+ тут (анти-приклад, якого це узагальнює: `mlmail/use-summary.js` чанкує
24
+ переклади проти omlx вручну, з вистражданими лімітами).
25
25
 
26
26
  ## Публічний API
27
27
 
@@ -29,6 +29,10 @@ docgen:
29
29
  що й у [`oneShotLocalCloud`] з `local-cloud.mjs`: явний
30
30
  `"provider/model-id"` або абстрактний тир (`min`/`avg`/`max`).
31
31
 
32
+ ## Сценарії використання
33
+
34
+ - `llm-lib/tests/batch.test.mjs` (submitBatch) — делегує modelSpecOrTier/items у native.submitBatch і віддає його результат; явний; кожен item нормалізується до {customId, prompt, system}, навіть без власного system; localProviders/system/chunkSize/concurrency прокидаються в options/config; onProgress прокидається останнім аргументом; ще 2
35
+
32
36
  ## Гарантії поведінки
33
37
 
34
38
  - Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
@@ -3,25 +3,43 @@ type: JS Module
3
3
  title: body-capture.mjs
4
4
  resource: llm-lib/lib/body-capture.mjs
5
5
  docgen:
6
- crc: 3e3be25e
6
+ crc: f4c5b984
7
+ model: openai-codex/gpt-5.5
8
+ tier: cloud-avg
9
+ score: 100
10
+ issues: judge:error
11
+ judgeModel: openai-codex/gpt-5.4-mini
7
12
  ---
8
13
 
9
14
  ## Огляд
10
15
 
11
- Захоплення повних тіл LLM-викликів (prompt+response) заміна колишнього requests.jsonl myllm-проксі, з перевагою: працює і для CLOUD-викликів (проксі бачив лише local), і не залежить від запущеного myllm. Увімкнено за замовчуванням — вимикається N_LLM_TRACE_BODIES=0. Не pi-coupled — публічний модуль пакета.
16
+ Файл керує локальним захопленням тіл LLM-викликів, щоб трасування могло посилатися на окремий артефакт із повним вмістом взаємодії.
17
+
18
+ `bodiesDir` визначає місце для таких артефактів, `bodyCaptureEnabled` вирішує, чи дозволене захоплення, а `captureBody` зберігає тіло виклику для подальшого аналізу.
19
+
20
+ Окремі локальні fail-safe гілки повертають порожнє значення замість винятку, коли захоплення неможливе або недоречне. Інші помилки можуть поширюватися назовні.
12
21
 
13
22
  ## Поведінка
14
23
 
15
- captureBody пише JSON-файл у ~/.n-cursor/llm-bodies/<chainId або caller>/<step>.json (ts, caller, chainId, chainStep, model, promptHash, prompt, output, usage, error); best-effort, ніколи не кидає; no-op (повертає null) коли body-capture вимкнено. При записі перевіряє сумарний розмір стору і видаляє найстаріші файли понад N_LLM_BODIES_MAX_MB (дефолт 500).
24
+ `captureBody` є точкою запису: спершу звіряє дозвіл через `bodyCaptureEnabled`, потім визначає корінь сховища через `bodiesDir` або переданий override, групує запис за ланцюжком чи викликачем і зберігає повне тіло LLM-виклику у JSON-файл.
25
+
26
+ Дані приходять із раннера LLM-виклику: фактичний prompt, відповідь або помилка, модель, usage та ідентифікатори трасування. Результат іде у файлове сховище, а назовні повертається шлях до створеного файлу або `null`, якщо захоплення вимкнене чи запис не вдався.
27
+
28
+ Захоплення увімкнене за замовчуванням і вимикається лише явним значенням `N_LLM_TRACE_BODIES=0`. Корінь сховища береться із `N_LLM_BODIES_DIR`, а без нього — з користувацької директорії під `.n-cursor/llm-bodies`.
29
+
30
+ Після успішного запису `captureBody` підтримує ліміт сховища: коли сумарний обсяг перевищує налаштований бюджет, найстаріші файли видаляються best-effort. Помилки запису, створення директорій або очищення не мають ламати LLM-виклик; у таких випадках модуль відмовляється від захоплення і повертає порожній результат.
16
31
 
17
32
  ## Публічний API
18
33
 
19
- bodiesDir()корінь стору (env N_LLM_BODIES_DIR).
20
- bodyCaptureEnabled()чи увімкнено (N_LLM_TRACE_BODIES!=='0').
21
- captureBody(record, opts?) шлях збереженого файлу або null.
34
+ - bodiesDir — Корінь стору (env-override `N_LLM_BODIES_DIR`).
35
+ - bodyCaptureEnabled — Чи body-capture увімкнено (дефолт увімкнено — вимикають свідомо `N_LLM_TRACE_BODIES=0`).
36
+ - captureBody — Захоплює одне тіло LLM-виклику (no-op, якщо `N_LLM_TRACE_BODIES` не `'1'`).
37
+
38
+ ## Сценарії використання
39
+
40
+ - `llm-lib/tests/body-capture.test.mjs` (bodyCaptureEnabled/bodiesDir; captureBody) — увімкнено за замовчуванням; N_LLM_TRACE_BODIES=0 вимикає; bodiesDir — env-override; no-op (null) коли вимкнено; пише JSON-файл під chainId, повне поле prompt/output/usage/error; ще 5
22
41
 
23
42
  ## Гарантії поведінки
24
43
 
25
- - Best-effort: жодна файлова помилка не валить виклик LLM.
26
- - Ретеншн: сумарний розмір стору не росте необмежено (авто-очистка найстаріших файлів).
27
- - Компоненти шляху (chainId/caller/step) санітизуються — без directory traversal.
44
+ - Містить локальні fail-safe гілки; інші помилки можуть поширюватися назовні.
45
+ - Деякі локальні fail-safe гілки повертають порожнє значення (напр. `null`) замість винятку.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@7n/llm-lib",
3
- "version": "2.10.1",
3
+ "version": "2.12.0",
4
4
  "description": "Тонкий шар роботи з LLM (локальні omlx + хмарні провайдери) поверх pi: model tiers, one-shot, agentic-раннери, write-guard, trace, telemetry, prompt-budget",
5
5
  "keywords": [
6
6
  "nitra",