Mercury Genesys Token Calculator
This commit is contained in:
172
calculators/Genesys_Token_Calculator/README.md
Normal file
172
calculators/Genesys_Token_Calculator/README.md
Normal file
@@ -0,0 +1,172 @@
|
||||
# Genesys Cloud AI — Token Calculator
|
||||
|
||||
A **Calculator** — a reusable vendor-pricing master (see
|
||||
[`docs/Calculator_Pattern_V1-00.md`](../../docs/Calculator_Pattern_V1-00.md))
|
||||
— built on the
|
||||
[Mercury Notebook Deliverable Pattern](../../docs/Mercury_Notebook_Pattern_V1-00.md).
|
||||
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`](genesyscalc/ratecard.py):
|
||||
|
||||
| Source | Published | What it gives |
|
||||
|---|---|---|
|
||||
| [Genesys Cloud tokens model](https://help.genesys.cloud/articles/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](https://help.genesys.cloud/articles/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:
|
||||
|
||||
1. **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).
|
||||
2. **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.
|
||||
3. **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.
|
||||
4. **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`](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.
|
||||
The `key` slugs 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
|
||||
|
||||
```bash
|
||||
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.
|
||||
|
||||
1. Diff the published table against `genesyscalc/ratecard.py`.
|
||||
2. Update the meters **and** `RATE_CARD_SOURCE_DATE` in the same edit.
|
||||
3. Update the pins in `tests/test_rate_card.py` in the same commit.
|
||||
4. Re-execute the notebook; update the gate's live-state pins if the defaults moved.
|
||||
5. Report the cost moves honestly.
|
||||
6. **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/`](../../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.
|
||||
Reference in New Issue
Block a user