Wayfarer Travel is a made-up travel brand, and this is the last demo in the gallery: one product that uses every feature the other demos show one at a time. You ask it for Lisbon from Tuesday to Thursday next week with a car from the airport. The planner shows packages, puts your pick on the itinerary, confirms a demo booking and books the trip's key hours on a real calendar.
The Features tab beside the demo names six features. Each one lights only when that feature really fires in your visit, from the run's own events, and says what fired. The tab's label and the strip above the stage count how many you've seen. Nothing lights on a timer or when the page loads.
The agent is configuration#
trip-planner is a Mindset agent made of five prompt fields, a model and a list of what it may use. There's no agent code in this page. The chat is the drop-in <mindset-agent> element, the same one Put an agent on your page starts with. The whole definition lives in demos/trip-planner/, and the repo is applied to the org through the admin MCP.
Scripts: the opening#
Where you see it: the greeting and the three trips offered as reply pills, before you type anything.
The agent has a one-phase script, trip-planner-flow. Its entry steps run on the platform before the model says anything: a greeting that says it is a demo, then the three trips. The phase is terminal with onComplete: "freeform", so the run completes straight away and the rest of the conversation is the agent's prompt with all its tools. That matters here: a phase that declares resources or vars filters out page tools, and the planner needs add_to_itinerary on every turn. The light comes on when the script's opening arrives in the chat.
On its own: Guided intake runs a claim through several phases, each with a gate.
Situational awareness: next week becomes dates#
Where you see it: your first message. The agent knows today's date without asking.
The page sends three values with every turn: today (the date and weekday), itinerary (what's on it now, as one line) and calendar_id (the demo calendar to book on). That's how the agent turns "next week" into a check-in date, and how it knows what you've already chosen. The light comes on when the first turn starts, because the awareness goes with it.
On its own: What's wrong with this one? shows an agent with no tools answering from awareness alone.
Functions: the hotels and cars#
Where you see it: the packages, and the booking references after you book.
The hotels and cars are literal sample stock inside functions. A function is a JSON pipeline: one step holds the stock, and every step after it is pure. trip-planner-plan-trip filters hotels by city and price cap, ranks them by rating, pairs each with the cheapest airport car and sorts the packages by total. trip-planner-search-hotels sorts by price, rating or minutes from the river, which is how "move my hotel nearer the river" works. trip-planner-book-hotel and trip-planner-book-car build a confirmation reference from your input and store nothing. A function call costs no model call and returns the same answer every time. The light comes on when a function call finishes.
On its own: Ask your data answers questions from what a function returns.
Where you see it: the option cards in the chat, and the booking form after Book now.
The option cards widget, trip-planner-option-cards, shows each package with its tag, its total and a Choose button. Pressing it sends your choice back to the agent, which is the widget round trip. Once something is on your itinerary, the page shows a Book now button. It sends "Book now" to the agent, which answers with the booking form widget, trip-planner-booking-form: the choice and dates, and a request for the traveler's name, with a one-click sample name. The agent books only after you've given a name. The light comes on when a widget arrives in the chat.
On its own: Widget round trip is about nothing else.
Page tools: the itinerary changes#
Where you see it: a stop drops onto the timeline and the trip calendar fills in when you choose.
The page gives the agent two page tools. add_to_itinerary puts a hotel or car on the itinerary and replaces the old one. remove_from_itinerary takes one off. Both check every argument before they touch the page: the stock id, the dates and the total. When a booking comes back, the page also copies its reference onto the itinerary from the run's tool_end event. The light comes on when a page tool finishes.
On its own: Store assistant filters a product grid and fills a basket.
Connections and approvals: the calendar#
Where you see it: the Calendar tab, after the booking.
The calendar is a live demo service with a keyed booking API and a public week view. The agent reaches it through an HTTP API connection, trip-planner calendar, that declares three operations: list_calendars, get_slots and book_slot. The API key is entered by a person on a credential capture page, so it never passes through a chat or the repo. After every booking the agent calls book_slot for the car pick-up, the hotel check-in and the check-out. book_slot writes, so it's governed: the org decides whether it runs straight away or waits for a person's approval.
The panel is honest about it. Until a real book_slot call comes back with a booking, the connection reads "Calendar connection not live yet", and a refused or failed call says so. The agent then says the calendar is offline, and the itinerary still updates. Once the connection's key is captured, the Calendar tab frames the service's public week view, which refreshes every two seconds and shows each slot only as Booked.
On its own: Help widget reads charges through an MCP connection and stops at a refund nobody has approved.
Under the hood#
The Under the hood tab shows each step as it happens: the function calls with their arguments, the widgets, the page tools and their results, and the calendar booking. Each row's kind matches a light on the Features tab.
Build the same thing#