Provide suggestions for running commands (restart/refresh/rebuild) (#62)

This commit is contained in:
Will Chen
2025-05-01 21:44:51 -07:00
committed by GitHub
parent a8fd91a410
commit 1bbfedc668
5 changed files with 149 additions and 1 deletions

View File

@@ -421,6 +421,87 @@ function WriteCodeProperlyButton() {
);
}
function RebuildButton() {
const { restartApp } = useRunApp();
const posthog = usePostHog();
const selectedAppId = useAtomValue(selectedAppIdAtom);
const handleRebuild = useCallback(async () => {
if (!selectedAppId) return;
posthog.capture("action:rebuild");
await restartApp({ removeNodeModules: true });
}, [selectedAppId, posthog, restartApp]);
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline" size="sm" onClick={handleRebuild}>
Rebuild app
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Rebuild the application</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}
function RestartButton() {
const { restartApp } = useRunApp();
const posthog = usePostHog();
const selectedAppId = useAtomValue(selectedAppIdAtom);
const handleRestart = useCallback(async () => {
if (!selectedAppId) return;
posthog.capture("action:restart");
await restartApp();
}, [selectedAppId, posthog, restartApp]);
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline" size="sm" onClick={handleRestart}>
Restart app
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Restart the development server</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}
function RefreshButton() {
const { refreshAppIframe } = useRunApp();
const posthog = usePostHog();
const handleRefresh = useCallback(() => {
posthog.capture("action:refresh");
refreshAppIframe();
}, [posthog, refreshAppIframe]);
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline" size="sm" onClick={handleRefresh}>
Refresh app
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Refresh the application preview</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}
function mapActionToButton(action: SuggestedAction) {
switch (action.id) {
case "summarize-in-new-chat":
@@ -429,6 +510,12 @@ function mapActionToButton(action: SuggestedAction) {
return <RefactorFileButton path={action.path} />;
case "write-code-properly":
return <WriteCodeProperlyButton />;
case "rebuild":
return <RebuildButton />;
case "restart":
return <RestartButton />;
case "refresh":
return <RefreshButton />;
default:
console.error(`Unsupported action: ${action.id}`);
return (

View File

@@ -18,6 +18,7 @@ import {
getDyadExecuteSqlTags,
getDyadRenameTags,
getDyadWriteTags,
getDyadCommandTags,
processFullResponseActions,
} from "../processors/response_processor";
import log from "electron-log";
@@ -247,6 +248,24 @@ const getProposalHandler = async (
id: "write-code-properly",
});
}
// Check for command tags and add corresponding actions
const commandTags = getDyadCommandTags(latestAssistantMessage.content);
if (commandTags.includes("rebuild")) {
actions.push({
id: "rebuild",
});
}
if (commandTags.includes("restart")) {
actions.push({
id: "restart",
});
}
if (commandTags.includes("refresh")) {
actions.push({
id: "refresh",
});
}
}
// Get all chat messages to calculate token usage

View File

@@ -138,6 +138,19 @@ export function getDyadExecuteSqlTags(fullResponse: string): SqlQuery[] {
return queries;
}
export function getDyadCommandTags(fullResponse: string): string[] {
const dyadCommandRegex =
/<dyad-command type="([^"]+)"[^>]*><\/dyad-command>/g;
let match;
const commands: string[] = [];
while ((match = dyadCommandRegex.exec(fullResponse)) !== null) {
commands.push(match[1]);
}
return commands;
}
interface Output {
message: string;
error: unknown;

View File

@@ -160,7 +160,10 @@ export type SuggestedAction =
| RestartAppAction
| SummarizeInNewChatAction
| RefactorFileAction
| WriteCodeProperlyAction;
| WriteCodeProperlyAction
| RebuildAction
| RestartAction
| RefreshAction;
export interface RestartAppAction {
id: "restart-app";
@@ -179,6 +182,18 @@ export interface RefactorFileAction {
path: string;
}
export interface RebuildAction {
id: "rebuild";
}
export interface RestartAction {
id: "restart";
}
export interface RefreshAction {
id: "refresh";
}
export interface ActionProposal {
type: "action-proposal";
actions: SuggestedAction[];

View File

@@ -2,6 +2,20 @@ export const SYSTEM_PROMPT = `
<role> You are Dyad, an AI editor that creates and modifies web applications. You assist users by chatting with them and making changes to their code in real-time. You understand that users can see a live preview of their application in an iframe on the right side of the screen while you make code changes.
Not every interaction requires code changes - you're happy to discuss, explain concepts, or provide guidance without modifying the codebase. When code changes are needed, you make efficient and effective updates to React codebases while following best practices for maintainability and readability. You take pride in keeping things simple and elegant. You are friendly and helpful, always aiming to provide clear explanations. </role>
# App Preview / Commands
Do *not* tell the user to run shell commands. Instead, they can do one of the following commands in the UI:
- **Rebuild**: This will rebuild the app from scratch. First it deletes the node_modules folder and then it re-installs the npm packages and then starts the app server.
- **Restart**: This will restart the app server.
- **Refresh**: This will refresh the app preview page.
You can suggest one of these commands by using the <dyad-command> tag like this:
<dyad-command type="rebuild"></dyad-command>
<dyad-command type="restart"></dyad-command>
<dyad-command type="refresh"></dyad-command>
If you output one of these commands, tell the user to look for the action button above the chat input.
# Guidelines