2025-02-27 14:08:24 -08:00
|
|
|
import "./index.css";
|
2025-02-18 19:35:46 +01:00
|
|
|
import { useStream } from "@langchain/langgraph-sdk/react";
|
|
|
|
|
import type { AIMessage, Message } from "@langchain/langgraph-sdk";
|
|
|
|
|
import { useState } from "react";
|
|
|
|
|
|
2025-02-27 14:08:24 -08:00
|
|
|
export default function StockPrice(props: {
|
|
|
|
|
instruction: string;
|
|
|
|
|
logo: string;
|
|
|
|
|
}) {
|
2025-02-18 19:35:46 +01:00
|
|
|
const [counter, setCounter] = useState(0);
|
|
|
|
|
|
|
|
|
|
// useStream should be able to be infered from context
|
|
|
|
|
const thread = useStream<{ messages: Message[] }, { messages: Message[] }>({
|
|
|
|
|
assistantId: "assistant_123",
|
|
|
|
|
apiUrl: "http://localhost:3123",
|
|
|
|
|
});
|
|
|
|
|
|
2025-02-28 14:15:37 -08:00
|
|
|
const messagesCopy = thread.messages;
|
|
|
|
|
|
|
|
|
|
const aiTool = messagesCopy
|
2025-02-18 19:35:46 +01:00
|
|
|
.slice()
|
|
|
|
|
.reverse()
|
|
|
|
|
.find(
|
|
|
|
|
(message): message is AIMessage =>
|
2025-02-27 14:08:24 -08:00
|
|
|
message.type === "ai" && !!message.tool_calls?.length,
|
2025-02-18 19:35:46 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const toolCallId = aiTool?.tool_calls?.[0]?.id;
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="flex flex-col gap-2 border border-solid border-slate-500 p-4 rounded-md">
|
|
|
|
|
Request: {props.instruction}
|
|
|
|
|
<button className="text-left" onClick={() => setCounter(counter + 1)}>
|
|
|
|
|
Click me
|
|
|
|
|
</button>
|
|
|
|
|
<p>Counter: {counter}</p>
|
|
|
|
|
{toolCallId && (
|
|
|
|
|
<button
|
|
|
|
|
className="text-left"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
thread.submit({
|
|
|
|
|
messages: [
|
|
|
|
|
{
|
|
|
|
|
type: "tool",
|
|
|
|
|
tool_call_id: toolCallId!,
|
|
|
|
|
name: "stockbroker",
|
|
|
|
|
content: "hey",
|
|
|
|
|
},
|
|
|
|
|
{ type: "human", content: `Buy ${counter}` },
|
|
|
|
|
],
|
|
|
|
|
});
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Buy
|
|
|
|
|
</button>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|