No EZGraph key required. Free production use. No runtime fee. Bring your own model provider. Support Jev. Run in your own infrastructure. Optional support is available.

6. Grounded presentation and booking

The goal

Let the model make a friendly hotel presentation without allowing it to invent a hotel, price, or booking.

Separate the draft from the release decision

PresentNode receives the current hotelFound list in its prompt. The model drafts a presentation and submits it with the publish_hotel_draft tool, which saves the draft and returns go(PresentationDecisionNode). The decision node’s evidence is the draft plus the exact saved hotels and criteria. It asks whether the draft is grounded (Noul) and scores completeness and clarity (Score, 0–2). Code releases the draft only when grounded.noul >= 0.85 and both scores are at least 1.5 with confidence of at least 0.75.

Either way, the node returns directTo(PresentNode, text). The text is the accepted draft or CriteriaHelper.renderHotelResults(hotels), a deterministic rendering of the saved results. The same rendering is the fallback when the decision provider is unavailable. The next customer turn resumes in PresentNode.

Validate selection against the result list

The chosen_hotel tool accepts a hotel name or a one-based number, but resolves it against the current hotelFound array. Names must match exactly, ignoring case. Unknown values return stay(...); only a listed hotel saves selectedHotel and a confirmation number and returns finish(...). A request to change criteria calls revise_search, which forwards the customer’s message to RouterDecisionNode.

Why it is written this way

A polished answer is not evidence. The customer sees a model draft only when it is supported by the actual search result, and a booking is bound to that same result list rather than a name the model happens to mention.

Next

Continue to 7. Fallbacks and evaluation.