@oh-my-pi/pi-ai 18.12.4 → 18.12.6

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,16 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [18.12.5] - 2026-10-21
6
+
7
+ ### Added
8
+
9
+ - Added OpenAI 12-hour prompt caching for GPT-5.6+ on the Responses API: `cacheRetention: "long"` now requests `prompt_cache_options.ttl: "12h"` (instead of the ignored legacy `prompt_cache_retention: "24h"`), and `promptCache.ttl` accepts `"12h"`
10
+
11
+ ### Fixed
12
+
13
+ - Fixed every OpenAI Codex request failing with HTTP 404 `{"detail":"Not Found"}` on personal ChatGPT accounts whose token is not region-pinned ([#16493](https://github.com/can1357/oh-my-pi/issues/16493))
14
+
5
15
  ## [18.12.4] - 2026-10-20
6
16
 
7
17
  ### Added
@@ -2303,21 +2313,4 @@
2303
2313
  - Fixed OAuth refresh persisting the rotated token by a positional index captured before the refresh `await`. A concurrent disable could reorder or shrink a provider's credential array while the refresh was in flight, landing the new token on the wrong row (or silently dropping it) and leaving accounts with a stale refresh token that failed — and was then disabled — on the next cycle. Refresh persistence, selection-index resync, and CAS-disable now address the row by id across `forceRefreshCredentialById`, candidate preflight, and in-stream selection (`#replaceCredentialById` / `#disableCredentialByIdIfMatches`).
2304
2314
  - Fixed `isDefinitiveOAuthFailure` treating a bare HTTP 403 (and generic `unauthorized` / access-token-expired wording) as a definitive credential failure, which permanently disabled healthy OAuth accounts on WAF, egress rate-limit, permission, and account-verification responses. Bare 403, rate limits (429), gateway/5xx, and more network errors (`ECONNRESET`, `ETIMEDOUT`, `EAI_AGAIN`, …) are now classified transient; only explicit dead-grant errors (`invalid_grant`, `invalid_token`, `unauthorized_client`, revoked, `refresh token … expired`) or a bare 401 tear the credential down.
2305
2315
 
2306
- ## [16.1.17] - 2026-06-24
2307
-
2308
- ### Added
2309
-
2310
- - Added provider-level `notes?: string[]` field to `UsageReport` for disclaimers that apply to every limit (e.g. "OMP-observed spend only"). The field is declared in both the `usage.ts` schema and the auth-broker wire schema copy so it survives the `"+": "reject"` deserialization gate. ([#3268](https://github.com/can1357/oh-my-pi/issues/3268))
2311
-
2312
- ### Fixed
2313
-
2314
- - Moved the OpenCode Go "OMP-observed spend only" disclaimer from per-limit `notes` to provider-level `notes`, so it renders once per provider instead of duplicating across every account × window. ([#3268](https://github.com/can1357/oh-my-pi/issues/3268))
2315
- - Fixed Anthropic rate-limit header usage cache entries retaining legacy missing account metadata after refresh.
2316
- - Fixed Anthropic-compatible budget-effort models dropping the selected effort before request serialization, so `output_config.effort` is emitted alongside `thinking.budget_tokens` when model metadata declares `mode: "anthropic-budget-effort"`.
2317
- - Fixed `anthropic-messages` silently dropping caller-supplied `Authorization` / `X-Api-Key` from `model.headers` and `ANTHROPIC_CUSTOM_HEADERS`, blocking custom proxy auth schemes. Non-OAuth requests now honor the caller's value (matching `openai-responses`); the lower-level client also suppresses its `X-Api-Key` add when a custom `Authorization` is supplied for a non-official endpoint so the proxy receives a single credential. OAuth bearer + Cloudflare AI Gateway keep their pre-existing enforced auth headers. ([#3391](https://github.com/can1357/oh-my-pi/issues/3391))
2318
- - Fixed Ollama Cloud `num_predict` ignoring the provider's 65536 output-token cap so stale `models.db` rows (or custom `modelOverrides` re-enabling output caps) that carried `maxTokens: 1048576` from a pre-omitMaxOutputTokens catalog 400'd every request with `max_tokens (1048576) exceeds model's maximum output tokens (65536) for model deepseek-v4-pro`. The Ollama provider now clamps `num_predict` for any `ollama-cloud` request at the documented 65536 cap before sending, independent of the cached spec's `maxTokens` and on top of the existing `omitMaxOutputTokens` policy — so the request stays valid even when the load-time policy never normalized the spec. Self-hosted `ollama` traffic is unaffected. ([#3392](https://github.com/can1357/oh-my-pi/issues/3392))
2319
- - Fixed OpenRouter Anthropic models on the Responses path omitting `cache_control`, so prompt caching engages without forcing Chat Completions. ([#3397](https://github.com/can1357/oh-my-pi/issues/3397))
2320
- - Fixed OpenRouter Anthropic Responses follow-up requests replaying prior reasoning items with stale signatures, which caused HTTP 400 `Invalid signature in thinking block` errors after a thinking turn. ([#3399](https://github.com/can1357/oh-my-pi/issues/3399))
2321
- - Fixed OpenRouter Anthropic models on the Responses path omitting `cache_control`, so prompt caching engages without forcing Chat Completions. `cacheRetention: "long"` now upgrades the breakpoint to `ttl: "1h"`. ([#3397](https://github.com/can1357/oh-my-pi/issues/3397))
2322
-
2323
- Older entries are archived in [packages/ai/CHANGELOG.md@47e6af055a17](https://github.com/can1357/oh-my-pi/blob/47e6af055a17862bc1cab6b5ebedd3db75ac2573/packages/ai/CHANGELOG.md).
2316
+ Older entries are archived in [packages/ai/CHANGELOG.md@7a5f1425b9bd](https://github.com/can1357/oh-my-pi/blob/7a5f1425b9bd79c3c74ae1d8946782b0494c8aa9/packages/ai/CHANGELOG.md).
@@ -5680,10 +5680,10 @@ export interface ResponseCreateParamsBase {
5680
5680
  * `prompt_cache_retention` is not specified.
5681
5681
  */
5682
5682
  prompt_cache_retention?: "in_memory" | "24h" | null;
5683
- /** Explicit prompt-cache mode and minimum lifetime for GPT-5.6+ models. */
5683
+ /** Explicit prompt-cache mode and minimum lifetime (`12h` is Responses-only) for GPT-5.6+ models. */
5684
5684
  prompt_cache_options?: {
5685
5685
  mode: "implicit" | "explicit";
5686
- ttl?: "30m";
5686
+ ttl?: "30m" | "12h";
5687
5687
  } | null;
5688
5688
  /**
5689
5689
  * **gpt-5 and o-series models only**
@@ -240,8 +240,12 @@ export interface AnthropicCompactionRequest {
240
240
  export interface OpenAIPromptCacheOptions {
241
241
  /** `explicit` disables OpenAI's automatic latest-message breakpoint. */
242
242
  mode: "implicit" | "explicit";
243
- /** The only currently supported minimum breakpoint lifetime. */
244
- ttl?: "30m";
243
+ /**
244
+ * Minimum cache lifetime. `30m` is OpenAI's default; `12h` (Responses API only)
245
+ * bills writes at 2.5× input instead of 1.25×. Defaults to `12h` when
246
+ * `cacheRetention` resolves to `long`, otherwise `30m`.
247
+ */
248
+ ttl?: "30m" | "12h";
245
249
  /** By default, mark one existing block from stable history; `none` suppresses that marker. */
246
250
  breakpoint?: "latest-stable-message" | "none";
247
251
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oh-my-pi/pi-ai",
3
- "version": "18.12.4",
3
+ "version": "18.12.6",
4
4
  "description": "Unified LLM API with automatic model discovery and provider configuration",
5
5
  "keywords": [
6
6
  "ai",
@@ -155,11 +155,11 @@
155
155
  "fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
156
156
  },
157
157
  "dependencies": {
158
- "@oh-my-pi/omptype": "18.12.4",
159
- "@oh-my-pi/pi-catalog": "18.12.4",
160
- "@oh-my-pi/pi-natives": "18.12.4",
161
- "@oh-my-pi/pi-utils": "18.12.4",
162
- "@oh-my-pi/pi-wire": "18.12.4"
158
+ "@oh-my-pi/omptype": "18.12.6",
159
+ "@oh-my-pi/pi-catalog": "18.12.6",
160
+ "@oh-my-pi/pi-natives": "18.12.6",
161
+ "@oh-my-pi/pi-utils": "18.12.6",
162
+ "@oh-my-pi/pi-wire": "18.12.6"
163
163
  },
164
164
  "devDependencies": {
165
165
  "@types/bun": "^1.3.14"
@@ -2006,6 +2006,12 @@ function applyOpenAIChatCompletionsPromptCachePolicy(
2006
2006
  return;
2007
2007
  }
2008
2008
 
2009
+ if (promptCache.ttl === "12h") {
2010
+ throw new AIError.ConfigurationError(
2011
+ `OpenAI 12h prompt caching is only available on the Responses API; ${model.provider}/${model.id} uses Chat Completions.`,
2012
+ );
2013
+ }
2014
+
2009
2015
  params.prompt_cache_key = promptCacheKey;
2010
2016
  params.prompt_cache_options = {
2011
2017
  mode: promptCache.mode,
@@ -5897,8 +5897,8 @@ export interface ResponseCreateParamsBase {
5897
5897
  * `prompt_cache_retention` is not specified.
5898
5898
  */
5899
5899
  prompt_cache_retention?: "in_memory" | "24h" | null;
5900
- /** Explicit prompt-cache mode and minimum lifetime for GPT-5.6+ models. */
5901
- prompt_cache_options?: { mode: "implicit" | "explicit"; ttl?: "30m" } | null;
5900
+ /** Explicit prompt-cache mode and minimum lifetime (`12h` is Responses-only) for GPT-5.6+ models. */
5901
+ prompt_cache_options?: { mode: "implicit" | "explicit"; ttl?: "30m" | "12h" } | null;
5902
5902
  /**
5903
5903
  * **gpt-5 and o-series models only**
5904
5904
  *
@@ -1564,10 +1564,11 @@ function applyOpenAIResponsesPromptCachePolicy(
1564
1564
  options: OpenAIResponsesOptions | undefined,
1565
1565
  statefulCacheBaseline?: ResponseInput,
1566
1566
  ): void {
1567
+ const cacheRetention = resolveCacheRetention(options?.cacheRetention);
1568
+ if (cacheRetention === "none") return;
1567
1569
  const promptCache = options?.promptCache;
1568
- if (!promptCache || resolveCacheRetention(options?.cacheRetention) === "none") return;
1569
1570
  if (!model.compat.supportsPromptCacheBreakpoints) {
1570
- if (promptCache.mode === "explicit") {
1571
+ if (promptCache?.mode === "explicit") {
1571
1572
  throw new AIError.ConfigurationError(
1572
1573
  `OpenAI explicit prompt caching is unsupported for ${model.provider}/${model.id}; enable compat.supportsPromptCacheBreakpoints only for a compatible endpoint.`,
1573
1574
  );
@@ -1575,11 +1576,15 @@ function applyOpenAIResponsesPromptCachePolicy(
1575
1576
  return;
1576
1577
  }
1577
1578
 
1579
+ // GPT-5.6+ replaces `prompt_cache_retention` with `prompt_cache_options.ttl`;
1580
+ // long retention selects the 12h minimum lifetime even without an explicit policy.
1581
+ const ttl = promptCache?.ttl ?? (cacheRetention === "long" ? "12h" : undefined);
1582
+ if (!promptCache && ttl === undefined) return;
1578
1583
  params.prompt_cache_options = {
1579
- mode: promptCache.mode,
1580
- ttl: promptCache.ttl ?? model.compat.promptCacheBreakpointTtl,
1584
+ mode: promptCache?.mode ?? "implicit",
1585
+ ttl: ttl ?? model.compat.promptCacheBreakpointTtl,
1581
1586
  };
1582
- if (promptCache.mode === "explicit" && promptCache.breakpoint !== "none")
1587
+ if (promptCache?.mode === "explicit" && promptCache.breakpoint !== "none")
1583
1588
  markLatestStableResponsesCacheBreakpoint(params.input, statefulCacheBaseline);
1584
1589
  }
1585
1590
 
@@ -1661,11 +1666,14 @@ export function buildParams(
1661
1666
  instructions: systemInstructions,
1662
1667
  stream: true,
1663
1668
  prompt_cache_key: promptCacheKey,
1664
- prompt_cache_retention: promptCacheKey
1665
- ? cacheRetention === "long" && model.compat.supportsLongPromptCacheRetention
1669
+ // GPT-5.6+ ignores the legacy retention field; its lifetime rides `prompt_cache_options.ttl`.
1670
+ prompt_cache_retention:
1671
+ promptCacheKey &&
1672
+ cacheRetention === "long" &&
1673
+ model.compat.supportsLongPromptCacheRetention &&
1674
+ !model.compat.supportsPromptCacheBreakpoints
1666
1675
  ? "24h"
1667
- : undefined
1668
- : undefined,
1676
+ : undefined,
1669
1677
  // Gateway routing: OpenRouter-only Responses wire field for sticky upstream
1670
1678
  // routing + observability grouping; no equivalent on direct OpenAI.
1671
1679
  session_id: model.compat.isOpenRouterHost ? getOpenRouterResponsesSessionId(options) : undefined,
package/src/types.ts CHANGED
@@ -461,8 +461,12 @@ export interface AnthropicCompactionRequest {
461
461
  export interface OpenAIPromptCacheOptions {
462
462
  /** `explicit` disables OpenAI's automatic latest-message breakpoint. */
463
463
  mode: "implicit" | "explicit";
464
- /** The only currently supported minimum breakpoint lifetime. */
465
- ttl?: "30m";
464
+ /**
465
+ * Minimum cache lifetime. `30m` is OpenAI's default; `12h` (Responses API only)
466
+ * bills writes at 2.5× input instead of 1.25×. Defaults to `12h` when
467
+ * `cacheRetention` resolves to `long`, otherwise `30m`.
468
+ */
469
+ ttl?: "30m" | "12h";
466
470
  /** By default, mark one existing block from stable history; `none` suppresses that marker. */
467
471
  breakpoint?: "latest-stable-message" | "none";
468
472
  }