alpha-engine-lib 0.40.0__tar.gz → 0.40.1__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.
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/PKG-INFO +1 -1
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/pyproject.toml +1 -1
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/__init__.py +1 -1
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/cost.py +31 -6
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib.egg-info/PKG-INFO +1 -1
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_cost.py +41 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/README.md +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/setup.cfg +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/agent_schemas.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/alerts.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/anthropic_payload.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/arcticdb.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/artifact_freshness.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/collector_results.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/dates.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/decision_capture.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/ec2_spot.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/email_sender.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/eval_artifacts.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/locks.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/logging.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/model_pricing.yaml +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/pillars.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/pipeline_status/__init__.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/pipeline_status/read.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/pipeline_status/registry.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/pipeline_status/templates.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/preflight.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/rag/__init__.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/rag/db.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/rag/embeddings.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/rag/migrations/0001_content_tsv.sql +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/rag/rerank.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/rag/retrieval.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/rag/schema.sql +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/reconcile.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/secrets.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/sources/__init__.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/sources/protocols.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/ssm_dispatcher.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/ssm_log_capture.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/telegram.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/trading_calendar.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/transparency.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/transparency_inventory.yaml +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/universe.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib.egg-info/SOURCES.txt +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib.egg-info/dependency_links.txt +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib.egg-info/requires.txt +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib.egg-info/top_level.txt +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_agent_schemas.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_alerts.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_anthropic_payload.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_arcticdb.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_artifact_freshness.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_collector_results.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_dates.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_decision_capture.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_ec2_spot.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_email_sender.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_eval_artifacts.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_locks.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_logging.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_pillars.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_pipeline_status_read.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_pipeline_status_registry.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_pipeline_status_templates.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_preflight.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_rag.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_rag_rerank.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_rag_retrieval_hybrid.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_reconcile.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_secrets.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_sources_protocols.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_ssm_dispatcher.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_ssm_log_capture.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_telegram.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_trading_calendar.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_transparency.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_universe.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_version_bump_workflow.py +0 -0
- {alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/tests/test_version_pin.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: alpha-engine-lib
|
|
3
|
-
Version: 0.40.
|
|
3
|
+
Version: 0.40.1
|
|
4
4
|
Summary: Shared utilities for the Alpha Engine modules: preflight, logging, ArcticDB, dates, decision capture, cost telemetry, Anthropic payload chokepoint, artifact freshness, RAG, agent schemas, SSM secrets, Telegram + SNS alerts, EC2 spot resilience, SSM log-capture, SSM dispatcher, Step-Functions execution-state projection, and S3-conditional-PUT writer locks. Full surface documented in README.
|
|
5
5
|
Author: Brian McMahon
|
|
6
6
|
License: Proprietary
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "alpha-engine-lib"
|
|
7
|
-
version = "0.40.
|
|
7
|
+
version = "0.40.1"
|
|
8
8
|
description = "Shared utilities for the Alpha Engine modules: preflight, logging, ArcticDB, dates, decision capture, cost telemetry, Anthropic payload chokepoint, artifact freshness, RAG, agent schemas, SSM secrets, Telegram + SNS alerts, EC2 spot resilience, SSM log-capture, SSM dispatcher, Step-Functions execution-state projection, and S3-conditional-PUT writer locks. Full surface documented in README."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
# EC2 still runs Python 3.9 on the always-on micro instance (boto3 drops
|
|
@@ -58,6 +58,7 @@ Workstream design: ``alpha-engine-config/private-docs/ROADMAP.md`` line ~1708
|
|
|
58
58
|
|
|
59
59
|
from __future__ import annotations
|
|
60
60
|
|
|
61
|
+
import re
|
|
61
62
|
from datetime import date, datetime, timezone
|
|
62
63
|
from importlib import resources
|
|
63
64
|
from pathlib import Path
|
|
@@ -68,6 +69,17 @@ from pydantic import BaseModel, ConfigDict, Field, model_validator
|
|
|
68
69
|
|
|
69
70
|
from alpha_engine_lib.decision_capture import ModelMetadata
|
|
70
71
|
|
|
72
|
+
# Anthropic SDK model IDs come in two forms: the family alias
|
|
73
|
+
# (e.g. ``claude-haiku-4-5``) and the dated snapshot form
|
|
74
|
+
# (e.g. ``claude-haiku-4-5-20251001``). ``Message.model`` returns the dated
|
|
75
|
+
# form even when the caller requested the alias, but our pricing YAML is
|
|
76
|
+
# keyed on the alias so a new snapshot date doesn't require a card refresh.
|
|
77
|
+
_DATED_SNAPSHOT_SUFFIX_RE = re.compile(r"-\d{8}$")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _strip_dated_snapshot_suffix(model_name: str) -> str:
|
|
81
|
+
return _DATED_SNAPSHOT_SUFFIX_RE.sub("", model_name)
|
|
82
|
+
|
|
71
83
|
if TYPE_CHECKING:
|
|
72
84
|
# Structural Protocol below describes the only attributes we touch on
|
|
73
85
|
# an Anthropic SDK ``Message`` — kept here so that ``anthropic`` does
|
|
@@ -172,14 +184,27 @@ class PriceTable(BaseModel):
|
|
|
172
184
|
component is used for lookup) or a ``date``. The returned card is
|
|
173
185
|
the one whose ``effective_from`` is the latest among cards ≤ ``at``.
|
|
174
186
|
|
|
175
|
-
|
|
176
|
-
|
|
187
|
+
Lookup tries the model name as-given first; on miss, retries with
|
|
188
|
+
any trailing ``-YYYYMMDD`` snapshot suffix stripped. This lets the
|
|
189
|
+
YAML stay keyed on family aliases (``claude-haiku-4-5``) while
|
|
190
|
+
accepting the dated form (``claude-haiku-4-5-20251001``) that the
|
|
191
|
+
Anthropic SDK returns in ``Message.model``.
|
|
192
|
+
|
|
193
|
+
Raises :exc:`PriceCardLookupError` if neither form matches.
|
|
177
194
|
"""
|
|
178
195
|
query_date = at.date() if isinstance(at, datetime) else at
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
196
|
+
|
|
197
|
+
def _candidates_for(name: str) -> list[PriceCard]:
|
|
198
|
+
return [
|
|
199
|
+
c for c in self.cards
|
|
200
|
+
if c.model_name == name and c.effective_from <= query_date
|
|
201
|
+
]
|
|
202
|
+
|
|
203
|
+
candidates = _candidates_for(model_name)
|
|
204
|
+
if not candidates:
|
|
205
|
+
alias = _strip_dated_snapshot_suffix(model_name)
|
|
206
|
+
if alias != model_name:
|
|
207
|
+
candidates = _candidates_for(alias)
|
|
183
208
|
if not candidates:
|
|
184
209
|
raise PriceCardLookupError(
|
|
185
210
|
f"No price card for model {model_name!r} active on {query_date}"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: alpha-engine-lib
|
|
3
|
-
Version: 0.40.
|
|
3
|
+
Version: 0.40.1
|
|
4
4
|
Summary: Shared utilities for the Alpha Engine modules: preflight, logging, ArcticDB, dates, decision capture, cost telemetry, Anthropic payload chokepoint, artifact freshness, RAG, agent schemas, SSM secrets, Telegram + SNS alerts, EC2 spot resilience, SSM log-capture, SSM dispatcher, Step-Functions execution-state projection, and S3-conditional-PUT writer locks. Full surface documented in README.
|
|
5
5
|
Author: Brian McMahon
|
|
6
6
|
License: Proprietary
|
|
@@ -155,6 +155,47 @@ class TestPriceTableLookup:
|
|
|
155
155
|
self.table.get("haiku", date(2025, 12, 31))
|
|
156
156
|
|
|
157
157
|
|
|
158
|
+
class TestPriceTableLookupDatedSnapshotSuffix:
|
|
159
|
+
"""Anthropic SDK returns ``Message.model`` in the dated snapshot form
|
|
160
|
+
(e.g. ``claude-haiku-4-5-20251001``) even when the caller requested
|
|
161
|
+
the alias; the YAML is keyed on the alias. Lookup must accept both.
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
def setup_method(self):
|
|
165
|
+
self.table = PriceTable(cards=[
|
|
166
|
+
_card("claude-haiku-4-5", 2026, 1, 1, in_p=1.0),
|
|
167
|
+
_card("claude-sonnet-4-6", 2026, 1, 1, in_p=3.0),
|
|
168
|
+
])
|
|
169
|
+
|
|
170
|
+
def test_dated_suffix_falls_back_to_alias(self):
|
|
171
|
+
c = self.table.get("claude-haiku-4-5-20251001", date(2026, 5, 28))
|
|
172
|
+
assert c.input_per_1m == 1.0
|
|
173
|
+
|
|
174
|
+
def test_alias_lookup_unchanged(self):
|
|
175
|
+
c = self.table.get("claude-haiku-4-5", date(2026, 5, 28))
|
|
176
|
+
assert c.input_per_1m == 1.0
|
|
177
|
+
|
|
178
|
+
def test_exact_dated_match_wins_over_alias_fallback(self):
|
|
179
|
+
# If someone adds a dated card explicitly, it takes precedence.
|
|
180
|
+
table = PriceTable(cards=[
|
|
181
|
+
_card("claude-haiku-4-5", 2026, 1, 1, in_p=1.0),
|
|
182
|
+
_card("claude-haiku-4-5-20251001", 2026, 1, 1, in_p=9.99),
|
|
183
|
+
])
|
|
184
|
+
c = table.get("claude-haiku-4-5-20251001", date(2026, 5, 28))
|
|
185
|
+
assert c.input_per_1m == 9.99
|
|
186
|
+
|
|
187
|
+
def test_unknown_alias_with_dated_suffix_still_hard_fails(self):
|
|
188
|
+
with pytest.raises(
|
|
189
|
+
PriceCardLookupError, match="claude-foo-9-9-20251001"
|
|
190
|
+
):
|
|
191
|
+
self.table.get("claude-foo-9-9-20251001", date(2026, 5, 28))
|
|
192
|
+
|
|
193
|
+
def test_non_dated_suffix_is_not_stripped(self):
|
|
194
|
+
# Bare 8-digit substring without leading dash → no normalization.
|
|
195
|
+
with pytest.raises(PriceCardLookupError):
|
|
196
|
+
self.table.get("claude-haiku-4-5.20251001", date(2026, 5, 28))
|
|
197
|
+
|
|
198
|
+
|
|
158
199
|
# ── compute_cost ──────────────────────────────────────────────────────────
|
|
159
200
|
|
|
160
201
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/anthropic_payload.py
RENAMED
|
File without changes
|
|
File without changes
|
{alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/artifact_freshness.py
RENAMED
|
File without changes
|
{alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/collector_results.py
RENAMED
|
File without changes
|
|
File without changes
|
{alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/decision_capture.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/pipeline_status/__init__.py
RENAMED
|
File without changes
|
{alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/pipeline_status/read.py
RENAMED
|
File without changes
|
{alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/pipeline_status/registry.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/sources/__init__.py
RENAMED
|
File without changes
|
{alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/sources/protocols.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/trading_calendar.py
RENAMED
|
File without changes
|
|
File without changes
|
{alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib/transparency_inventory.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib.egg-info/requires.txt
RENAMED
|
File without changes
|
{alpha_engine_lib-0.40.0 → alpha_engine_lib-0.40.1}/src/alpha_engine_lib.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|