feat: Add Diff View and File History Tracking

- Implemented a new Diff View in the Workbench to visualize file changes
- Added file history tracking with detailed change information
- Enhanced FileTree and FileModifiedDropdown to show line additions and deletions
- Integrated file history saving and retrieval in ActionRunner
- Updated Workbench view types to include 'diff' option
- Added support for inline and side-by-side diff view modes
This commit is contained in:
Toddyclipsgg
2025-02-23 07:55:38 -03:00
parent 8c72ed76b3
commit ab6f5328b4
17 changed files with 1192 additions and 77 deletions

View File

@@ -34,6 +34,7 @@ import ChatAlert from './ChatAlert';
import type { ModelInfo } from '~/lib/modules/llm/types';
import ProgressCompilation from './ProgressCompilation';
import type { ProgressAnnotation } from '~/types/context';
import type { ActionRunner } from '~/lib/runtime/action-runner';
import { LOCAL_PROVIDERS } from '~/lib/stores/settings';
const TEXTAREA_MIN_HEIGHT = 76;
@@ -68,6 +69,7 @@ interface BaseChatProps {
actionAlert?: ActionAlert;
clearAlert?: () => void;
data?: JSONValue[] | undefined;
actionRunner?: ActionRunner;
}
export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
@@ -102,6 +104,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
actionAlert,
clearAlert,
data,
actionRunner,
},
ref,
) => {
@@ -304,7 +307,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
data-chat-visible={showChat}
>
<ClientOnly>{() => <Menu />}</ClientOnly>
<div className="flex flex-col lg:flex-row overflow-y-auto w-full h-full">
<div ref={scrollRef} className="flex flex-col lg:flex-row overflow-y-auto w-full h-full">
<div className={classNames(styles.Chat, 'flex flex-col flex-grow lg:min-w-[var(--chat-min-width)] h-full')}>
{!chatStarted && (
<div id="intro" className="mt-[16vh] max-w-chat mx-auto text-center px-4 lg:px-0">
@@ -318,40 +321,39 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
)}
<div
className={classNames('pt-6 px-2 sm:px-6', {
'h-full flex flex-col pb-4 overflow-y-auto': chatStarted,
'h-full flex flex-col': chatStarted,
})}
ref={scrollRef}
>
<ClientOnly>
{() => {
return chatStarted ? (
<div className="flex-1 w-full max-w-chat pb-6 mx-auto z-1">
<Messages
ref={messageRef}
className="flex flex-col "
messages={messages}
isStreaming={isStreaming}
/>
</div>
<Messages
ref={messageRef}
className="flex flex-col w-full flex-1 max-w-chat pb-6 mx-auto z-1"
messages={messages}
isStreaming={isStreaming}
/>
) : null;
}}
</ClientOnly>
<div
className={classNames('flex flex-col gap-4 w-full max-w-chat mx-auto z-prompt', {
className={classNames('flex flex-col gap-4 w-full max-w-chat mx-auto z-prompt mb-6', {
'sticky bottom-2': chatStarted,
'position-absolute': chatStarted,
})}
>
{actionAlert && (
<ChatAlert
alert={actionAlert}
clearAlert={() => clearAlert?.()}
postMessage={(message) => {
sendMessage?.({} as any, message);
clearAlert?.();
}}
/>
)}
<div className="bg-bolt-elements-background-depth-2">
{actionAlert && (
<ChatAlert
alert={actionAlert}
clearAlert={() => clearAlert?.()}
postMessage={(message) => {
sendMessage?.({} as any, message);
clearAlert?.();
}}
/>
)}
</div>
{progressAnnotations && <ProgressCompilation data={progressAnnotations} />}
<div
className={classNames(
@@ -585,16 +587,15 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
</div>
</div>
</div>
{!chatStarted && (
<div className="flex flex-col justify-center mt-6 gap-5">
<div className="flex flex-col justify-center gap-5">
{!chatStarted && (
<div className="flex justify-center gap-2">
<div className="flex items-center gap-2">
{ImportButtons(importChat)}
<GitCloneButton importChat={importChat} className="min-w-[120px]" />
</div>
{ImportButtons(importChat)}
<GitCloneButton importChat={importChat} />
</div>
{ExamplePrompts((event, messageInput) => {
)}
{!chatStarted &&
ExamplePrompts((event, messageInput) => {
if (isStreaming) {
handleStop?.();
return;
@@ -602,11 +603,18 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
handleSendMessage?.(event, messageInput);
})}
<StarterTemplates />
</div>
)}
{!chatStarted && <StarterTemplates />}
</div>
</div>
<ClientOnly>{() => <Workbench chatStarted={chatStarted} isStreaming={isStreaming} />}</ClientOnly>
<ClientOnly>
{() => (
<Workbench
actionRunner={actionRunner ?? ({} as ActionRunner)}
chatStarted={chatStarted}
isStreaming={isStreaming}
/>
)}
</ClientOnly>
</div>
</div>
);