LangGraph.js Generative UI Examples

repository·main·Indexed 19 days ago

https://github.com/langchain-ai/langgraphjs-gen-ui-examples

A collection of LangGraph-based agents demonstrating Generative UI capabilities. It showcases how agents can trigger specialized React components—such as stock tickers, travel booking tools, and code editors—within the Agent Chat UI. Includes examples of Human-in-the-Loop (HITL) workflows using the HumanInterrupt schema and streaming UI components as artifacts.

Tokens
10.7K
Snippets
30
Records
41
Agent score
64%

What's inside langgraphjs-gen-ui-examples

  1. Implement Human-in-the-Loop with the Email Agent

    main

    The email_agent (accessed via email_agent graph ID) demonstrates how to handle user interruptions using the HumanInterrupt schema. When the agent reaches a point requiring user input, it throws an interrupt that the Agent Chat UI detects to render interactive components.

    Trigger Prompt:

    • Write me an email to <email> about <description>

    Supported UI Actions:

    • Accept: Sends the email as is.
    • Edit: Allows editing fields before sending.
    • Respond: Allows providing text feedback to rewrite the email.
    • Ignore: Ends the graph without action.
    • Mark as resolved: Resumes the graph at the __end__ node, ending the session.
  2. Setup LangGraph Generative UI Examples

    main

    To run the generative UI examples locally, follow these steps:

    1. Clone the repository:

      git clone https://github.com/langchain-ai/langgraphjs-gen-ui-examples.git
      cd langgraphjs-gen-ui-examples
    2. Install dependencies using pnpm:

      pnpm install
    3. Configure environment variables: Copy the example file to .env:

      cp .env.example .env

      Set the following keys in your .env file:

      • OPENAI_API_KEY (Required)
      • GOOGLE_API_KEY (Required)
      • ANTHROPIC_API_KEY (Optional, used for the pizza ordering agent)
      • FINANCIAL_DATASETS_API_KEY (Optional, used for the stockbroker graph)
      • LANGSMITH_API_KEY, LANGSMITH_PROJECT, LANGSMITH_TRACING_V2 (Optional, for observability)
    4. Start the LangGraph server:

      pnpm agent

      The server will typically start at http://localhost:2024.

    git clone https://github.com/langchain-ai/langgraphjs-gen-ui-examples.git
    cd langgraphjs-gen-ui-examples
    pnpm install
    cp .env.example .env
    pnpm agent
  3. Test agents using Graph IDs

    main

    The repository provides several pre-configured agents accessible via specific graph_id values. You can use these IDs to test different generative UI capabilities in the Agent Chat UI:

    • agent: The primary supervisor agent. It routes requests to specialized subgraphs like Stockbroker, Trip Planner, Open Code, or Order Pizza.
    • chat: A basic LLM chat agent with no tools or generative UI components.
    • email_agent: A demonstration of Human-in-the-Loop (HITL) capabilities using the HumanInterrupt schema.
    • writer: A demonstration of streaming generative UI components as an artifact (e.g., a short story rendered in a side panel).
  4. Understand the Writer Agent state schema

    main

    The WriterAnnotation defines the state for the writer agent. It extends GenerativeUIAnnotation to support real-time UI updates alongside message history.

    KeyTypeDescription
    messagesGenerativeUIAnnotation.spec.messagesThe conversation history.
    uiGenerativeUIAnnotation.spec.uiThe stream of UI component updates.
    context{ writer?: { selected?: string } }Metadata used to provide context to the LLM (e.g., text selected by a user in a UI).

    This schema allows the agent to not only respond with text but also to control specific UI components (like a document editor) by pushing updates to the ui array.

  5. Submit a booking via thread.submit in AccommodationsList

    main

    When a user clicks the "Book" button in the SelectedAccommodation view, the component uses the thread.submit method from the LangGraph SDK to update the conversation state. It sends a tool message containing the booking details and a human message confirming the action, then instructs the graph to move to the generalInput node.

    Message Structure:

    • Type: tool
    • tool_call_id: The original toolCallId.
    • id: A new ID prefixed with DO_NOT_RENDER_ID_PREFIX and a uuidv4().
    • name: book-accommodation
    • content: A JSON string containing accommodation and tripDetails.
    • Type: human
    • content: A string confirming the booking (e.g., "Booked [Name] for [Guests].")
    • goto: "generalInput"
    thread.submit(
      {},
      {
        command: {
          update: {
            messages: [
              {
                type: "tool",
                tool_call_id: toolCallId,
                id: `${DO_NOT_RENDER_ID_PREFIX}${uuidv4()}`,
                name: "book-accommodation",
                content: JSON.stringify(orderDetails),
              },
              {
                type: "human",
                content: `Booked ${accommodation.name} for ${tripDetails.numberOfGuests}.`,
              },
            ],
          },
          goto: "generalInput",
        },
      },
    );
  6. Submit tool responses via thread.submit in BuyStock

    main

    When implementing Generative UI components that perform actions (like BuyStock), use thread.submit to update the conversation state and navigate the graph.

    To successfully complete a tool execution, the command.update.messages array should include:

    1. A message of type: "tool" containing the tool_call_id and a JSON-stringified content object representing the tool's result.
    2. A message of type: "human" providing a natural language confirmation of the user's action.

    You can also use the goto key in the command object to transition the graph to a specific node (e.g., generalInput) after the tool response is processed.

    thread.submit(
      {},
      {
        command: {
          update: {
            messages: [
              {
                type: "tool",
                tool_call_id: toolCallId,
                id: `${DO_NOT_RENDER_ID_PREFIX}${uuidv4()}`,
                name: "buy-stock",
                content: JSON.stringify(orderDetails),
              },
              {
                type: "human",
                content: `Purchased ${quantity} shares of ${snapshot.ticker} at ${snapshot.price} per share`,
              },
            ],
          },
          goto: "generalInput",
        },
      },
    );
  7. Order Pizza Graph workflow structure

    main

    The Order Pizza Graph is a compiled StateGraph with the following node sequence:

    1. findStore: Uses a Claude 3.5 Sonnet model to extract location and an optional pizza_company from the message history. It simulates finding a shop and returns a ToolMessage with shop details.
    2. orderPizza: Uses the model to extract address, phone_number, and the order details, then simulates placing the order by returning a success ToolMessage.

    Workflow Path: START -> findStore -> orderPizza -> END

  8. Use the Trip Planner agent via the Supervisor

    main

    The Trip Planner agent renders UI for booking accommodations and restaurants. It is accessed through the agent graph ID via the Supervisor.

    Test Prompts:

    • Show me places to stay in <location>
    • Recommend some restaurants for me in <location>

    Extracted Parameters:

    • location (Required)
    • startDate (Optional, defaults to 4 weeks from now)
    • endDate (Optional, defaults to 5 weeks from now)
    • numberOfGuests (Optional, defaults to 2)
  9. Use the Stockbroker agent via the Supervisor

    main

    The Stockbroker agent provides generative UI for financial data. It is accessed through the agent graph ID via the Supervisor.

    Test Prompts:

    • What's the current price of <ticker> (Renders current price UI)
    • I want to buy <quantity> shares of <ticker> (Renders a UI to buy stock)
    • Show me my portfolio (Renders portfolio UI)
  10. Stream UI components as artifacts with the Writer Agent

    main

    The writer agent (accessed via the writer graph ID, or via the Supervisor using the agent ID) demonstrates how to stream generative UI components as an artifact. This is useful for long-form content like stories that should appear in a side panel while being generated.

    Test Prompt:

    • Write me a short story about a <topic>
  11. Configure the Supervisor Agent with SupervisorZodConfiguration

    main

    The SupervisorZodConfiguration schema defines the available parameters for configuring a Supervisor Agent. It is used to control the model selection, generation randomness, and token limits.

    Available configuration keys:

    • model: (string, optional) The model ID in provider/model_name format. Defaults to anthropic/claude-3-7-sonnet-latest. Supported options include various Claude and OpenAI models.
    • temperature: (number, optional) Controls randomness from 0 (deterministic) to 2 (creative). Defaults to 0.7.
    • maxTokens: (number, optional) The maximum number of tokens to generate. Defaults to 1000.
    • systemPrompt: (string, optional) A custom system prompt to be used in all generations.
    import { SupervisorZodConfiguration } from './path-to-types';
    
    const config = {
      model: 'openai/gpt-4o',
      temperature: 0.5,
      maxTokens: 2000,
      systemPrompt: 'You are a helpful supervisor agent.'
    };
  12. Use the stockbrokerGraph instance

    main

    The stockbrokerGraph is a compiled LangGraph instance designed for stockbroker agentic workflows. It uses the StockbrokerAnnotation for state management and includes an agent node that utilizes callTools. You can import this graph to run stock-related agentic tasks within your application.

    import { stockbrokerGraph } from './src/agent/stockbroker/index';
    
    // Example usage of the compiled graph
    const result = await stockbrokerGraph.invoke({
      // initial state based on StockbrokerAnnotation
    });