Genesys Cloud AI — Token Calculator
A Calculator — a reusable vendor-pricing master (see
docs/Calculator_Pattern_V1-00.md)
— built on the
Mercury Notebook Deliverable Pattern.
It prices what Genesys Cloud AI costs to run, from the vendor's own
published rate card. Unlike a TEI study it computes no benefits and no NPV:
its "numbers" are a run-rate, a per-feature breakdown, and a range.
The Mercury stage is the screen you share with a client while you size their AI footprint together; the consultant run-book, the verification gate, and the machine-readable appendix live backstage and export as LLM input for a downstream business case.
The anchor: the vendor's published rate card
The meters are Genesys' own, transcribed verbatim into
genesyscalc/ratecard.py:
| Source | Published | What it gives |
|---|---|---|
| Genesys Cloud tokens model | 2026-07-12 | 20 token meters, the free monthly allowance, the highest-tier rule, the Copilot exclusion |
| Genesys Enhanced TTS pricing | 2026-05-22 | $/million characters — not token-metered |
That file is immutable. When Genesys republishes, re-anchoring is a deliberate act with its own protocol — see Re-anchoring below.
Four published rules the obvious arithmetic gets wrong
Each is enforced in the engine, pinned by a test, and reported in the notebook's warnings rather than silently applied:
- The 15-second per-call round-up. "Genesys rounds up each call to the next 15-second increment." Applied per call and then summed — averaging first understates the bill. A 40-second average bills as 45 (+12.5%); a 5-second bot greeting bills as 15 (3× its duration).
- The free monthly allowance. 250 tokens named / 350 concurrent, which "renew each month and do not carry over" — so it is a real deduction, and an unused remainder is discarded, never banked.
- The highest-tier rule. "Genesys bases charges on the highest tier (price) resource…" — so the deflection shares are a partition, not overlapping rates. An interaction is charged once, at the highest tier it touched. Summing tiers independently over-bills.
- Copilot covers Supervisor summaries. Enabling Agent Copilot makes AI Summary & Insights free; billing both double-charges.
What the client sees (the stage)
The published rate card as the vendor prints it, then three KPI cards (token cost, text-to-speech, total run-rate with a $/interaction figure), the allowance shown as the deduction it is, a per-feature cost breakdown, the list-price → negotiated walk, text-to-speech as its own clearly separated line, an adoption scenario range, and a tornado of what actually moves the number.
Text-to-speech is never folded silently into the token subtotal: the grand total always shows tokens and TTS as two labelled components.
You drive it from the sidebar — licence model, currency, token price and concession, the three deflection shares, average bot seconds, and a per-feature enable. Every change re-renders the numbers (Mercury re-runs the cells below the widgets).
Where the content lives: in the notebook
Two tagged cells of
notebooks/genesys_token_calculator.ipynb
carry everything a consultant edits — in Jupyter, never in a .py file:
topic-bank— the feature catalogue: each priced capability's client-facing title, what it does for them, and the sizing question to ask. Thekeyslugs must match published meter keys (a test pins this), and they are stable identities the widgets, notes and JSON export all key off.engagement-data— the client facts: volumes by channel, headcount, licence model, and the negotiated commercial terms (contracted rate, concession). Illustrative placeholders in this master; filled in the engagement copy.
The published rates are deliberately not content — nobody in this repo authors them, and editing them is forbidden. They are the vendor's record, so they live in the engine as an anchor. See the Calculator Pattern for the full boundary.
genesyscalc/ holds code only — the meter schema, the anchor, and the
arithmetic. The test suite reads the tagged cells straight out of the notebook
(no kernel) and pins content shape, so pytest guards the catalogue exactly
as shipped.
Layout
notebooks/genesys_token_calculator.ipynb # THE deliverable — content + data + presentation
# tagged: topic-bank · engagement-data ·
# presentation ×8 · gate · data-appendix
genesyscalc/ # the engine — code only, no content, mypy --strict
ratecard.py # THE VERBATIM ANCHOR — published meters, 2026-07-12
meters.py # schema: Confidence, LicenceModel, MeterBasis, Tier, Meter, TokenPrice
usage.py # volumes → units → tokens (round-up, tier partition, Copilot rule)
billing.py # tokens → dollars (ceil, allowance, price, concession)
tts.py # the NON-token line — own source, own rounding, EOS/EOL
model.py # orchestration: CalculatorInputs → CalculatorResult
sensitivity.py # sweeps + tornado data (no plotting)
appendix.py # the machine-readable JSON payload
staging.py # stage/backstage detection (+ backstage_md)
scripts/export_report.py # execute once → exports/*.html + LLM-ready *.md
tests/ # rate-card tripwire, hand-checked arithmetic, content pins, staging
exports/ # generated report sources (never committed)
Run
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
mercury --working-dir . # serve the stage (share this screen)
jupyter lab # analyst view
pytest # rate card + engine + content + staging pins
mypy # strict
jupyter nbconvert --to notebook --execute --inplace notebooks/genesys_token_calculator.ipynb
python scripts/export_report.py # exports/*.html + *.md for the LLM handoff
The .md export opens with a generated preamble (what the document is, the
engagement line, which rate card produced the numbers) and ends with the
Model state (JSON) block — the machine source of truth, carrying
rate_card.source_date. A cost figure without its rate-card date is not
auditable.
Re-anchoring — when Genesys republishes
The rate card is a living anchor: immutable until the vendor changes it, then updated deliberately. Never partially re-anchor, and never bump the date without the pins.
- Diff the published table against
genesyscalc/ratecard.py. - Update the meters and
RATE_CARD_SOURCE_DATEin the same edit. - Update the pins in
tests/test_rate_card.pyin the same commit. - Re-execute the notebook; update the gate's live-state pins if the defaults moved.
- Report the cost moves honestly.
- Show-first — the user sees the rate diff and the KPI move before it lands.
tests/test_rate_card.py is the tripwire: it pins all 20 rows by exact
feature wording and exact rate string, so a silent transcription drift or an
un-noticed republication breaks the build rather than quietly moving a
client-facing number.
Extending
New or reshaped catalogue content is an edit to the notebook's topic-bank
cell in JupyterLab, then re-run the notebook (the gate recounts the
catalogue and checks every key against the published meters) and re-pin
tests/test_catalogue.py. New logic goes in genesyscalc/ with pins in
tests/, before the notebook section that renders it.
Non-goals
- Not a business case. No benefits, no NPV, no payback, no ROI, no P&L. If
a client needs those, that is a Study — see
studies/. A calculator that grows a benefit model has stopped being a calculator. - Not contractual pricing. A planning model at list rates unless a contracted rate is entered. Genesys quotes; this estimates.
- Not a platform TCO. Genesys Cloud CX seat licensing is out of scope — this prices the AI meters and Enhanced TTS only.
Running this for a client? Don't fill client data into this master —
copy the directory out of Palladium, stamp it
YYYYMM_Client_Genesys_Token_Calculator, provision a fresh venv there, fill
the engagement-data cell in the copy, and treat the copy as confidential
(CLAUDE.md § Confidentiality). A test in this master fails if a client name
lands in engagement-data here.