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() {
|
||||
const chatId = useAtomValue(selectedChatIdAtom);
|
||||
const appId = useAtomValue(selectedAppIdAtom);
|
||||
const { streamMessage, isStreaming } = useStreamChat();
|
||||
const { streamMessage } = useStreamChat();
|
||||
const navigate = useNavigate();
|
||||
const onClick = async () => {
|
||||
if (!appId) {
|
||||
@@ -385,38 +414,19 @@ function SummarizeInNewChatButton() {
|
||||
}
|
||||
};
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
disabled={isStreaming}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
<SuggestionButton
|
||||
onClick={onClick}
|
||||
tooltipText="Creating a new chat makes the AI more focused and efficient"
|
||||
>
|
||||
Summarize to new chat
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Creating a new chat makes the AI more focused and efficient</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</SuggestionButton>
|
||||
);
|
||||
}
|
||||
|
||||
function RefactorFileButton({ path }: { path: string }) {
|
||||
const chatId = useAtomValue(selectedChatIdAtom);
|
||||
const { streamMessage, isStreaming } = useStreamChat();
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
disabled={isStreaming}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
const { streamMessage } = useStreamChat();
|
||||
const onClick = () => {
|
||||
if (!chatId) {
|
||||
console.error("No chat id found");
|
||||
return;
|
||||
@@ -426,33 +436,23 @@ function RefactorFileButton({ path }: { path: string }) {
|
||||
chatId,
|
||||
redo: false,
|
||||
});
|
||||
}}
|
||||
};
|
||||
return (
|
||||
<SuggestionButton
|
||||
onClick={onClick}
|
||||
tooltipText="Refactor the file to improve maintainability"
|
||||
>
|
||||
<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>
|
||||
</SuggestionButton>
|
||||
);
|
||||
}
|
||||
|
||||
function WriteCodeProperlyButton() {
|
||||
const chatId = useAtomValue(selectedChatIdAtom);
|
||||
const { streamMessage, isStreaming } = useStreamChat();
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
disabled={isStreaming}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
const { streamMessage } = useStreamChat();
|
||||
const onClick = () => {
|
||||
if (!chatId) {
|
||||
console.error("No chat id found");
|
||||
return;
|
||||
@@ -462,29 +462,23 @@ function WriteCodeProperlyButton() {
|
||||
chatId,
|
||||
redo: false,
|
||||
});
|
||||
}}
|
||||
};
|
||||
return (
|
||||
<SuggestionButton
|
||||
onClick={onClick}
|
||||
tooltipText="Write code properly (useful when AI generates the code in the wrong format)"
|
||||
>
|
||||
Write code properly
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>
|
||||
Write code properly (useful when AI generates the code in the wrong
|
||||
format)
|
||||
</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</SuggestionButton>
|
||||
);
|
||||
}
|
||||
|
||||
function RebuildButton() {
|
||||
const { restartApp } = useRunApp();
|
||||
const { isStreaming } = useStreamChat();
|
||||
const posthog = usePostHog();
|
||||
const selectedAppId = useAtomValue(selectedAppIdAtom);
|
||||
|
||||
const handleRebuild = useCallback(async () => {
|
||||
const onClick = useCallback(async () => {
|
||||
if (!selectedAppId) return;
|
||||
|
||||
posthog.capture("action:rebuild");
|
||||
@@ -492,33 +486,18 @@ function RebuildButton() {
|
||||
}, [selectedAppId, posthog, restartApp]);
|
||||
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
disabled={isStreaming}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={handleRebuild}
|
||||
>
|
||||
<SuggestionButton onClick={onClick} tooltipText="Rebuild the application">
|
||||
Rebuild app
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Rebuild the application</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</SuggestionButton>
|
||||
);
|
||||
}
|
||||
|
||||
function RestartButton() {
|
||||
const { isStreaming } = useStreamChat();
|
||||
const { restartApp } = useRunApp();
|
||||
const posthog = usePostHog();
|
||||
const selectedAppId = useAtomValue(selectedAppIdAtom);
|
||||
|
||||
const handleRestart = useCallback(async () => {
|
||||
const onClick = useCallback(async () => {
|
||||
if (!selectedAppId) return;
|
||||
|
||||
posthog.capture("action:restart");
|
||||
@@ -526,54 +505,51 @@ function RestartButton() {
|
||||
}, [selectedAppId, posthog, restartApp]);
|
||||
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
disabled={isStreaming}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={handleRestart}
|
||||
<SuggestionButton
|
||||
onClick={onClick}
|
||||
tooltipText="Restart the development server"
|
||||
>
|
||||
Restart app
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Restart the development server</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</SuggestionButton>
|
||||
);
|
||||
}
|
||||
|
||||
function RefreshButton() {
|
||||
const { refreshAppIframe } = useRunApp();
|
||||
const { isStreaming } = useStreamChat();
|
||||
const posthog = usePostHog();
|
||||
|
||||
const handleRefresh = useCallback(() => {
|
||||
const onClick = useCallback(() => {
|
||||
posthog.capture("action:refresh");
|
||||
refreshAppIframe();
|
||||
}, [posthog, refreshAppIframe]);
|
||||
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
disabled={isStreaming}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={handleRefresh}
|
||||
<SuggestionButton
|
||||
onClick={onClick}
|
||||
tooltipText="Refresh the application preview"
|
||||
>
|
||||
Refresh app
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Refresh the application preview</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</SuggestionButton>
|
||||
);
|
||||
}
|
||||
|
||||
function KeepGoingButton() {
|
||||
const { streamMessage } = useStreamChat();
|
||||
const chatId = useAtomValue(selectedChatIdAtom);
|
||||
const onClick = () => {
|
||||
if (!chatId) {
|
||||
console.error("No chat id found");
|
||||
return;
|
||||
}
|
||||
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 />;
|
||||
case "refresh":
|
||||
return <RefreshButton />;
|
||||
case "keep-going":
|
||||
return <KeepGoingButton />;
|
||||
default:
|
||||
console.error(`Unsupported action: ${action.id}`);
|
||||
return (
|
||||
@@ -603,8 +581,8 @@ function mapActionToButton(action: SuggestedAction) {
|
||||
|
||||
function ActionProposalActions({ proposal }: { proposal: ActionProposal }) {
|
||||
return (
|
||||
<div className="border-b border-border p-2 flex items-center justify-between">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="border-b border-border p-2 pb-0 flex items-center justify-between">
|
||||
<div className="flex items-center space-x-2 overflow-x-auto pb-2">
|
||||
{proposal.actions.map((action) => mapActionToButton(action))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -297,7 +297,10 @@ const getProposalHandler = async (
|
||||
});
|
||||
}
|
||||
}
|
||||
if (actions.length > 0 && latestAssistantMessage) {
|
||||
if (latestAssistantMessage) {
|
||||
actions.push({
|
||||
id: "keep-going",
|
||||
});
|
||||
return {
|
||||
proposal: {
|
||||
type: "action-proposal",
|
||||
|
||||
@@ -166,7 +166,8 @@ export type SuggestedAction =
|
||||
| WriteCodeProperlyAction
|
||||
| RebuildAction
|
||||
| RestartAction
|
||||
| RefreshAction;
|
||||
| RefreshAction
|
||||
| KeepGoingAction;
|
||||
|
||||
export interface RestartAppAction {
|
||||
id: "restart-app";
|
||||
@@ -197,6 +198,10 @@ export interface RefreshAction {
|
||||
id: "refresh";
|
||||
}
|
||||
|
||||
export interface KeepGoingAction {
|
||||
id: "keep-going";
|
||||
}
|
||||
|
||||
export interface ActionProposal {
|
||||
type: "action-proposal";
|
||||
actions: SuggestedAction[];
|
||||
|
||||
Reference in New Issue
Block a user