@oh-my-pi/pi-catalog 18.10.2 → 18.10.4

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.
Files changed (58) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +4 -2
  3. package/dist/types/build.d.ts +3 -2
  4. package/dist/types/compat/image-tokenization.d.ts +9 -1
  5. package/dist/types/compat/request-size.d.ts +11 -3
  6. package/dist/types/compat/thinking-replay.d.ts +9 -0
  7. package/dist/types/model-thinking.d.ts +11 -1
  8. package/dist/types/models.d.ts +16 -1
  9. package/dist/types/pricing.d.ts +37 -1
  10. package/dist/types/types.d.ts +29 -7
  11. package/dist/types/wire/codex.d.ts +2 -0
  12. package/package.json +4 -4
  13. package/src/build.ts +141 -80
  14. package/src/compat/axes.ts +64 -2
  15. package/src/compat/cascade.ts +4 -1
  16. package/src/compat/image-tokenization.ts +28 -10
  17. package/src/compat/request-size.ts +18 -5
  18. package/src/compat/resolve.ts +46 -7
  19. package/src/compat/rules/README.md +15 -3
  20. package/src/compat/rules/classes/anthropic.kdl +43 -2
  21. package/src/compat/rules/classes/gemini.kdl +28 -0
  22. package/src/compat/rules/classes/meta.kdl +7 -0
  23. package/src/compat/rules/classes/openai.kdl +26 -3
  24. package/src/compat/rules/classes/xai.kdl +26 -0
  25. package/src/compat/rules/providers/amazon-bedrock.kdl +1 -0
  26. package/src/compat/rules/providers/anthropic.kdl +13 -0
  27. package/src/compat/rules/providers/cursor.kdl +50 -1
  28. package/src/compat/rules/providers/devin.kdl +110 -5
  29. package/src/compat/rules/providers/google-antigravity.kdl +26 -0
  30. package/src/compat/rules/providers/google-gemini-cli.kdl +1 -0
  31. package/src/compat/rules/providers/google-vertex.kdl +1 -0
  32. package/src/compat/rules/providers/google.kdl +1 -0
  33. package/src/compat/rules/providers/image-tokenization.kdl +2 -1
  34. package/src/compat/rules/providers/meta.kdl +16 -0
  35. package/src/compat/rules/providers/muse-code.kdl +49 -0
  36. package/src/compat/rules/providers/openai-codex.kdl +8 -0
  37. package/src/compat/rules/providers/openai.kdl +1 -0
  38. package/src/compat/rules/providers/openrouter.kdl +1 -0
  39. package/src/compat/rules/providers/umans.kdl +1 -0
  40. package/src/compat/rules/providers/xai-oauth.kdl +3 -0
  41. package/src/compat/rules/providers/xai.kdl +3 -0
  42. package/src/compat/rules/runtime/behavior.kdl +3 -3
  43. package/src/compat/rules/taxonomy/_collapse.kdl +11 -0
  44. package/src/compat/rules/taxonomy/meta.kdl +3 -0
  45. package/src/compat/rules.json +1 -1
  46. package/src/compat/thinking-replay.ts +33 -0
  47. package/src/discovery/codex.ts +0 -4
  48. package/src/discovery/cursor.ts +25 -11
  49. package/src/discovery/devin.ts +5 -3
  50. package/src/model-thinking.ts +13 -1
  51. package/src/model-tokenizer.ts +7 -1
  52. package/src/models.json +1 -1
  53. package/src/models.ts +26 -12
  54. package/src/pricing.ts +123 -12
  55. package/src/provider-models/bundled-references.ts +5 -2
  56. package/src/provider-models/openai-compat.ts +69 -4
  57. package/src/types.ts +31 -6
  58. package/src/wire/codex.ts +17 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,67 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [18.10.4] - 2026-10-13
6
+
7
+ ### Added
8
+
9
+ - Added Muse Code's subscription-only Muse Wonder Full and Wonder contributor tiers with the `max` effort, recording API-equivalent cost instead of $0: Wonder Full at Muse Wonder's $4 input / $0.20 cached / $20 output per 1M tokens, contributor tiers at the measured $1.60 / $0.08 / $8 ([#15522](https://github.com/can1357/oh-my-pi/pull/15522) by [@eggpeat](https://github.com/eggpeat))
10
+ - Added the `classifier-cot-extraction` rule axis, set for Claude, marking models whose classifier refuses earlier reasoning quoted back into their input ([#15436](https://github.com/can1357/oh-my-pi/pull/15436) by [@will-bogusz](https://github.com/will-bogusz))
11
+ - Added Gemini 4 Argon pricing on Cursor ($2 input / $0.10 cached / $10 output per 1M tokens) and Google Antigravity, which now uses Google's first-party rate instead of showing $0 ([#15620](https://github.com/can1357/oh-my-pi/pull/15620) by [@eggpeat](https://github.com/eggpeat))
12
+ - Added scheduled list-price changes to `cost-patch`, as `cost-fallback` already allowed: a dated `effective-rates` card sets the price from its date, and each request is priced at the card in force when it was made, even on models loaded before the change, on rebuilt models, and on Cursor lanes priced from a sibling's card. A malformed dated card now fails the model build instead of silently keeping the old price. `getEffectiveTokenCost` returns that card for price displays, and `hasRecurringTariff` tells these dated-only schedules apart from peak/off-peak tariffs, which alone show a status-line arrow ([#15620](https://github.com/can1357/oh-my-pi/pull/15620) by [@eggpeat](https://github.com/eggpeat))
13
+
14
+ ### Changed
15
+
16
+ - Devin models with a long-context price tier (GPT-5.4 through 5.6 standard lanes, GPT-6 through 6.1, Gemini Pro, and Grok 4.5 through 4.7) now default to a 272K or 200K context window, where that pricing starts; run `/extended-context on` to use the full window at long-context rates ([#14891](https://github.com/can1357/oh-my-pi/pull/14891) by [@eggpeat](https://github.com/eggpeat)).
17
+ - Devin SWE-2, SWE-1.7, and GLM-5.2 fallback pricing no longer charges cache writes at the input rate, since Devin publishes no cache-write rate for them ([#14891](https://github.com/can1357/oh-my-pi/pull/14891) by [@eggpeat](https://github.com/eggpeat)).
18
+ - Google Antigravity now lists Gemini 4 Argon once, with selectable low, medium, and high thinking levels, instead of a separate entry per thinking tier ([#15620](https://github.com/can1357/oh-my-pi/pull/15620) by [@eggpeat](https://github.com/eggpeat))
19
+ - Gemini 4 Argon on Google, Vertex, Google Antigravity, and Cursor moves to Google's $4 input / $0.20 cached / $20 output list price on 2026-12-01 (midnight US Pacific), including requests on models loaded before then, without a catalog update ([#15620](https://github.com/can1357/oh-my-pi/pull/15620) by [@eggpeat](https://github.com/eggpeat))
20
+ - Devin SWE-2's promotional fallback price now ends on 2027-01-01 for requests on models loaded before then too ([#15620](https://github.com/can1357/oh-my-pi/pull/15620) by [@eggpeat](https://github.com/eggpeat))
21
+
22
+ ### Fixed
23
+
24
+ - Fixed Devin Claude and GPT-5.6 through GPT-6 models pricing prompt-cache writes at $0; they now use Devin's published rate of 1.25x input, and Adaptive uses its input rate ([#14891](https://github.com/can1357/oh-my-pi/pull/14891) by [@eggpeat](https://github.com/eggpeat)).
25
+ - Fixed Devin GPT-5.4 through GPT-6.1, Gemini Pro, and Grok 4.5 through 4.7 models missing the long-context price tiers Devin publishes above 272K and 200K prompt tokens ([#14891](https://github.com/can1357/oh-my-pi/pull/14891) by [@eggpeat](https://github.com/eggpeat)).
26
+ - Fixed Devin Fusion pairings ignoring their lead model's rules, including its cache-write rate and long-context tier ([#14891](https://github.com/can1357/oh-my-pi/pull/14891) by [@eggpeat](https://github.com/eggpeat)).
27
+ - Fixed Kilo and NanoGPT models showing stale or missing prices (for example Gemini 4 Argon at $4/$20 instead of $2/$10, and many models at $0); prices now come from each gateway's live model list ([#15623](https://github.com/can1357/oh-my-pi/pull/15623) by [@eggpeat](https://github.com/eggpeat))
28
+ - Fixed NanoGPT models showing their raw id as the name and no context window (disabling auto-compaction) when the bundled catalog lacked them; names, context windows and output limits now come from NanoGPT's live model list ([#15623](https://github.com/can1357/oh-my-pi/pull/15623) by [@eggpeat](https://github.com/eggpeat))
29
+
30
+ ### Removed
31
+
32
+ - Removed the Codex `toolMode` model field (`code_mode_only`); Codex discovery no longer maps `tool_mode`
33
+
34
+ ## [18.10.3] - 2026-10-12
35
+
36
+ ### Breaking Changes
37
+
38
+ - `resolveInlineImageByteBudget(model, officialEndpoint)` and `resolveImageCountBudget(model, officialEndpoint)` take whether the request reaches the official endpoint instead of reading `compat.officialEndpoint`, which misses request-time reroutes such as `ANTHROPIC_BASE_URL`; pass pi-ai's `reachesOfficialEndpoint(model)` ([#15434](https://github.com/can1357/oh-my-pi/pull/15434) by [@will-bogusz](https://github.com/will-bogusz))
39
+
40
+ ### Added
41
+
42
+ - Added Muse Wonder (`muse-wonder-1.0`) to Meta and Muse Code with its `minimal`–`max` effort ladder and pricing
43
+ - Added the `thinking-unverified` rule axis: on hosts whose model list carries no capability metadata (Meta, Muse Code), unrecognized models now offer an opt-in thinking ladder (`ThinkingConfig.unverified`) instead of none
44
+ - Added `thinking-unverified` axis for offering reasoning ladders on unclassified model IDs
45
+ - Added `Muse Wonder 1.0` model definition to Meta provider
46
+ - Added the opt-in `snapcompact-image-reads` axis: snapcompact images a fresh `read` result only for readers whose rule sets it; Claude Opus 5.5 and later opt in ([#14249](https://github.com/can1357/oh-my-pi/pull/14249) by [@will-bogusz](https://github.com/will-bogusz))
47
+ - Added the `image-count-budget` rule for how many images one request may carry (Anthropic 90, Codex 200, other hosts unchanged) and the `official-image-count-budget` override that applies only on the official endpoint: Anthropic 600 (100 on 200k-window Claude models), Codex 2,000 ([#15434](https://github.com/can1357/oh-my-pi/pull/15434) by [@will-bogusz](https://github.com/will-bogusz))
48
+ - Added a 24 MB inline-image byte budget for the Codex backend, which now counts as its official endpoint at its default URL and at paths under it such as `/codex/responses` ([#15434](https://github.com/can1357/oh-my-pi/pull/15434) by [@will-bogusz](https://github.com/will-bogusz))
49
+ - Added `isOfficialCodexApiUrl` to `wire/codex`, moved from pi-ai ([#15434](https://github.com/can1357/oh-my-pi/pull/15434) by [@will-bogusz](https://github.com/will-bogusz))
50
+ - Added `verified` to `image-tokenization` rules, marking the Claude 4.7+ high-res tier and the GPT-5.5 to 6.1 and gpt-6-astra rules as matching measured provider billing ([#15442](https://github.com/can1357/oh-my-pi/pull/15442) by [@will-bogusz](https://github.com/will-bogusz))
51
+ - Added the `image-max-edge` axis and `resolveImageMaxEdge()` for hosts that shrink images before the model reads them; Cursor's Claude and GPT models and its `default` (Auto) route fit 1024×1024 ([#15448](https://github.com/can1357/oh-my-pi/pull/15448) by [@will-bogusz](https://github.com/will-bogusz))
52
+ - Added the `thinking-replay-tokens` axis; Claude lines set it to `output` on every host, since a replayed signed thinking block bills the turn's full reasoning, not the signature's bytes ([#15446](https://github.com/can1357/oh-my-pi/pull/15446) by [@will-bogusz](https://github.com/will-bogusz))
53
+ - Added a KDL opt-in for sibling subagent prompt-cache sharing, enabled for Muse Code's Spark 1.3, Wonder 1.0, and Wonder Full 1.0 variants over the Responses API ([#15467](https://github.com/can1357/oh-my-pi/pull/15467) by [@iliaal](https://github.com/iliaal))
54
+
55
+ ### Changed
56
+
57
+ - Updated model definitions and compatibility rules for provider metadata
58
+ - Google Antigravity, xAI and Cursor requests keep up to 60 images, 20 for Claude on Antigravity and Cursor, up from 5; this counts snapcompact frames and live screenshots together ([#15449](https://github.com/can1357/oh-my-pi/pull/15449) by [@will-bogusz](https://github.com/will-bogusz))
59
+ - Snapcompact sizes archives at the frame prices measured for Antigravity Gemini (a fixed 1,089 tokens), Grok 4.6 to 4.20, and Claude Sonnet 4.6's standard tier ([#15449](https://github.com/can1357/oh-my-pi/pull/15449) by [@will-bogusz](https://github.com/will-bogusz))
60
+
61
+ ### Fixed
62
+
63
+ - Applied `max-image-dimension` and `max-image-payload-bytes` to Google API models, and declared the 5 MiB per-image limit of Claude on Google Antigravity ([#15444](https://github.com/can1357/oh-my-pi/pull/15444) by [@will-bogusz](https://github.com/will-bogusz))
64
+ - Fixed local token counts for OpenAI GPT-5 and later models (Codex, OpenAI, Azure, OpenRouter, Copilot and other hosts) reading about 12% low: their text is now counted with o200k_base instead of a bytes/4 estimate ([#15447](https://github.com/can1357/oh-my-pi/pull/15447) by [@will-bogusz](https://github.com/will-bogusz))
65
+
5
66
  ## [18.10.2] - 2026-10-12
6
67
 
7
68
  ### Added
package/README.md CHANGED
@@ -47,12 +47,14 @@ The `models` subpath (also exported from the root) provides timestamp-aware pric
47
47
  | `calculateCost(model, usage, timestamp?)` | Updates and returns `usage.cost` using `model.cost`. |
48
48
  | `calculateUsageCost(cost, usage, timestamp?)` | Updates and returns `usage.cost` using a `ModelCost`. |
49
49
  | `calculateUncachedInputCost(cost, promptInputTokens, timestamp?)` | Returns the cost of a fully uncached prompt. |
50
- | `getTimeBasedPricingPeriod(cost, timestamp?)` | Returns `"peak"`, `"off-peak"`, or `undefined` without a schedule. |
50
+ | `getEffectiveTokenCost(cost, timestamp?)` | Returns the base card in force: the latest due effective rate, else the row's own legs. |
51
+ | `getTimeBasedPricingPeriod(cost, timestamp?)` | Returns `"peak"`, `"off-peak"`, or `undefined` without a recurring tariff. |
52
+ | `hasRecurringTariff(schedule)` | Whether a `TimeBasedCost` carries a peak/off-peak tariff rather than only dated rate cards. |
51
53
  | `getNextTimeBasedPricingTransition(cost, timestamp?)` | Returns the next actual peak/off-peak change strictly after the timestamp, or `undefined` if none exists. |
52
54
 
53
55
  Timestamps are Unix milliseconds; omitted timestamps use the current time for scheduled pricing. Flat token prices are unaffected. Pricing selects the latest applicable effective rate card, then its long-context tier, then the peak/off-peak multiplier. A transition query concerns the recurring tariff, not dated rate-card changes.
54
56
 
55
- `ModelCost.timeBased` is optional typed metadata (`TimeBasedCost`): `offPeakMultiplier`, `peakWindows` (UTC `weekdays`, Sunday = 0, and start-inclusive/end-exclusive `startMinute`/`endMinute`), and optional `effectiveRates`. Each effective rate is a complete `TokenCost` with an `effectiveFrom` Unix-millisecond timestamp and optional `longContext` tier, replacing the base card from that instant.
57
+ `ModelCost.timeBased` is optional typed metadata (`TimeBasedCost`): `offPeakMultiplier`, `peakWindows` (UTC `weekdays`, Sunday = 0, and start-inclusive/end-exclusive `startMinute`/`endMinute`), and optional `effectiveRates`. Each effective rate is a complete `TokenCost` with an `effectiveFrom` Unix-millisecond timestamp and optional `longContext` tier, replacing the base card from that instant. A schedule with no peak windows at a 1x off-peak multiplier has no recurring tariff, only dated rate cards: `cost-patch`/`cost-fallback` `effective-rates` compile to one, so a row built before a scheduled price change still prices later requests at the new card.
56
58
 
57
59
  Pass the request-start timestamp when estimating request usage, then preserve the resulting monetary amounts rather than repricing history at display time. OMP does this using the assistant message timestamp; it is an estimation convention, not a claim about server billing across boundaries. Prefer monetary costs reported by a provider when available.
58
60
 
@@ -9,8 +9,9 @@
9
9
  import { type Api, type Model, type ModelSpec } from "./types.js";
10
10
  /**
11
11
  * Applies reviewed catalog-data value corrections (`cost-patch`,
12
- * `cache-read-at-input-rate`, `limits-patch`, `long-context-cost`,
13
- * `context-window-floor`, `input-modalities`) onto an upstream-sourced spec. Applied by
12
+ * `cache-read-at-input-rate`, `cache-write-rate`, `limits-patch`,
13
+ * `long-context-cost`, `context-window-floor`, `input-modalities`) onto an
14
+ * upstream-sourced spec. Applied by
14
15
  * `buildModel` to every upstream-sourced spec; user-authored overrides are
15
16
  * recomposed after building by the override applicators, so explicit user
16
17
  * limits and pricing still win.
@@ -23,7 +23,7 @@ export interface OpenAiPatchTokenization {
23
23
  auto: "high" | "original";
24
24
  }
25
25
  /** One model line's image billing rule: the vendor formula and its per-model numbers. */
26
- export type ImageTokenization = OpenAiPatchTokenization
26
+ export type ImageTokenization = (OpenAiPatchTokenization
27
27
  /** Anthropic 28px patches, resized to fit a padded-edge limit and a visual-token budget. */
28
28
  | {
29
29
  regime: "anthropic-patch";
@@ -34,6 +34,9 @@ export type ImageTokenization = OpenAiPatchTokenization
34
34
  | {
35
35
  regime: "fixed";
36
36
  tokens: number;
37
+ }) & {
38
+ /** Provider billing was measured to match this rule; unset for docs-only rules and wire fallbacks. */
39
+ verified?: boolean;
37
40
  };
38
41
  /** What reads the image: a built model, any `{ id }` with optional host and identity, or just a wire `{ api }`. */
39
42
  export interface ImageTokenizationTarget {
@@ -48,5 +51,10 @@ export interface ImageTokenizationTarget {
48
51
  * unregistered API).
49
52
  */
50
53
  export declare function resolveImageTokenization(target: ImageTokenizationTarget): ImageTokenization | undefined;
54
+ /**
55
+ * Longest image edge the reader's host passes to the model (`image-max-edge`),
56
+ * or undefined when the host keeps the image's size.
57
+ */
58
+ export declare function resolveImageMaxEdge(target: ImageTokenizationTarget): number | undefined;
51
59
  /** Billed input tokens for one image of `size` under `rule`; only `openai-patch` reads `detail`. */
52
60
  export declare function imageTokens(rule: ImageTokenization, size: ImageSize, detail?: ImageDetail): number;
@@ -1,7 +1,15 @@
1
1
  import type { Model } from "../types.js";
2
2
  /**
3
3
  * Maximum encoded inline-image bytes retained per request for a deployment with a documented body-size limit.
4
- * The axis is a host contract: a rerouted `baseUrl` (proxy, gateway) imposes its own limit, so the budget
5
- * applies only while the model targets its official endpoint.
4
+ * The axis is a host contract: a rerouted endpoint (proxy, gateway) imposes its own limit, so the budget applies
5
+ * only when `officialEndpoint` says the request reaches the model's official endpoint. `compat.officialEndpoint`
6
+ * classifies only the configured `baseUrl`; pi-ai's `reachesOfficialEndpoint` also follows request-time reroutes.
6
7
  */
7
- export declare function resolveInlineImageByteBudget(model: Model): number | undefined;
8
+ export declare function resolveInlineImageByteBudget(model: Model, officialEndpoint: boolean): number | undefined;
9
+ /**
10
+ * Most images one request to this deployment may carry, or `undefined` when no rule names the host. The
11
+ * `official-image-count-budget` axis replaces `image-count-budget` only when `officialEndpoint` says the request
12
+ * reaches the model's official endpoint (see {@link resolveInlineImageByteBudget}); a rerouted endpoint keeps the
13
+ * provider's generic budget.
14
+ */
15
+ export declare function resolveImageCountBudget(model: Model, officialEndpoint: boolean): number | undefined;
@@ -0,0 +1,9 @@
1
+ import type { ImageTokenizationTarget } from "./image-tokenization.js";
2
+ /**
3
+ * `output`: the reasoning the signature carries, at the size its turn billed
4
+ * as output; the signature's own bytes are free. `signature`: the signature's
5
+ * bytes stand in for that reasoning.
6
+ */
7
+ export type ThinkingReplayTokens = "output" | "signature";
8
+ /** How `reader` bills replayed thinking; `signature` unless its lineage declares otherwise. */
9
+ export declare function resolveThinkingReplayTokens(reader: ImageTokenizationTarget): ThinkingReplayTokens;
@@ -7,7 +7,7 @@
7
7
  * id parsing, no host matching, no compat detection per request.
8
8
  */
9
9
  import { Effort } from "./effort.js";
10
- import type { Api, Model, ModelSpec } from "./types.js";
10
+ import type { Api, Model, ModelSpec, ThinkingConfig } from "./types.js";
11
11
  /**
12
12
  * Runtime helpers read baked metadata only, so they accept both pre-build
13
13
  * specs and built models.
@@ -19,6 +19,16 @@ type ApiModel<TApi extends Api = Api> = ModelSpec<TApi> | Model<TApi>;
19
19
  * controllable effort surface (`thinking: undefined`).
20
20
  */
21
21
  export declare function getSupportedEfforts<TApi extends Api>(model: ApiModel<TApi>): readonly Effort[];
22
+ /**
23
+ * Neutral view of a model whose thinking ladder is unverified: `reasoning: false`
24
+ * and no ladder. Re-entering policy resolution starts from it (the ladder is
25
+ * derived output, not authored input), and requests without an effort send it so
26
+ * no reasoning or disable fields reach an upstream that may reject them.
27
+ */
28
+ export declare function withoutUnverifiedThinking<T extends {
29
+ reasoning: boolean;
30
+ thinking?: ThinkingConfig;
31
+ }>(model: T): T;
22
32
  /**
23
33
  * Clamps a requested thinking level against explicit model metadata.
24
34
  *
@@ -1,5 +1,5 @@
1
1
  import MODELS from "./models.json";
2
- import type { Api, KnownProvider, Model, ModelCost, ModelPricingStatus, Usage } from "./types.js";
2
+ import type { Api, KnownProvider, Model, ModelCost, ModelPricingStatus, TimeBasedCost, TokenCost, Usage } from "./types.js";
3
3
  export type GeneratedProvider = keyof typeof MODELS;
4
4
  /** Whether `provider` has bundled rows in models.json (e.g. a provider id authored in KDL). */
5
5
  export declare function isGeneratedProvider(provider: string): provider is GeneratedProvider;
@@ -8,6 +8,21 @@ export declare function getBundledProviders(): KnownProvider[];
8
8
  export declare function getBundledModels(provider: GeneratedProvider): Model<Api>[];
9
9
  /** Resolve display semantics without mistaking an absent rate card for a free model. */
10
10
  export declare function getModelPricingStatus(model: Pick<Model<Api>, "cost" | "pricingStatus">): ModelPricingStatus;
11
+ /**
12
+ * The base token card in force at `timestamp` (Unix ms, default now): the
13
+ * latest due `timeBased` effective rate, else the row's own legs. Price
14
+ * displays read this rather than the scalar legs, which keep the card current
15
+ * when the row was built while bundles, caches, and long sessions outlive it.
16
+ * Applies no long-context tier or peak/off-peak multiplier.
17
+ */
18
+ export declare function getEffectiveTokenCost(cost: ModelCost, timestamp?: number): TokenCost;
19
+ /**
20
+ * Whether a schedule carries a recurring peak/off-peak tariff. A schedule with
21
+ * no peak windows at a 1x off-peak multiplier only carries dated rate cards
22
+ * (`cost-patch`/`cost-fallback` `effective-rates`): its price changes on a
23
+ * date, never by time of day.
24
+ */
25
+ export declare function hasRecurringTariff(schedule: TimeBasedCost): boolean;
11
26
  /** Return the recurring UTC tariff period, independently of its monetary multiplier. */
12
27
  export declare function getTimeBasedPricingPeriod(cost: ModelCost, timestamp?: number): "peak" | "off-peak" | undefined;
13
28
  /** Return the next actual peak/off-peak change strictly after the Unix-ms timestamp. */
@@ -1,5 +1,41 @@
1
- import type { TimeBasedCost } from "./types.js";
1
+ import type { EffectiveTokenCost, ModelCost, TimeBasedCost, TokenCost } from "./types.js";
2
2
  /** Validate serialized schedules before admitting cached model rows. */
3
3
  export declare function isTimeBasedCost(value: unknown): value is TimeBasedCost;
4
4
  /** KDL object children are named records; normalize them once while constructing the model. */
5
5
  export declare function materializeTimeBasedCost(value: unknown): TimeBasedCost;
6
+ /**
7
+ * The latest `effectiveRates` card of a materialized schedule due at
8
+ * `timestamp`, or undefined before the first one (or without a schedule).
9
+ */
10
+ export declare function dueEffectiveRate(schedule: TimeBasedCost | undefined, timestamp: number): EffectiveTokenCost | undefined;
11
+ /** A `cost-patch`/`cost-fallback` dated card: the legs it overwrites from `effectiveFrom` (Unix ms). */
12
+ export interface DatedCostCard extends Partial<TokenCost> {
13
+ effectiveFrom: number;
14
+ }
15
+ /**
16
+ * Parse the compiled `effective-rates` block of a `cost-patch` or
17
+ * `cost-fallback` payload into dated cards, ascending by date. Throws on a
18
+ * malformed card, so a typo in a rule fails the build instead of silently
19
+ * leaving the old price in force.
20
+ */
21
+ export declare function parseDatedCostCards(costAxis: unknown, axis: "cost-patch" | "cost-fallback"): DatedCostCard[];
22
+ /**
23
+ * Earliest instant a rate card can name (the `Date` range minimum). A leading
24
+ * card from here holds the price in force before the first dated change.
25
+ */
26
+ export declare const EARLIEST_EFFECTIVE_FROM = -8640000000000000;
27
+ /** A schedule of dated rate cards alone: no peak windows, no off-peak discount. */
28
+ export declare const NO_RECURRING_TARIFF: TimeBasedCost;
29
+ /**
30
+ * A flat card plus its dated overrides as a request-time `ModelCost`: the
31
+ * card due at `now` in the scalar legs, and every period (a leading card for
32
+ * the base price, then each dated card over the previous one) in a
33
+ * `timeBased` schedule without a recurring tariff. The plain card when no
34
+ * dated card exists.
35
+ */
36
+ export declare function datedCost(base: TokenCost, cards: readonly DatedCostCard[], now?: number): ModelCost;
37
+ /**
38
+ * Overwrite `cost` legs with the latest dated card due at `now`. Leaves
39
+ * `cost` unchanged before the first card.
40
+ */
41
+ export declare function applyDueDatedCostCard(cost: TokenCost, cards: readonly DatedCostCard[], now?: number): void;
@@ -93,6 +93,14 @@ export interface ThinkingConfig {
93
93
  * provides an explicit wire off-path.
94
94
  */
95
95
  requiresEffort?: boolean;
96
+ /**
97
+ * The catalog has no evidence this model reasons (unclassified id, no
98
+ * capability metadata). The ladder is offered for the user to opt into:
99
+ * sessions leave thinking unset until the user picks an effort, and a
100
+ * request without an effort goes out as non-reasoning (see
101
+ * `withoutUnverifiedThinking`).
102
+ */
103
+ unverified?: boolean;
96
104
  }
97
105
  export type Provider = string;
98
106
  /** Token budgets for each thinking level (token-based providers only) */
@@ -936,9 +944,11 @@ export interface ResolvedOpenAIResponsesCompat extends ResolvedOpenAISharedCompa
936
944
  isVercelGatewayHost: boolean;
937
945
  /**
938
946
  * The configured endpoint is first-party OpenAI (`provider === "openai"` on
939
- * an `api.openai.com` or unset baseUrl). Gates official-only Responses
940
- * behavior: default-on stateful `previous_response_id` chaining and the
941
- * `text.verbosity` field.
947
+ * an `api.openai.com` or unset baseUrl), or the Codex backend
948
+ * (`openai-codex-responses` on the default Codex baseUrl). Gates platform
949
+ * OpenAI's official-only Responses behavior (default-on stateful
950
+ * `previous_response_id` chaining and the `text.verbosity` field; the Codex
951
+ * adapter is not governed by either gate) and host request-size budgets.
942
952
  */
943
953
  officialEndpoint: boolean;
944
954
  /** Run Harmony-protocol leak detection/mitigation on streamed output. */
@@ -1063,18 +1073,32 @@ export interface GoogleCompat {
1063
1073
  antigravityUsageLabel?: string;
1064
1074
  /** Strip image inputs before encoding (text-only serving of a multimodal id). */
1065
1075
  stripImageInput?: boolean;
1076
+ /**
1077
+ * Largest width or height a single image may carry for a Claude reader on
1078
+ * this host (see {@link AnthropicCompat.maxImageDimension}). Setting this or
1079
+ * {@link maxImagePayloadBytes} turns on Claude's image clamp, many-image
1080
+ * cap included; unset leaves images as sent.
1081
+ */
1082
+ maxImageDimension?: number;
1083
+ /**
1084
+ * Largest base64 payload a single image may carry, in bytes (see
1085
+ * {@link AnthropicCompat.maxImagePayloadBytes}).
1086
+ */
1087
+ maxImagePayloadBytes?: number;
1066
1088
  /** Thinking-loop watchdog guard family applied to streamed reasoning. */
1067
1089
  thinkingLoopGuard?: "gemini" | "deepseek" | "xai";
1068
1090
  /** See {@link BedrockCompat.supportsSamplingParams}. */
1069
1091
  supportsSamplingParams?: boolean;
1070
1092
  }
1071
1093
  /** Fully-resolved google-API compat view, materialized once by `buildModel`. */
1072
- export type ResolvedGoogleCompat = Required<Omit<GoogleCompat, "streamFirstEventTimeoutMs" | "streamIdleTimeoutMs" | "thinkingLoopGuard" | "antigravityUsageLabel" | "supportsSamplingParams">> & {
1094
+ export type ResolvedGoogleCompat = Required<Omit<GoogleCompat, "streamFirstEventTimeoutMs" | "streamIdleTimeoutMs" | "thinkingLoopGuard" | "antigravityUsageLabel" | "supportsSamplingParams" | "maxImageDimension" | "maxImagePayloadBytes">> & {
1073
1095
  streamFirstEventTimeoutMs?: number;
1074
1096
  streamIdleTimeoutMs?: number;
1075
1097
  thinkingLoopGuard?: GoogleCompat["thinkingLoopGuard"];
1076
1098
  antigravityUsageLabel?: string;
1077
1099
  supportsSamplingParams?: boolean;
1100
+ maxImageDimension?: number;
1101
+ maxImagePayloadBytes?: number;
1078
1102
  };
1079
1103
  /** Sparse, user-authored compat overrides for a given API (models.json / config vocabulary). */
1080
1104
  export type CompatConfigOf<TApi extends Api> = TApi extends "openai-completions" | "openrouter" | "openai-responses" | "azure-openai-responses" | "openai-codex-responses" ? OpenAICompat : TApi extends "anthropic-messages" ? AnthropicCompat : TApi extends "bedrock-converse-stream" ? BedrockCompat : TApi extends "devin-agent" ? DevinCompat : TApi extends "google-generative-ai" | "google-vertex" | "google-gemini-cli" ? GoogleCompat : undefined;
@@ -1153,7 +1177,7 @@ export interface ModelCost extends TokenCost {
1153
1177
  * generations rather than providers: DeepSeek V3 through V4 share
1154
1178
  * `"deepseek-v3"`; Kimi K2 through K3 share `"kimi-k2"`.
1155
1179
  */
1156
- export type ModelTokenizer = "claude-v3" | "claude-v47" | "claude-v5" | "claude-v5-sonnet" | "qwen3" | "deepseek-v3" | "kimi-k2" | "glm5";
1180
+ export type ModelTokenizer = "claude-v3" | "claude-v47" | "claude-v5" | "claude-v5-sonnet" | "qwen3" | "deepseek-v3" | "kimi-k2" | "glm5" | "o200k";
1157
1181
  /** One account's discovered entitlements on a model; see {@link Model.accountAccess}. */
1158
1182
  export interface ModelAccountAccess {
1159
1183
  /**
@@ -1377,8 +1401,6 @@ export interface Model<TApi extends Api = Api> {
1377
1401
  preferWebsockets?: boolean;
1378
1402
  /** Codex Responses Lite transport: send the lite marker and carry instructions/tools as input items (mirrors codex-rs `use_responses_lite`). */
1379
1403
  useResponsesLite?: boolean;
1380
- /** Codex Code Mode restriction: model expects tools routed through a programmatic exec surface (mirrors codex-rs `tool_mode`). */
1381
- toolMode?: "code_mode_only";
1382
1404
  /**
1383
1405
  * Service-tier ids the provider advertises for this model (Codex discovery
1384
1406
  * `service_tiers[].id`, e.g. `priority`, `ultrafast`). Absent when the
@@ -2,6 +2,8 @@
2
2
  * Constants for OpenAI Codex (ChatGPT OAuth) backend
3
3
  */
4
4
  export declare const CODEX_BASE_URL = "https://chatgpt.com/backend-api";
5
+ /** Strict official-Codex endpoint check; exact origin or a path boundary after {@link CODEX_BASE_URL}. */
6
+ export declare function isOfficialCodexApiUrl(baseUrl: string | undefined): boolean;
5
7
  /**
6
8
  * Pinned OpenAI Codex client version (corresponds to @openai/codex package version).
7
9
  * Updated from npm by `bun run check-spoofed-versions --update`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oh-my-pi/pi-catalog",
3
- "version": "18.10.2",
3
+ "version": "18.10.4",
4
4
  "description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence",
5
5
  "keywords": [
6
6
  "ai",
@@ -93,12 +93,12 @@
93
93
  "gen:proto": "bun scripts/generate-protocols.ts"
94
94
  },
95
95
  "dependencies": {
96
- "@oh-my-pi/omptype": "18.10.2",
97
- "@oh-my-pi/pi-utils": "18.10.2"
96
+ "@oh-my-pi/omptype": "18.10.4",
97
+ "@oh-my-pi/pi-utils": "18.10.4"
98
98
  },
99
99
  "devDependencies": {
100
100
  "@bgotink/kdl": "0.4.0",
101
- "@oh-my-pi/pi-ai": "18.10.2",
101
+ "@oh-my-pi/pi-ai": "18.10.4",
102
102
  "@types/bun": "^1.3.14"
103
103
  },
104
104
  "engines": {