metergraph-core 0.2.35__tar.gz → 0.2.37__tar.gz

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 (18) hide show
  1. {metergraph_core-0.2.35/src/metergraph_core.egg-info → metergraph_core-0.2.37}/PKG-INFO +8 -1
  2. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/README.md +7 -0
  3. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/pyproject.toml +1 -1
  4. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/src/metergraph_core/catalog.py +46 -0
  5. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/src/metergraph_core/data/prices.yaml +50 -2
  6. {metergraph_core-0.2.35 → metergraph_core-0.2.37/src/metergraph_core.egg-info}/PKG-INFO +8 -1
  7. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/MANIFEST.in +0 -0
  8. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/setup.cfg +0 -0
  9. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/src/metergraph_core/__init__.py +0 -0
  10. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/src/metergraph_core/billing.py +0 -0
  11. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/src/metergraph_core/data/models.yaml +0 -0
  12. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/src/metergraph_core/loader.py +0 -0
  13. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/src/metergraph_core/models.py +0 -0
  14. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/src/metergraph_core/retrieval.py +0 -0
  15. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/src/metergraph_core.egg-info/SOURCES.txt +0 -0
  16. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/src/metergraph_core.egg-info/dependency_links.txt +0 -0
  17. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/src/metergraph_core.egg-info/requires.txt +0 -0
  18. {metergraph_core-0.2.35 → metergraph_core-0.2.37}/src/metergraph_core.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: metergraph-core
3
- Version: 0.2.35
3
+ Version: 0.2.37
4
4
  Summary: Reusable MeterGraph catalog and deterministic billing engine
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: >=3.10
@@ -81,6 +81,13 @@ and surrounding whitespace, applies the configured region fallback and
81
81
  effective-date windows, and returns `None` when no exact model/channel price
82
82
  exists. It never substitutes a direct-provider price for a gateway price.
83
83
 
84
+ On Bedrock only (provider `bedrock` for `cost`, channel `aws-bedrock` or
85
+ `aws-bedrock-geo` for `resolve_price`), an id with no exact alias falls back to
86
+ the id without its model-version suffix (`anthropic.claude-sonnet-5-v1:0` to
87
+ `anthropic.claude-sonnet-5`) and then without a `global.` inference-profile
88
+ prefix, the latter only onto an `aws-bedrock` alias. Geographic prefixes such as
89
+ `us.` or `eu.` are never stripped, because they bill on `aws-bedrock-geo`.
90
+
84
91
  `LoadedCatalog.currency` is currently always `USD`, and
85
92
  `LoadedCatalog.pricing_verified_at` records when the bundled catalog was last
86
93
  checked against its linked provider sources.
@@ -69,6 +69,13 @@ and surrounding whitespace, applies the configured region fallback and
69
69
  effective-date windows, and returns `None` when no exact model/channel price
70
70
  exists. It never substitutes a direct-provider price for a gateway price.
71
71
 
72
+ On Bedrock only (provider `bedrock` for `cost`, channel `aws-bedrock` or
73
+ `aws-bedrock-geo` for `resolve_price`), an id with no exact alias falls back to
74
+ the id without its model-version suffix (`anthropic.claude-sonnet-5-v1:0` to
75
+ `anthropic.claude-sonnet-5`) and then without a `global.` inference-profile
76
+ prefix, the latter only onto an `aws-bedrock` alias. Geographic prefixes such as
77
+ `us.` or `eu.` are never stripped, because they bill on `aws-bedrock-geo`.
78
+
72
79
  `LoadedCatalog.currency` is currently always `USD`, and
73
80
  `LoadedCatalog.pricing_verified_at` records when the bundled catalog was last
74
81
  checked against its linked provider sources.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "metergraph-core"
3
- version = "0.2.35"
3
+ version = "0.2.37"
4
4
  description = "Reusable MeterGraph catalog and deterministic billing engine"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -1,5 +1,6 @@
1
1
  """Effective-dated model catalog and deterministic token-cost enrichment."""
2
2
 
3
+ import re
3
4
  from dataclasses import dataclass
4
5
  from datetime import date, datetime, timezone
5
6
  from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
@@ -71,6 +72,35 @@ _INPUT_INCLUDES_CACHE_READ_PAIRS = frozenset({
71
72
  })
72
73
 
73
74
 
75
+ # Bedrock ids carry a model-version suffix (`anthropic.claude-sonnet-5-v1:0`)
76
+ # and may name the global inference profile (`global.`). Both are fallbacks
77
+ # tried only after an exact match fails, and only on Bedrock. Geographic
78
+ # profile prefixes (`us.`, `eu.`, ...) are never stripped: they bill on
79
+ # aws-bedrock-geo, and the bare id would price them at the lower rate.
80
+ _BEDROCK_CHANNEL = "aws-bedrock"
81
+ _BEDROCK_CHANNELS = frozenset({_BEDROCK_CHANNEL, "aws-bedrock-geo"})
82
+ _BEDROCK_VERSION_SUFFIX = re.compile(r"-v\d+(?::\d+)?$")
83
+ _BEDROCK_GLOBAL_PREFIX = "global."
84
+
85
+
86
+ def _bedrock_fallback_ids(model_key: str) -> tuple[tuple[str, bool], ...]:
87
+ """Candidate ids for an unmatched Bedrock model, most specific first.
88
+
89
+ Each candidate is paired with whether it dropped the ``global.`` prefix;
90
+ such a match is only valid on the in-region ``aws-bedrock`` channel.
91
+ """
92
+ unversioned = _BEDROCK_VERSION_SUFFIX.sub("", model_key)
93
+ candidates: list[tuple[str, bool]] = []
94
+ if unversioned != model_key:
95
+ candidates.append((unversioned, False))
96
+ if model_key.startswith(_BEDROCK_GLOBAL_PREFIX):
97
+ for name in dict.fromkeys((model_key, unversioned)):
98
+ bare = name[len(_BEDROCK_GLOBAL_PREFIX):]
99
+ if bare:
100
+ candidates.append((bare, True))
101
+ return tuple(candidates)
102
+
103
+
74
104
  def counts_cache_read_in_input(
75
105
  publisher: Any, channel: Any, rules: Mapping[str, Any]
76
106
  ) -> bool:
@@ -474,6 +504,13 @@ class CatalogSnapshot:
474
504
  model_key = str(model or "").strip().lower()
475
505
  channel_key = str(channel or "").strip().lower()
476
506
  alias = self._deployment_aliases.get((model_key, channel_key))
507
+ if alias is None and channel_key in _BEDROCK_CHANNELS:
508
+ for candidate, dropped_global in _bedrock_fallback_ids(model_key):
509
+ if dropped_global and channel_key != _BEDROCK_CHANNEL:
510
+ continue
511
+ alias = self._deployment_aliases.get((candidate, channel_key))
512
+ if alias is not None:
513
+ break
477
514
  if alias is None:
478
515
  return None
479
516
  price = self._price_for(alias, at)
@@ -503,6 +540,15 @@ class CatalogSnapshot:
503
540
  provider_key = _PROVIDER_ALIASES.get(provider_key, provider_key)
504
541
  model_key = str(model or "").strip().lower()
505
542
  alias = self._aliases.get((provider_key, model_key))
543
+ if alias is None and provider_key == "bedrock":
544
+ for candidate, dropped_global in _bedrock_fallback_ids(model_key):
545
+ found = self._aliases.get((provider_key, candidate))
546
+ if found is None or found.pricing_channel not in _BEDROCK_CHANNELS:
547
+ continue
548
+ if dropped_global and found.pricing_channel != _BEDROCK_CHANNEL:
549
+ continue
550
+ alias = found
551
+ break
506
552
  if alias is None:
507
553
  return CostResult(None, None, None, "unpriced", ("unknown_model",))
508
554
  price = self._price_for(alias, at)
@@ -6,18 +6,34 @@
6
6
  #
7
7
  # Community updates welcome: add an alias or price entry with its provider
8
8
  # source_url and open a PR. CI validates structure and date overlaps.
9
- version: "2026-09-24"
9
+ version: "2026-09-28"
10
10
  currency: USD
11
- pricing_verified_at: "2026-09-24"
11
+ pricing_verified_at: "2026-09-28"
12
12
  models:
13
13
  - canonical_id: openai/gpt-6-sol
14
14
  publisher: openai
15
15
  aliases:
16
+ - {provider: openai, alias: gpt-6-sol, channel: openai-api}
17
+ - {provider: litellm, alias: gpt-6-sol, channel: openai-api}
18
+ - {provider: unknown, alias: gpt-6-sol, channel: openai-api}
16
19
  - provider: openai
17
20
  alias: openai/gpt-6-sol
18
21
  channel: vercel-ai-gateway
19
22
  rules: {input_includes_cache_read: true, input_includes_cache_write: true}
20
23
  prices:
24
+ - channel: openai-api
25
+ region: global
26
+ effective_from: "2026-09-22"
27
+ input_per_mtok: 2.00
28
+ output_per_mtok: 10.00
29
+ cache_read_per_mtok: 0.20
30
+ cache_write_5m_per_mtok: 2.50
31
+ batch_input_per_mtok: 1.00
32
+ batch_output_per_mtok: 5.00
33
+ rules:
34
+ input_includes_cache_read: true
35
+ long_context: {threshold: 272000, input_multiplier: 2, output_multiplier: 1.5}
36
+ source_url: https://developers.openai.com/api/docs/models/gpt-6-sol
21
37
  - channel: vercel-ai-gateway
22
38
  region: global
23
39
  effective_from: "2026-09-23"
@@ -33,11 +49,27 @@ models:
33
49
  - canonical_id: openai/gpt-6-luna
34
50
  publisher: openai
35
51
  aliases:
52
+ - {provider: openai, alias: gpt-6-luna, channel: openai-api}
53
+ - {provider: litellm, alias: gpt-6-luna, channel: openai-api}
54
+ - {provider: unknown, alias: gpt-6-luna, channel: openai-api}
36
55
  - provider: openai
37
56
  alias: openai/gpt-6-luna
38
57
  channel: vercel-ai-gateway
39
58
  rules: {input_includes_cache_read: true, input_includes_cache_write: true}
40
59
  prices:
60
+ - channel: openai-api
61
+ region: global
62
+ effective_from: "2026-09-22"
63
+ input_per_mtok: 0.10
64
+ output_per_mtok: 0.50
65
+ cache_read_per_mtok: 0.01
66
+ cache_write_5m_per_mtok: 0.125
67
+ batch_input_per_mtok: 0.05
68
+ batch_output_per_mtok: 0.25
69
+ rules:
70
+ input_includes_cache_read: true
71
+ long_context: {threshold: 272000, input_multiplier: 2, output_multiplier: 1.5}
72
+ source_url: https://developers.openai.com/api/docs/models/gpt-6-luna
41
73
  - channel: vercel-ai-gateway
42
74
  region: global
43
75
  effective_from: "2026-09-23"
@@ -53,11 +85,27 @@ models:
53
85
  - canonical_id: openai/gpt-6-astra
54
86
  publisher: openai
55
87
  aliases:
88
+ - {provider: openai, alias: gpt-6-astra, channel: openai-api}
89
+ - {provider: litellm, alias: gpt-6-astra, channel: openai-api}
90
+ - {provider: unknown, alias: gpt-6-astra, channel: openai-api}
56
91
  - provider: openai
57
92
  alias: openai/gpt-6-astra
58
93
  channel: vercel-ai-gateway
59
94
  rules: {input_includes_cache_read: true, input_includes_cache_write: true}
60
95
  prices:
96
+ - channel: openai-api
97
+ region: global
98
+ effective_from: "2026-09-03"
99
+ input_per_mtok: 10.00
100
+ output_per_mtok: 50.00
101
+ cache_read_per_mtok: 1.00
102
+ cache_write_5m_per_mtok: 12.50
103
+ batch_input_per_mtok: 5.00
104
+ batch_output_per_mtok: 25.00
105
+ rules:
106
+ input_includes_cache_read: true
107
+ long_context: {threshold: 272000, input_multiplier: 2, output_multiplier: 1.5}
108
+ source_url: https://developers.openai.com/api/docs/models/gpt-6-astra
61
109
  - channel: vercel-ai-gateway
62
110
  region: global
63
111
  effective_from: "2026-09-23"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: metergraph-core
3
- Version: 0.2.35
3
+ Version: 0.2.37
4
4
  Summary: Reusable MeterGraph catalog and deterministic billing engine
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: >=3.10
@@ -81,6 +81,13 @@ and surrounding whitespace, applies the configured region fallback and
81
81
  effective-date windows, and returns `None` when no exact model/channel price
82
82
  exists. It never substitutes a direct-provider price for a gateway price.
83
83
 
84
+ On Bedrock only (provider `bedrock` for `cost`, channel `aws-bedrock` or
85
+ `aws-bedrock-geo` for `resolve_price`), an id with no exact alias falls back to
86
+ the id without its model-version suffix (`anthropic.claude-sonnet-5-v1:0` to
87
+ `anthropic.claude-sonnet-5`) and then without a `global.` inference-profile
88
+ prefix, the latter only onto an `aws-bedrock` alias. Geographic prefixes such as
89
+ `us.` or `eu.` are never stripped, because they bill on `aws-bedrock-geo`.
90
+
84
91
  `LoadedCatalog.currency` is currently always `USD`, and
85
92
  `LoadedCatalog.pricing_verified_at` records when the bundled catalog was last
86
93
  checked against its linked provider sources.