Add a keep going suggestion (#201)
This commit is contained in:
@@ -362,10 +362,39 @@ export function ChatInput({ chatId }: { chatId?: number }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function SuggestionButton({
|
||||||
|
children,
|
||||||
|
onClick,
|
||||||
|
tooltipText,
|
||||||
|
}: {
|
||||||
|
onClick: () => void;
|
||||||
|
children: React.ReactNode;
|
||||||
|
tooltipText: string;
|
||||||
|
}) {
|
||||||
|
const { isStreaming } = useStreamChat();
|
||||||
|
return (
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<Button
|
||||||
|
disabled={isStreaming}
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>{tooltipText}</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function SummarizeInNewChatButton() {
|
function SummarizeInNewChatButton() {
|
||||||
const chatId = useAtomValue(selectedChatIdAtom);
|
const chatId = useAtomValue(selectedChatIdAtom);
|
||||||
const appId = useAtomValue(selectedAppIdAtom);
|
const appId = useAtomValue(selectedAppIdAtom);
|
||||||
const { streamMessage, isStreaming } = useStreamChat();
|
const { streamMessage } = useStreamChat();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const onClick = async () => {
|
const onClick = async () => {
|
||||||
if (!appId) {
|
if (!appId) {
|
||||||
@@ -385,106 +414,71 @@ function SummarizeInNewChatButton() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<TooltipProvider>
|
<SuggestionButton
|
||||||
<Tooltip>
|
onClick={onClick}
|
||||||
<TooltipTrigger asChild>
|
tooltipText="Creating a new chat makes the AI more focused and efficient"
|
||||||
<Button
|
>
|
||||||
disabled={isStreaming}
|
Summarize to new chat
|
||||||
variant="outline"
|
</SuggestionButton>
|
||||||
size="sm"
|
|
||||||
onClick={onClick}
|
|
||||||
>
|
|
||||||
Summarize to new chat
|
|
||||||
</Button>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent>
|
|
||||||
<p>Creating a new chat makes the AI more focused and efficient</p>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function RefactorFileButton({ path }: { path: string }) {
|
function RefactorFileButton({ path }: { path: string }) {
|
||||||
const chatId = useAtomValue(selectedChatIdAtom);
|
const chatId = useAtomValue(selectedChatIdAtom);
|
||||||
const { streamMessage, isStreaming } = useStreamChat();
|
const { streamMessage } = useStreamChat();
|
||||||
|
const onClick = () => {
|
||||||
|
if (!chatId) {
|
||||||
|
console.error("No chat id found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
streamMessage({
|
||||||
|
prompt: `Refactor ${path} and make it more modular`,
|
||||||
|
chatId,
|
||||||
|
redo: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<TooltipProvider>
|
<SuggestionButton
|
||||||
<Tooltip>
|
onClick={onClick}
|
||||||
<TooltipTrigger asChild>
|
tooltipText="Refactor the file to improve maintainability"
|
||||||
<Button
|
>
|
||||||
disabled={isStreaming}
|
<span className="max-w-[180px] overflow-hidden whitespace-nowrap text-ellipsis">
|
||||||
variant="outline"
|
Refactor {path.split("/").slice(-2).join("/")}
|
||||||
size="sm"
|
</span>
|
||||||
onClick={() => {
|
</SuggestionButton>
|
||||||
if (!chatId) {
|
|
||||||
console.error("No chat id found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
streamMessage({
|
|
||||||
prompt: `Refactor ${path} and make it more modular`,
|
|
||||||
chatId,
|
|
||||||
redo: false,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="max-w-[180px] overflow-hidden whitespace-nowrap text-ellipsis">
|
|
||||||
Refactor {path.split("/").slice(-2).join("/")}
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent>
|
|
||||||
<p>Refactor {path} to improve maintainability</p>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function WriteCodeProperlyButton() {
|
function WriteCodeProperlyButton() {
|
||||||
const chatId = useAtomValue(selectedChatIdAtom);
|
const chatId = useAtomValue(selectedChatIdAtom);
|
||||||
const { streamMessage, isStreaming } = useStreamChat();
|
const { streamMessage } = useStreamChat();
|
||||||
|
const onClick = () => {
|
||||||
|
if (!chatId) {
|
||||||
|
console.error("No chat id found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
streamMessage({
|
||||||
|
prompt: `Write the code in the previous message in the correct format using \`<dyad-write>\` tags!`,
|
||||||
|
chatId,
|
||||||
|
redo: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<TooltipProvider>
|
<SuggestionButton
|
||||||
<Tooltip>
|
onClick={onClick}
|
||||||
<TooltipTrigger asChild>
|
tooltipText="Write code properly (useful when AI generates the code in the wrong format)"
|
||||||
<Button
|
>
|
||||||
disabled={isStreaming}
|
Write code properly
|
||||||
variant="outline"
|
</SuggestionButton>
|
||||||
size="sm"
|
|
||||||
onClick={() => {
|
|
||||||
if (!chatId) {
|
|
||||||
console.error("No chat id found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
streamMessage({
|
|
||||||
prompt: `Write the code in the previous message in the correct format using \`<dyad-write>\` tags!`,
|
|
||||||
chatId,
|
|
||||||
redo: false,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Write code properly
|
|
||||||
</Button>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent>
|
|
||||||
<p>
|
|
||||||
Write code properly (useful when AI generates the code in the wrong
|
|
||||||
format)
|
|
||||||
</p>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function RebuildButton() {
|
function RebuildButton() {
|
||||||
const { restartApp } = useRunApp();
|
const { restartApp } = useRunApp();
|
||||||
const { isStreaming } = useStreamChat();
|
|
||||||
const posthog = usePostHog();
|
const posthog = usePostHog();
|
||||||
const selectedAppId = useAtomValue(selectedAppIdAtom);
|
const selectedAppId = useAtomValue(selectedAppIdAtom);
|
||||||
|
|
||||||
const handleRebuild = useCallback(async () => {
|
const onClick = useCallback(async () => {
|
||||||
if (!selectedAppId) return;
|
if (!selectedAppId) return;
|
||||||
|
|
||||||
posthog.capture("action:rebuild");
|
posthog.capture("action:rebuild");
|
||||||
@@ -492,33 +486,18 @@ function RebuildButton() {
|
|||||||
}, [selectedAppId, posthog, restartApp]);
|
}, [selectedAppId, posthog, restartApp]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TooltipProvider>
|
<SuggestionButton onClick={onClick} tooltipText="Rebuild the application">
|
||||||
<Tooltip>
|
Rebuild app
|
||||||
<TooltipTrigger asChild>
|
</SuggestionButton>
|
||||||
<Button
|
|
||||||
disabled={isStreaming}
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={handleRebuild}
|
|
||||||
>
|
|
||||||
Rebuild app
|
|
||||||
</Button>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent>
|
|
||||||
<p>Rebuild the application</p>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function RestartButton() {
|
function RestartButton() {
|
||||||
const { isStreaming } = useStreamChat();
|
|
||||||
const { restartApp } = useRunApp();
|
const { restartApp } = useRunApp();
|
||||||
const posthog = usePostHog();
|
const posthog = usePostHog();
|
||||||
const selectedAppId = useAtomValue(selectedAppIdAtom);
|
const selectedAppId = useAtomValue(selectedAppIdAtom);
|
||||||
|
|
||||||
const handleRestart = useCallback(async () => {
|
const onClick = useCallback(async () => {
|
||||||
if (!selectedAppId) return;
|
if (!selectedAppId) return;
|
||||||
|
|
||||||
posthog.capture("action:restart");
|
posthog.capture("action:restart");
|
||||||
@@ -526,54 +505,51 @@ function RestartButton() {
|
|||||||
}, [selectedAppId, posthog, restartApp]);
|
}, [selectedAppId, posthog, restartApp]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TooltipProvider>
|
<SuggestionButton
|
||||||
<Tooltip>
|
onClick={onClick}
|
||||||
<TooltipTrigger asChild>
|
tooltipText="Restart the development server"
|
||||||
<Button
|
>
|
||||||
disabled={isStreaming}
|
Restart app
|
||||||
variant="outline"
|
</SuggestionButton>
|
||||||
size="sm"
|
|
||||||
onClick={handleRestart}
|
|
||||||
>
|
|
||||||
Restart app
|
|
||||||
</Button>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent>
|
|
||||||
<p>Restart the development server</p>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function RefreshButton() {
|
function RefreshButton() {
|
||||||
const { refreshAppIframe } = useRunApp();
|
const { refreshAppIframe } = useRunApp();
|
||||||
const { isStreaming } = useStreamChat();
|
|
||||||
const posthog = usePostHog();
|
const posthog = usePostHog();
|
||||||
|
|
||||||
const handleRefresh = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
posthog.capture("action:refresh");
|
posthog.capture("action:refresh");
|
||||||
refreshAppIframe();
|
refreshAppIframe();
|
||||||
}, [posthog, refreshAppIframe]);
|
}, [posthog, refreshAppIframe]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TooltipProvider>
|
<SuggestionButton
|
||||||
<Tooltip>
|
onClick={onClick}
|
||||||
<TooltipTrigger asChild>
|
tooltipText="Refresh the application preview"
|
||||||
<Button
|
>
|
||||||
disabled={isStreaming}
|
Refresh app
|
||||||
variant="outline"
|
</SuggestionButton>
|
||||||
size="sm"
|
);
|
||||||
onClick={handleRefresh}
|
}
|
||||||
>
|
|
||||||
Refresh app
|
function KeepGoingButton() {
|
||||||
</Button>
|
const { streamMessage } = useStreamChat();
|
||||||
</TooltipTrigger>
|
const chatId = useAtomValue(selectedChatIdAtom);
|
||||||
<TooltipContent>
|
const onClick = () => {
|
||||||
<p>Refresh the application preview</p>
|
if (!chatId) {
|
||||||
</TooltipContent>
|
console.error("No chat id found");
|
||||||
</Tooltip>
|
return;
|
||||||
</TooltipProvider>
|
}
|
||||||
|
streamMessage({
|
||||||
|
prompt: "Keep going",
|
||||||
|
chatId,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<SuggestionButton onClick={onClick} tooltipText="Keep going">
|
||||||
|
Keep going
|
||||||
|
</SuggestionButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -591,6 +567,8 @@ function mapActionToButton(action: SuggestedAction) {
|
|||||||
return <RestartButton />;
|
return <RestartButton />;
|
||||||
case "refresh":
|
case "refresh":
|
||||||
return <RefreshButton />;
|
return <RefreshButton />;
|
||||||
|
case "keep-going":
|
||||||
|
return <KeepGoingButton />;
|
||||||
default:
|
default:
|
||||||
console.error(`Unsupported action: ${action.id}`);
|
console.error(`Unsupported action: ${action.id}`);
|
||||||
return (
|
return (
|
||||||
@@ -603,8 +581,8 @@ function mapActionToButton(action: SuggestedAction) {
|
|||||||
|
|
||||||
function ActionProposalActions({ proposal }: { proposal: ActionProposal }) {
|
function ActionProposalActions({ proposal }: { proposal: ActionProposal }) {
|
||||||
return (
|
return (
|
||||||
<div className="border-b border-border p-2 flex items-center justify-between">
|
<div className="border-b border-border p-2 pb-0 flex items-center justify-between">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2 overflow-x-auto pb-2">
|
||||||
{proposal.actions.map((action) => mapActionToButton(action))}
|
{proposal.actions.map((action) => mapActionToButton(action))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -297,7 +297,10 @@ const getProposalHandler = async (
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (actions.length > 0 && latestAssistantMessage) {
|
if (latestAssistantMessage) {
|
||||||
|
actions.push({
|
||||||
|
id: "keep-going",
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
proposal: {
|
proposal: {
|
||||||
type: "action-proposal",
|
type: "action-proposal",
|
||||||
|
|||||||
@@ -166,7 +166,8 @@ export type SuggestedAction =
|
|||||||
| WriteCodeProperlyAction
|
| WriteCodeProperlyAction
|
||||||
| RebuildAction
|
| RebuildAction
|
||||||
| RestartAction
|
| RestartAction
|
||||||
| RefreshAction;
|
| RefreshAction
|
||||||
|
| KeepGoingAction;
|
||||||
|
|
||||||
export interface RestartAppAction {
|
export interface RestartAppAction {
|
||||||
id: "restart-app";
|
id: "restart-app";
|
||||||
@@ -197,6 +198,10 @@ export interface RefreshAction {
|
|||||||
id: "refresh";
|
id: "refresh";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface KeepGoingAction {
|
||||||
|
id: "keep-going";
|
||||||
|
}
|
||||||
|
|
||||||
export interface ActionProposal {
|
export interface ActionProposal {
|
||||||
type: "action-proposal";
|
type: "action-proposal";
|
||||||
actions: SuggestedAction[];
|
actions: SuggestedAction[];
|
||||||
|
|||||||
Reference in New Issue
Block a user