@oh-my-pi/pi-catalog 18.3.3 → 18.3.5

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,13 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [18.3.5] - 2026-09-27
6
+
7
+ ### Added
8
+
9
+ - Added the `openai` web-search grounding for OpenAI API models that support Responses web search (`gpt-5.5`, `gpt-5.6-luna`, `gpt-6-astra`, `gpt-6-luna`) ([#13467](https://github.com/can1357/oh-my-pi/pull/13467) by [@anatoli-tsinovoy](https://github.com/anatoli-tsinovoy)).
10
+ - Added `Model.promptCache`, per-retention-tier prompt-cache entry lifetimes in seconds (`short` / `long`), declared per provider through the `prompt-cache` KDL rule (bundled: direct Anthropic, 5 min / 1 h). Custom models and `modelOverrides` opt in with the models.yml `promptCache` key ([#12699](https://github.com/can1357/oh-my-pi/pull/12699) by [@KamijoToma](https://github.com/KamijoToma)).
11
+
5
12
  ## [18.3.1] - 2026-09-25
6
13
 
7
14
  ### Added
@@ -12,7 +12,7 @@ export type ModelKind = (typeof MODEL_KINDS)[number];
12
12
  export declare const KIND_API_KINDS: readonly ["image", "tts", "stt", "embedding", "rerank", "video"];
13
13
  export type KindApiKind = (typeof KIND_API_KINDS)[number];
14
14
  /** Grounding transport available to chat models selected by the web role. */
15
- export type WebSearchGrounding = "gemini" | "anthropic" | "codex" | "xai" | "openrouter";
15
+ export type WebSearchGrounding = "gemini" | "anthropic" | "codex" | "xai" | "openrouter" | "openai";
16
16
  /** Non-chat runner protocols accepted by catalog seeds, outside the chat dispatch union. */
17
17
  export declare const RUNNER_APIS: readonly ["local-inference", "web-search", "typesafe", "openrouter-decisions", "openai-images", "openrouter-images", "xai-tts", "openai-speech", "openai-embeddings", "openrouter-rerank", "openrouter-video", "openai-transcriptions"];
18
18
  /** Resolve a model's kind while preserving chat semantics for existing catalog rows. */
@@ -951,6 +951,12 @@ export interface TimeBasedCost {
951
951
  peakWindows: readonly PeakPricingWindow[];
952
952
  effectiveRates?: readonly EffectiveTokenCost[];
953
953
  }
954
+ /**
955
+ * Best-effort prompt-cache entry lifetime in seconds for each retention tier a
956
+ * request can ask for. A missing tier means the lifetime is unknown; consumers
957
+ * must not schedule cache warming against unknown lifetimes.
958
+ */
959
+ export type ModelPromptCache = Partial<Record<"short" | "long", number>>;
954
960
  /** Base token rates plus optional long-context and time-based pricing. */
955
961
  export interface ModelCost extends TokenCost {
956
962
  longContext?: LongContextTokenCost;
@@ -1077,6 +1083,14 @@ export interface Model<TApi extends Api = Api> {
1077
1083
  */
1078
1084
  accountAccess?: Readonly<Record<string, ModelAccountAccess>>;
1079
1085
  cost: ModelCost;
1086
+ /**
1087
+ * Prompt-cache entry lifetime per retention tier, in seconds. Populated only
1088
+ * for providers whose cache-expiry and replay behavior has been validated
1089
+ * for cache warming (direct Anthropic: 5m / 1h). A missing entry means the
1090
+ * provider's cache behavior is unknown — such models are never warmed.
1091
+ * Custom models and provider overrides opt in via models.yml `promptCache`.
1092
+ */
1093
+ promptCache?: ModelPromptCache;
1080
1094
  /** Premium Copilot requests charged per user-initiated request (defaults to 1). */
1081
1095
  premiumMultiplier?: number;
1082
1096
  contextWindow: number | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oh-my-pi/pi-catalog",
3
- "version": "18.3.3",
3
+ "version": "18.3.5",
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.3.3",
97
- "@oh-my-pi/pi-utils": "18.3.3"
96
+ "@oh-my-pi/omptype": "18.3.5",
97
+ "@oh-my-pi/pi-utils": "18.3.5"
98
98
  },
99
99
  "devDependencies": {
100
100
  "@bgotink/kdl": "0.4.0",
101
- "@oh-my-pi/pi-ai": "18.3.3",
101
+ "@oh-my-pi/pi-ai": "18.3.5",
102
102
  "@types/bun": "^1.3.14"
103
103
  },
104
104
  "engines": {
package/src/build.ts CHANGED
@@ -82,7 +82,8 @@ function applyCatalogAssignments<TApi extends Api>(model: Model<TApi>, catalog:
82
82
  webSearch === "anthropic" ||
83
83
  webSearch === "codex" ||
84
84
  webSearch === "xai" ||
85
- webSearch === "openrouter"
85
+ webSearch === "openrouter" ||
86
+ webSearch === "openai"
86
87
  ) {
87
88
  model.webSearch = webSearch;
88
89
  }
@@ -97,6 +98,15 @@ function applyCatalogAssignments<TApi extends Api>(model: Model<TApi>, catalog:
97
98
  }
98
99
  const priority = catalog.priority;
99
100
  if (typeof priority === "number") model.priority = priority;
101
+ const promptCache = objectPayload(catalog.promptCache);
102
+ if (promptCache !== undefined) {
103
+ const short = numberField(promptCache, "short");
104
+ const long = numberField(promptCache, "long");
105
+ model.promptCache = {
106
+ ...(short !== undefined && { short }),
107
+ ...(long !== undefined && { long }),
108
+ };
109
+ }
100
110
  const applyPatchToolType = catalog.applyPatchToolType;
101
111
  if (applyPatchToolType === "freeform" || applyPatchToolType === "function") {
102
112
  model.applyPatchToolType = applyPatchToolType;
@@ -331,10 +331,11 @@ export const AXES: Readonly<Record<string, AxisDef>> = {
331
331
  key: "webSearch",
332
332
  set: "catalog",
333
333
  shape: "scalar",
334
- values: ["gemini", "anthropic", "codex", "xai", "openrouter"],
334
+ values: ["gemini", "anthropic", "codex", "xai", "openrouter", "openai"],
335
335
  },
336
336
  "limits-patch": { key: "limitsPatch", set: "catalog", shape: "object" },
337
337
  "long-context-cost": { key: "longContext", set: "catalog", shape: "object" },
338
+ "prompt-cache": { key: "promptCache", set: "catalog", shape: "object" },
338
339
  "long-usage-limit-fallback": { key: "longUsageLimitFallback", set: "catalog", shape: "scalar" },
339
340
  "max-context-window": { key: "maxContextWindow", set: "catalog", shape: "scalar" },
340
341
  "requires-cursor-tool-schema-projection": {
@@ -6,6 +6,14 @@ provider "anthropic" {
6
6
  discovery label="Anthropic"
7
7
  web-search "anthropic"
8
8
 
9
+ // Prompt-cache entry lifetimes per retention tier, in seconds; feeds the
10
+ // coding agent's cache warmer. 5m writes for pay-per-token keys, 1h for
11
+ // retention-tier "long" requests.
12
+ prompt-cache {
13
+ short 300
14
+ long 3600
15
+ }
16
+
9
17
  // Curated Anthropic models that are live or limited-availability on the
10
18
  // first-party `/v1/models` endpoint but that stencil.so has not catalogued
11
19
  // yet. Seeded so the bundled catalog is never gated on stencil.so's update
@@ -3,6 +3,12 @@
3
3
  provider "openai" {
4
4
  default-model "gpt-5.5"
5
5
  env "OPENAI_API_KEY"
6
+ // Responses web search is documented for GPT-5.5 and GPT-6 Astra, and has
7
+ // been live-verified for GPT-6 Luna and GPT-5.6 Luna. Keep this capability
8
+ // model-scoped so realtime and other unverified OpenAI models stay excluded.
9
+ models "gpt-5.5" "gpt-6-astra" "gpt-6-luna" "gpt-5.6-luna" {
10
+ web-search "openai"
11
+ }
6
12
  kind-apis {
7
13
  embedding "openai-embeddings"
8
14
  image "openai-responses"