Merge pull request #39 from langchain-ai/dqbd/sdk-js-0.0.52
feat: upgrade to 0.0.52
This commit is contained in:
@@ -106,17 +106,22 @@ export async function executor(
|
||||
|
||||
const fullWriteAccess = !!config.configurable?.permissions?.full_write_access;
|
||||
|
||||
const msg = ui.create("proposed-change", {
|
||||
ui.push(
|
||||
{
|
||||
name: "proposed-change",
|
||||
content: {
|
||||
toolCallId,
|
||||
change: updateFileContents,
|
||||
planItem: nextPlanItem,
|
||||
fullWriteAccess,
|
||||
});
|
||||
msg.additional_kwargs["message_id"] = aiMessage.id;
|
||||
},
|
||||
},
|
||||
{ message: aiMessage },
|
||||
);
|
||||
|
||||
return {
|
||||
messages: [aiMessage],
|
||||
ui: [msg],
|
||||
ui: ui.items,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -86,13 +86,18 @@ export async function planner(
|
||||
],
|
||||
};
|
||||
|
||||
const msg = ui.create("code-plan", {
|
||||
ui.push(
|
||||
{
|
||||
name: "code-plan",
|
||||
content: {
|
||||
toolCallId,
|
||||
executedPlans,
|
||||
rejectedPlans,
|
||||
remainingPlans,
|
||||
});
|
||||
msg.additional_kwargs["message_id"] = aiMessage.id;
|
||||
},
|
||||
},
|
||||
{ message: aiMessage },
|
||||
);
|
||||
|
||||
const toolMessage: ToolMessage = {
|
||||
type: "tool",
|
||||
@@ -103,7 +108,7 @@ export async function planner(
|
||||
|
||||
return {
|
||||
messages: [aiMessage, toolMessage],
|
||||
ui: [msg],
|
||||
ui: ui.items,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -176,29 +176,38 @@ export async function callTools(
|
||||
|
||||
if (stockbrokerToolCall) {
|
||||
const prices = await getPricesForTicker(stockbrokerToolCall.args.ticker);
|
||||
ui.write("stock-price", {
|
||||
ticker: stockbrokerToolCall.args.ticker,
|
||||
...prices,
|
||||
});
|
||||
ui.push(
|
||||
{
|
||||
name: "stock-price",
|
||||
content: { ticker: stockbrokerToolCall.args.ticker, ...prices },
|
||||
},
|
||||
{ message },
|
||||
);
|
||||
}
|
||||
if (portfolioToolCall) {
|
||||
ui.write("portfolio", {});
|
||||
ui.push({ name: "portfolio", content: {} }, { message });
|
||||
}
|
||||
if (buyStockToolCall) {
|
||||
const snapshot = await getPriceSnapshotForTicker(
|
||||
buyStockToolCall.args.ticker,
|
||||
);
|
||||
ui.write("buy-stock", {
|
||||
ui.push(
|
||||
{
|
||||
name: "buy-stock",
|
||||
content: {
|
||||
toolCallId:
|
||||
message.tool_calls?.find((tc) => tc.name === "buy-stock")?.id ?? "",
|
||||
snapshot,
|
||||
quantity: buyStockToolCall.args.quantity,
|
||||
});
|
||||
},
|
||||
},
|
||||
{ message },
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
messages: [message],
|
||||
ui: ui.collect as StockbrokerUpdate["ui"],
|
||||
ui: ui.items,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -87,32 +87,56 @@ export async function callTools(
|
||||
}
|
||||
|
||||
if (tripPlan.listAccommodations) {
|
||||
ui.write("accommodations-list", {
|
||||
ui.push(
|
||||
{
|
||||
name: "accommodations-list",
|
||||
content: {
|
||||
toolCallId,
|
||||
...getAccommodationsListProps(state.tripDetails),
|
||||
});
|
||||
},
|
||||
},
|
||||
{ message: response },
|
||||
);
|
||||
}
|
||||
if (tripPlan.bookAccommodation && tripPlan.accommodationName) {
|
||||
ui.write("book-accommodation", {
|
||||
ui.push(
|
||||
{
|
||||
name: "book-accommodation",
|
||||
content: {
|
||||
tripDetails: state.tripDetails,
|
||||
accommodationName: tripPlan.accommodationName,
|
||||
});
|
||||
},
|
||||
},
|
||||
{ message: response },
|
||||
);
|
||||
}
|
||||
|
||||
if (tripPlan.listRestaurants) {
|
||||
ui.write("restaurants-list", { tripDetails: state.tripDetails });
|
||||
ui.push(
|
||||
{
|
||||
name: "restaurants-list",
|
||||
content: { tripDetails: state.tripDetails },
|
||||
},
|
||||
{ message: response },
|
||||
);
|
||||
}
|
||||
|
||||
if (tripPlan.bookRestaurant && tripPlan.restaurantName) {
|
||||
ui.write("book-restaurant", {
|
||||
ui.push(
|
||||
{
|
||||
name: "book-restaurant",
|
||||
content: {
|
||||
tripDetails: state.tripDetails,
|
||||
restaurantName: tripPlan.restaurantName,
|
||||
});
|
||||
},
|
||||
},
|
||||
{ message: response },
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
messages: [response],
|
||||
ui: ui.collect as TripPlannerUpdate["ui"],
|
||||
ui: ui.items,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"@langchain/langgraph": "^0.2.49",
|
||||
"@langchain/langgraph-api": "^0.0.14",
|
||||
"@langchain/langgraph-cli": "^0.0.14",
|
||||
"@langchain/langgraph-sdk": "^0.0.50",
|
||||
"@langchain/langgraph-sdk": "^0.0.52",
|
||||
"@langchain/openai": "^0.4.4",
|
||||
"@radix-ui/react-avatar": "^1.1.3",
|
||||
"@radix-ui/react-dialog": "^1.1.6",
|
||||
|
||||
6337
pnpm-lock.yaml
generated
6337
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -7,8 +7,8 @@ import { MarkdownText } from "../markdown-text";
|
||||
import { LoadExternalComponent } from "@langchain/langgraph-sdk/react-ui";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ToolCalls, ToolResult } from "./tool-calls";
|
||||
import { StringParam, useQueryParam } from "use-query-params";
|
||||
import { MessageContentComplex } from "@langchain/core/messages";
|
||||
import { Fragment } from "react/jsx-runtime";
|
||||
|
||||
function CustomComponent({
|
||||
message,
|
||||
@@ -17,32 +17,28 @@ function CustomComponent({
|
||||
message: Message;
|
||||
thread: ReturnType<typeof useStreamContext>;
|
||||
}) {
|
||||
const [apiUrl] = useQueryParam("apiUrl", StringParam);
|
||||
const meta = thread.getMessagesMetadata(message);
|
||||
const seenState = meta?.firstSeenState;
|
||||
const customComponents = seenState?.values.ui
|
||||
?.slice()
|
||||
.filter(
|
||||
({ additional_kwargs }) =>
|
||||
additional_kwargs.run_id === seenState.metadata?.run_id &&
|
||||
(!additional_kwargs.message_id ||
|
||||
additional_kwargs.message_id === message.id),
|
||||
.filter(({ additional_kwargs }) =>
|
||||
!additional_kwargs.message_id
|
||||
? additional_kwargs.run_id === seenState.metadata?.run_id
|
||||
: additional_kwargs.message_id === message.id,
|
||||
);
|
||||
|
||||
if (!customComponents?.length) return null;
|
||||
return (
|
||||
<div key={message.id}>
|
||||
<Fragment key={message.id}>
|
||||
{customComponents.map((customComponent) => (
|
||||
<LoadExternalComponent
|
||||
key={customComponent.id}
|
||||
apiUrl={apiUrl ?? undefined}
|
||||
assistantId="agent"
|
||||
stream={thread}
|
||||
message={customComponent}
|
||||
meta={{ ui: customComponent }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
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,
|
||||
import {
|
||||
uiMessageReducer,
|
||||
type UIMessage,
|
||||
type RemoveUIMessage,
|
||||
} from "@langchain/langgraph-sdk/react-ui";
|
||||
import { useQueryParam, StringParam } from "use-query-params";
|
||||
import { Input } from "@/components/ui/input";
|
||||
@@ -24,7 +25,7 @@ const useTypedStream = useStream<
|
||||
messages?: Message[] | Message | string;
|
||||
ui?: (UIMessage | RemoveUIMessage)[] | UIMessage | RemoveUIMessage;
|
||||
};
|
||||
CustomUpdateType: UIMessage | RemoveUIMessage;
|
||||
CustomEventType: UIMessage | RemoveUIMessage;
|
||||
}
|
||||
>;
|
||||
|
||||
@@ -53,6 +54,12 @@ const StreamSession = ({
|
||||
apiKey: apiKey ?? undefined,
|
||||
assistantId,
|
||||
threadId: threadId ?? null,
|
||||
onCustomEvent: (event, options) => {
|
||||
options.mutate((prev) => {
|
||||
const ui = uiMessageReducer(prev.ui ?? [], event);
|
||||
return { ...prev, ui };
|
||||
});
|
||||
},
|
||||
onThreadId: (id) => {
|
||||
setThreadId(id);
|
||||
// Refetch threads list when thread ID changes.
|
||||
|
||||
Reference in New Issue
Block a user