import React, { createContext, useContext, ReactNode, useState } from "react"; import { useStream } from "@langchain/langgraph-sdk/react"; import { type Message } from "@langchain/langgraph-sdk"; import type { UIMessage, RemoveUIMessage, } from "@langchain/langgraph-sdk/react-ui"; import { useQueryParam, StringParam } from "use-query-params"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { LangGraphLogoSVG } from "@/components/icons/langgraph"; import { Label } from "@/components/ui/label"; import { ArrowRight } from "lucide-react"; import { PasswordInput } from "@/components/ui/password-input"; import { getApiKey } from "@/lib/api-key"; export type StateType = { messages: Message[]; ui?: UIMessage[] }; const useTypedStream = useStream< StateType, { UpdateType: { messages?: Message[] | Message | string; ui?: (UIMessage | RemoveUIMessage)[] | UIMessage | RemoveUIMessage; }; CustomUpdateType: UIMessage | RemoveUIMessage; } >; type StreamContextType = ReturnType; const StreamContext = createContext(undefined); const StreamSession = ({ children, apiKey, apiUrl, assistantId, }: { children: ReactNode; apiKey: string | null; apiUrl: string; assistantId: string; }) => { const [threadId, setThreadId] = useQueryParam("threadId", StringParam); const streamValue = useTypedStream({ apiUrl, apiKey: apiKey ?? undefined, assistantId, threadId: threadId ?? null, onThreadId: setThreadId, }); return ( {children} ); }; export const StreamProvider: React.FC<{ children: ReactNode }> = ({ children, }) => { const [apiUrl, setApiUrl] = useQueryParam("apiUrl", StringParam); const [apiKey, _setApiKey] = useState(() => { return getApiKey(); }); const setApiKey = (key: string) => { window.localStorage.setItem("lg:chat:apiKey", key); _setApiKey(key); }; const [assistantId, setAssistantId] = useQueryParam( "assistantId", StringParam, ); if (!apiUrl || !assistantId) { return (

LangGraph Chat

Welcome to LangGraph Chat! Before you get started, you need to enter the URL of the deployment and the assistant / graph ID.

{ e.preventDefault(); const form = e.target as HTMLFormElement; const formData = new FormData(form); const apiUrl = formData.get("apiUrl") as string; const assistantId = formData.get("assistantId") as string; const apiKey = formData.get("apiKey") as string; setApiUrl(apiUrl); setApiKey(apiKey); setAssistantId(assistantId); form.reset(); }} className="flex flex-col gap-6 p-6 bg-muted/50" >

This is the URL of your LangGraph deployment. Can be a local, or production deployment.

This is the ID of the graph (can be the graph name), or assistant to fetch threads from, and invoke when actions are taken.

This is NOT required if using a local LangGraph server. This value is stored in your browser's local storage and is only used to authenticate requests sent to your LangGraph server.

); } return ( {children} ); }; // Create a custom hook to use the context export const useStreamContext = (): StreamContextType => { const context = useContext(StreamContext); if (context === undefined) { throw new Error("useStreamContext must be used within a StreamProvider"); } return context; }; export default StreamContext;