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