1. A fifteen-turn live QuoteGraph replay
Read this first. This is a complete passing provider-backed run with QUOTE_GRAPH_CURRENT_DATE frozen to 2027-06-01. The model wording may vary; catalog resolution, coverage policy, calculated premiums, state transitions, and the final completed state are the durable contracts.
Run it yourself
- 1
- 2
cd ezgraph-demo
npm run test2:quote-graph
The script sets USE_ENV=1 KEEP_SESSION=1. The test sends all fifteen turns through one retained session, judges each response semantically, and inspects the final node-owned state. Without USE_ENV=1 it is skipped; with it, it needs working provider credentials.
Captured live transcript
-
1 · driver stage greeting
YouHi, I'd like a quote for my car insurance.
BotAbsolutely — I can help with that.
What’s your full name?
-
2 · name and birth date
YouJamie Rivera, born April 12, 1993.
BotThanks, Jamie. What state is your driver’s license issued in, and is it valid or a learner’s permit?
-
3 · driver capture advances to vehicle
YouLicensed in Oregon, valid license, for about 10 years.
BotThanks — I’ve saved Jamie Rivera, born 1993-04-12, with a valid Oregon license and 10 years licensed.
What’s the vehicle’s year, make, and model?
-
4 · trim disambiguation
YouIt's a 2019 Toyota Camry.
BotI found a few 2019 Toyota Camry trims. Which one is yours: LE, SE, or XSE?
-
5 · resolved vehicle asks usage
BotGot it — 2019 Toyota Camry SE.
Do you own it, finance it, or lease it? And about how many miles do you drive per year?
-
6 · ownership and mileage
YouI finance it and drive about 12,000 miles a year.
BotThanks. Where is it usually parked overnight: garage, driveway, or street?
-
7 · vehicle capture advances to history
BotSure — I just need two things:
- Do you currently have auto insurance?
- In the past 12 months, did your coverage lapse at any point?
Also, please list any incidents in the last 5 years with the month as YYYY-MM, or say “none.” Categories are:
- at-fault accident
- not-at-fault accident
- violation (like a speeding ticket)
- comprehensive claim (theft, glass, weather, animal damage)
-
8 · insurance status
YouI'm insured today and had no lapse in the past year.
BotThanks. Any incidents in the last 5 years? Please list the month as YYYY-MM for any:
- at-fault accident
- not-at-fault accident
- violation
- comprehensive claim
“None” is perfectly fine.
-
9 · history capture advances to coverage
YouJust one speeding ticket in March 2026, nothing else.
BotSince the Camry is financed, it needs both collision and comprehensive coverage.
Which liability level would you like: state minimum, standard, or premium? And would you like $250, $500, or $1,000 deductibles for collision and comprehensive?
-
10 · liability selection
YouStandard liability, please.
BotYou got it. Since it’s financed, I still need deductibles for both collision and comprehensive.
Would you like $250, $500, or $1,000 for each?
-
11 · lender rule blocks liability-only
YouCan I skip collision and comprehensive entirely?
BotBecause the car is financed, collision and comprehensive are required, so you can’t skip them entirely.
Which deductibles would you like for collision and comprehensive: $250, $500, or $1,000 each?
-
12 · deductibles and extras
YouFine, $500 deductibles for both, and add rental reimbursement but no roadside.
BotGot it. What date would you like the policy to start? It can start today through 60 days from today.
-
13 · coverage capture presents quote tiers
BotHere are your quote options, starting on June 15, 2027:
-
Saver — $99.96/month
- Liability: State-minimum
- Deductibles: $1,000 collision / $1,000 comprehensive
- Extras: None
-
Selected — $140.43/month
- Liability: Standard
- Deductibles: $500 collision / $500 comprehensive
- Extras: Rental
- Recommended based on your choices
-
Shield — $182.17/month
- Liability: Premium
- Deductibles: $250 collision / $250 comprehensive
- Extras: Rental and roadside
You can:
- Pick a tier — for example, “I’ll take Selected”
- Adjust the quote — for example, “What if my deductible were $1,000?”
- Start over on coverage — and we can rework the choices from scratch
-
14 · deductible what-if adjustment
YouWhat would it cost if both deductibles were $1000?
BotHere is the updated quote:
- Saver — state-minimum liability, $1000/$1000 deductibles, no extras: $99.96/mo
- Your selection — standard liability, $1000/$1000 deductibles, rental: $130.49/mo
- Shield — premium liability, $250/$250 deductibles, rental + roadside: $182.17/mo
Adjust anything else, accept a tier, or rework the coverage.
-
15 · acceptance completes the quote · completed
YouAccept my selected option, please.
BotYou’re all set — your selected coverage (Your selection) is locked in at $130.49/month starting 2027-06-15. Your quote reference is QT-648463.
The final turn locks the current calculated tier, creates a quote reference, sets completed: true, and leaves the accepted tier in QuoteNode state.
Under the hood
The transcript shows what the customer saw. This table shows which nodes ran, which tools changed state or moved the conversation, and who wrote each reply. The replay records replies rather than tool calls, so the tool column is inferred from each reply and the node code. Turns 14 and 15 match the code's templates word for word.
| Turn | Customer | Nodes | Tool and result | Reply written by |
| 1 | Hi, I'd like a quote… | DriverNode | — | model |
| 2 | Jamie Rivera, born April 12, 1993. | DriverNode | — | model |
| 3 | Licensed in Oregon, valid license, for about 10 years. | DriverNode → VehicleNode | capture_driver → go(VehicleNode) | model (VehicleNode) |
| 4 | It's a 2019 Toyota Camry. | VehicleNode | resolve_vehicle → stay() with three trims | model |
| 5 | The SE trim. | VehicleNode | resolve_vehicle with a trim → stay(), one vehicle resolved | model |
| 6 | I finance it and drive about 12,000 miles a year. | VehicleNode | — | model |
| 7 | In my driveway. | VehicleNode → HistoryNode | capture_vehicle_use → go(HistoryNode) + stage message | model (HistoryNode) |
| 8 | I'm insured today and had no lapse in the past year. | HistoryNode | — | model |
| 9 | Just one speeding ticket in March 2026, nothing else. | HistoryNode → CoverageNode | capture_history → go(CoverageNode) + stage message | model (CoverageNode) |
| 10 | Standard liability, please. | CoverageNode | — | model |
| 11 | Can I skip collision and comprehensive entirely? | CoverageNode | none needed; the rule is in the prompt and enforced in code | model |
| 12 | Fine, $500 deductibles for both… | CoverageNode | — | model |
| 13 | Start it on June 15. | CoverageNode → QuoteNode | select_coverage → rating → go(QuoteNode) + stage message | model (QuoteNode) |
| 14 | What would it cost if both deductibles were $1000? | QuoteNode | adjust_quote → rating → direct(text) | code |
| 15 | Accept my selected option, please. | QuoteNode → end | accept_quote → finish(text) | code |
Four things are worth noticing before the lessons take the graph apart:
- Most turns call no tool. A stage's model keeps asking questions until it has everything its tool needs. State changes only when a handler accepts a complete, valid submission.
- A stage change happens inside one turn. On turns 3, 7, 9, and 13 one node saves its facts and returns
go(), and the next node writes the reply. The customer never sees a “moving on” message from the old stage.
- Every price comes from code. The rating engine priced the tiers on turn 13, and the model presented them from JSON. On turn 14 the model only chose
adjust_quote; the numbers and the wording came from code, with no second model call.
- Acceptance is a business event, not a sentence. Turn 15 completes because
accept_quote found selected in the saved tiers. The confirmation, premium, start date, and reference number are all code-owned.
Two small inconsistencies are visible too. The model called the middle tier “Selected” on turn 13, while the code's label on turn 14 is “Your selection”. And the confirmation on turn 15 reads “your selected coverage (Your selection)”. Lesson 9 explains both.
Next
2. Graph, state, and ownership maps the nodes and durable values behind the replay.