@7n/llm-lib 3.0.2 → 3.1.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,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.1.0] - 2026-08-08
4
+
5
+ ### Fixed
6
+
7
+ - runOneShot тепер конвертує stopReason='error' (pi проковтнула провал провайдера без винятку, напр. вичерпані внутрішні connection-retry) у справжній error з errorMessage провайдера — раніше consumers бачили error:null при порожньому content, невідрізниме від легітимної порожньої відповіді, і тихо продовжували, вважаючи виклик успішним
8
+
9
+ ## [3.0.3] - 2026-08-08
10
+
11
+ ### Changed
12
+
13
+ - chore(release): синк пінів платформних napi-пакетів @7n/llm-lib
14
+
3
15
  ## [3.0.2] - 2026-08-07
4
16
 
5
17
  ### Changed
package/lib/one-shot.mjs CHANGED
@@ -77,7 +77,10 @@ async function defaultCreateSession({ registry, model, cwd, thinkingLevel, maxTo
77
77
  * }} args параметри; `maxTokens` — per-call стеля відповіді (undefined → дефолт пакета, 0 → без стелі);
78
78
  * `chain` — handle зі startChain: виклик стає кроком ланцюжка (chain-поля у trace, X-Chain-* заголовки локальним моделям)
79
79
  * @returns {Promise<{ content: string, usage: object|null, error: string|null, model: string|null, stopReason: string|null, caller: string }>} результат;
80
- * `stopReason` — фініш останнього assistant-повідомлення (`'length'` = відповідь обрізана стелею; політика повтору — за колером)
80
+ * `stopReason` — фініш останнього assistant-повідомлення (`'length'` = відповідь обрізана стелею; політика повтору — за колером);
81
+ * `stopReason === 'error'` завжди дає непорожній `error` (з `errorMessage` провайдера чи дефолтним текстом) —
82
+ * pi не завжди кидає виняток при провалі провайдера (вичерпані внутрішні retry), тож без цього `error: null`
83
+ * при порожньому `content` виглядало б так само, як легітимна порожня відповідь
81
84
  */
82
85
  export async function runOneShot({
83
86
  messages,
@@ -142,12 +145,14 @@ export async function runOneShot({
142
145
  let text = ''
143
146
  let usage = null
144
147
  let stopReason = null
148
+ let providerErrorMessage = null
145
149
  session.subscribe(event => {
146
150
  if (event.type === 'message_update' && event.assistantMessageEvent?.type === 'text_delta') {
147
151
  text += event.assistantMessageEvent.delta ?? ''
148
152
  } else if (event.type === 'message_end' && event.message) {
149
153
  if (event.message.usage) usage = event.message.usage
150
154
  stopReason = event.message.stopReason ?? null
155
+ if (event.message.errorMessage) providerErrorMessage = event.message.errorMessage
151
156
  }
152
157
  })
153
158
 
@@ -159,6 +164,18 @@ export async function runOneShot({
159
164
  failOnMemoryGuard(promptError, userText)
160
165
  }
161
166
 
167
+ // pi не завжди кидає при провалі провайдера (напр. вичерпані внутрішні
168
+ // retry на connection-error): `session.prompt()` резолвиться штатно, а
169
+ // єдиний слід — `stopReason: 'error'` на `message_end` (задокументований
170
+ // третій стан поруч із `stop`/`length`/`toolUse`/`aborted`, з `errorMessage`
171
+ // поряд — `docs/custom-provider.md` пакета pi-coding-agent). Без цього
172
+ // consumers (docgen callLlm: `if (res.error) throw ...`) бачать
173
+ // `error: null, content: ''` — не відрізнити від легітимної порожньої
174
+ // відповіді, і тихо продовжують, вважаючи виклик успішним.
175
+ if (!promptError && stopReason === 'error') {
176
+ promptError = providerErrorMessage ?? 'pi: stopReason=error (без деталей від провайдера)'
177
+ }
178
+
162
179
  // spec порожній/нерозв'язаний ('' → pi сам вибирає дефолт) — беремо фактично
163
180
  // резолвлену pi-модель із сесії, щоб chain.note()/trace не бачили порожній
164
181
  // model і не потрапляли в неявний cloud-бакет (isLocalModel('') === false).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@7n/llm-lib",
3
- "version": "3.0.2",
3
+ "version": "3.1.0",
4
4
  "description": "Тонкий шар роботи з LLM (локальні omlx + хмарні провайдери) поверх pi: model tiers, one-shot, agentic-раннери, write-guard, trace, telemetry, prompt-budget",
5
5
  "keywords": [
6
6
  "nitra",
@@ -56,8 +56,8 @@
56
56
  "access": "public"
57
57
  },
58
58
  "optionalDependencies": {
59
- "@7n/llm-lib-darwin-arm64": "3.0.2",
60
- "@7n/llm-lib-linux-x64": "3.0.2"
59
+ "@7n/llm-lib-darwin-arm64": "3.0.3",
60
+ "@7n/llm-lib-linux-x64": "3.0.3"
61
61
  },
62
62
  "peerDependencies": {
63
63
  "@earendil-works/pi-ai": "~0.80.10",