mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-09-30 08:03:15 +00:00
Staging june24 (#319)
* empty state programmer planner tabs * add scroll: on pageload, buttonclick, tabswitch * format * init step dark mode style * format * submit button styling * improve to use brand variant * increase to 8x8px and change padding to adjust btn pos * minor format * fix light theme repo hover styling * bump deps * fix input button styling * fix styling for scroll to bottom --------- Co-authored-by: starmorph <dylan@starmorph.com> Co-authored-by: Dylan Boudro <121908331+starmorph@users.noreply.github.com>
This commit is contained in:
parent
64d34aa7bb
commit
9d7a74a976
10 changed files with 243 additions and 118 deletions
|
|
@ -27,7 +27,7 @@
|
|||
"@langchain/core": "^0.3.56",
|
||||
"@langchain/google-genai": "^0.2.9",
|
||||
"@langchain/langgraph": "^0.3.3",
|
||||
"@langchain/langgraph-sdk": "^0.0.84",
|
||||
"@langchain/langgraph-sdk": "^0.0.85",
|
||||
"@langchain/openai": "^0.5.10",
|
||||
"@octokit/rest": "^22.0.0",
|
||||
"@open-swe/shared": "*",
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
"dependencies": {
|
||||
"@langchain/core": "^0.3.57",
|
||||
"@langchain/langgraph": "^0.3.3",
|
||||
"@langchain/langgraph-sdk": "^0.0.83",
|
||||
"@langchain/langgraph-sdk": "^0.0.85",
|
||||
"@open-swe/shared": "*",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.14",
|
||||
"@radix-ui/react-avatar": "^1.1.3",
|
||||
|
|
|
|||
|
|
@ -41,9 +41,15 @@ export function InitializeStep({
|
|||
|
||||
const stepStatusIcon = {
|
||||
waiting: (
|
||||
<div className={cn("h-3.5 w-3.5 rounded-full border border-gray-300")} />
|
||||
<div
|
||||
className={cn(
|
||||
"h-3.5 w-3.5 rounded-full border border-gray-300 dark:border-gray-600",
|
||||
)}
|
||||
/>
|
||||
),
|
||||
generating: (
|
||||
<Loader2 className="h-3.5 w-3.5 animate-spin text-gray-500 dark:text-gray-400" />
|
||||
),
|
||||
generating: <Loader2 className="h-3.5 w-3.5 animate-spin text-gray-500" />,
|
||||
success: <CheckCircle className="h-3.5 w-3.5 text-green-500" />,
|
||||
error: <XCircle className="h-3.5 w-3.5 text-red-500" />,
|
||||
};
|
||||
|
|
@ -53,11 +59,15 @@ export function InitializeStep({
|
|||
case "loading":
|
||||
return (
|
||||
<div
|
||||
className={cn("h-3.5 w-3.5 rounded-full border border-gray-300")}
|
||||
className={cn(
|
||||
"h-3.5 w-3.5 rounded-full border border-gray-300 dark:border-gray-600",
|
||||
)}
|
||||
/>
|
||||
);
|
||||
case "generating":
|
||||
return <Loader2 className="h-3.5 w-3.5 animate-spin text-gray-500" />;
|
||||
return (
|
||||
<Loader2 className="h-3.5 w-3.5 animate-spin text-gray-500 dark:text-gray-400" />
|
||||
);
|
||||
case "done":
|
||||
return success ? (
|
||||
<CheckCircle className="h-3.5 w-3.5 text-green-500" />
|
||||
|
|
@ -79,11 +89,11 @@ export function InitializeStep({
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="overflow-hidden rounded-md border border-gray-200">
|
||||
<div className="overflow-hidden rounded-md border border-gray-200 dark:border-gray-700">
|
||||
{/* Collapse/Expand Icon */}
|
||||
<div className="relative flex items-center border-b border-gray-200 bg-gray-50 p-2">
|
||||
<GitBranch className="mr-2 h-3.5 w-3.5 text-gray-500" />
|
||||
<span className="flex-1 text-xs font-normal text-gray-800">
|
||||
<div className="relative flex items-center border-b border-gray-200 bg-gray-50 p-2 dark:border-gray-700 dark:bg-gray-800">
|
||||
<GitBranch className="mr-2 h-3.5 w-3.5 text-gray-500 dark:text-gray-400" />
|
||||
<span className="flex-1 text-xs font-normal text-gray-800 dark:text-gray-200">
|
||||
{getStatusText()}
|
||||
</span>
|
||||
{getStatusIcon()}
|
||||
|
|
@ -118,7 +128,7 @@ export function InitializeStep({
|
|||
] ?? (
|
||||
<div
|
||||
className={cn(
|
||||
"h-3.5 w-3.5 rounded-full border border-gray-300",
|
||||
"h-3.5 w-3.5 rounded-full border border-gray-300 dark:border-gray-600",
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
|
|
@ -128,7 +138,7 @@ export function InitializeStep({
|
|||
"font-normal",
|
||||
step.status === "error"
|
||||
? "text-red-500"
|
||||
: "text-gray-800",
|
||||
: "text-gray-800 dark:text-gray-200",
|
||||
)}
|
||||
>
|
||||
{step.name}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ export function RepositoryBranchSelectors() {
|
|||
const [threadId] = useQueryState("threadId");
|
||||
const chatStarted = !!threadId;
|
||||
const defaultButtonStyles =
|
||||
"bg-inherit border-none text-gray-500 hover:text-gray-300 text-xs p-0 h-fit hover:bg-inherit";
|
||||
"bg-inherit border-none text-gray-500 hover:text-black dark:hover:text-gray-300 text-xs p-0 h-fit hover:bg-inherit";
|
||||
const defaultStylesChatStarted =
|
||||
"hover:bg-inherit cursor-default hover:cursor-default hover:text-gray-300 hover:border-gray-300 hover:ring-inherit";
|
||||
"hover:bg-inherit cursor-default hover:cursor-default hover:text-black dark:hover:text-gray-300 hover:border-gray-300 hover:ring-inherit";
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
|
|
|
|||
|
|
@ -155,13 +155,13 @@ export function TerminalInput({
|
|||
<Button
|
||||
onClick={handleSend}
|
||||
disabled={disabled || !message.trim() || !selectedRepository}
|
||||
size="sm"
|
||||
className="bg-muted-foreground/20 hover:bg-muted-foreground/30 h-7 w-7 self-end p-0 dark:bg-gray-700 hover:dark:bg-gray-600"
|
||||
size="icon"
|
||||
variant="brand"
|
||||
>
|
||||
{loading ? (
|
||||
<Loader2 className="size-3 animate-spin" />
|
||||
<Loader2 className="size-4 animate-spin" />
|
||||
) : (
|
||||
<Send className="size-3" />
|
||||
<Send className="size-4" />
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
"use client";
|
||||
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { useState } from "react";
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import {
|
||||
ArrowLeft,
|
||||
GitBranch,
|
||||
Send,
|
||||
Terminal,
|
||||
Clock,
|
||||
User,
|
||||
Bot,
|
||||
Copy,
|
||||
|
|
@ -23,10 +24,16 @@ import { ThreadDisplayInfo } from "./types";
|
|||
import { useStream } from "@langchain/langgraph-sdk/react";
|
||||
import { ManagerGraphState } from "@open-swe/shared/open-swe/manager/types";
|
||||
import { PlannerGraphState } from "@open-swe/shared/open-swe/planner/types";
|
||||
import { GraphState } from "@open-swe/shared/open-swe/types";
|
||||
import { ActionsRenderer } from "./actions-renderer";
|
||||
import { ThemeToggle } from "../theme-toggle";
|
||||
import { HumanMessage } from "@langchain/core/messages";
|
||||
import { DO_NOT_RENDER_ID_PREFIX } from "@open-swe/shared/constants";
|
||||
import { StickToBottom } from "use-stick-to-bottom";
|
||||
import {
|
||||
StickyToBottomContent,
|
||||
ScrollToBottom,
|
||||
} from "../../utils/scroll-utils";
|
||||
|
||||
const PROGRAMMER_ASSISTANT_ID = process.env.NEXT_PUBLIC_PROGRAMMER_ASSISTANT_ID;
|
||||
const PLANNER_ASSISTANT_ID = process.env.NEXT_PUBLIC_PLANNER_ASSISTANT_ID;
|
||||
|
|
@ -100,9 +107,23 @@ export function ThreadView({
|
|||
const [programmerSession, setProgrammerSession] =
|
||||
useState<ManagerGraphState["programmerSession"]>();
|
||||
|
||||
if (!stream.messages?.length) {
|
||||
return null;
|
||||
}
|
||||
const prevMessageLength = useRef(0);
|
||||
useEffect(() => {
|
||||
if (
|
||||
stream.messages &&
|
||||
stream.messages.length !== prevMessageLength.current
|
||||
) {
|
||||
prevMessageLength.current = stream.messages.length;
|
||||
}
|
||||
}, [stream.messages]);
|
||||
|
||||
useEffect(() => {
|
||||
// Auto-scroll to bottom when tab switches (requirement fulfilled)
|
||||
// StickToBottom handles the actual scrolling via scrollToBottom()
|
||||
}, [selectedTab]);
|
||||
|
||||
// Don't early return for empty messages - show loading/empty state instead
|
||||
// This prevents blank pages when navigating to existing threads
|
||||
|
||||
const handleSendMessage = () => {
|
||||
if (chatInput.trim()) {
|
||||
|
|
@ -179,40 +200,58 @@ export function ThreadView({
|
|||
{/* Left Side - Chat Interface */}
|
||||
<div className="border-border bg-muted/30 flex h-full w-1/3 flex-col border-r dark:bg-gray-950">
|
||||
{/* Chat Messages */}
|
||||
<div className="flex-1 space-y-4 overflow-y-auto p-4">
|
||||
{filteredMessages.map((message) => (
|
||||
<div
|
||||
key={message.id}
|
||||
className="group flex gap-3"
|
||||
>
|
||||
<div className="flex-shrink-0">
|
||||
{message.type === "human" ? (
|
||||
<div className="bg-muted flex h-6 w-6 items-center justify-center rounded-full dark:bg-gray-700">
|
||||
<User className="text-muted-foreground h-3 w-3" />
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-blue-100 dark:bg-blue-900">
|
||||
<Bot className="h-3 w-3 text-blue-700 dark:text-blue-400" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="relative flex-1 space-y-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-muted-foreground text-xs font-medium">
|
||||
{message.type === "human" ? "You" : "Agent"}
|
||||
</span>
|
||||
<div className="relative flex-1">
|
||||
<StickToBottom
|
||||
className="absolute inset-0"
|
||||
initial={false}
|
||||
>
|
||||
<StickyToBottomContent
|
||||
className="h-full overflow-y-auto"
|
||||
contentClassName="space-y-4 p-4"
|
||||
content={
|
||||
<>
|
||||
{filteredMessages.map((message) => (
|
||||
<div
|
||||
key={message.id}
|
||||
className="group flex gap-3"
|
||||
>
|
||||
<div className="flex-shrink-0">
|
||||
{message.type === "human" ? (
|
||||
<div className="bg-muted flex h-6 w-6 items-center justify-center rounded-full dark:bg-gray-700">
|
||||
<User className="text-muted-foreground h-3 w-3" />
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-blue-100 dark:bg-blue-900">
|
||||
<Bot className="h-3 w-3 text-blue-700 dark:text-blue-400" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="relative flex-1 space-y-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-muted-foreground text-xs font-medium">
|
||||
{message.type === "human" ? "You" : "Agent"}
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-foreground text-sm leading-relaxed">
|
||||
{getMessageContentString(message.content)}
|
||||
</div>
|
||||
<div className="absolute right-0 -bottom-5 opacity-0 transition-opacity group-hover:opacity-100">
|
||||
<MessageCopyButton
|
||||
content={getMessageContentString(message.content)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
}
|
||||
footer={
|
||||
<div className="absolute right-0 left-0 bottom-4 flex justify-center w-full">
|
||||
<ScrollToBottom className="animate-in fade-in-0 zoom-in-95" />
|
||||
</div>
|
||||
<div className="text-foreground text-sm leading-relaxed">
|
||||
{getMessageContentString(message.content)}
|
||||
</div>
|
||||
<div className="absolute right-0 -bottom-5 opacity-0 transition-opacity group-hover:opacity-100">
|
||||
<MessageCopyButton
|
||||
content={getMessageContentString(message.content)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
}
|
||||
/>
|
||||
</StickToBottom>
|
||||
</div>
|
||||
|
||||
{/* Chat Input - Fixed at bottom */}
|
||||
|
|
@ -233,10 +272,10 @@ export function ThreadView({
|
|||
<Button
|
||||
onClick={handleSendMessage}
|
||||
disabled={!chatInput.trim()}
|
||||
size="sm"
|
||||
className="bg-muted hover:bg-muted/80 h-10 w-10 self-end p-0 dark:bg-gray-700 hover:dark:bg-gray-600"
|
||||
size="icon"
|
||||
variant="brand"
|
||||
>
|
||||
<Send className="h-4 w-4" />
|
||||
<Send className="size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<div className="text-muted-foreground mt-2 text-xs">
|
||||
|
|
@ -247,56 +286,87 @@ export function ThreadView({
|
|||
|
||||
{/* Right Side - Actions & Plan */}
|
||||
<div className="flex h-full flex-1 flex-col">
|
||||
<div className="flex-1 space-y-4 overflow-y-auto p-4">
|
||||
<Tabs
|
||||
defaultValue="planner"
|
||||
className="w-full"
|
||||
value={selectedTab}
|
||||
onValueChange={(value) =>
|
||||
setSelectedTab(value as "planner" | "programmer")
|
||||
}
|
||||
<div className="relative flex-1">
|
||||
<StickToBottom
|
||||
className="absolute inset-0"
|
||||
initial={true}
|
||||
>
|
||||
<TabsList className="bg-muted/70 dark:bg-gray-800">
|
||||
<TabsTrigger value="planner">Planner</TabsTrigger>
|
||||
<TabsTrigger value="programmer">Programmer</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="planner">
|
||||
<Card className="border-border bg-card px-0 py-4 dark:bg-gray-950">
|
||||
<CardContent className="space-y-2 p-3 pt-0">
|
||||
{plannerThreadId &&
|
||||
plannerRunId &&
|
||||
PLANNER_ASSISTANT_ID && (
|
||||
<ActionsRenderer<PlannerGraphState>
|
||||
graphId={PLANNER_ASSISTANT_ID}
|
||||
threadId={plannerThreadId}
|
||||
runId={plannerRunId}
|
||||
setProgrammerSession={setProgrammerSession}
|
||||
programmerSession={programmerSession}
|
||||
setSelectedTab={setSelectedTab}
|
||||
/>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
<TabsContent value="programmer">
|
||||
<Card className="border-border bg-card px-0 py-4 dark:bg-gray-950">
|
||||
<CardContent className="space-y-2 p-3 pt-0">
|
||||
{programmerSession && PROGRAMMER_ASSISTANT_ID && (
|
||||
<ActionsRenderer<PlannerGraphState>
|
||||
graphId={PROGRAMMER_ASSISTANT_ID}
|
||||
threadId={programmerSession.threadId}
|
||||
runId={programmerSession.runId}
|
||||
/>
|
||||
)}
|
||||
{!programmerSession && (
|
||||
<div className="text-muted-foreground text-xs">
|
||||
No programmer session
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
<StickyToBottomContent
|
||||
className="h-full overflow-y-auto"
|
||||
contentClassName="space-y-4 p-4"
|
||||
content={
|
||||
<Tabs
|
||||
defaultValue="planner"
|
||||
className="w-full"
|
||||
value={selectedTab}
|
||||
onValueChange={(value) =>
|
||||
setSelectedTab(value as "planner" | "programmer")
|
||||
}
|
||||
>
|
||||
<TabsList className="bg-muted/70 dark:bg-gray-800">
|
||||
<TabsTrigger value="planner">Planner</TabsTrigger>
|
||||
<TabsTrigger value="programmer">Programmer</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="planner">
|
||||
<Card className="border-border bg-card px-0 py-4 dark:bg-gray-950">
|
||||
<CardContent className="space-y-2 p-3 pt-0">
|
||||
{plannerThreadId &&
|
||||
plannerRunId &&
|
||||
PLANNER_ASSISTANT_ID && (
|
||||
<ActionsRenderer<PlannerGraphState>
|
||||
graphId={PLANNER_ASSISTANT_ID}
|
||||
threadId={plannerThreadId}
|
||||
runId={plannerRunId}
|
||||
setProgrammerSession={setProgrammerSession}
|
||||
programmerSession={programmerSession}
|
||||
setSelectedTab={setSelectedTab}
|
||||
/>
|
||||
)}
|
||||
{!(
|
||||
plannerThreadId &&
|
||||
plannerRunId &&
|
||||
PLANNER_ASSISTANT_ID
|
||||
) && (
|
||||
<div className="flex items-center justify-center gap-2 py-8">
|
||||
<Clock className="text-muted-foreground size-4" />
|
||||
<span className="text-muted-foreground text-sm">
|
||||
No planner session
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
<TabsContent value="programmer">
|
||||
<Card className="border-border bg-card px-0 py-4 dark:bg-gray-950">
|
||||
<CardContent className="space-y-2 p-3 pt-0">
|
||||
{programmerSession && PROGRAMMER_ASSISTANT_ID && (
|
||||
<ActionsRenderer<GraphState>
|
||||
graphId={PROGRAMMER_ASSISTANT_ID}
|
||||
threadId={programmerSession.threadId}
|
||||
runId={programmerSession.runId}
|
||||
/>
|
||||
)}
|
||||
{!programmerSession && (
|
||||
<div className="flex items-center justify-center gap-2 py-8">
|
||||
<Terminal className="text-muted-foreground size-4" />
|
||||
<span className="text-muted-foreground text-sm">
|
||||
No programmer session
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
}
|
||||
footer={
|
||||
<div className="absolute right-0 left-0 bottom-4 flex justify-center w-full">
|
||||
<ScrollToBottom className="animate-in fade-in-0 zoom-in-95" />
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</StickToBottom>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
45
apps/web/src/utils/scroll-utils.tsx
Normal file
45
apps/web/src/utils/scroll-utils.tsx
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { ReactNode } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ArrowDown } from "lucide-react";
|
||||
import { useStickToBottomContext } from "use-stick-to-bottom";
|
||||
|
||||
export function StickyToBottomContent(props: {
|
||||
content: ReactNode;
|
||||
footer?: ReactNode;
|
||||
className?: string;
|
||||
contentClassName?: string;
|
||||
}) {
|
||||
const context = useStickToBottomContext();
|
||||
return (
|
||||
<div
|
||||
ref={context.scrollRef}
|
||||
style={{ width: "100%", height: "100%" }}
|
||||
className={props.className}
|
||||
>
|
||||
<div
|
||||
ref={context.contentRef}
|
||||
className={props.contentClassName}
|
||||
>
|
||||
{props.content}
|
||||
</div>
|
||||
{props.footer}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function ScrollToBottom(props: { className?: string }) {
|
||||
const { isAtBottom, scrollToBottom } = useStickToBottomContext();
|
||||
|
||||
if (isAtBottom) return null;
|
||||
return (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className={props.className}
|
||||
onClick={() => scrollToBottom()}
|
||||
>
|
||||
<ArrowDown className="h-4 w-4" />
|
||||
<span>Scroll to bottom</span>
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
"typescript": "^5"
|
||||
},
|
||||
"resolutions": {
|
||||
"@langchain/langgraph-sdk": "^0.0.83",
|
||||
"@langchain/langgraph-sdk": "^0.0.85",
|
||||
"@langchain/core": "^0.3.58"
|
||||
},
|
||||
"packageManager": "yarn@3.5.1"
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
"dependencies": {
|
||||
"@langchain/core": "^0.3.56",
|
||||
"@langchain/langgraph": "^0.3.3",
|
||||
"@langchain/langgraph-sdk": "^0.0.83",
|
||||
"@langchain/langgraph-sdk": "^0.0.85",
|
||||
"@octokit/rest": "^22.0.0",
|
||||
"zod": "^3.25.32"
|
||||
},
|
||||
|
|
|
|||
14
yarn.lock
14
yarn.lock
|
|
@ -1803,9 +1803,9 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@langchain/langgraph-sdk@npm:^0.0.83":
|
||||
version: 0.0.83
|
||||
resolution: "@langchain/langgraph-sdk@npm:0.0.83"
|
||||
"@langchain/langgraph-sdk@npm:^0.0.85":
|
||||
version: 0.0.85
|
||||
resolution: "@langchain/langgraph-sdk@npm:0.0.85"
|
||||
dependencies:
|
||||
"@types/json-schema": ^7.0.15
|
||||
p-queue: ^6.6.2
|
||||
|
|
@ -1819,7 +1819,7 @@ __metadata:
|
|||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
checksum: c6d037b8b9486456a8180d892e8b05ad3c2332456d7d237597720ebe42dd6b126f1aed963a0d2a681405724b7b8e0eac0607994b8e527d2f0e756e4c9e30c19e
|
||||
checksum: f6d206c718cf4cb5d69dd677f2afa38325fdd69b485310a6beb61f06f24b2b4a8c0446eacbe7911c02cedc8bd4b719e22894c6f9b93572e6665c6a609cc9f511
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
@ -2264,7 +2264,7 @@ __metadata:
|
|||
"@langchain/google-genai": ^0.2.9
|
||||
"@langchain/langgraph": ^0.3.3
|
||||
"@langchain/langgraph-cli": latest
|
||||
"@langchain/langgraph-sdk": ^0.0.84
|
||||
"@langchain/langgraph-sdk": ^0.0.85
|
||||
"@langchain/openai": ^0.5.10
|
||||
"@octokit/rest": ^22.0.0
|
||||
"@open-swe/shared": "*"
|
||||
|
|
@ -2299,7 +2299,7 @@ __metadata:
|
|||
"@eslint/js": ^9.19.0
|
||||
"@langchain/core": ^0.3.56
|
||||
"@langchain/langgraph": ^0.3.3
|
||||
"@langchain/langgraph-sdk": ^0.0.83
|
||||
"@langchain/langgraph-sdk": ^0.0.85
|
||||
"@octokit/rest": ^22.0.0
|
||||
"@octokit/types": ^12.0.0
|
||||
"@tsconfig/recommended": ^1.0.8
|
||||
|
|
@ -2324,7 +2324,7 @@ __metadata:
|
|||
"@eslint/js": ^9.19.0
|
||||
"@langchain/core": ^0.3.57
|
||||
"@langchain/langgraph": ^0.3.3
|
||||
"@langchain/langgraph-sdk": ^0.0.83
|
||||
"@langchain/langgraph-sdk": ^0.0.85
|
||||
"@open-swe/shared": "*"
|
||||
"@radix-ui/react-alert-dialog": ^1.1.14
|
||||
"@radix-ui/react-avatar": ^1.1.3
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue