@pydantic/genai-prices 0.0.23 → 0.0.24

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/dist/index.d.cts CHANGED
@@ -1,3 +1,9 @@
1
+ export declare interface ArrayMatch {
2
+ field: string;
3
+ match: MatchLogic;
4
+ type: 'array-match';
5
+ }
6
+
1
7
  export declare function calcPrice(usage: Usage, modelId: string, options?: PriceOptions): PriceCalculationResult;
2
8
 
3
9
  export declare interface ConditionalPrice {
@@ -5,6 +11,8 @@ export declare interface ConditionalPrice {
5
11
  prices: ModelPrice;
6
12
  }
7
13
 
14
+ export declare type ExtractPath = (ArrayMatch | string)[] | string;
15
+
8
16
  export declare function extractUsage(provider: Provider, responseData: unknown, apiFlavor?: string): [string, Usage];
9
17
 
10
18
  export declare function findProvider(options: ProviderFindOptions): Provider | undefined;
@@ -140,13 +148,13 @@ export declare interface Usage {
140
148
  export declare interface UsageExtractor {
141
149
  api_flavor: string;
142
150
  mappings: UsageExtractorMapping[];
143
- model_path: string | string[];
144
- root: string | string[];
151
+ model_path: ExtractPath;
152
+ root: ExtractPath;
145
153
  }
146
154
 
147
155
  export declare interface UsageExtractorMapping {
148
156
  dest: 'cache_audio_read_tokens' | 'cache_read_tokens' | 'cache_write_tokens' | 'input_audio_tokens' | 'input_tokens' | 'output_audio_tokens' | 'output_tokens';
149
- path: string | string[];
157
+ path: ExtractPath;
150
158
  required: boolean;
151
159
  }
152
160
 
package/dist/index.d.ts CHANGED
@@ -1,3 +1,9 @@
1
+ export declare interface ArrayMatch {
2
+ field: string;
3
+ match: MatchLogic;
4
+ type: 'array-match';
5
+ }
6
+
1
7
  export declare function calcPrice(usage: Usage, modelId: string, options?: PriceOptions): PriceCalculationResult;
2
8
 
3
9
  export declare interface ConditionalPrice {
@@ -5,6 +11,8 @@ export declare interface ConditionalPrice {
5
11
  prices: ModelPrice;
6
12
  }
7
13
 
14
+ export declare type ExtractPath = (ArrayMatch | string)[] | string;
15
+
8
16
  export declare function extractUsage(provider: Provider, responseData: unknown, apiFlavor?: string): [string, Usage];
9
17
 
10
18
  export declare function findProvider(options: ProviderFindOptions): Provider | undefined;
@@ -140,13 +148,13 @@ export declare interface Usage {
140
148
  export declare interface UsageExtractor {
141
149
  api_flavor: string;
142
150
  mappings: UsageExtractorMapping[];
143
- model_path: string | string[];
144
- root: string | string[];
151
+ model_path: ExtractPath;
152
+ root: ExtractPath;
145
153
  }
146
154
 
147
155
  export declare interface UsageExtractorMapping {
148
156
  dest: 'cache_audio_read_tokens' | 'cache_read_tokens' | 'cache_write_tokens' | 'input_audio_tokens' | 'input_tokens' | 'output_audio_tokens' | 'output_tokens';
149
- path: string | string[];
157
+ path: ExtractPath;
150
158
  required: boolean;
151
159
  }
152
160
 
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- const f = [
1
+ const w = [
2
2
  {
3
3
  id: "anthropic",
4
4
  name: "Anthropic",
@@ -1519,8 +1519,8 @@ Compared to other leading proprietary and open-weights models Command A delivers
1519
1519
  extractors: [
1520
1520
  {
1521
1521
  api_flavor: "default",
1522
- root: "UsageMetadata",
1523
- model_path: "model",
1522
+ root: "usageMetadata",
1523
+ model_path: "modelVersion",
1524
1524
  mappings: [
1525
1525
  {
1526
1526
  path: "promptTokenCount",
@@ -1528,10 +1528,35 @@ Compared to other leading proprietary and open-weights models Command A delivers
1528
1528
  required: !0
1529
1529
  },
1530
1530
  {
1531
- path: "cachedContentTokenCount",
1531
+ path: [
1532
+ "cacheTokensDetails",
1533
+ {
1534
+ type: "array-match",
1535
+ field: "modality",
1536
+ match: {
1537
+ equals: "TEXT"
1538
+ }
1539
+ },
1540
+ "tokenCount"
1541
+ ],
1532
1542
  dest: "cache_read_tokens",
1533
1543
  required: !1
1534
1544
  },
1545
+ {
1546
+ path: [
1547
+ "cacheTokensDetails",
1548
+ {
1549
+ type: "array-match",
1550
+ field: "modality",
1551
+ match: {
1552
+ equals: "AUDIO"
1553
+ }
1554
+ },
1555
+ "tokenCount"
1556
+ ],
1557
+ dest: "cache_audio_read_tokens",
1558
+ required: !1
1559
+ },
1535
1560
  {
1536
1561
  path: "candidatesTokenCount",
1537
1562
  dest: "output_tokens",
@@ -10856,23 +10881,23 @@ Compared to other leading proprietary and open-weights models Command A delivers
10856
10881
  ]
10857
10882
  }
10858
10883
  ];
10859
- function x(t, e) {
10884
+ function y(t, e) {
10860
10885
  if (e <= 0) return 0;
10861
10886
  let a = 0;
10862
- const i = [...t.tiers].sort((r, s) => r.start - s.start), o = i[0]?.start ?? e, m = Math.min(e, o);
10863
- a += m * t.base / 1e6;
10887
+ const i = [...t.tiers].sort((r, s) => r.start - s.start), o = i[0]?.start ?? e, n = Math.min(e, o);
10888
+ a += n * t.base / 1e6;
10864
10889
  for (let r = 0; r < i.length; r++) {
10865
- const s = i[r], n = i[r + 1]?.start ?? 1 / 0, u = Math.max(0, Math.min(e, n) - s.start);
10890
+ const s = i[r], m = i[r + 1]?.start ?? 1 / 0, u = Math.max(0, Math.min(e, m) - s.start);
10866
10891
  u > 0 && (a += u * s.price / 1e6);
10867
10892
  }
10868
10893
  return a;
10869
10894
  }
10870
- function l(t, e, a) {
10871
- return t === void 0 || e === void 0 ? 0 : typeof t == "number" ? t * e / 1e6 : x(t, e);
10895
+ function p(t, e, a) {
10896
+ return t === void 0 || e === void 0 ? 0 : typeof t == "number" ? t * e / 1e6 : y(t, e);
10872
10897
  }
10873
- function B(t, e) {
10898
+ function M(t, e) {
10874
10899
  let a = 0, i = 0;
10875
- a += l(e.input_mtok, t.input_tokens), a += l(e.cache_write_mtok, t.cache_write_tokens), a += l(e.cache_read_mtok, t.cache_read_tokens), a += l(e.input_audio_mtok, t.input_audio_tokens), a += l(e.cache_audio_read_mtok, t.cache_audio_read_tokens), i += l(e.output_mtok, t.output_tokens), i += l(e.output_audio_mtok, t.output_audio_tokens), e.requests_kcount !== void 0 && (a += e.requests_kcount / 1e3);
10900
+ a += p(e.input_mtok, t.input_tokens), a += p(e.cache_write_mtok, t.cache_write_tokens), a += p(e.cache_read_mtok, t.cache_read_tokens), a += p(e.input_audio_mtok, t.input_audio_tokens), a += p(e.cache_audio_read_mtok, t.cache_audio_read_tokens), i += p(e.output_mtok, t.output_tokens), i += p(e.output_audio_mtok, t.output_audio_tokens), e.requests_kcount !== void 0 && (a += e.requests_kcount / 1e3);
10876
10901
  const o = a + i;
10877
10902
  return {
10878
10903
  input_price: a,
@@ -10880,7 +10905,7 @@ function B(t, e) {
10880
10905
  total_price: o
10881
10906
  };
10882
10907
  }
10883
- function y(t, e) {
10908
+ function I(t, e) {
10884
10909
  if (!Array.isArray(t.prices))
10885
10910
  return t.prices;
10886
10911
  for (let a = t.prices.length - 1; a >= 0; a--) {
@@ -10891,150 +10916,167 @@ function y(t, e) {
10891
10916
  if (e >= new Date(o.start_date))
10892
10917
  return i.prices;
10893
10918
  } else {
10894
- const m = e.toISOString().slice(11, 19), r = o.start_time, s = o.end_time;
10919
+ const n = e.toISOString().slice(11, 19), r = o.start_time, s = o.end_time;
10895
10920
  if (s < r) {
10896
- if (m >= r || m < s)
10921
+ if (n >= r || n < s)
10897
10922
  return i.prices;
10898
- } else if (m >= r && m < s)
10923
+ } else if (n >= r && n < s)
10899
10924
  return i.prices;
10900
10925
  }
10901
10926
  }
10902
10927
  return t.prices[0].prices;
10903
10928
  }
10904
- function d(t, e) {
10905
- return "or" in t ? t.or.some((a) => d(a, e)) : "and" in t ? t.and.every((a) => d(a, e)) : "equals" in t ? e === t.equals : "starts_with" in t ? e.startsWith(t.starts_with) : "ends_with" in t ? e.endsWith(t.ends_with) : "contains" in t ? e.includes(t.contains) : "regex" in t ? new RegExp(t.regex).test(e) : !1;
10929
+ function h(t, e) {
10930
+ return "or" in t ? t.or.some((a) => h(a, e)) : "and" in t ? t.and.every((a) => h(a, e)) : "equals" in t ? e === t.equals : "starts_with" in t ? e.startsWith(t.starts_with) : "ends_with" in t ? e.endsWith(t.ends_with) : "contains" in t ? e.includes(t.contains) : "regex" in t ? new RegExp(t.regex).test(e) : !1;
10906
10931
  }
10907
- function M(t, e) {
10932
+ function P(t, e) {
10908
10933
  const a = e.toLowerCase().trim(), i = t.find((o) => o.id === a);
10909
- return i || t.find((o) => o.provider_match && d(o.provider_match, a));
10934
+ return i || t.find((o) => o.provider_match && h(o.provider_match, a));
10910
10935
  }
10911
- function w(t, { modelId: e, providerApiUrl: a, providerId: i }) {
10936
+ function v(t, { modelId: e, providerApiUrl: a, providerId: i }) {
10912
10937
  if (i)
10913
- return M(t, i);
10938
+ return P(t, i);
10914
10939
  if (a)
10915
10940
  return t.find((o) => new RegExp(o.api_pattern).test(a));
10916
10941
  if (e)
10917
- return t.find((o) => o.model_match && d(o.model_match, e));
10942
+ return t.find((o) => o.model_match && h(o.model_match, e));
10918
10943
  }
10919
- function I(t, e) {
10920
- return t.find((a) => d(a.match, e));
10944
+ function L(t, e) {
10945
+ return t.find((a) => h(a.match, e));
10921
10946
  }
10922
- const P = "https://raw.githubusercontent.com/pydantic/genai-prices/main/prices/data.json";
10923
- let h = f, g = Promise.resolve(f), q = null;
10924
- function L(t) {
10925
- "then" in t ? (g = t, t.then((e) => {
10926
- h = e;
10927
- })) : (g = Promise.resolve(t), h = t);
10947
+ const T = "https://raw.githubusercontent.com/pydantic/genai-prices/main/prices/data.json";
10948
+ let _ = w, q = Promise.resolve(w), b = null;
10949
+ function G(t) {
10950
+ "then" in t ? (q = t, t.then((e) => {
10951
+ _ = e;
10952
+ })) : (q = Promise.resolve(t), _ = t);
10928
10953
  }
10929
- function T(t) {
10930
- q = t;
10954
+ function S(t) {
10955
+ b = t;
10931
10956
  }
10932
- function R(t) {
10957
+ function z(t) {
10933
10958
  t({
10934
- onCalc: T,
10935
- remoteDataUrl: P,
10936
- setProviderData: L
10959
+ onCalc: S,
10960
+ remoteDataUrl: T,
10961
+ setProviderData: G
10937
10962
  });
10938
10963
  }
10939
- function A() {
10940
- return g;
10964
+ function N() {
10965
+ return q;
10941
10966
  }
10942
- function C(t, e, a) {
10943
- q?.();
10944
- const i = e.toLowerCase().trim(), o = a?.provider ?? w(h, { modelId: i, providerApiUrl: a?.providerApiUrl, providerId: a?.providerId });
10967
+ function Q(t, e, a) {
10968
+ b?.();
10969
+ const i = e.toLowerCase().trim(), o = a?.provider ?? v(_, { modelId: i, providerApiUrl: a?.providerApiUrl, providerId: a?.providerId });
10945
10970
  if (!o) return null;
10946
- const m = I(o.models, i);
10947
- if (!m) return null;
10948
- const r = a?.timestamp ?? /* @__PURE__ */ new Date(), s = y(m, r), n = B(t, s);
10971
+ const n = L(o.models, i);
10972
+ if (!n) return null;
10973
+ const r = a?.timestamp ?? /* @__PURE__ */ new Date(), s = I(n, r), m = M(t, s);
10949
10974
  return {
10950
10975
  auto_update_timestamp: void 0,
10951
- model: m,
10976
+ model: n,
10952
10977
  model_price: s,
10953
10978
  provider: o,
10954
- ...n
10979
+ ...m
10955
10980
  };
10956
10981
  }
10957
- function z(t) {
10958
- return q?.(), w(h, t);
10982
+ function E(t) {
10983
+ return b?.(), v(_, t);
10959
10984
  }
10960
- function N(t, e, a) {
10985
+ function O(t, e, a) {
10961
10986
  if (!t.extractors)
10962
10987
  throw new Error("No extraction logic defined for this provider");
10963
10988
  let i;
10964
10989
  if (a) {
10965
- const n = t.extractors.find((u) => u.api_flavor === a);
10966
- if (n)
10967
- i = n;
10990
+ const m = t.extractors.find((u) => u.api_flavor === a);
10991
+ if (m)
10992
+ i = m;
10968
10993
  else {
10969
- const u = t.extractors.map((p) => p.api_flavor).join(", ");
10994
+ const u = t.extractors.map((l) => l.api_flavor).join(", ");
10970
10995
  throw new Error(`Unknown apiFlavor '${a}', allowed values: ${u}`);
10971
10996
  }
10972
10997
  } else if (t.extractors.length === 1)
10973
10998
  i = t.extractors[0];
10974
10999
  else
10975
11000
  throw new Error("No apiFlavor specified and multiple extractors available");
10976
- if (!b.guard(e))
11001
+ if (!k.guard(e))
10977
11002
  throw new Error(`Expected response data to be a mapping object, got ${c(e)}`);
10978
- const o = _(i.model_path, e, G, !0, []), m = v(i.root), r = _(m, e, b, !0, []), s = {};
10979
- for (const n of i.mappings) {
10980
- const u = _(n.path, r, S, n.required, m);
11003
+ const o = g(i.model_path, e, A, !0, []), n = x(i.root), r = g(n, e, k, !0, []), s = {};
11004
+ for (const m of i.mappings) {
11005
+ const u = g(m.path, r, C, m.required, n);
10981
11006
  if (u !== null) {
10982
- const p = s[n.dest] ?? 0;
10983
- s[n.dest] = p + u;
11007
+ const l = s[m.dest] ?? 0;
11008
+ s[m.dest] = l + u;
10984
11009
  }
10985
11010
  }
10986
11011
  if (!Object.keys(s).length)
10987
11012
  throw new Error(`No usage information found at ${JSON.stringify(i.root)}`);
10988
11013
  return [o, s];
10989
11014
  }
10990
- function _(t, e, a, i, o) {
10991
- const [m, ...r] = v(t).reverse();
10992
- if (typeof m != "string")
10993
- throw new Error(`Expected last step of path to be a string, got ${c(m)}`);
10994
- let s = e;
11015
+ function g(t, e, a, i, o) {
11016
+ const [n, ...r] = x(t).reverse();
11017
+ if (typeof n != "string")
11018
+ throw new Error(`Expected last step of path to be a string, got ${c(n)}`);
10995
11019
  r.reverse();
10996
- const n = [];
10997
- for (const p of r) {
10998
- n.push(p), s = s[p];
10999
- const k = c(s);
11000
- if (k === "undefined") {
11001
- if (i)
11002
- throw new Error(`Missing value at \`${[...o, ...n].join(".")}\``);
11003
- return null;
11004
- } else if (k !== "mapping")
11005
- throw new Error(`Expected \`${[...o, ...n].join(".")}\` value to be a mapping, got ${k}`);
11020
+ let s = e;
11021
+ const m = [];
11022
+ for (const l of r) {
11023
+ if (m.push(l), typeof l == "object")
11024
+ if (Array.isArray(s))
11025
+ s = R(l, s);
11026
+ else
11027
+ throw new Error(`Expected \`${d(o, m)}\` value to be a mapping, got ${c(s)}`);
11028
+ else if (k.guard(s))
11029
+ s = s[l];
11030
+ else
11031
+ throw new Error(`Expected \`${d(o, m)}\` value to be a mapping, got ${c(s)}`);
11032
+ if (typeof s > "u")
11033
+ if (i) {
11034
+ const B = typeof l == "object" ? "Unable to find item" : "Missing value";
11035
+ throw new Error(`${B} at \`${d(o, m)}\``);
11036
+ } else
11037
+ return null;
11006
11038
  }
11007
- const u = s[m];
11039
+ if (!k.guard(s))
11040
+ throw new Error(`Expected \`${d(o, m)}\` value to be a mapping, got ${c(s)}`);
11041
+ const u = s[n];
11008
11042
  if (typeof u > "u") {
11009
11043
  if (i)
11010
- throw n.push(m), new Error(`Missing value at \`${[...o, ...n].join(".")}\``);
11044
+ throw m.push(n), new Error(`Missing value at \`${d(o, m)}\``);
11011
11045
  return null;
11012
11046
  }
11013
11047
  if (a.guard(u))
11014
11048
  return u;
11015
- throw n.push(m), new Error(`Expected \`${[...o, ...n].join(".")}\` value to be a ${a.name}, got ${c(u)}`);
11049
+ throw m.push(n), new Error(`Expected \`${d(o, m)}\` value to be a ${a.name}, got ${c(u)}`);
11050
+ }
11051
+ function R(t, e) {
11052
+ for (const a of e)
11053
+ if (k.guard(a)) {
11054
+ const i = a[t.field];
11055
+ if (typeof i == "string" && h(t.match, i))
11056
+ return a;
11057
+ }
11016
11058
  }
11017
- function v(t) {
11059
+ function x(t) {
11018
11060
  return Array.isArray(t) ? [...t] : [t];
11019
11061
  }
11020
11062
  function c(t) {
11021
11063
  return t === null ? "null" : Array.isArray(t) ? "array" : typeof t == "object" ? "mapping" : typeof t;
11022
11064
  }
11023
- const b = {
11065
+ const k = {
11024
11066
  guard: (t) => c(t) === "mapping",
11025
11067
  name: "mapping"
11026
- }, G = {
11068
+ }, A = {
11027
11069
  guard: (t) => typeof t == "string",
11028
11070
  name: "string"
11029
- }, S = {
11071
+ }, C = {
11030
11072
  guard: (t) => typeof t == "number",
11031
11073
  name: "number"
11032
- };
11074
+ }, d = (t, e) => [...t.map(f), ...e.map(f)].join("."), f = (t) => typeof t == "string" ? t : JSON.stringify(t);
11033
11075
  export {
11034
- P as REMOTE_DATA_JSON_URL,
11035
- C as calcPrice,
11036
- N as extractUsage,
11037
- z as findProvider,
11038
- R as updatePrices,
11039
- A as waitForUpdate
11076
+ T as REMOTE_DATA_JSON_URL,
11077
+ Q as calcPrice,
11078
+ O as extractUsage,
11079
+ E as findProvider,
11080
+ z as updatePrices,
11081
+ N as waitForUpdate
11040
11082
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pydantic/genai-prices",
3
- "version": "0.0.23",
3
+ "version": "0.0.24",
4
4
  "description": "Calculate prices for calling LLM inference APIs",
5
5
  "author": "Pydantic Team",
6
6
  "type": "module",