@oh-my-pi/pi-catalog 18.8.1 → 18.8.2

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,12 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [18.8.2] - 2026-10-07
6
+
7
+ ### Fixed
8
+
9
+ - Fixed Anthropic requests carrying too many inline screenshot bytes by exposing a provider image-byte budget, applied only on the official endpoint ([#14453](https://github.com/can1357/oh-my-pi/issues/14453)).
10
+
5
11
  ## [18.8.1] - 2026-10-07
6
12
 
7
13
  ### Fixed
@@ -0,0 +1,7 @@
1
+ import type { Model } from "../types.js";
2
+ /**
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.
6
+ */
7
+ export declare function resolveInlineImageByteBudget(model: Model): number | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oh-my-pi/pi-catalog",
3
- "version": "18.8.1",
3
+ "version": "18.8.2",
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.8.1",
97
- "@oh-my-pi/pi-utils": "18.8.1"
96
+ "@oh-my-pi/omptype": "18.8.2",
97
+ "@oh-my-pi/pi-utils": "18.8.2"
98
98
  },
99
99
  "devDependencies": {
100
100
  "@bgotink/kdl": "0.4.0",
101
- "@oh-my-pi/pi-ai": "18.8.1",
101
+ "@oh-my-pi/pi-ai": "18.8.2",
102
102
  "@types/bun": "^1.3.14"
103
103
  },
104
104
  "engines": {
@@ -395,6 +395,7 @@ export const AXES: Readonly<Record<string, AxisDef>> = {
395
395
  /** How the model line bills an input image; shape and formulas in `./image-tokenization`. */
396
396
  "image-tokenization": { key: "imageTokenization", set: "catalog", shape: "object" },
397
397
  "image-model": { key: "imageModel", set: "catalog", shape: "scalar" },
398
+ "inline-image-byte-budget": { key: "inlineImageByteBudget", set: "catalog", shape: "scalar" },
398
399
  "limits-patch": { key: "limitsPatch", set: "catalog", shape: "object" },
399
400
  "long-context-cost": { key: "longContext", set: "catalog", shape: "object" },
400
401
  "prompt-cache": { key: "promptCache", set: "catalog", shape: "object" },
@@ -0,0 +1,25 @@
1
+ import { toModelSpec } from "../provider-models/bundled-references";
2
+ import type { Model } from "../types";
3
+ import { resolveCatalogAxes } from "./resolve";
4
+
5
+ const imageBudgetCache = new Map<string, number | null>();
6
+ const IMAGE_BUDGET_CACHE_MAX = 8192;
7
+
8
+ /**
9
+ * Maximum encoded inline-image bytes retained per request for a deployment with a documented body-size limit.
10
+ * The axis is a host contract: a rerouted `baseUrl` (proxy, gateway) imposes its own limit, so the budget
11
+ * applies only while the model targets its official endpoint.
12
+ */
13
+ export function resolveInlineImageByteBudget(model: Model): number | undefined {
14
+ const compat = model.compat;
15
+ if (!compat || !("officialEndpoint" in compat) || !compat.officialEndpoint) return undefined;
16
+ const key = `${model.provider} ${model.id} ${model.api}`;
17
+ let budget = imageBudgetCache.get(key);
18
+ if (budget === undefined) {
19
+ const value = resolveCatalogAxes(toModelSpec(model)).inlineImageByteBudget;
20
+ budget = typeof value === "number" && Number.isFinite(value) && value > 0 ? value : null;
21
+ if (imageBudgetCache.size >= IMAGE_BUDGET_CACHE_MAX) imageBudgetCache.clear();
22
+ imageBudgetCache.set(key, budget);
23
+ }
24
+ return budget ?? undefined;
25
+ }
@@ -217,6 +217,8 @@ One object axis carries a computed form: `long-context-cost` accepts either the
217
217
 
218
218
  `context-window-authoritative #true` preserves a host's supplied context window through runtime model selection instead of applying inferred expansion or reference-price-tier caps. Explicit user context overrides still apply afterward. It applies to rows materialized through `buildModel` (discovery and regenerated bundles). See [`providers/factory-droid.kdl`](providers/factory-droid.kdl).
219
219
 
220
+ `inline-image-byte-budget` caps retained base64 image characters for a deployment's request body. It leaves room for tool schemas and text beneath the provider's body-size limit; the coding agent reads it through `resolveInlineImageByteBudget` before sending live history. The budget applies only while `compat.officialEndpoint` holds: a custom `baseUrl` imposes its own body limit.
221
+
220
222
  The routed-subscription registry axes (`upstream-rotation`, `region-upstreams-global|us|eu`, `region-limits-eu`, `credit-rates`, `list-price-from`, `routing-family`, `policy-aliases`, `entitlement`, `default-reasoning-off`) describe a gateway whose proxy fans one model out to several upstreams. They are read through `src/compat/factory-droid.ts` by Factory Droid discovery and its request provider, not materialized by `buildModel`. A provider-wide `region-upstreams-*` rule is the upstream serving table and a model rule replaces it for that region. `list-price-from "<provider>" ["<id>"]` shows a bundled row's list price beside the subscription's own billing; unlike seed values it is resolved at runtime and degrades to the seed's zero cost when the row is gone. See [`providers/factory-droid.kdl`](providers/factory-droid.kdl), whose wire and billing pool per model are `api-routes` and `quota-tiers` rules in `runtime/behavior.kdl`.
221
223
 
222
224
  ### Time-based pricing
@@ -68,6 +68,13 @@ provider "anthropic" {
68
68
  // combines this fact with a per-request effective-URL check, so it never
69
69
  // authorizes a block on its own.
70
70
  first-party-provider #true
71
+ // Messages requests cap at 32 MB. Reserve 8 MB for text, tools, and JSON
72
+ // framing when retaining inline base64 images in a long conversation.
73
+ // Applied only on the official endpoint; a custom baseUrl has its own limit.
74
+ // https://platform.claude.com/docs/en/api/overview#request-size-limits
75
+ on-api "anthropic-messages" {
76
+ inline-image-byte-budget 24000000
77
+ }
71
78
  class "anthropic" {
72
79
  revision ">=3.7 <4.6" {
73
80
  thinking-efforts "minimal" "low" "medium" "high" "xhigh"