Michael Thomson
Router agent and four domain agents

Tripp

Plan a trip by talking to it. Places move between confirmed, possible, and discarded columns on a live board, and nothing dropped is ever really gone — discarded is a place you can change your mind from.

Overview

A clean demonstration of an agentic application: a router that delegates to four domain agents, each with its own tools, mutating shared trip state that the user sees change as it happens. The agent service is stateless and never writes — the Express backend is the only writer.

What it does
  • 01Router delegating to four domain agents
  • 02Stateful board the agent mutates live
  • 03Discarded places stay recoverable
  • 04Suggestions arrive as cards, not prose
  • 05Agent reasoning printed as a readable tree
  • 06Public landing page runs the real board

Three services

frontend/
  • React, Vite, TypeScript
  • The board, chat, voice
backend/
  • Express, TypeScript, Mongo
  • Accounts, trips, plan limits
  • The only writer
agents/
  • FastAPI, LangChain
  • A router and four domain agents
  • Stateless

Watching the agent think

At debug level the routing prints as a tree — which agent was chosen, what it was asked, every tool call with its arguments, and what came back. Provider SDK logging is pinned lower, because at debug it buries the trace it is meant to sit beside.

One turn
  1. router→
  2. delegate to places→
  3. set_place_status→
  4. p2 discarded→
  5. delegate to budget→
  6. router answers

Decisions that came from getting it wrong first

Capabilities
  • Suggestions return as cards the traveller ticks, not a prose list they would have to retype — nothing reaches the trip until it is chosen
  • Photo lookups cache two ways: a search that found nothing holds for a month, a failed search for ten minutes, because caching a throttled minute for a month left four cities with no photographs
  • Lookups queue three at a time, since a page showing eight places asks for eight the moment it renders
  • The signed-out landing page runs the real board on sample data — a screenshot cannot make that claim
Built with
ReactTypeScriptViteExpressMongoDBPythonFastAPILangChainDocker