fix: initial prompt not filled in after accepting new recipe (#3637)

This commit is contained in:
Zane
2025-07-31 10:49:28 -07:00
committed by GitHub
parent f1907abacb
commit b5e73c4c89
5 changed files with 40 additions and 27 deletions
+16 -1
View File
@@ -61,6 +61,7 @@ import { MainPanelLayout } from './Layout/MainPanelLayout';
import ChatInput from './ChatInput';
import { ScrollArea, ScrollAreaHandle } from './ui/scroll-area';
import { RecipeWarningModal } from './ui/RecipeWarningModal';
import ParameterInputModal from './ParameterInputModal';
import { useChatEngine } from '../hooks/useChatEngine';
import { useRecipeManager } from '../hooks/useRecipeManager';
import { useSessionContinuation } from '../hooks/useSessionContinuation';
@@ -188,6 +189,9 @@ function BaseChatContent({
recipeConfig,
initialPrompt,
isGeneratingRecipe,
isParameterModalOpen,
setIsParameterModalOpen,
handleParameterSubmit,
handleAutoExecution,
recipeError,
setRecipeError,
@@ -524,7 +528,7 @@ function BaseChatContent({
chatState={chatState}
onStop={onStopGoose}
commandHistory={commandHistory}
initialValue={_input || (messages.length === 0 ? initialPrompt : '')}
initialValue={_input || ''}
setView={setView}
numTokens={sessionTokenCount}
inputTokens={sessionInputTokens || localInputTokens}
@@ -537,6 +541,8 @@ function BaseChatContent({
sessionCosts={sessionCosts}
setIsGoosehintsModalOpen={setIsGoosehintsModalOpen}
recipeConfig={recipeConfig}
recipeAccepted={recipeAccepted}
initialPrompt={initialPrompt}
{...customChatInputProps}
/>
</div>
@@ -564,6 +570,15 @@ function BaseChatContent({
}}
/>
{/* Recipe Parameter Modal */}
{isParameterModalOpen && recipeConfig?.parameters && (
<ParameterInputModal
parameters={recipeConfig.parameters}
onSubmit={handleParameterSubmit}
onClose={() => setIsParameterModalOpen(false)}
/>
)}
{/* Recipe Error Modal */}
{recipeError && (
<div className="fixed inset-0 z-[300] flex items-center justify-center bg-black/50">
+16
View File
@@ -75,6 +75,8 @@ interface ChatInputProps {
setIsGoosehintsModalOpen?: (isOpen: boolean) => void;
disableAnimation?: boolean;
recipeConfig?: Recipe | null;
recipeAccepted?: boolean;
initialPrompt?: string;
}
export default function ChatInput({
@@ -95,6 +97,8 @@ export default function ChatInput({
sessionCosts,
setIsGoosehintsModalOpen,
recipeConfig,
recipeAccepted,
initialPrompt,
}: ChatInputProps) {
const [_value, setValue] = useState(initialValue);
const [displayValue, setDisplayValue] = useState(initialValue); // For immediate visual feedback
@@ -200,6 +204,18 @@ export default function ChatInput({
setHasUserTyped(false);
}, [initialValue]); // Keep only initialValue as a dependency
// Handle recipe prompt updates
useEffect(() => {
// If recipe is accepted and we have an initial prompt, and no messages yet, set the prompt
if (recipeAccepted && initialPrompt && messages.length === 0 && !displayValue.trim()) {
setDisplayValue(initialPrompt);
setValue(initialPrompt);
setTimeout(() => {
textAreaRef.current?.focus();
}, 0);
}
}, [recipeAccepted, initialPrompt, messages.length, displayValue]);
// Draft functionality - load draft if no initial value or recipe
useEffect(() => {
// Reset draft loaded flag when context changes
+1 -17
View File
@@ -28,7 +28,6 @@ import { useEffect, useState } from 'react';
import { useLocation } from 'react-router-dom';
import { type View, ViewOptions } from '../App';
import BaseChat from './BaseChat';
import ParameterInputModal from './ParameterInputModal';
import { useRecipeManager } from '../hooks/useRecipeManager';
import { useIsMobile } from '../hooks/use-mobile';
import { useSidebar } from './ui/sidebar';
@@ -57,13 +56,7 @@ export default function Pair({
const [isTransitioningFromHub, setIsTransitioningFromHub] = useState(false);
// Get recipe configuration and parameter handling
const {
recipeConfig,
initialPrompt: recipeInitialPrompt,
isParameterModalOpen,
setIsParameterModalOpen,
handleParameterSubmit,
} = useRecipeManager(chat.messages, location.state);
const { initialPrompt: recipeInitialPrompt } = useRecipeManager(chat.messages, location.state);
// Handle recipe loading from recipes view - reset chat if needed
useEffect(() => {
@@ -196,15 +189,6 @@ export default function Pair({
showPopularTopics={!isTransitioningFromHub} // Don't show popular topics while transitioning from Hub
suppressEmptyState={isTransitioningFromHub} // Suppress all empty state content while transitioning from Hub
/>
{/* Recipe Parameter Modal */}
{isParameterModalOpen && recipeConfig?.parameters && (
<ParameterInputModal
parameters={recipeConfig.parameters}
onSubmit={handleParameterSubmit}
onClose={() => setIsParameterModalOpen(false)}
/>
)}
</>
);
}
@@ -256,7 +256,7 @@ export default function ModelsBottomBar({
<>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={handleViewRecipe}>
<span>View Recipe</span>
<span>View/Edit Recipe</span>
<Eye className="ml-auto h-4 w-4" />
</DropdownMenuItem>
<DropdownMenuItem onClick={handleSaveRecipeClick}>
+6 -8
View File
@@ -129,7 +129,9 @@ export const useRecipeManager = (messages: Message[], locationState?: LocationSt
// Get the recipe's initial prompt (always return the actual prompt, don't modify based on conversation state)
const initialPrompt = useMemo(() => {
if (!recipeConfig?.prompt || !recipeAccepted) return '';
if (!recipeConfig?.prompt || !recipeAccepted) {
return '';
}
const hasRequiredParams = recipeConfig.parameters && recipeConfig.parameters.length > 0;
@@ -138,13 +140,9 @@ export const useRecipeManager = (messages: Message[], locationState?: LocationSt
return substituteParameters(recipeConfig.prompt, recipeParameters);
}
// If there are no parameters, return the original prompt.
if (!hasRequiredParams) {
return recipeConfig.prompt;
}
// Otherwise, we are waiting for parameters, so the input should be empty.
return '';
// Always return the original prompt, whether it has parameters or not
// The user should see the prompt with parameter placeholders before filling them in
return recipeConfig.prompt;
}, [recipeConfig, recipeParameters, recipeAccepted]);
// Handle parameter submission