Mercury Genesys Token Calculator
This commit is contained in:
140
calculators/Genesys_Token_Calculator/scripts/export_report.py
Normal file
140
calculators/Genesys_Token_Calculator/scripts/export_report.py
Normal file
@@ -0,0 +1,140 @@
|
||||
"""Export the token calculator as an LLM-readable report source.
|
||||
|
||||
Executes the notebook ONCE (widget defaults — or whatever scenario you've
|
||||
set and saved in the notebook), then converts the executed copy twice:
|
||||
|
||||
exports/genesys_token_calculator.html — human-reviewable, full presentation
|
||||
exports/genesys_token_calculator.md — leanest LLM input: presentation-tagged
|
||||
cells (setup, widgets, tables, charts)
|
||||
are stripped, a framing preamble is
|
||||
prepended, and the data appendix ends
|
||||
the file with one fenced JSON block —
|
||||
the machine source of truth.
|
||||
|
||||
Engagement identity (client, date, preparer) is read from the notebook's
|
||||
``engagement-data`` cell and stamped into the preamble, alongside the
|
||||
rate-card source date — a cost figure without its rate card is not auditable.
|
||||
|
||||
Run from the calculator root: python scripts/export_report.py
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
NOTEBOOK = ROOT / "notebooks" / "genesys_token_calculator.ipynb"
|
||||
EXPORTS = ROOT / "exports"
|
||||
|
||||
# Cells tagged with any of these never reach the .md export — they are stage
|
||||
# presentation (source and widget-repr noise), not the priced record.
|
||||
STRIP_TAGS_FROM_MD = '{"presentation"}'
|
||||
|
||||
|
||||
def engagement_data() -> dict[str, Any]:
|
||||
"""Exec the engagement-data cell (same trick as tests/conftest.py)."""
|
||||
import nbformat
|
||||
|
||||
nb = nbformat.read(NOTEBOOK, as_version=4)
|
||||
cells = [c for c in nb.cells if "engagement-data" in c.metadata.get("tags", [])]
|
||||
assert len(cells) == 1, "expected exactly one engagement-data cell"
|
||||
ns: dict[str, Any] = {}
|
||||
exec(compile(cells[0].source, f"{NOTEBOOK.name} [engagement-data]", "exec"), ns)
|
||||
return ns["ENGAGEMENT"] # type: ignore[no-any-return]
|
||||
|
||||
|
||||
def preamble() -> str:
|
||||
sys.path.insert(0, str(ROOT))
|
||||
from genesyscalc.ratecard import RATE_CARD_SOURCE, RATE_CARD_SOURCE_DATE
|
||||
from genesyscalc.tts import TTS_SOURCE, TTS_SOURCE_DATE
|
||||
|
||||
eng = engagement_data()
|
||||
who = " · ".join(
|
||||
str(eng[k]).strip()
|
||||
for k in ("client", "prepared_date", "prepared_by")
|
||||
if str(eng.get(k, "")).strip()
|
||||
)
|
||||
line = who or "master copy — illustrative placeholders; no client data."
|
||||
return "\n".join(
|
||||
[
|
||||
"<!-- Export preamble — generated by scripts/export_report.py -->",
|
||||
"**What this is** — a costed Genesys Cloud AI scenario, produced from",
|
||||
"the Mercury-served token calculator. It is a **planning model**: list",
|
||||
"rates unless a contracted rate was entered, and never a quote.",
|
||||
"",
|
||||
f"**Engagement** — {line}",
|
||||
"",
|
||||
f"**Rate card** — [{RATE_CARD_SOURCE}]({RATE_CARD_SOURCE}), published",
|
||||
f"**{RATE_CARD_SOURCE_DATE}**. Text-to-speech is priced separately from",
|
||||
f"[{TTS_SOURCE}]({TTS_SOURCE}) (published {TTS_SOURCE_DATE}) and is",
|
||||
"billed per character, not in tokens — it is reported as its own line",
|
||||
"and never folded into the token subtotal.",
|
||||
"",
|
||||
"**How to read it** — first the content as annotated source (the feature",
|
||||
"catalogue, then the engagement data), then the scenario state, the",
|
||||
"verification gate, and finally the data appendix: the published rate",
|
||||
"card, the per-feature cost table, the scenario comparison, the applied",
|
||||
"rules and warnings, and — last — **Model state (JSON)**, one fenced",
|
||||
"`json` block. Where prose and JSON disagree, the JSON block is the",
|
||||
"source of truth; its `rate_card.source_date` says which published rate",
|
||||
"card produced these numbers.",
|
||||
"",
|
||||
"---",
|
||||
"",
|
||||
"",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
if len(sys.argv) > 1 and sys.argv[1] not in NOTEBOOK.name:
|
||||
sys.exit(f"no notebook matches {sys.argv[1]!r}")
|
||||
EXPORTS.mkdir(exist_ok=True)
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
executed = Path(tmp) / NOTEBOOK.name
|
||||
# 1. Execute once — both formats convert the same scenario state.
|
||||
# (Never combine --execute with TagRemovePreprocessor in one call:
|
||||
# the cell could be stripped before it runs.)
|
||||
subprocess.run(
|
||||
[
|
||||
sys.executable, "-m", "nbconvert", "--execute",
|
||||
"--to", "notebook", "--output", str(executed), str(NOTEBOOK),
|
||||
],
|
||||
check=True, cwd=ROOT,
|
||||
)
|
||||
# 2. HTML — full presentation, human review artifact.
|
||||
subprocess.run(
|
||||
[
|
||||
sys.executable, "-m", "nbconvert", "--to", "html",
|
||||
"--output-dir", str(EXPORTS), "--output", NOTEBOOK.stem,
|
||||
str(executed),
|
||||
],
|
||||
check=True, cwd=ROOT,
|
||||
)
|
||||
# 3. Markdown — LLM artifact: strip presentation cells.
|
||||
subprocess.run(
|
||||
[
|
||||
sys.executable, "-m", "nbconvert", "--to", "markdown",
|
||||
"--output-dir", str(EXPORTS), "--output", NOTEBOOK.stem,
|
||||
"--TagRemovePreprocessor.enabled=True",
|
||||
f"--TagRemovePreprocessor.remove_cell_tags={STRIP_TAGS_FROM_MD}",
|
||||
str(executed),
|
||||
],
|
||||
check=True, cwd=ROOT,
|
||||
)
|
||||
|
||||
# 4. Prepend the framing preamble to the markdown export.
|
||||
md = EXPORTS / f"{NOTEBOOK.stem}.md"
|
||||
md.write_text(preamble() + md.read_text(encoding="utf-8"), encoding="utf-8")
|
||||
|
||||
for p in sorted(EXPORTS.iterdir()):
|
||||
if p.suffix in (".html", ".md"):
|
||||
print(f"wrote {p.relative_to(ROOT)} ({p.stat().st_size / 1024:,.0f} KB)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user