Merge branch 'main' of https://github.com/langchain-ai/agent-ui-demo into brace/hookup-accommodations
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { StockbrokerState } from "../types";
|
||||
import { StockbrokerState, StockbrokerUpdate } from "../types";
|
||||
import { ChatOpenAI } from "@langchain/openai";
|
||||
import { typedUi } from "@langchain/langgraph-sdk/react-ui/server";
|
||||
import type ComponentMap from "../../uis/index";
|
||||
@@ -32,7 +32,7 @@ const STOCKBROKER_TOOLS = [
|
||||
export async function callTools(
|
||||
state: StockbrokerState,
|
||||
config: LangGraphRunnableConfig,
|
||||
): Promise<Partial<StockbrokerState>> {
|
||||
): Promise<StockbrokerUpdate> {
|
||||
const ui = typedUi<typeof ComponentMap>(config);
|
||||
|
||||
const message = await llm.bindTools(STOCKBROKER_TOOLS).invoke([
|
||||
@@ -65,8 +65,7 @@ export async function callTools(
|
||||
|
||||
return {
|
||||
messages: [message],
|
||||
// TODO: Fix the ui return type.
|
||||
ui: ui.collect as any[],
|
||||
ui: ui.collect as StockbrokerUpdate["ui"],
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,3 +8,4 @@ export const StockbrokerAnnotation = Annotation.Root({
|
||||
});
|
||||
|
||||
export type StockbrokerState = typeof StockbrokerAnnotation.State;
|
||||
export type StockbrokerUpdate = typeof StockbrokerAnnotation.Update;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { ChatOpenAI } from "@langchain/openai";
|
||||
import { TripPlannerState } from "../types";
|
||||
import { TripPlannerState, TripPlannerUpdate } from "../types";
|
||||
import { z } from "zod";
|
||||
import { formatMessages } from "agent/utils/format-messages";
|
||||
|
||||
export async function classify(
|
||||
state: TripPlannerState,
|
||||
): Promise<Partial<TripPlannerState>> {
|
||||
): Promise<TripPlannerUpdate> {
|
||||
if (!state.tripDetails) {
|
||||
// Can not classify if tripDetails are undefined
|
||||
return {};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ChatOpenAI } from "@langchain/openai";
|
||||
import { TripDetails, TripPlannerState } from "../types";
|
||||
import { TripDetails, TripPlannerState, TripPlannerUpdate } from "../types";
|
||||
import { z } from "zod";
|
||||
import { formatMessages } from "agent/utils/format-messages";
|
||||
|
||||
@@ -43,7 +43,7 @@ function calculateDates(
|
||||
|
||||
export async function extraction(
|
||||
state: TripPlannerState,
|
||||
): Promise<Partial<TripPlannerState>> {
|
||||
): Promise<TripPlannerUpdate> {
|
||||
const schema = z.object({
|
||||
location: z
|
||||
.string()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TripPlannerState } from "../types";
|
||||
import { TripPlannerState, TripPlannerUpdate } from "../types";
|
||||
import { ChatOpenAI } from "@langchain/openai";
|
||||
import { typedUi } from "@langchain/langgraph-sdk/react-ui/server";
|
||||
import type ComponentMap from "../../uis/index";
|
||||
@@ -49,7 +49,7 @@ const schema = z.object({
|
||||
export async function callTools(
|
||||
state: TripPlannerState,
|
||||
config: LangGraphRunnableConfig,
|
||||
): Promise<Partial<TripPlannerState>> {
|
||||
): Promise<TripPlannerUpdate> {
|
||||
if (!state.tripDetails) {
|
||||
throw new Error("No trip details found");
|
||||
}
|
||||
@@ -111,8 +111,7 @@ export async function callTools(
|
||||
|
||||
return {
|
||||
messages: [response],
|
||||
// TODO: Fix the ui return type.
|
||||
ui: ui.collect as any[],
|
||||
ui: ui.collect as TripPlannerUpdate["ui"],
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -16,3 +16,4 @@ export const TripPlannerAnnotation = Annotation.Root({
|
||||
});
|
||||
|
||||
export type TripPlannerState = typeof TripPlannerAnnotation.State;
|
||||
export type TripPlannerUpdate = typeof TripPlannerAnnotation.Update;
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
import { MessagesAnnotation, Annotation } from "@langchain/langgraph";
|
||||
import { uiMessageReducer } from "@langchain/langgraph-sdk/react-ui/types";
|
||||
import {
|
||||
RemoveUIMessage,
|
||||
UIMessage,
|
||||
uiMessageReducer,
|
||||
} from "@langchain/langgraph-sdk/react-ui/server";
|
||||
|
||||
export const GenerativeUIAnnotation = Annotation.Root({
|
||||
messages: MessagesAnnotation.spec["messages"],
|
||||
ui: Annotation({ default: () => [], reducer: uiMessageReducer }),
|
||||
ui: Annotation<
|
||||
UIMessage[],
|
||||
UIMessage | RemoveUIMessage | (UIMessage | RemoveUIMessage)[]
|
||||
>({ default: () => [], reducer: uiMessageReducer }),
|
||||
timestamp: Annotation<number>,
|
||||
next: Annotation<"stockbroker" | "tripPlanner" | "generalInput">(),
|
||||
});
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
import "./index.css";
|
||||
import { useStream } from "@langchain/langgraph-sdk/react";
|
||||
import type { AIMessage, Message } from "@langchain/langgraph-sdk";
|
||||
import {
|
||||
useStreamContext,
|
||||
type UIMessage,
|
||||
} from "@langchain/langgraph-sdk/react-ui";
|
||||
import type { AIMessage, Message, ToolMessage } from "@langchain/langgraph-sdk";
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
|
||||
export default function StockPrice(props: {
|
||||
instruction: string;
|
||||
logo: string;
|
||||
}) {
|
||||
const thread = useStreamContext<
|
||||
{ messages: Message[]; ui: UIMessage[] },
|
||||
{ MetaType: { ui: UIMessage | undefined } }
|
||||
>();
|
||||
|
||||
const [quantity, setQuantity] = useState(1);
|
||||
const [stockData, setStockData] = useState({
|
||||
symbol: "AAPL",
|
||||
@@ -51,23 +59,16 @@ export default function StockPrice(props: {
|
||||
const [limitPrice, setLimitPrice] = useState(stockData.price.toFixed(2));
|
||||
const [showOrderSuccess, setShowOrderSuccess] = useState(false);
|
||||
|
||||
// useStream should be able to be infered from context
|
||||
const thread = useStream<{ messages: Message[] }>({
|
||||
assistantId: "assistant_123",
|
||||
apiUrl: "http://localhost:3123",
|
||||
});
|
||||
|
||||
const messagesCopy = thread.messages;
|
||||
|
||||
const aiTool = messagesCopy
|
||||
.slice()
|
||||
.reverse()
|
||||
.find(
|
||||
(message): message is AIMessage =>
|
||||
message.type === "ai" && !!message.tool_calls?.length,
|
||||
);
|
||||
const aiTool = thread.messages.findLast(
|
||||
(message): message is AIMessage =>
|
||||
message.type === "ai" && !!message.tool_calls?.length,
|
||||
);
|
||||
|
||||
const toolCallId = aiTool?.tool_calls?.[0]?.id;
|
||||
const toolResponse = thread.messages.findLast(
|
||||
(message): message is ToolMessage =>
|
||||
message.type === "tool" && message.tool_call_id === toolCallId,
|
||||
);
|
||||
|
||||
// Simulated price history generation on component mount
|
||||
useEffect(() => {
|
||||
@@ -248,6 +249,7 @@ export default function StockPrice(props: {
|
||||
const range = max - min || 1;
|
||||
const chartPath = generateChartPath();
|
||||
|
||||
if (toolResponse) return <div>Responded</div>;
|
||||
return (
|
||||
<div className="w-full max-w-md bg-white rounded-xl shadow-lg overflow-hidden border border-gray-200">
|
||||
<div
|
||||
|
||||
@@ -58,9 +58,9 @@
|
||||
"zod": "^3.24.2"
|
||||
},
|
||||
"resolutions": {
|
||||
"@langchain/langgraph-api": "next",
|
||||
"@langchain/langgraph-cli": "next",
|
||||
"@langchain/langgraph-sdk": "next"
|
||||
"@langchain/langgraph-api": "0.0.14-experimental.1",
|
||||
"@langchain/langgraph-cli": "0.0.14-experimental.1",
|
||||
"@langchain/langgraph-sdk": "0.0.47-experimental.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.19.0",
|
||||
|
||||
40
pnpm-lock.yaml
generated
40
pnpm-lock.yaml
generated
@@ -5,9 +5,9 @@ settings:
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
overrides:
|
||||
"@langchain/langgraph-api": next
|
||||
"@langchain/langgraph-cli": next
|
||||
"@langchain/langgraph-sdk": next
|
||||
"@langchain/langgraph-api": 0.0.14-experimental.1
|
||||
"@langchain/langgraph-cli": 0.0.14-experimental.1
|
||||
"@langchain/langgraph-sdk": 0.0.47-experimental.0
|
||||
|
||||
importers:
|
||||
.:
|
||||
@@ -34,14 +34,14 @@ importers:
|
||||
specifier: ^0.2.49
|
||||
version: 0.2.49(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0)
|
||||
"@langchain/langgraph-api":
|
||||
specifier: next
|
||||
version: 0.0.14-experimental.0(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(@langchain/langgraph-checkpoint@0.0.15(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2))))(@langchain/langgraph@0.2.49(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0))(openai@4.85.4(zod@3.24.2))(typescript@5.7.3)
|
||||
specifier: 0.0.14-experimental.1
|
||||
version: 0.0.14-experimental.1(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(@langchain/langgraph-checkpoint@0.0.15(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2))))(@langchain/langgraph@0.2.49(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0))(openai@4.85.4(zod@3.24.2))(typescript@5.7.3)
|
||||
"@langchain/langgraph-cli":
|
||||
specifier: next
|
||||
version: 0.0.14-experimental.0(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(@langchain/langgraph-checkpoint@0.0.15(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2))))(@langchain/langgraph@0.2.49(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0))(openai@4.85.4(zod@3.24.2))(typescript@5.7.3)
|
||||
specifier: 0.0.14-experimental.1
|
||||
version: 0.0.14-experimental.1(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(@langchain/langgraph-checkpoint@0.0.15(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2))))(@langchain/langgraph@0.2.49(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0))(openai@4.85.4(zod@3.24.2))(typescript@5.7.3)
|
||||
"@langchain/langgraph-sdk":
|
||||
specifier: next
|
||||
version: 0.0.46-experimental.0(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0)
|
||||
specifier: 0.0.47-experimental.0
|
||||
version: 0.0.47-experimental.0(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0)
|
||||
"@langchain/openai":
|
||||
specifier: ^0.4.4
|
||||
version: 0.4.4(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))
|
||||
@@ -1087,10 +1087,10 @@ packages:
|
||||
peerDependencies:
|
||||
"@langchain/core": ">=0.3.17 <0.4.0"
|
||||
|
||||
"@langchain/langgraph-api@0.0.14-experimental.0":
|
||||
"@langchain/langgraph-api@0.0.14-experimental.1":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-Cc72BHOXS0DhDvlkF3eW6V9CxvMRm0BI2J+ftpZUDG4s3nJjnp4p5F/fXkCnu9hks7w9IUrp4CGXzK4LUEf2iw==,
|
||||
integrity: sha512-gSQzZZk9tIrxXMQjudQbYHXPeK7l3Y/YbzCtnH6hWHvETQOZApUn0G18O5hWT9iYaAzZfSS8ExG7y6YM0MsFTQ==,
|
||||
}
|
||||
engines: { node: ^18.19.0 || >=20.16.0 }
|
||||
peerDependencies:
|
||||
@@ -1108,18 +1108,18 @@ packages:
|
||||
peerDependencies:
|
||||
"@langchain/core": ">=0.2.31 <0.4.0"
|
||||
|
||||
"@langchain/langgraph-cli@0.0.14-experimental.0":
|
||||
"@langchain/langgraph-cli@0.0.14-experimental.1":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-31rdexCp4tR5849Qe3lstVai6VDm5+CFniGSQT08dghlITm4G0g35/jak9dFksavwLJ1NxeMTLuNJUfB5MocyA==,
|
||||
integrity: sha512-S8Y7WrBPsNZR7wUyWj3De0sEdTTf+ipJf1lCrJho+moL9TVXUXUE+oFoMb1G/uHvt8Q/FCSE9BfadEg4JUb5MQ==,
|
||||
}
|
||||
engines: { node: ^18.19.0 || >=20.16.0 }
|
||||
hasBin: true
|
||||
|
||||
"@langchain/langgraph-sdk@0.0.46-experimental.0":
|
||||
"@langchain/langgraph-sdk@0.0.47-experimental.0":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-ADzrxf/Rx8I2fe2lcXgIsB/3sG0uTLsG8S+HIA749yveWo1SQrlcy9+Smkla16y9PWdQpKeztrhNGI5g0BKxDw==,
|
||||
integrity: sha512-di60Pi2knQbe/sjOB3gNbNQNuTIhj0Yjls0SfEYeWDHirSN9heumPB/oxvwaxLBA8JKhuHg2h5lKUxAIT4b+aA==,
|
||||
}
|
||||
peerDependencies:
|
||||
"@langchain/core": ">=0.2.31 <0.4.0"
|
||||
@@ -5996,7 +5996,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- zod
|
||||
|
||||
"@langchain/langgraph-api@0.0.14-experimental.0(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(@langchain/langgraph-checkpoint@0.0.15(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2))))(@langchain/langgraph@0.2.49(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0))(openai@4.85.4(zod@3.24.2))(typescript@5.7.3)":
|
||||
"@langchain/langgraph-api@0.0.14-experimental.1(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(@langchain/langgraph-checkpoint@0.0.15(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2))))(@langchain/langgraph@0.2.49(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0))(openai@4.85.4(zod@3.24.2))(typescript@5.7.3)":
|
||||
dependencies:
|
||||
"@babel/code-frame": 7.26.2
|
||||
"@hono/node-server": 1.13.8(hono@4.7.2)
|
||||
@@ -6032,11 +6032,11 @@ snapshots:
|
||||
"@langchain/core": 0.3.41(openai@4.85.4(zod@3.24.2))
|
||||
uuid: 10.0.0
|
||||
|
||||
"@langchain/langgraph-cli@0.0.14-experimental.0(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(@langchain/langgraph-checkpoint@0.0.15(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2))))(@langchain/langgraph@0.2.49(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0))(openai@4.85.4(zod@3.24.2))(typescript@5.7.3)":
|
||||
"@langchain/langgraph-cli@0.0.14-experimental.1(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(@langchain/langgraph-checkpoint@0.0.15(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2))))(@langchain/langgraph@0.2.49(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0))(openai@4.85.4(zod@3.24.2))(typescript@5.7.3)":
|
||||
dependencies:
|
||||
"@babel/code-frame": 7.26.2
|
||||
"@commander-js/extra-typings": 13.1.0(commander@13.1.0)
|
||||
"@langchain/langgraph-api": 0.0.14-experimental.0(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(@langchain/langgraph-checkpoint@0.0.15(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2))))(@langchain/langgraph@0.2.49(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0))(openai@4.85.4(zod@3.24.2))(typescript@5.7.3)
|
||||
"@langchain/langgraph-api": 0.0.14-experimental.1(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(@langchain/langgraph-checkpoint@0.0.15(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2))))(@langchain/langgraph@0.2.49(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0))(openai@4.85.4(zod@3.24.2))(typescript@5.7.3)
|
||||
chokidar: 4.0.3
|
||||
commander: 13.1.0
|
||||
dedent: 1.5.3
|
||||
@@ -6061,7 +6061,7 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
"@langchain/langgraph-sdk@0.0.46-experimental.0(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0)":
|
||||
"@langchain/langgraph-sdk@0.0.47-experimental.0(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0)":
|
||||
dependencies:
|
||||
"@types/json-schema": 7.0.15
|
||||
p-queue: 6.6.2
|
||||
@@ -6075,7 +6075,7 @@ snapshots:
|
||||
dependencies:
|
||||
"@langchain/core": 0.3.41(openai@4.85.4(zod@3.24.2))
|
||||
"@langchain/langgraph-checkpoint": 0.0.15(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))
|
||||
"@langchain/langgraph-sdk": 0.0.46-experimental.0(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0)
|
||||
"@langchain/langgraph-sdk": 0.0.47-experimental.0(@langchain/core@0.3.41(openai@4.85.4(zod@3.24.2)))(react@19.0.0)
|
||||
uuid: 10.0.0
|
||||
zod: 3.24.2
|
||||
transitivePeerDependencies:
|
||||
|
||||
@@ -4,7 +4,7 @@ import { getContentString } from "../utils";
|
||||
import { BranchSwitcher, CommandBar } from "./shared";
|
||||
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
|
||||
import { MarkdownText } from "../markdown-text";
|
||||
import { LoadExternalComponent } from "@langchain/langgraph-sdk/react-ui/client";
|
||||
import { LoadExternalComponent } from "@langchain/langgraph-sdk/react-ui";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ToolCalls, ToolResult } from "./tool-calls";
|
||||
|
||||
@@ -36,6 +36,7 @@ function CustomComponent({
|
||||
assistantId="agent"
|
||||
stream={thread}
|
||||
message={customComponent}
|
||||
meta={{ ui: customComponent }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { type Message } from "@langchain/langgraph-sdk";
|
||||
import type {
|
||||
UIMessage,
|
||||
RemoveUIMessage,
|
||||
} from "@langchain/langgraph-sdk/react-ui/types";
|
||||
} 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";
|
||||
@@ -110,7 +110,9 @@ export const StreamProvider: React.FC<{ children: ReactNode }> = ({
|
||||
className="flex flex-col gap-6 p-6 bg-muted/50"
|
||||
>
|
||||
<div className="flex flex-col gap-2">
|
||||
<Label htmlFor="apiUrl">Deployment URL</Label>
|
||||
<Label htmlFor="apiUrl">
|
||||
Deployment URL<span className="text-rose-500">*</span>
|
||||
</Label>
|
||||
<p className="text-muted-foreground text-sm">
|
||||
This is the URL of your LangGraph deployment. Can be a local, or
|
||||
production deployment.
|
||||
@@ -120,11 +122,14 @@ export const StreamProvider: React.FC<{ children: ReactNode }> = ({
|
||||
name="apiUrl"
|
||||
className="bg-background"
|
||||
defaultValue={apiUrl ?? "http://localhost:2024"}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2">
|
||||
<Label htmlFor="assistantId">Assistant / Graph ID</Label>
|
||||
<Label htmlFor="assistantId">
|
||||
Assistant / Graph ID<span className="text-rose-500">*</span>
|
||||
</Label>
|
||||
<p className="text-muted-foreground text-sm">
|
||||
This is the ID of the graph (can be the graph name), or
|
||||
assistant to fetch threads from, and invoke when actions are
|
||||
@@ -135,14 +140,17 @@ export const StreamProvider: React.FC<{ children: ReactNode }> = ({
|
||||
name="assistantId"
|
||||
className="bg-background"
|
||||
defaultValue={assistantId ?? "agent"}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2">
|
||||
<Label htmlFor="apiKey">LangSmith API Key</Label>
|
||||
<p className="text-muted-foreground text-sm">
|
||||
This value is stored in your browser's local storage and is only
|
||||
used to authenticate requests sent to your LangGraph server.
|
||||
This is <strong>NOT</strong> 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.
|
||||
</p>
|
||||
<PasswordInput
|
||||
id="apiKey"
|
||||
|
||||
Reference in New Issue
Block a user