@oh-my-pi/pi-ai 15.11.8 → 15.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 +6 -0
- package/package.json +3 -3
- package/src/providers/anthropic.ts +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [15.12.0] - 2026-06-12
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Fixed Anthropic requests bypassing lone-surrogate sanitization after payload hooks or Anthropic-origin tool-call replay: the model itself can emit unpaired surrogate escapes in its own tool-argument JSON (streamed out fine, then rejected with `400 The request body is not valid JSON` on every subsequent request, bricking the session). The final Anthropic payload is now deep-sanitized with `toWellFormed()` immediately before SDK serialization; the pass is identity-preserving, so well-formed arguments stay byte-identical and prompt-cache prefixes are unaffected.
|
|
10
|
+
|
|
5
11
|
## [15.11.8] - 2026-06-12
|
|
6
12
|
|
|
7
13
|
### Breaking Changes
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-ai",
|
|
4
|
-
"version": "15.
|
|
4
|
+
"version": "15.12.0",
|
|
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,8 +38,8 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@bufbuild/protobuf": "^2.12.0",
|
|
41
|
-
"@oh-my-pi/pi-catalog": "15.
|
|
42
|
-
"@oh-my-pi/pi-utils": "15.
|
|
41
|
+
"@oh-my-pi/pi-catalog": "15.12.0",
|
|
42
|
+
"@oh-my-pi/pi-utils": "15.12.0",
|
|
43
43
|
"openai": "^6.39.0",
|
|
44
44
|
"partial-json": "^0.1.7",
|
|
45
45
|
"zod": "4.4.3"
|
|
@@ -1639,6 +1639,7 @@ export const streamAnthropic: StreamFunction<"anthropic-messages"> = (
|
|
|
1639
1639
|
if (replacementPayload !== undefined) {
|
|
1640
1640
|
nextParams = replacementPayload as typeof nextParams;
|
|
1641
1641
|
}
|
|
1642
|
+
nextParams = toWellFormedDeep(nextParams) as typeof nextParams;
|
|
1642
1643
|
rawRequestDump = {
|
|
1643
1644
|
provider: model.provider,
|
|
1644
1645
|
api: output.api,
|
|
@@ -3075,13 +3076,12 @@ export function convertAnthropicMessages(
|
|
|
3075
3076
|
type: "tool_use",
|
|
3076
3077
|
id: block.id,
|
|
3077
3078
|
name: isOAuthToken ? applyClaudeToolPrefix(block.name) : block.name,
|
|
3078
|
-
//
|
|
3079
|
-
//
|
|
3080
|
-
//
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
: toWellFormedDeep(block.arguments ?? {}),
|
|
3079
|
+
// Always sanitize: the model itself can emit lone-surrogate escapes
|
|
3080
|
+
// in tool-argument JSON (streamed out fine, rejected with a 400 on
|
|
3081
|
+
// replay by Anthropic's strict UTF-8 validation). toWellFormedDeep
|
|
3082
|
+
// is identity-preserving, so well-formed arguments stay
|
|
3083
|
+
// byte-identical and prompt-cache prefixes are unaffected.
|
|
3084
|
+
input: toWellFormedDeep(block.arguments ?? {}),
|
|
3085
3085
|
});
|
|
3086
3086
|
}
|
|
3087
3087
|
}
|