feat: implement basic web app

This commit is contained in:
Henry Li
2026-01-15 23:40:21 +08:00
parent c7d68c6d3f
commit cecc684de1
49 changed files with 4142 additions and 626 deletions

View File

@@ -0,0 +1,17 @@
"use client";
import { Client as LangGraphClient } from "@langchain/langgraph-sdk/client";
let _singleton: LangGraphClient | null = null;
export function getLangGraphClient(): LangGraphClient {
let url: URL | null = null;
if (typeof window === "undefined") {
url = new URL("/api/langgraph", "http://localhost:3000");
} else {
url = new URL("/api/langgraph", window.location.origin);
}
_singleton ??= new LangGraphClient({
apiUrl: "http://localhost:2024",
});
return _singleton;
}

View File

@@ -0,0 +1,45 @@
import type { ThreadsClient } from "@langchain/langgraph-sdk/client";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import type { MessageThread, MessageThreadState } from "../thread";
import { getLangGraphClient } from "./client";
export function useThreads(
params: Parameters<ThreadsClient["search"]>[0] = {
limit: 50,
sortBy: "updated_at",
sortOrder: "desc",
},
) {
const langGraphClient = getLangGraphClient();
return useQuery<MessageThread[]>({
queryKey: ["threads", "search", params],
queryFn: async () => {
const response =
await langGraphClient.threads.search<MessageThreadState>(params);
return response as MessageThread[];
},
});
}
export function useDeleteThread() {
const queryClient = useQueryClient();
const langGraphClient = getLangGraphClient();
return useMutation({
mutationFn: async ({ threadId }: { threadId: string }) => {
await langGraphClient.threads.delete(threadId);
},
onSuccess(_, { threadId }) {
queryClient.setQueriesData(
{
queryKey: ["threads", "search"],
exact: false,
},
(oldData: Array<MessageThread>) => {
return oldData.filter((t) => t.thread_id !== threadId);
},
);
},
});
}

View File

@@ -0,0 +1,2 @@
export * from "./client";
export * from "./hooks";