@oh-my-pi/pi-catalog 17.1.7 → 17.1.8
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 +10 -0
- package/dist/types/hosts.d.ts +13 -0
- package/package.json +3 -3
- package/src/hosts.ts +18 -0
- package/src/models.ts +29 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [17.1.8] - 2026-07-28
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added `resolveVertexEndpointHost(location)` utility to resolve the correct Vertex AI API endpoint hostnames for global, multi-region, and regional locations.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Fixed an issue where `calculateCost` under-reported Anthropic cache-write costs by honoring the `usage.cttl` breakdown to correctly price 1-hour retention writes at 2x the base input rate.
|
|
14
|
+
|
|
5
15
|
## [17.1.7] - 2026-07-27
|
|
6
16
|
|
|
7
17
|
### Added
|
package/dist/types/hosts.d.ts
CHANGED
|
@@ -136,6 +136,19 @@ export declare function modelMatchesHost(model: {
|
|
|
136
136
|
provider: string;
|
|
137
137
|
baseUrl: string;
|
|
138
138
|
}, host: KnownHost): boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Hostname for a Vertex AI GenerateContent / rawPredict / OpenAI-compat
|
|
141
|
+
* request for the given location.
|
|
142
|
+
*
|
|
143
|
+
* - `global` → global endpoint (`aiplatform.googleapis.com`)
|
|
144
|
+
* - `eu` / `us` multi-regions → REP endpoints (`aiplatform.{eu|us}.rep.googleapis.com`)
|
|
145
|
+
* - every other location → regional (`{location}-aiplatform.googleapis.com`)
|
|
146
|
+
*
|
|
147
|
+
* Multi-region codes do NOT follow the regional `{location}-aiplatform` pattern;
|
|
148
|
+
* interpolating them that way yields hosts like `eu-aiplatform.googleapis.com`
|
|
149
|
+
* that 404.
|
|
150
|
+
*/
|
|
151
|
+
export declare function resolveVertexEndpointHost(location: string): string;
|
|
139
152
|
/** Vertex AI express-mode OpenAI-compatible endpoint (`…/endpoints/openapi`). */
|
|
140
153
|
export declare function isVertexExpressOpenAIUrl(baseUrl: string): boolean;
|
|
141
154
|
/** Vertex AI Anthropic raw-predict endpoints (`:streamRawPredict` / `:rawPredict`). */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-catalog",
|
|
4
|
-
"version": "17.1.
|
|
4
|
+
"version": "17.1.8",
|
|
5
5
|
"description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@bufbuild/protobuf": "^2.12.1",
|
|
37
|
-
"@oh-my-pi/pi-utils": "17.1.
|
|
37
|
+
"@oh-my-pi/pi-utils": "17.1.8",
|
|
38
38
|
"arktype": "2.2.3",
|
|
39
39
|
"zod": "^4"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@oh-my-pi/pi-ai": "17.1.
|
|
42
|
+
"@oh-my-pi/pi-ai": "17.1.8",
|
|
43
43
|
"@types/bun": "^1.3.14"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|
package/src/hosts.ts
CHANGED
|
@@ -111,6 +111,24 @@ function includesAsciiCaseInsensitive(value: string, lowerNeedle: string): boole
|
|
|
111
111
|
|
|
112
112
|
// --- Endpoint-shape predicates (URL path/verb shapes, not vendor hosts) ---
|
|
113
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Hostname for a Vertex AI GenerateContent / rawPredict / OpenAI-compat
|
|
116
|
+
* request for the given location.
|
|
117
|
+
*
|
|
118
|
+
* - `global` → global endpoint (`aiplatform.googleapis.com`)
|
|
119
|
+
* - `eu` / `us` multi-regions → REP endpoints (`aiplatform.{eu|us}.rep.googleapis.com`)
|
|
120
|
+
* - every other location → regional (`{location}-aiplatform.googleapis.com`)
|
|
121
|
+
*
|
|
122
|
+
* Multi-region codes do NOT follow the regional `{location}-aiplatform` pattern;
|
|
123
|
+
* interpolating them that way yields hosts like `eu-aiplatform.googleapis.com`
|
|
124
|
+
* that 404.
|
|
125
|
+
*/
|
|
126
|
+
export function resolveVertexEndpointHost(location: string): string {
|
|
127
|
+
if (location === "global") return "aiplatform.googleapis.com";
|
|
128
|
+
if (location === "eu" || location === "us") return `aiplatform.${location}.rep.googleapis.com`;
|
|
129
|
+
return `${location}-aiplatform.googleapis.com`;
|
|
130
|
+
}
|
|
131
|
+
|
|
114
132
|
/** Vertex AI express-mode OpenAI-compatible endpoint (`…/endpoints/openapi`). */
|
|
115
133
|
export function isVertexExpressOpenAIUrl(baseUrl: string): boolean {
|
|
116
134
|
return baseUrl.includes("/endpoints/openapi");
|
package/src/models.ts
CHANGED
|
@@ -48,10 +48,38 @@ export function calculateCost<TApi extends Api>(model: Model<TApi>, usage: Usage
|
|
|
48
48
|
usage.cost.input = (model.cost.input / 1000000) * (usage.input + (orchestration?.input ?? 0));
|
|
49
49
|
usage.cost.output = (model.cost.output / 1000000) * (usage.output + (orchestration?.output ?? 0));
|
|
50
50
|
usage.cost.cacheRead = (model.cost.cacheRead / 1000000) * (usage.cacheRead + (orchestration?.cacheRead ?? 0));
|
|
51
|
-
usage.cost.cacheWrite = (model
|
|
51
|
+
usage.cost.cacheWrite = cacheWriteCost(model, usage);
|
|
52
52
|
usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
|
|
53
53
|
return usage.cost;
|
|
54
54
|
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Price cache-write tokens, honoring the TTL breakdown when the provider reports one.
|
|
58
|
+
*
|
|
59
|
+
* `model.cost.cacheWrite` is the 5-minute write rate (Anthropic bills 5m writes at
|
|
60
|
+
* 1.25x base input). When `usage.cttl` is present the write mixes 5m and 1h
|
|
61
|
+
* breakpoints — omp defaults to 1h retention on first-party Anthropic, and 1h writes
|
|
62
|
+
* bill at 2x base input — so each component is priced at its own rate instead of the
|
|
63
|
+
* flat 5m rate. Deriving 1h from `input * 2` (Anthropic's published multiplier) is
|
|
64
|
+
* model-independent and stays correct even for legacy entries whose stored
|
|
65
|
+
* `cacheWrite` scalar drifts from 1.25x input. Providers that omit `cttl`
|
|
66
|
+
* (everyone but Anthropic) keep the flat-rate calculation.
|
|
67
|
+
*
|
|
68
|
+
* The breakdown is documented to sum to `usage.cacheWrite`, but the two are written
|
|
69
|
+
* from independent wire fields (`cache_creation` vs `cache_creation_input_tokens`),
|
|
70
|
+
* so any unattributed remainder is priced at the flat rate instead of being dropped:
|
|
71
|
+
* a partial or stale breakdown must never make write tokens free.
|
|
72
|
+
*/
|
|
73
|
+
function cacheWriteCost<TApi extends Api>(model: Model<TApi>, usage: Usage): number {
|
|
74
|
+
const rate5m = model.cost.cacheWrite / 1000000;
|
|
75
|
+
const cttl = usage.cttl;
|
|
76
|
+
if (!cttl) return rate5m * usage.cacheWrite;
|
|
77
|
+
const fiveMinute = cttl.ephemeral5m ?? 0;
|
|
78
|
+
const oneHour = cttl.ephemeral1h ?? 0;
|
|
79
|
+
const residual = Math.max(0, usage.cacheWrite - fiveMinute - oneHour);
|
|
80
|
+
return rate5m * (fiveMinute + residual) + ((model.cost.input * 2) / 1000000) * oneHour;
|
|
81
|
+
}
|
|
82
|
+
|
|
55
83
|
/**
|
|
56
84
|
* Check if two models are equal by comparing both their id and provider.
|
|
57
85
|
* Returns false if either model is null or undefined.
|