Log and transcript fields

A stateful agent needs more than slots. It needs a transcript of what has been said, plus a stage label that describes where the conversation is right now. Both live inside the same TypedDict, and together they make the graph observable and testable.

booking_graph.py
python
def _append_message(state: BookingState, role: str, content: str) -> None:
    messages = state.get("messages") or []
    messages.append({"role": role, "content": content})
    state["messages"] = messages

The transcript is a list of role/content dicts, exactly the shape most chat completion APIs already expect. Appending is a helper so every node reads and writes it the same way.

Flashcards: Flashcards

Loading practice…

service.py
python
async def chat(self, thread_id: str, user_message: str) -> Dict[str, Any]:
    """Run one turn through the graph. MemorySaver resumes prior state."""
    config = {"configurable": {"thread_id": thread_id}}

    turn_input: Dict[str, Any] = {
        "user_message": user_message,
        "thread_id": thread_id,
    }
    # Append the user message to running transcript.
    prior = self._graph.get_state(config)
    prior_messages = []
    if prior and prior.values:
        prior_messages = list(prior.values.get("messages") or [])
    prior_messages.append({"role": "user", "content": user_message})
    turn_input["messages"] = prior_messages

    result = await self._graph.ainvoke(turn_input, config=config)

Every chat turn pulls the prior transcript from the checkpointer, appends the new user message, invokes the graph, and lets the nodes write their reply back into state.

Quiz: Quiz

Loading practice…