metergraph-core 0.2.35__tar.gz → 0.2.36__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.36}/PKG-INFO +8 -1
  2. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/README.md +7 -0
  3. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/pyproject.toml +1 -1
  4. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/src/metergraph_core/catalog.py +46 -0
  5. {metergraph_core-0.2.35 → metergraph_core-0.2.36/src/metergraph_core.egg-info}/PKG-INFO +8 -1
  6. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/MANIFEST.in +0 -0
  7. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/setup.cfg +0 -0
  8. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/src/metergraph_core/__init__.py +0 -0
  9. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/src/metergraph_core/billing.py +0 -0
  10. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/src/metergraph_core/data/models.yaml +0 -0
  11. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/src/metergraph_core/data/prices.yaml +0 -0
  12. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/src/metergraph_core/loader.py +0 -0
  13. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/src/metergraph_core/models.py +0 -0
  14. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/src/metergraph_core/retrieval.py +0 -0
  15. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/src/metergraph_core.egg-info/SOURCES.txt +0 -0
  16. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/src/metergraph_core.egg-info/dependency_links.txt +0 -0
  17. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/src/metergraph_core.egg-info/requires.txt +0 -0
  18. {metergraph_core-0.2.35 → metergraph_core-0.2.36}/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.36
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.36"
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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: metergraph-core
3
- Version: 0.2.35
3
+ Version: 0.2.36
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.