@oh-my-pi/pi-ai 16.1.19 → 16.1.20

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
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [16.1.20] - 2026-06-25
6
+
7
+ ### Fixed
8
+
9
+ - Fixed Ollama/Ollama Cloud native chat responses that finish with `done_reason: "length"` and no assistant content surfacing as a normal empty stop; they now become a context-window error instead of entering empty-stop retry recovery. ([#3464](https://github.com/can1357/oh-my-pi/issues/3464))
10
+ - Fixed direct Anthropic Claude Sonnet/Haiku 4.5 requests serializing `output_config.effort`. The catalog classification (`packages/catalog/src/model-thinking.ts`) drove the `anthropic-budget-effort` branch in `buildParams`, which Anthropic's first-party Messages API rejects on Sonnet/Haiku 4.5 with HTTP 400 `This model does not support the effort parameter.` Sonnet/Haiku 4.5 now use plain `thinking.budget_tokens`; Opus 4.5 still emits `output_config.effort` because Anthropic supports it there. ([#3497](https://github.com/can1357/oh-my-pi/issues/3497))
11
+
5
12
  ## [16.1.19] - 2026-06-25
6
13
 
7
14
  ### Fixed
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-ai",
4
- "version": "16.1.19",
4
+ "version": "16.1.20",
5
5
  "description": "Unified LLM API with automatic model discovery and provider configuration",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
@@ -38,9 +38,9 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@bufbuild/protobuf": "^2.12.0",
41
- "@oh-my-pi/pi-catalog": "16.1.19",
42
- "@oh-my-pi/pi-utils": "16.1.19",
43
- "@oh-my-pi/pi-wire": "16.1.19",
41
+ "@oh-my-pi/pi-catalog": "16.1.20",
42
+ "@oh-my-pi/pi-utils": "16.1.20",
43
+ "@oh-my-pi/pi-wire": "16.1.20",
44
44
  "arktype": "^2.2.0",
45
45
  "zod": "^4"
46
46
  },
@@ -437,6 +437,17 @@ function mapDoneReason(doneReason: string | undefined, output: AssistantMessage)
437
437
  return "stop";
438
438
  }
439
439
 
440
+ const EMPTY_OLLAMA_LENGTH_COMPLETION_MESSAGE =
441
+ "Model returned no content: prompt filled the context window; raise Ollama num_ctx or shorten the prompt.";
442
+
443
+ function hasVisibleAssistantContent(output: AssistantMessage): boolean {
444
+ return output.content.some(block => {
445
+ if (block.type === "text") return block.text.trim().length > 0;
446
+ if (block.type === "thinking") return block.thinking.trim().length > 0;
447
+ return block.type === "toolCall";
448
+ });
449
+ }
450
+
440
451
  const OLLAMA_RETRY_DELAYS_MS = [2_000, 5_000, 10_000];
441
452
 
442
453
  export const streamOllama: StreamFunction<"ollama-chat"> = (
@@ -702,6 +713,10 @@ export const streamOllama: StreamFunction<"ollama-chat"> = (
702
713
  }
703
714
  endActiveThinkingBlock();
704
715
  endActiveTextBlock();
716
+ if (output.stopReason === "length" && !hasVisibleAssistantContent(output)) {
717
+ output.stopReason = "error";
718
+ output.errorMessage = EMPTY_OLLAMA_LENGTH_COMPLETION_MESSAGE;
719
+ }
705
720
  // Tool calls always mean "execute and continue" in the OpenAI/Ollama contract.
706
721
  // If the turn produced tool-call blocks but reported a natural `stop`, promote
707
722
  // to `toolUse` so the agent loop runs them (it gates execution on the stop
@@ -713,6 +728,11 @@ export const streamOllama: StreamFunction<"ollama-chat"> = (
713
728
  if (firstTokenTime) {
714
729
  output.ttft = firstTokenTime - startTime;
715
730
  }
731
+ if (output.stopReason === "error") {
732
+ stream.push({ type: "error", reason: "error", error: output });
733
+ stream.end();
734
+ return;
735
+ }
716
736
  const doneReason =
717
737
  output.stopReason === "length" ? "length" : output.stopReason === "toolUse" ? "toolUse" : "stop";
718
738
  stream.push({ type: "done", reason: doneReason, message: output });