UNPKG

@langgraph-js/sdk

Version:

The UI SDK for LangGraph - seamlessly integrate your AI agents with frontend interfaces

64 lines (63 loc) 2.62 kB
import { createElement, createContext, useContext, useMemo, useEffect, useRef } from "react"; import { createChatStore, useUnionStore } from "../ui-store/index.js"; import { useStore } from "@nanostores/react"; const ChatContext = createContext(undefined); export const useChat = () => { const context = useContext(ChatContext); if (!context) { throw new Error("useChat must be used within a ChatProvider"); } return context; }; export const ChatProvider = ({ children, defaultAgent = "", apiUrl = "http://localhost:8123", defaultHeaders, withCredentials = false, fetch, showHistory = false, showGraph = false, fallbackToAvailableAssistants = false, autoRestoreLastSession = false, onInitError, client, legacyMode = false, }) => { // 使用 useMemo 稳定 defaultHeaders 的引用 const stableHeaders = useMemo(() => defaultHeaders || {}, [defaultHeaders]); // 使用 useRef 保存 onInitError 的最新引用 const onInitErrorRef = useRef(onInitError); useEffect(() => { onInitErrorRef.current = onInitError; }, [onInitError]); const store = useMemo(() => { const baseFetch = fetch || globalThis.fetch; const F = withCredentials ? (url, options) => { options.credentials = "include"; return baseFetch(url, options); } : baseFetch; const config = { apiUrl, defaultHeaders: stableHeaders, callerOptions: { fetch: F, maxRetries: 1, }, legacyMode, }; /** @ts-ignore */ if (client) config.client = client; return createChatStore(defaultAgent, config, { showHistory, showGraph, fallbackToAvailableAssistants, autoRestoreLastSession, }); }, [defaultAgent, apiUrl, stableHeaders, withCredentials, fetch, showHistory, showGraph, fallbackToAvailableAssistants, autoRestoreLastSession]); const unionStore = useUnionStore(store, useStore); // 使用 ref 标记是否已初始化 const initializedRef = useRef(false); useEffect(() => { if (initializedRef.current) { return; } initializedRef.current = true; unionStore.initClient().catch((err) => { console.error(err); if (onInitErrorRef.current) { onInitErrorRef.current(err, unionStore.currentAgent); } }); }, [unionStore]); return createElement(ChatContext.Provider, { value: unionStore }, children); };