"""The machine-readable model state (Mercury Notebook Pattern ยง5). Plotly figures export as JavaScript an LLM cannot read, so the exported ``.md`` ends with one JSON block carrying everything the figures showed. ``rate_card.source_date`` is the most important field here: it tells a consumer of the export *which* published rate card produced these numbers. A cost figure without its rate-card date is not auditable. """ from __future__ import annotations from typing import Any from .model import CalculatorInputs, CalculatorResult, cost_per_interaction from .ratecard import ( RATE_CARD_SOURCE, RATE_CARD_SOURCE_DATE, VOICE_BOT_ROUNDUP_SECONDS, ) from .tts import TTS_SOURCE, TTS_SOURCE_DATE def result_json( result: CalculatorResult, inputs: CalculatorInputs, meta: dict[str, Any] | None = None, ) -> dict[str, Any]: """The export payload: provenance, inputs, lines, totals, warnings.""" totals = result.totals payload: dict[str, Any] = { "rate_card": { "source": RATE_CARD_SOURCE, "source_date": RATE_CARD_SOURCE_DATE, "voice_bot_roundup_seconds": VOICE_BOT_ROUNDUP_SECONDS, }, "tts_source": {"source": TTS_SOURCE, "source_date": TTS_SOURCE_DATE}, "inputs": { "users": inputs.users, "licence_model": inputs.licence.value, "enabled_features": sorted(inputs.enabled), "apply_allowance": inputs.apply_allowance, "volumes": { k: v for k, v in vars(inputs.volumes).items() if not k.startswith("_") }, "deflection_mix": { "bot_only_share": inputs.mix.bot_only_share, "virtual_agent_share": inputs.mix.virtual_agent_share, "agentic_va_share": inputs.mix.agentic_va_share, "agent_handled_share": inputs.mix.agent_handled_share, }, "price": { "currency": inputs.price.currency, "list_rate": inputs.price.list_rate, "contracted_rate": inputs.price.contracted_rate, "concession_pct": inputs.price.concession_pct, "effective_rate": inputs.price.effective_rate(), }, "voice_bot": ( { "calls_per_month": inputs.voice_bot.calls_per_month, "avg_bot_seconds_per_call": ( inputs.voice_bot.avg_bot_seconds_per_call ), } if inputs.voice_bot is not None else None ), "tts": ( { "calls_monthly": inputs.tts.calls_monthly, "chars_per_call": inputs.tts.chars_per_call, "tier": inputs.tts.tier, } if inputs.tts is not None else None ), }, "lines": [ { "key": line.key, "feature": line.feature, "units_monthly": line.units_monthly, "unit_label": line.unit_label, "tokens_monthly": line.tokens_monthly, "cost_monthly": line.cost_monthly, "cost_annual": line.cost_annual, "confidence": line.confidence.value, } for line in result.lines ], "totals": { "consumption_tokens_monthly": totals.consumption_tokens_monthly, "subscription_tokens_monthly": totals.subscription_tokens_monthly, "gross_tokens_monthly": totals.gross_tokens_monthly, "allowance_tokens_monthly": totals.allowance_tokens_monthly, "billable_tokens_monthly": totals.billable_tokens_monthly, "currency": totals.currency, "effective_rate": totals.effective_rate, "token_cost_monthly": totals.token_cost_monthly, "token_cost_annual": totals.token_cost_annual, "list_cost_annual": totals.list_cost_annual, "concession_saving_annual": totals.concession_saving_annual, "tts_cost_annual": result.tts_cost_annual, "grand_total_annual": result.grand_total_annual, "cost_per_interaction": cost_per_interaction(result, inputs.volumes), }, "tts": ( { "tier": result.tts.tier, "rate_per_million_chars": result.tts.rate_per_million_chars, "total_chars_monthly": result.tts.total_chars_monthly, "free_share": result.tts.free_share, "billable_chars_monthly": result.tts.billable_chars_monthly, "billed_millions_monthly": result.tts.billed_millions_monthly, "cost_monthly": result.tts.cost_monthly, "cost_annual": result.tts.cost_annual, } if result.tts is not None else None ), "warnings": list(result.warnings), } if meta: payload["meta"] = meta return payload