@jaypie/mcp 0.8.181 → 0.8.182

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/dist/assets.js CHANGED
@@ -55,11 +55,11 @@ function getMcpAssetPaths() {
55
55
  */
56
56
  function getMcpBuildInfo() {
57
57
  return {
58
- commit: "9b837db4"
58
+ commit: "91eb8a17"
59
59
  ,
60
- version: "0.8.181"
60
+ version: "0.8.182"
61
61
  ,
62
- versionString: "@jaypie/mcp@0.8.181#9b837db4"
62
+ versionString: "@jaypie/mcp@0.8.182#91eb8a17"
63
63
  ,
64
64
  };
65
65
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaypie/mcp",
3
- "version": "0.8.181",
3
+ "version": "0.8.182",
4
4
  "description": "Jaypie MCP",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,9 @@
1
+ ---
2
+ version: 1.2.117
3
+ date: 2026-10-05
4
+ summary: Pulls @jaypie/llm 1.3.58
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - **`@jaypie/llm` 1.3.58**: a `format` request answered with no content fails over instead of resolving with `content: undefined`, and throws `LlmIncompleteError` when every model comes back empty; Gemini block reasons and `OTHER` finishes count as incomplete.
@@ -0,0 +1,28 @@
1
+ ---
2
+ version: 1.3.58
3
+ date: 2026-10-05
4
+ summary: A format request answered with no content fails over instead of resolving with undefined content, and throws LlmIncompleteError when every model comes back empty
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ ### Empty structured output (issue #608)
10
+
11
+ `operate` with `format` resolved successfully when the provider returned no content (observed: Gemini, 0 output tokens, `fallbackUsed: false`, no warning). The caller received `content: undefined`.
12
+
13
+ - Empty content (`undefined`, `null`, or whitespace) on a `format` request settles `status: "incomplete"` with `error.reason: "incomplete"`, `error.detail` `Model returned no content: <stop reason>`, and `stopReason: "other"`. It logs at `warn` with the provider's stop reason.
14
+ - Adapters with a corrective turn (Fireworks, Google) try it once before settling empty. Salvage and fresh-context conversion are skipped: there is no text to read.
15
+ - A fallback chain moves past an empty response like any cut-off. An earlier partial is kept over a later empty response.
16
+ - When only empty responses come back, `operate` throws `LlmIncompleteError` (status 502) whatever `incomplete` says: there is no partial to return.
17
+ - Requests without `format` are unchanged.
18
+
19
+ ### Gemini stop reasons
20
+
21
+ - A blocked prompt returns no candidate; `promptFeedback.blockReason` is now reported as the stop reason, so it fails over and names its cause.
22
+ - `OTHER`, `LANGUAGE`, `IMAGE_SAFETY`, and `MALFORMED_FUNCTION_CALL` are incomplete finishes. `IMAGE_SAFETY` normalizes to `content_filter`.
23
+
24
+ ## Testing
25
+
26
+ - `OperateLoop` specs cover empty and whitespace content with `format`, the corrective turn on empty content, settling empty once turns run out, no conversion of empty content, and unchanged behavior without `format`.
27
+ - `Llm` class specs cover failover on empty content, throwing for a lone model and a whole chain, and a partial kept over a later empty response.
28
+ - `runWithFallback`, `GoogleAdapter`, and `incompleteReason` specs cover `isEmptyResult`, the block reason, and the new Gemini finishes.
@@ -0,0 +1,10 @@
1
+ ---
2
+ version: 0.8.182
3
+ date: 2026-10-05
4
+ summary: Release notes for @jaypie/llm 1.3.58 and jaypie 1.2.117; llm skill documents empty format responses
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - **Release notes**: `@jaypie/llm` 1.3.58 and `jaypie` 1.2.117
10
+ - **`llm` skill**: documents how an empty `format` response fails over and throws
package/skills/llm.md CHANGED
@@ -857,6 +857,8 @@ try {
857
857
 
858
858
  An incomplete `content` is the raw partial text, a string even when `format` was requested: a truncated answer is not the object the format promises. Check `status` (or use `incomplete: "throw"`) before reading `content` as the formatted object.
859
859
 
860
+ A `format` request answered with **no content** (zero output tokens, an empty candidate, a blocked prompt) settles incomplete with `error.detail` `Model returned no content: <stop reason>`, logged at `warn`, and `stopReason: "other"`. An adapter that supports the corrective turn tries it once first. A chain moves past an empty response like any cut-off, and an earlier partial is kept over a later empty one. When nothing but empty responses come back, `operate` throws `LlmIncompleteError` whatever `incomplete` says: there is no partial to return (issue #608).
861
+
860
862
  ### Provider Options in a Chain
861
863
 
862
864
  `providerOptions` belongs to the model it was written for. Per-call `providerOptions` reach the primary only (including its linger pass); a fallback receives only the `providerOptions` on its own entry, or none. Options shaped for one provider (OpenAI `reasoning`, Gemini `thinkingConfig`) would otherwise break every other provider in the chain. Prefer first-class `effort` and `temperature`, which translate per provider.
@@ -1068,7 +1070,7 @@ exactly like a provider rate limit.
1068
1070
  | ------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1069
1071
  | `max_turns` | 429 | The model asked for another tool call after `turns` ran out. Nothing failed; the run did not converge. |
1070
1072
  | `tool_errors` | 502 | Tool execution failed six times in a row and the loop stopped. |
1071
- | `incomplete` | 502 | The provider cut the model off before it finished (an output token ceiling, a content filter). `content` holds the partial text; `error.detail` names the provider's reason and `stopReason` normalizes it. A fallback chain moves past it. |
1073
+ | `incomplete` | 502 | The provider cut the model off before it finished (an output token ceiling, a content filter). `content` holds the partial text; `error.detail` names the provider's reason and `stopReason` normalizes it. A fallback chain moves past it. With `format`, empty content settles here too and throws once the chain is spent. |
1072
1074
 
1073
1075
  ```typescript
1074
1076
  import { LlmResponseErrorReason } from "@jaypie/llm";