2025-05-28 12:26:47 -07:00
|
|
|
import { useStreamContext } from "@/providers/Stream";
|
|
|
|
|
import { Message } from "@langchain/langgraph-sdk";
|
|
|
|
|
import { useState } from "react";
|
|
|
|
|
import { getContentString } from "../utils";
|
|
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
|
import { Textarea } from "@/components/ui/textarea";
|
|
|
|
|
import { BranchSwitcher, CommandBar } from "./shared";
|
|
|
|
|
import { MultimodalPreview } from "@/components/thread/MultimodalPreview";
|
|
|
|
|
import { isBase64ContentBlock } from "@/lib/multimodal-utils";
|
feat: Update chat UI to be Open SWE specific (#76) (#91)
* init repo-selector
* add branch selector UI, extend GH hook w branch info
* add reconnectOnMount: true resumeStream, remove repo description from selector, fix styling
* styling repo + branch
* udpate getBranch calls to include targetRepo arg
* format
* add search to repo + branch selectors
* add settings icon link to /github for dev convenience
* add default branch selection
* format
* minor cleanup
* init task list UI demo
* individual task component
* tasks real data
* task visual improvement
* persisting tasks, navigate to thread onClick
* task UI
* TaskSidebar, Navigate to tasks
* org tasks by thread
* group by thread
* improve sidebar, task-list, rm github modal on refresh
* collapse sidebar works when viewing a thread
* remove micro-tasks expansion from threads component, change taskId to taskIndex for persistence + simplicity
* init config sidebar ui
* open and close config sidebar
* add ref for getAllTasks + add graph_id metadata
* format
* create threadItem component
* format
* add threadUtils
* centralize + refactor types
* format
* improve thread status, realtime updates
* fix scroll issue
* remove temperature from config-sidebar
* Change model via sidebar
* fix flashing on updates
* init plan UI
* centralize types
* self CR: refactoring, cleanup, remove comments, add todos
* CR: clean comments + logs, fix repo selector bug
* fix: Update example env file in web (#77)
* disable auto scroll on pageload
* reposelector: use default branch not main master
* remove archived tab temp, default branch listed first in branchSelector dropdown
* auto select first repo
* improve status indicator
* refactor status indicator
* simplify status implementation to use Langgraph
* util moved from provider to thread-utils
* linting, improve task completion logic
* feat: Support followup requests (#60)
* feat: Support followup requests
* cr
* cr
* fix
* account for pr already exists
* remove task provider
* fix: Better prompting and context provided for codebase structure awareness (#85)
* fix: Better prompting and context provided for codebase structure awareness
* cr
* linting + skeleton loader
* fix: branch selector, add github api pagination
* small branch update
* update task completion status realtime
* threadItem stream remove flashing/polling
* feat: Create a shared package (#89)
* feat: Create a shared package
* formatting
* fix: drop passing target repo to getBranchName
* drop docs
* use shared package for config fields in config sidebar
* fix: styling and structure for repo/branch selectors
* fix: use shared types/objects for config fields
* default key for configs
* fix: improved styling for threads
* fix renering num tasks
* disable repo branch selector when chat started
* cr
* cr
* bump deps
* fix: rendering plan in interrupt
* cr
* cr
---------
Co-authored-by: Dylan Boudro <121908331+starmorph@users.noreply.github.com>
2025-06-08 17:29:40 -07:00
|
|
|
import { BaseMessage } from "@langchain/core/messages";
|
2025-05-28 12:26:47 -07:00
|
|
|
|
|
|
|
|
function EditableContent({
|
|
|
|
|
value,
|
|
|
|
|
setValue,
|
|
|
|
|
onSubmit,
|
|
|
|
|
}: {
|
|
|
|
|
value: string;
|
|
|
|
|
setValue: React.Dispatch<React.SetStateAction<string>>;
|
|
|
|
|
onSubmit: () => void;
|
|
|
|
|
}) {
|
|
|
|
|
const handleKeyDown = (e: React.KeyboardEvent) => {
|
|
|
|
|
if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
onSubmit();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Textarea
|
|
|
|
|
value={value}
|
|
|
|
|
onChange={(e) => setValue(e.target.value)}
|
|
|
|
|
onKeyDown={handleKeyDown}
|
|
|
|
|
className="focus-visible:ring-0"
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function HumanMessage({
|
|
|
|
|
message,
|
|
|
|
|
isLoading,
|
|
|
|
|
}: {
|
|
|
|
|
message: Message;
|
|
|
|
|
isLoading: boolean;
|
|
|
|
|
}) {
|
|
|
|
|
const thread = useStreamContext();
|
|
|
|
|
const meta = thread.getMessagesMetadata(message);
|
|
|
|
|
const parentCheckpoint = meta?.firstSeenState?.parent_checkpoint;
|
|
|
|
|
|
|
|
|
|
const [isEditing, setIsEditing] = useState(false);
|
|
|
|
|
const [value, setValue] = useState("");
|
|
|
|
|
const contentString = getContentString(message.content);
|
|
|
|
|
|
|
|
|
|
const handleSubmitEdit = () => {
|
|
|
|
|
setIsEditing(false);
|
|
|
|
|
|
|
|
|
|
const newMessage: Message = { type: "human", content: value };
|
|
|
|
|
thread.submit(
|
feat: Update chat UI to be Open SWE specific (#76) (#91)
* init repo-selector
* add branch selector UI, extend GH hook w branch info
* add reconnectOnMount: true resumeStream, remove repo description from selector, fix styling
* styling repo + branch
* udpate getBranch calls to include targetRepo arg
* format
* add search to repo + branch selectors
* add settings icon link to /github for dev convenience
* add default branch selection
* format
* minor cleanup
* init task list UI demo
* individual task component
* tasks real data
* task visual improvement
* persisting tasks, navigate to thread onClick
* task UI
* TaskSidebar, Navigate to tasks
* org tasks by thread
* group by thread
* improve sidebar, task-list, rm github modal on refresh
* collapse sidebar works when viewing a thread
* remove micro-tasks expansion from threads component, change taskId to taskIndex for persistence + simplicity
* init config sidebar ui
* open and close config sidebar
* add ref for getAllTasks + add graph_id metadata
* format
* create threadItem component
* format
* add threadUtils
* centralize + refactor types
* format
* improve thread status, realtime updates
* fix scroll issue
* remove temperature from config-sidebar
* Change model via sidebar
* fix flashing on updates
* init plan UI
* centralize types
* self CR: refactoring, cleanup, remove comments, add todos
* CR: clean comments + logs, fix repo selector bug
* fix: Update example env file in web (#77)
* disable auto scroll on pageload
* reposelector: use default branch not main master
* remove archived tab temp, default branch listed first in branchSelector dropdown
* auto select first repo
* improve status indicator
* refactor status indicator
* simplify status implementation to use Langgraph
* util moved from provider to thread-utils
* linting, improve task completion logic
* feat: Support followup requests (#60)
* feat: Support followup requests
* cr
* cr
* fix
* account for pr already exists
* remove task provider
* fix: Better prompting and context provided for codebase structure awareness (#85)
* fix: Better prompting and context provided for codebase structure awareness
* cr
* linting + skeleton loader
* fix: branch selector, add github api pagination
* small branch update
* update task completion status realtime
* threadItem stream remove flashing/polling
* feat: Create a shared package (#89)
* feat: Create a shared package
* formatting
* fix: drop passing target repo to getBranchName
* drop docs
* use shared package for config fields in config sidebar
* fix: styling and structure for repo/branch selectors
* fix: use shared types/objects for config fields
* default key for configs
* fix: improved styling for threads
* fix renering num tasks
* disable repo branch selector when chat started
* cr
* cr
* bump deps
* fix: rendering plan in interrupt
* cr
* cr
---------
Co-authored-by: Dylan Boudro <121908331+starmorph@users.noreply.github.com>
2025-06-08 17:29:40 -07:00
|
|
|
{ messages: [newMessage] as unknown as BaseMessage[] },
|
2025-05-28 12:26:47 -07:00
|
|
|
{
|
|
|
|
|
checkpoint: parentCheckpoint,
|
|
|
|
|
streamMode: ["values"],
|
|
|
|
|
optimisticValues: (prev) => {
|
|
|
|
|
const values = meta?.firstSeenState?.values;
|
|
|
|
|
if (!values) return prev;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
...values,
|
feat: Update chat UI to be Open SWE specific (#76) (#91)
* init repo-selector
* add branch selector UI, extend GH hook w branch info
* add reconnectOnMount: true resumeStream, remove repo description from selector, fix styling
* styling repo + branch
* udpate getBranch calls to include targetRepo arg
* format
* add search to repo + branch selectors
* add settings icon link to /github for dev convenience
* add default branch selection
* format
* minor cleanup
* init task list UI demo
* individual task component
* tasks real data
* task visual improvement
* persisting tasks, navigate to thread onClick
* task UI
* TaskSidebar, Navigate to tasks
* org tasks by thread
* group by thread
* improve sidebar, task-list, rm github modal on refresh
* collapse sidebar works when viewing a thread
* remove micro-tasks expansion from threads component, change taskId to taskIndex for persistence + simplicity
* init config sidebar ui
* open and close config sidebar
* add ref for getAllTasks + add graph_id metadata
* format
* create threadItem component
* format
* add threadUtils
* centralize + refactor types
* format
* improve thread status, realtime updates
* fix scroll issue
* remove temperature from config-sidebar
* Change model via sidebar
* fix flashing on updates
* init plan UI
* centralize types
* self CR: refactoring, cleanup, remove comments, add todos
* CR: clean comments + logs, fix repo selector bug
* fix: Update example env file in web (#77)
* disable auto scroll on pageload
* reposelector: use default branch not main master
* remove archived tab temp, default branch listed first in branchSelector dropdown
* auto select first repo
* improve status indicator
* refactor status indicator
* simplify status implementation to use Langgraph
* util moved from provider to thread-utils
* linting, improve task completion logic
* feat: Support followup requests (#60)
* feat: Support followup requests
* cr
* cr
* fix
* account for pr already exists
* remove task provider
* fix: Better prompting and context provided for codebase structure awareness (#85)
* fix: Better prompting and context provided for codebase structure awareness
* cr
* linting + skeleton loader
* fix: branch selector, add github api pagination
* small branch update
* update task completion status realtime
* threadItem stream remove flashing/polling
* feat: Create a shared package (#89)
* feat: Create a shared package
* formatting
* fix: drop passing target repo to getBranchName
* drop docs
* use shared package for config fields in config sidebar
* fix: styling and structure for repo/branch selectors
* fix: use shared types/objects for config fields
* default key for configs
* fix: improved styling for threads
* fix renering num tasks
* disable repo branch selector when chat started
* cr
* cr
* bump deps
* fix: rendering plan in interrupt
* cr
* cr
---------
Co-authored-by: Dylan Boudro <121908331+starmorph@users.noreply.github.com>
2025-06-08 17:29:40 -07:00
|
|
|
messages: [
|
|
|
|
|
...(values.messages ?? []),
|
|
|
|
|
newMessage,
|
|
|
|
|
] as unknown as BaseMessage[],
|
2025-05-28 12:26:47 -07:00
|
|
|
};
|
|
|
|
|
},
|
2025-05-28 13:25:30 -07:00
|
|
|
config: {
|
|
|
|
|
recursion_limit: 400,
|
|
|
|
|
},
|
2025-05-28 12:26:47 -07:00
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div
|
|
|
|
|
className={cn(
|
|
|
|
|
"group ml-auto flex items-center gap-2",
|
|
|
|
|
isEditing && "w-full max-w-xl",
|
|
|
|
|
)}
|
|
|
|
|
>
|
|
|
|
|
<div className={cn("flex flex-col gap-2", isEditing && "w-full")}>
|
|
|
|
|
{isEditing ? (
|
|
|
|
|
<EditableContent
|
|
|
|
|
value={value}
|
|
|
|
|
setValue={setValue}
|
|
|
|
|
onSubmit={handleSubmitEdit}
|
|
|
|
|
/>
|
|
|
|
|
) : (
|
|
|
|
|
<div className="flex flex-col gap-2">
|
|
|
|
|
{/* Render images and files if no text */}
|
|
|
|
|
{Array.isArray(message.content) && message.content.length > 0 && (
|
|
|
|
|
<div className="flex flex-wrap items-end justify-end gap-2">
|
|
|
|
|
{message.content.reduce<React.ReactNode[]>(
|
|
|
|
|
(acc, block, idx) => {
|
|
|
|
|
if (isBase64ContentBlock(block)) {
|
|
|
|
|
acc.push(
|
|
|
|
|
<MultimodalPreview
|
|
|
|
|
key={idx}
|
|
|
|
|
block={block}
|
|
|
|
|
size="md"
|
|
|
|
|
/>,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return acc;
|
|
|
|
|
},
|
|
|
|
|
[],
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
{/* Render text if present, otherwise fallback to file/image name */}
|
|
|
|
|
{contentString ? (
|
2025-05-28 15:18:58 -07:00
|
|
|
<p className="bg-muted ml-auto w-fit rounded-3xl px-4 py-2 whitespace-pre-wrap">
|
2025-05-28 12:26:47 -07:00
|
|
|
{contentString}
|
|
|
|
|
</p>
|
|
|
|
|
) : null}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
className={cn(
|
|
|
|
|
"ml-auto flex items-center gap-2 transition-opacity",
|
|
|
|
|
"opacity-0 group-focus-within:opacity-100 group-hover:opacity-100",
|
|
|
|
|
isEditing && "opacity-100",
|
|
|
|
|
)}
|
|
|
|
|
>
|
|
|
|
|
<BranchSwitcher
|
|
|
|
|
branch={meta?.branch}
|
|
|
|
|
branchOptions={meta?.branchOptions}
|
|
|
|
|
onSelect={(branch) => thread.setBranch(branch)}
|
|
|
|
|
isLoading={isLoading}
|
|
|
|
|
/>
|
|
|
|
|
<CommandBar
|
|
|
|
|
isLoading={isLoading}
|
|
|
|
|
content={contentString}
|
|
|
|
|
isEditing={isEditing}
|
|
|
|
|
setIsEditing={(c) => {
|
|
|
|
|
if (c) {
|
|
|
|
|
setValue(contentString);
|
|
|
|
|
}
|
|
|
|
|
setIsEditing(c);
|
|
|
|
|
}}
|
|
|
|
|
handleSubmitEdit={handleSubmitEdit}
|
|
|
|
|
isHumanMessage={true}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|