Versioned state schemas, failure semantics, and debug CLI for the Antaris Analytics Suite.
Project description
antaris-contracts
Shared contracts layer for the Antaris Analytics Suite.
v4.0.0 — Unified state schemas • Migration tooling • Fail-closed semantics • Debug CLI
Version aligned with antaris-suite v4.0.0. Apache 2.0 license.
antaris-contracts defines the versioned state schemas, failure semantics, migration tooling, and debug CLI shared across every antaris package. It is the single source of truth for how data is shaped, how failures are handled, and how state evolves across versions — without coupling the packages to each other.
Zero runtime dependencies. Pure Python stdlib. 60+ tests. Safe to import anywhere.
Installation
pip install antaris-contracts
Requires Python 3.9+.
Versioned State Schemas
Every antaris package persists state through dataclass contracts defined here. All schemas carry a schema_version field, support to_dict() / from_dict() / to_json() / from_json() round-trips, and silently ignore unknown keys for forward compatibility.
MemoryState (antaris_contracts.schemas.memory)
from antaris_contracts import MemoryEntry, MemoryShard, MemoryIndex, SearchResult
# Create a memory entry
entry = MemoryEntry(
content="User prefers concise responses",
source="conversation.py",
line=42,
category="preference",
importance=0.9,
confidence=0.85,
memory_type="semantic",
tags=["user-pref", "style"],
)
# Serialize → dict → JSON → back
restored = MemoryEntry.from_json(entry.to_json())
assert restored.content == entry.content
# Shards track on-disk partitions with integrity checks
shard = MemoryShard(
shard_id="shard_2026-02_preference",
category="preference",
entries=[entry],
entry_count=1, # mismatch with len(entries) = partial write
)
# Index is a derived cache — rebuildable from shards
index = MemoryIndex(
total_entries=150,
shard_count=6,
categories=["general", "preference", "strategic"],
shard_manifest={"shard_2026-02_preference.json": "abc123"},
)
RouterState (antaris_contracts.schemas.router)
from antaris_contracts import ClassificationResult, RouteDecision, RouterState
# Task classification output
classification = ClassificationResult(
tier="complex",
confidence=0.92,
reasoning=["multi-step reasoning", "code generation detected"],
signals=["code_block", "chain_of_thought"],
)
# Routing decision with SLA tracking and fallback chain
decision = RouteDecision(
model="claude-sonnet-4-5-20250929",
provider="anthropic",
tier="complex",
confidence=0.92,
confidence_basis="classifier",
reasoning=["high complexity tier", "SLA-compliant model selected"],
fallback_chain=["claude-haiku-4-5-20251001", "gpt-4o-mini"],
classification=classification,
sla_compliant=True,
supports_streaming=True,
)
# Persisted router state with cost tracking
state = RouterState(
session_id="sess-abc123",
total_requests=250,
total_cost_usd=1.47,
requests_by_tier={"simple": 180, "complex": 70},
cost_by_model={"claude-sonnet-4-5-20250929": 1.20, "claude-haiku-4-5-20251001": 0.27},
recent_decisions=[decision],
)
GuardState (antaris_contracts.schemas.guard)
from antaris_contracts import (
PatternMatch, GuardDecision, GuardPolicyRule, GuardPolicy, AuditRecord,
)
# Pattern match from injection detection
match = PatternMatch(
pattern_id="prompt-injection-01",
pattern_type="injection",
matched_text="ignore all previous instructions",
score=0.95,
severity="high",
)
# Guard decision — fail-closed on crash (CRITICAL, is_safe=False)
decision = GuardDecision(
threat_level="BLOCKED",
is_safe=False,
is_blocked=True,
matches=[match],
score=0.95,
message="Prompt injection detected",
pii_found=False,
audit_id="audit-xyz",
)
# Composable security policy
policy = GuardPolicy(
policy_id="strict-prod",
name="strict",
rules=[
GuardPolicyRule(rule_id="r1", rule_type="injection_scan", enabled=True),
GuardPolicyRule(rule_id="r2", rule_type="pii_filter", enabled=True),
GuardPolicyRule(rule_id="r3", rule_type="rate_limit",
parameters={"rpm": 60}),
],
threat_threshold=0.5,
block_threshold=0.8,
enable_pii_filter=True,
)
# Append-only audit log entry
record = AuditRecord(
audit_id="audit-xyz",
timestamp="2026-02-20T14:30:00Z",
source_id="user-123",
action="block",
risk_level="high",
decision=decision,
)
ContextState (antaris_contracts.schemas.context)
from antaris_contracts import ContextItem, ContextSection, ContextPacket
# Build a context window with budgeted sections
memories_section = ContextSection(
name="memories",
budget=1024,
used=256,
compression_level="light",
items=[
ContextItem(content="User prefers Python", tokens=4, priority=0.9),
ContextItem(content="Last error was ImportError", tokens=6, priority=0.7),
],
)
packet = ContextPacket(
task="Debug the authentication module",
memories=[{"content": "auth uses JWT", "importance": 0.8}],
pitfalls=["Don't expose tokens in logs"],
sections=[memories_section],
total_budget=4096,
total_used=256,
strategy="hybrid",
)
# If total_budget is exceeded, lowest-priority sections are dropped — never
# silently truncated mid-entry
PipelineState (antaris_contracts.schemas.telemetry)
from antaris_contracts import (
TelemetryEvent, PerformanceMetrics,
MODULE_PIPELINE, MODULE_GUARD, MODULE_ROUTER,
BASIS_CLASSIFIER, BASIS_GUARD,
)
# Unified telemetry event emitted by every antaris module
event = TelemetryEvent(
event_id="ev-001",
timestamp="2026-02-20T14:30:00Z",
session_id="sess-abc123",
module=MODULE_ROUTER,
event_type="route_selected",
confidence=0.92,
basis=BASIS_CLASSIFIER,
evidence=["multi_step_reasoning", "code_block_detected"],
payload={"model": "claude-sonnet-4-5-20250929", "tier": "complex"},
performance=PerformanceMetrics(latency_ms=45.2, cost_usd=0.000125),
correlations=["ev-000"], # related events
triggers=["ev-002"], # events this one caused
user_id="u-123",
trace_id="trace-abc",
)
# Append to JSONL log
with open("telemetry.jsonl", "a") as f:
f.write(event.to_jsonl_line())
Migration Tooling
State schemas evolve across versions. The migration system provides chained migrations, automatic version detection, and explicit failure on unknown versions — no silent data corruption.
Version Chain
2.0.0 → 2.1.0 → 2.1.1 → 2.2.0 (current)
Each step adds fields with safe defaults. Migrations are pure functions (dict-in, dict-out) with no I/O.
Migrate Persisted Data
from antaris_contracts import migrate, SchemaVersion
from antaris_contracts.migration import MigrationError, get_migration_path
import json
# Auto-detect source version from data
raw = json.loads(open("state.json").read())
migrated = migrate(raw) # → schema_version="2.2.0"
# Explicit source and target
migrated = migrate(raw, from_version="2.0.0", to_version="2.2.0")
# Same-version is a safe no-op (returns deep copy)
migrated = migrate(raw, to_version="2.2.0")
# Dry-run: inspect the migration path without applying
steps = get_migration_path("2.0.0", "2.2.0")
# → [("2.0.0", "2.2.0")] (direct path registered)
steps = get_migration_path("2.1.0", "2.2.0")
# → [("2.1.0", "2.2.0")] (direct shortcut)
steps = get_migration_path("2.1.1", "2.2.0")
# → [("2.1.1", "2.2.0")]
What Each Migration Adds
| Step | Fields Added |
|---|---|
| 2.0.0 → 2.1.0 | memory_type, type_metadata, correlations, triggers |
| 2.1.0 → 2.1.1 | trace_id, removes _heartbeat_contaminated artifact |
| 2.1.1 → 2.2.0 | escalated, original_confidence, escalation_reason, sla_compliant, sla_breaches, sla_adjustments, ab_variant, explanation, supports_streaming, pattern_version, audit_id, user_id, conversation_id, agent_id, strategy |
Error Handling
from antaris_contracts.migration import MigrationError
# Unknown version → MigrationError
migrate({"schema_version": "9.9.9"})
# MigrationError: Unknown source schema version: '9.9.9'
# Downgrade → MigrationError
migrate({"schema_version": "2.2.0"}, to_version="2.0.0")
# MigrationError: Downgrade not supported: 2.2.0 → 2.0.0
# Missing version with no from_version → MigrationError
migrate({"content": "no version field"})
# MigrationError: Cannot determine source schema version
Version Enum
from antaris_contracts import SchemaVersion
# All known versions in order
SchemaVersion.ordered()
# → [V2_0_0, V2_1_0, V2_1_1, V2_2_0]
# Comparison
SchemaVersion.V2_0_0 < SchemaVersion.V2_2_0 # True
SchemaVersion.V2_2_0 <= SchemaVersion.V2_2_0 # True
Failure Semantics
Every schema documents its failure behavior as inspectable, predictable objects — not hidden exceptions. The contracts define how each component degrades:
| Component | Failure Mode | Behavior |
|---|---|---|
| MemoryEntry | Deserialization failure | Skip and log — never silently mutate |
| MemoryEntry | Empty content |
Rejected at ingest time |
| MemoryEntry | Missing hash |
Recomputed from (source, line, content[:100]) |
| MemoryShard | Partial write | Detected via entry_count mismatch; discard and reload from WAL |
| MemoryIndex | Corruption | Delete and rebuild from shards (index is a cache) |
| RouterState | File corruption | Reset to empty state, log warning |
| ClassificationResult | All classifiers fail | Return tier="simple", confidence=0.0 |
| RouteDecision | Primary model down | Iterate fallback_chain; never silently drop |
| GuardDecision | Classifier crash | Fail-closed: threat_level="CRITICAL", is_safe=False |
| GuardPolicy | Parse failure | Keep previous policy active, emit warning |
| AuditRecord | Write failure | Best-effort; log error, don't affect guard decision |
| ContextPacket | Budget exceeded | Drop lowest-priority sections — never truncate mid-entry |
| ContextSection | Compression failure | Use uncompressed content as fallback |
| TelemetryEvent | Sink failure | Non-fatal; write warning to stderr, pipeline continues |
Concurrency Model
| Component | Contract |
|---|---|
| MemoryShard | File lock held during write; reads are lock-free (MVCC-style) |
| MemoryIndex | Atomic writes via temp-file + rename pattern |
| RouterState | Last-writer-wins for cost tracking (acceptable approximation) |
| GuardPolicy | Atomic reload: new policy replaces old only after successful parse |
| AuditRecord | Append-mode writes; partial JSON lines are skipped on read |
| TelemetryEvent | Append-only JSONL; partial line writes produce invalid lines skipped on read |
Debug CLI
antaris-debug is installed as a console script. Zero dependencies beyond stdlib.
Inspect a Memory Store
$ antaris-debug memory inspect ./my_agent_workspace
============================================================
Memory Store: ./my_agent_workspace
============================================================
Index file: PRESENT
Index entries: 150
Index shards: 6
Tag index: 12 tags
Schema ver: 2.2.0
Last modified: 2026-02-20 14:30:00 UTC
Shards on disk: 6
shard_2026-01_general.json 45 entries [OK]
shard_2026-01_strategic.json 12 entries [OK]
shard_2026-02_general.json 68 entries [OK]
shard_2026-02_preference.json 25 entries [OK]
Total entries (actual scan): 150
Index health: OK
============================================================
Search Memories
$ antaris-debug memory search ./my_agent_workspace "authentication bug"
Memory search: 'authentication bug'
Store: ./my_agent_workspace
Found 3 matching entries — showing top 3
[1] score=1.800 hits=2
JWT token validation was failing because the secret was rotated but the cache...
source=debug_session.py type=episodic importance=0.90 confidence=1.00
[2] score=0.850 hits=1
User reported authentication timeout after 30s idle
source=ticket_1234.md type=episodic importance=0.85 confidence=0.90
Validate a Schema File
$ antaris-debug schema validate ./state.json
Schema validation: ./state.json
(root) OK [MemoryEntry] schema_version=2.2.0 extra_fields=8
Result: 1 object(s) 0 error(s) 0 warning(s)
VALIDATION PASSED
Validates against all known contract signatures — MemoryEntry, MemoryShard, MemoryIndex, RouterState, RouteDecision, GuardDecision, GuardPolicy, ContextPacket, TelemetryEvent, and more. Detects schema version mismatches and missing required fields.
Tail Telemetry Logs
$ antaris-debug telemetry tail ./telemetry.jsonl -n 5
Telemetry tail: ./telemetry.jsonl
Total events: 1240 — showing last 5
2026-02-20 14:30:00 UTC [ router] route_selected conf=0.920 basis=classifier
evidence: ['multi_step_reasoning', 'code_block_detected']
perf: lat=45.2ms, cost=$0.000125
2026-02-20 14:30:01 UTC [ guard] guard_decision conf=1.000 basis=guard
2026-02-20 14:30:01 UTC [ context] context_built conf=1.000 basis=context_budget
perf: lat=12.3ms
2026-02-20 14:30:02 UTC [pipeline] request_complete
perf: lat=892.0ms, cost=$0.003200
2026-02-20 14:30:05 UTC [ memory] memory_stored conf=0.850
Telemetry Summary and Dashboard
# Aggregate stats by module and event type
$ antaris-debug telemetry summary ./telemetry.jsonl
# Rich dashboard with latency percentiles and guard allow/deny ratio
$ antaris-debug telemetry dashboard ./telemetry.jsonl
Trace a Pipeline Session
$ antaris-debug pipeline trace sess-abc123 ./telemetry.jsonl
Pipeline trace: session_id='sess-abc123'
Source: ./telemetry.jsonl
Found 8 events out of 1240 total
[ 1] 2026-02-20 14:30:00 UTC [pipeline] request_start
[ 2] 2026-02-20 14:30:00 UTC [ router] route_selected [lat=45.2ms]
[ 3] 2026-02-20 14:30:01 UTC [ guard] guard_decision [lat=8.1ms]
[ 4] 2026-02-20 14:30:01 UTC [ context] context_built [lat=12.3ms]
[ 5] 2026-02-20 14:30:02 UTC [pipeline] request_complete [lat=892.0ms]
Testing
52 tests covering all schemas, serialization round-trips, migration chains, version ordering, and error paths:
cd antaris-contracts && python -m pytest tests/ -v
Zero Runtime Dependencies
antaris-contracts has no runtime dependencies beyond the Python standard library. It is safe to import in any environment — no version conflicts, no transitive dependencies, no surprises.
Part of the Antaris Analytics Suite — v3.1.0
- antaris-memory — Persistent memory for AI agents
- antaris-router — Adaptive model routing with SLA enforcement
- antaris-guard — Security and prompt injection detection
- antaris-context — Context window optimization
- antaris-pipeline — Agent orchestration pipeline
- antaris-contracts — Versioned schemas, failure semantics, and debug CLI (this package)
Phase 4 Roadmap
v2.0: Enhanced state versioning (backward compatibility guarantees)
v3.0+: Multi-tenant schema isolation (support for shared memory pools across teams)
Full Documentation
📖 Read the full antaris-contracts documentation on antarisanalytics.ai
Phase 4 Roadmap
v2.0: Enhanced state versioning and backward compatibility guarantees — multi-version support in migrations
v3.0+: Multi-tenant schema isolation and shared memory pool support across team agents
v4.0+: Pluggable schema validators and custom failure semantics per tenant
License
Apache 2.0 — see LICENSE
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file antaris_contracts-4.6.5.tar.gz.
File metadata
- Download URL: antaris_contracts-4.6.5.tar.gz
- Upload date:
- Size: 36.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0c17a8032493b5019b7347c4217e1ce6b2d42103f42c591851a9a1e1dfd93d5a
|
|
| MD5 |
287b40235bfda15ee8a1bfd6c1057bf2
|
|
| BLAKE2b-256 |
50fae7c75b5e734ea0be12c5ed3f6e22dfcb1c8b5e91a91e415ce68a72d9c821
|
File details
Details for the file antaris_contracts-4.6.5-py3-none-any.whl.
File metadata
- Download URL: antaris_contracts-4.6.5-py3-none-any.whl
- Upload date:
- Size: 32.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e0cbb13247a187ae3e198145b229a4321119824549ed140690eb568ff4041ee
|
|
| MD5 |
8893b6bedd06a257f85a00567aa85afd
|
|
| BLAKE2b-256 |
4471a6652e844fd322ec22a61b325942b820d989344869947510c2aa90835b2a
|