Explicit thinking (#183)

This commit is contained in:
Will Chen
2025-05-16 22:35:08 -07:00
committed by GitHub
parent f9f33596bd
commit 63e41454c7
3 changed files with 144 additions and 0 deletions

View File

@@ -9,6 +9,7 @@ import { DyadExecuteSql } from "./DyadExecuteSql";
import { DyadAddIntegration } from "./DyadAddIntegration"; import { DyadAddIntegration } from "./DyadAddIntegration";
import { DyadEdit } from "./DyadEdit"; import { DyadEdit } from "./DyadEdit";
import { DyadCodebaseContext } from "./DyadCodebaseContext"; import { DyadCodebaseContext } from "./DyadCodebaseContext";
import { DyadThink } from "./DyadThink";
import { CodeHighlight } from "./CodeHighlight"; import { CodeHighlight } from "./CodeHighlight";
import { useAtomValue } from "jotai"; import { useAtomValue } from "jotai";
import { isStreamingAtom } from "@/atoms/chatAtoms"; import { isStreamingAtom } from "@/atoms/chatAtoms";
@@ -119,6 +120,7 @@ function preprocessUnclosedTags(content: string): {
"dyad-chat-summary", "dyad-chat-summary",
"dyad-edit", "dyad-edit",
"dyad-codebase-context", "dyad-codebase-context",
"think",
]; ];
let processedContent = content; let processedContent = content;
@@ -183,6 +185,7 @@ function parseCustomTags(content: string): ContentPiece[] {
"dyad-chat-summary", "dyad-chat-summary",
"dyad-edit", "dyad-edit",
"dyad-codebase-context", "dyad-codebase-context",
"think",
]; ];
const tagPattern = new RegExp( const tagPattern = new RegExp(
@@ -268,6 +271,18 @@ function renderCustomTag(
const { tag, attributes, content, inProgress } = tagInfo; const { tag, attributes, content, inProgress } = tagInfo;
switch (tag) { switch (tag) {
case "think":
return (
<DyadThink
node={{
properties: {
state: getState({ isStreaming, inProgress }),
},
}}
>
{content}
</DyadThink>
);
case "dyad-write": case "dyad-write":
return ( return (
<DyadWrite <DyadWrite

View File

@@ -0,0 +1,75 @@
import React, { useState, useEffect } from "react";
import { Brain, ChevronDown, ChevronUp, Loader } from "lucide-react";
import { VanillaMarkdownParser } from "./DyadMarkdownParser";
import { CustomTagState } from "./stateTypes";
interface DyadThinkProps {
node?: any;
children?: React.ReactNode;
}
export const DyadThink: React.FC<DyadThinkProps> = ({ children, node }) => {
const state = node?.properties?.state as CustomTagState;
const inProgress = state === "pending";
const [isExpanded, setIsExpanded] = useState(inProgress);
// Collapse when transitioning from in-progress to not-in-progress
useEffect(() => {
if (!inProgress && isExpanded) {
setIsExpanded(false);
}
}, [inProgress]);
return (
<div
className={`relative bg-(--background-lightest) dark:bg-zinc-900 hover:bg-(--background-lighter) rounded-lg px-4 py-2 border my-2 cursor-pointer ${
inProgress ? "border-purple-500" : "border-border"
}`}
onClick={() => setIsExpanded(!isExpanded)}
role="button"
aria-expanded={isExpanded}
tabIndex={0}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
setIsExpanded(!isExpanded);
}
}}
>
{/* Top-left label badge */}
<div
className="absolute top-2 left-2 flex items-center gap-1 px-2 py-0.5 rounded text-xs font-semibold text-purple-500 bg-white dark:bg-zinc-900"
style={{ zIndex: 1 }}
>
<Brain size={16} className="text-purple-500" />
<span>Thinking</span>
{inProgress && (
<Loader size={14} className="ml-1 text-purple-500 animate-spin" />
)}
</div>
{/* Indicator icon */}
<div className="absolute top-2 right-2 p-1 text-gray-500">
{isExpanded ? <ChevronUp size={16} /> : <ChevronDown size={16} />}
</div>
{/* Main content with smooth transition */}
<div
className="pt-6 overflow-hidden transition-all duration-300 ease-in-out"
style={{
maxHeight: isExpanded ? "1000px" : "0px",
opacity: isExpanded ? 1 : 0,
marginBottom: isExpanded ? "0" : "-6px", // Compensate for padding
}}
>
<div className="px-0 text-sm text-gray-600 dark:text-gray-300">
{typeof children === "string" ? (
<VanillaMarkdownParser content={children} />
) : (
children
)}
</div>
</div>
</div>
);
};

View File

@@ -1,3 +1,55 @@
export const THINKING_PROMPT = `
# Thinking Process
Before responding to user requests, ALWAYS use <think></think> tags to carefully plan your approach. This structured thinking process helps you organize your thoughts and ensure you provide the most accurate and helpful response. Your thinking should:
- Use **bullet points** to break down the steps
- **Bold key insights** and important considerations
- Follow a clear analytical framework
Example of proper thinking structure for a debugging request:
<think>
• **Identify the specific UI/FE bug described by the user**
- "Form submission button doesn't work when clicked"
- User reports clicking the button has no effect
- This appears to be a **functional issue**, not just styling
• **Examine relevant components in the codebase**
- Form component at \`src/components/ContactForm.jsx\`
- Button component at \`src/components/Button.jsx\`
- Form submission logic in \`src/utils/formHandlers.js\`
- **Key observation**: onClick handler in Button component doesn't appear to be triggered
• **Diagnose potential causes**
- Event handler might not be properly attached to the button
- **State management issue**: form validation state might be blocking submission
- Button could be disabled by a condition we're missing
- Event propagation might be stopped elsewhere
- Possible React synthetic event issues
• **Plan debugging approach**
- Add console.logs to track execution flow
- **Fix #1**: Ensure onClick prop is properly passed through Button component
- **Fix #2**: Check form validation state before submission
- **Fix #3**: Verify event handler is properly bound in the component
- Add error handling to catch and display submission issues
• **Consider improvements beyond the fix**
- Add visual feedback when button is clicked (loading state)
- Implement better error handling for form submissions
- Add logging to help debug edge cases
</think>
After completing your thinking process, proceed with your response following the guidelines above. Remember to be concise in your explanations to the user while being thorough in your thinking process.
This structured thinking ensures you:
1. Don't miss important aspects of the request
2. Consider all relevant factors before making changes
3. Deliver more accurate and helpful responses
4. Maintain a consistent approach to problem-solving
`;
export const SYSTEM_PROMPT = ` 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. <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> 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>
@@ -290,6 +342,8 @@ Available packages and libraries:
- You have ALL the necessary Radix UI components installed. - You have ALL the necessary Radix UI components installed.
- Use prebuilt components from the shadcn/ui library after importing them. Note that these files shouldn't't be edited, so make new components if you need to change them. - Use prebuilt components from the shadcn/ui library after importing them. Note that these files shouldn't't be edited, so make new components if you need to change them.
${THINKING_PROMPT}
# REMEMBER # REMEMBER
> **CODE FORMATTING IS NON-NEGOTIABLE:** > **CODE FORMATTING IS NON-NEGOTIABLE:**