@oh-my-pi/pi-ai 18.2.10 → 18.2.11
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 +5 -15
- package/package.json +6 -6
- package/src/usage/alibaba-token-plan.ts +14 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.2.11] - 2026-09-23
|
|
6
|
+
|
|
5
7
|
### Fixed
|
|
6
8
|
|
|
7
|
-
- Fixed Claude Opus 5.5
|
|
9
|
+
- Fixed Claude Opus 5.5 not applying a mid-session switch to high-effort reasoning when the session started without an explicit effort setting.
|
|
10
|
+
- Fixed Alibaba Token Plan monthly quotas not appearing in usage reports or the status line.
|
|
8
11
|
|
|
9
12
|
## [18.2.9] - 2026-09-22
|
|
10
13
|
|
|
@@ -2278,17 +2281,4 @@
|
|
|
2278
2281
|
- Preserved Anthropic `stop_details` on assistant messages so refusal and sensitive classifier stops remain structurally visible to callers. ([#2290](https://github.com/can1357/oh-my-pi/issues/2290))
|
|
2279
2282
|
- Fixed OpenAI Responses, Azure OpenAI Responses, and OpenAI Completions streams hanging until the 120s idle watchdog errored the turn when a provider delivers the terminal frame but never sends `[DONE]` nor closes the connection. `processResponsesStream` now breaks out of the event loop on `response.completed`/`response.incomplete` (mirroring the Codex websocket/SSE terminal break), and the completions consumer breaks once `finish_reason` plus a usage payload arrived — or, for hosts that never send usage, ends the stream cleanly via a short post-finish grace window (`iterateWithTerminalGrace`) that aborts the transport to release the socket.
|
|
2280
2283
|
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
### Added
|
|
2284
|
-
|
|
2285
|
-
- Added optional `ImageContent.detail` (`"auto" | "low" | "high" | "original"`): an OpenAI resolution hint forwarded by the `openai-responses` serializers (default stays `auto`) and by `openai-completions` for the values Chat Completions supports. `"original"` preserves native resolution — required for snapcompact frames, whose pixel-font glyphs do not survive the default downscale. Providers without a detail knob ignore the field.
|
|
2286
|
-
|
|
2287
|
-
### Fixed
|
|
2288
|
-
|
|
2289
|
-
- Fixed OpenRouter DeepSeek V4 strict tool schemas nesting `anyOf` inside the nullable wrapper for optional unions, which produced a branch without `type` and triggered OpenRouter's `Invalid tool parameters schema : field anyOf: missing field type` 400. ([#2270](https://github.com/can1357/oh-my-pi/issues/2270))
|
|
2290
|
-
- Hardened strict tool-schema handling beyond the optional-union case: `enforceStrictSchema` now splices natively nested pure unions into the parent `anyOf` (only when the inner node carries no constraining siblings, since sibling keywords are conjunctive with `anyOf`), so source schemas with nested unions no longer produce type-less `anyOf` branches that strict upstream validators reject. ([#2270](https://github.com/can1357/oh-my-pi/issues/2270))
|
|
2291
|
-
- Made the openai-completions non-strict retry reachable for `"mixed"` strict mode (previously gated to `all_strict`, i.e. Cerebras only) and taught it to recognize upstream tool-schema validation 400s (`Invalid tool parameters schema …`, `Invalid schema for function …`). A matching rejection now retries the request with base (non-strict) schemas and persists `strictToolsDisabled` on the provider session, so later requests skip the doomed strict attempt instead of paying a 400 + retry round-trip each turn. ([#2270](https://github.com/can1357/oh-my-pi/issues/2270))
|
|
2292
|
-
- Cross-model `anthropic-messages → anthropic-messages` continuations now preserve prior assistant turns' reasoning chains end-to-end: every prior `thinking`/`redactedThinking` block survives (not just the latest surviving assistant), and third-party ↔ third-party replays keep their signatures intact so the reasoning chain stays signed for the next turn. Signatures are stripped (and any `redacted_thinking` sibling without a native landing spot is dropped) only when an official Anthropic endpoint is on either end of the replay — official Anthropic cryptographically binds reasoning signatures to its key+session+model, while compatible reasoning endpoints (Z.AI, DeepSeek, custom anthropic-messages providers configured via `models.yaml`) treat them as opaque continuation hints. Source-side official detection uses the canonical catalog provider id `"anthropic"` (assistant messages carry no `baseUrl`); target-side detection reuses the baked `compat.officialEndpoint` flag. Latest-turn byte-for-byte behavior (Anthropic's "thinking blocks in the latest assistant message cannot be modified" rule) and existing aborted/errored last-block sanitization are unchanged. ([#2257](https://github.com/can1357/oh-my-pi/issues/2257), [#2265](https://github.com/can1357/oh-my-pi/issues/2265))
|
|
2293
|
-
|
|
2294
|
-
Older entries are archived in [packages/ai/CHANGELOG.md@1f7329fc2c7c](https://github.com/can1357/oh-my-pi/blob/1f7329fc2c7c366b38731738e0db9c170f9bb348/packages/ai/CHANGELOG.md).
|
|
2284
|
+
Older entries are archived in [packages/ai/CHANGELOG.md@d58593a30902](https://github.com/can1357/oh-my-pi/blob/d58593a3090258473304608d68ffd1f620e6b695/packages/ai/CHANGELOG.md).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-ai",
|
|
3
|
-
"version": "18.2.
|
|
3
|
+
"version": "18.2.11",
|
|
4
4
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -152,11 +152,11 @@
|
|
|
152
152
|
"fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
|
|
153
153
|
},
|
|
154
154
|
"dependencies": {
|
|
155
|
-
"@oh-my-pi/omptype": "18.2.
|
|
156
|
-
"@oh-my-pi/pi-catalog": "18.2.
|
|
157
|
-
"@oh-my-pi/pi-natives": "18.2.
|
|
158
|
-
"@oh-my-pi/pi-utils": "18.2.
|
|
159
|
-
"@oh-my-pi/pi-wire": "18.2.
|
|
155
|
+
"@oh-my-pi/omptype": "18.2.11",
|
|
156
|
+
"@oh-my-pi/pi-catalog": "18.2.11",
|
|
157
|
+
"@oh-my-pi/pi-natives": "18.2.11",
|
|
158
|
+
"@oh-my-pi/pi-utils": "18.2.11",
|
|
159
|
+
"@oh-my-pi/pi-wire": "18.2.11"
|
|
160
160
|
},
|
|
161
161
|
"devDependencies": {
|
|
162
162
|
"@types/bun": "^1.3.14"
|
|
@@ -93,9 +93,9 @@ function usageStatus(usedFraction: number): UsageLimit["status"] {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
function buildLimit(
|
|
96
|
-
id: "5h" | "7d",
|
|
96
|
+
id: "5h" | "7d" | "monthly",
|
|
97
97
|
label: string,
|
|
98
|
-
durationMs: number,
|
|
98
|
+
durationMs: number | undefined,
|
|
99
99
|
usedFraction: number | undefined,
|
|
100
100
|
resetsAt: number | undefined,
|
|
101
101
|
accountId: string | undefined,
|
|
@@ -105,7 +105,7 @@ function buildLimit(
|
|
|
105
105
|
id: `credits:${id}`,
|
|
106
106
|
label,
|
|
107
107
|
scope: { provider: PROVIDER, ...(accountId ? { accountId } : {}), windowId: id },
|
|
108
|
-
window: { id, label, durationMs, ...(resetsAt ? { resetsAt } : {}) },
|
|
108
|
+
window: { id, label, ...(durationMs !== undefined ? { durationMs } : {}), ...(resetsAt ? { resetsAt } : {}) },
|
|
109
109
|
amount: { used: usedFraction * 100, usedFraction, unit: "percent" },
|
|
110
110
|
status: usageStatus(usedFraction),
|
|
111
111
|
};
|
|
@@ -245,6 +245,17 @@ async function fetchAlibabaTokenPlanUsage(
|
|
|
245
245
|
parsePositiveTimestamp(responseData.per1WeekResetTime),
|
|
246
246
|
accountId,
|
|
247
247
|
),
|
|
248
|
+
// Monthly-only plans report just this bucket, and the console never
|
|
249
|
+
// states its span (calendar months differ), so the window carries a
|
|
250
|
+
// reset deadline without a duration.
|
|
251
|
+
buildLimit(
|
|
252
|
+
"monthly",
|
|
253
|
+
"Monthly Credits",
|
|
254
|
+
undefined,
|
|
255
|
+
parseUsedFraction(responseData.per1MonthPercentage),
|
|
256
|
+
parsePositiveTimestamp(responseData.per1MonthResetTime),
|
|
257
|
+
accountId,
|
|
258
|
+
),
|
|
248
259
|
].filter((limit): limit is UsageLimit => limit !== undefined);
|
|
249
260
|
if (limits.length === 0) return null;
|
|
250
261
|
return {
|