mirror of
https://github.com/block/goose.git
synced 2026-07-17 12:56:20 +02:00
replace recipeConfig with recipe everywhere
This commit is contained in:
@@ -123,7 +123,7 @@ vi.mock('./contexts/ChatContext', () => ({
|
||||
title: 'Test Chat',
|
||||
messages: [],
|
||||
messageHistoryIndex: 0,
|
||||
recipeConfig: null,
|
||||
recipe: null,
|
||||
},
|
||||
setChat: vi.fn(),
|
||||
setPairChat: vi.fn(), // Keep this from HEAD
|
||||
|
||||
@@ -297,7 +297,7 @@ export function AppInner() {
|
||||
title: 'Pair Chat',
|
||||
messages: [],
|
||||
messageHistoryIndex: 0,
|
||||
recipeConfig: null,
|
||||
recipe: null,
|
||||
});
|
||||
|
||||
const { addExtension } = useConfig();
|
||||
|
||||
@@ -153,14 +153,14 @@ function BaseChatContent({
|
||||
},
|
||||
onMessageSent: () => {
|
||||
// Mark that user has started using the recipe
|
||||
if (recipeConfig) {
|
||||
if (recipe) {
|
||||
setHasStartedUsingRecipe(true);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Use recipe state - no complex heuristics
|
||||
const recipeState = useRecipeState(location.state?.recipeConfig || chat.recipeConfig);
|
||||
const recipeState = useRecipeState(location.state?.recipe || chat.recipe);
|
||||
|
||||
// Local UI state for modals
|
||||
const [isParameterModalOpen, setIsParameterModalOpen] = useState(false);
|
||||
@@ -168,7 +168,7 @@ function BaseChatContent({
|
||||
const [readyForAutoUserPrompt, setReadyForAutoUserPrompt] = useState(false);
|
||||
|
||||
// Computed values using the simple approach
|
||||
const recipeConfig = recipeState.recipe;
|
||||
const recipe = recipeState.recipe;
|
||||
const recipeParameters = chat.recipeParameters;
|
||||
const filteredParameters = recipeState.filteredParameters;
|
||||
const hasAllRequiredParameters = recipeState.hasAllRequiredParameters(recipeParameters || null);
|
||||
@@ -205,15 +205,15 @@ function BaseChatContent({
|
||||
isParameterModalOpen,
|
||||
messages.length,
|
||||
chat.sessionId,
|
||||
recipeConfig?.title,
|
||||
recipe?.title,
|
||||
]);
|
||||
|
||||
// Handle recipe warning modal display
|
||||
useEffect(() => {
|
||||
if (recipeConfig && !recipeAccepted && hasSecurityWarnings) {
|
||||
if (recipe && !recipeAccepted && hasSecurityWarnings) {
|
||||
setIsRecipeWarningModalOpen(true);
|
||||
}
|
||||
}, [recipeConfig, recipeAccepted, hasSecurityWarnings]);
|
||||
}, [recipe, recipeAccepted, hasSecurityWarnings]);
|
||||
|
||||
useEffect(() => {
|
||||
setReadyForAutoUserPrompt(true);
|
||||
@@ -229,11 +229,7 @@ function BaseChatContent({
|
||||
setIsParameterModalOpen(false);
|
||||
|
||||
try {
|
||||
await updateSystemPromptWithParameters(
|
||||
chat.sessionId,
|
||||
inputValues,
|
||||
recipeConfig || undefined
|
||||
);
|
||||
await updateSystemPromptWithParameters(chat.sessionId, inputValues, recipe || undefined);
|
||||
// Update session user recipe values via API
|
||||
await updateSessionUserRecipeValues({
|
||||
path: { session_id: chat.sessionId },
|
||||
@@ -257,8 +253,8 @@ function BaseChatContent({
|
||||
const handleAutoExecution = React.useCallback(
|
||||
(append: (message: Message) => void, isLoading: boolean, onAutoExecute?: () => void) => {
|
||||
if (
|
||||
recipeConfig?.isScheduledExecution &&
|
||||
recipeConfig?.prompt &&
|
||||
recipe?.isScheduledExecution &&
|
||||
recipe?.prompt &&
|
||||
(!recipeState.requiresParameters || recipeParameters) &&
|
||||
messages.length === 0 &&
|
||||
!isLoading &&
|
||||
@@ -266,8 +262,8 @@ function BaseChatContent({
|
||||
recipeAccepted
|
||||
) {
|
||||
const finalPrompt = recipeParameters
|
||||
? substituteParameters(recipeConfig.prompt, recipeParameters)
|
||||
: recipeConfig.prompt;
|
||||
? substituteParameters(recipe.prompt, recipeParameters)
|
||||
: recipe.prompt;
|
||||
|
||||
const userMessage = createUserMessage(finalPrompt);
|
||||
append(userMessage);
|
||||
@@ -275,8 +271,8 @@ function BaseChatContent({
|
||||
}
|
||||
},
|
||||
[
|
||||
recipeConfig?.isScheduledExecution,
|
||||
recipeConfig?.prompt,
|
||||
recipe?.isScheduledExecution,
|
||||
recipe?.prompt,
|
||||
recipeState.requiresParameters,
|
||||
recipeParameters,
|
||||
messages.length,
|
||||
@@ -294,7 +290,7 @@ function BaseChatContent({
|
||||
setChat({
|
||||
...chat,
|
||||
messages: [],
|
||||
recipeConfig: recipe,
|
||||
recipe: recipe,
|
||||
recipeParameters: null,
|
||||
});
|
||||
};
|
||||
@@ -302,7 +298,7 @@ function BaseChatContent({
|
||||
// Reset recipe usage tracking when recipe changes
|
||||
useEffect(() => {
|
||||
const previousTitle = currentRecipeTitle;
|
||||
const newTitle = recipeConfig?.title || null;
|
||||
const newTitle = recipe?.title || null;
|
||||
const hasRecipeChanged = newTitle !== currentRecipeTitle;
|
||||
|
||||
if (hasRecipeChanged) {
|
||||
@@ -320,7 +316,7 @@ function BaseChatContent({
|
||||
setHasStartedUsingRecipe(true);
|
||||
}
|
||||
}
|
||||
}, [recipeConfig?.title, currentRecipeTitle, messages.length]);
|
||||
}, [recipe?.title, currentRecipeTitle, messages.length]);
|
||||
|
||||
// Handle recipe auto-execution
|
||||
useEffect(() => {
|
||||
@@ -374,7 +370,7 @@ function BaseChatContent({
|
||||
const combinedTextFromInput = customEvent.detail?.value || '';
|
||||
|
||||
// Mark that user has started using the recipe when they submit a message
|
||||
if (recipeConfig && combinedTextFromInput.trim()) {
|
||||
if (recipe && combinedTextFromInput.trim()) {
|
||||
setHasStartedUsingRecipe(true);
|
||||
}
|
||||
|
||||
@@ -391,7 +387,7 @@ function BaseChatContent({
|
||||
// Wrapper for append that tracks recipe usage
|
||||
const appendWithTracking = (text: string | Message) => {
|
||||
// Mark that user has started using the recipe when they use append
|
||||
if (recipeConfig) {
|
||||
if (recipe) {
|
||||
setHasStartedUsingRecipe(true);
|
||||
}
|
||||
append(text);
|
||||
@@ -435,14 +431,12 @@ function BaseChatContent({
|
||||
paddingY={0}
|
||||
>
|
||||
{/* Recipe agent header - sticky at top of chat container */}
|
||||
{recipeConfig?.title && (
|
||||
{recipe?.title && (
|
||||
<div className="sticky top-0 z-10 bg-background-default px-0 -mx-6 mb-6 pt-6">
|
||||
<AgentHeader
|
||||
title={recipeConfig.title}
|
||||
title={recipe.title}
|
||||
profileInfo={
|
||||
recipeConfig.profile
|
||||
? `${recipeConfig.profile} - ${recipeConfig.mcps || 12} MCPs`
|
||||
: undefined
|
||||
recipe.profile ? `${recipe.profile} - ${recipe.mcps || 12} MCPs` : undefined
|
||||
}
|
||||
onChangeProfile={() => {
|
||||
console.log('Change profile clicked');
|
||||
@@ -456,14 +450,12 @@ function BaseChatContent({
|
||||
{renderBeforeMessages && renderBeforeMessages()}
|
||||
|
||||
{/* Recipe Activities - always show when recipe is active and accepted */}
|
||||
{recipeConfig && recipeAccepted && !suppressEmptyState && (
|
||||
{recipe && recipeAccepted && !suppressEmptyState && (
|
||||
<div className={hasStartedUsingRecipe ? 'mb-6' : ''}>
|
||||
<RecipeActivities
|
||||
append={(text: string) => appendWithTracking(text)}
|
||||
activities={
|
||||
Array.isArray(recipeConfig.activities) ? recipeConfig.activities : null
|
||||
}
|
||||
title={recipeConfig.title}
|
||||
activities={Array.isArray(recipe.activities) ? recipe.activities : null}
|
||||
title={recipe.title}
|
||||
parameterValues={recipeParameters || {}}
|
||||
/>
|
||||
</div>
|
||||
@@ -555,7 +547,7 @@ function BaseChatContent({
|
||||
|
||||
<div className="block h-8" />
|
||||
</>
|
||||
) : !recipeConfig && showPopularTopics ? (
|
||||
) : !recipe && showPopularTopics ? (
|
||||
/* Show PopularChatTopics when no messages, no recipe, and showPopularTopics is true (Pair view) */
|
||||
<PopularChatTopics append={(text: string) => append(text)} />
|
||||
) : null /* Show nothing when messages.length === 0 && suppressEmptyState === true */
|
||||
@@ -603,7 +595,7 @@ function BaseChatContent({
|
||||
disableAnimation={disableAnimation}
|
||||
sessionCosts={sessionCosts}
|
||||
setIsGoosehintsModalOpen={setIsGoosehintsModalOpen}
|
||||
recipeConfig={recipeConfig}
|
||||
recipe={recipe}
|
||||
recipeAccepted={recipeAccepted}
|
||||
initialPrompt={initialPrompt}
|
||||
toolCount={toolCount || 0}
|
||||
@@ -620,9 +612,9 @@ function BaseChatContent({
|
||||
onConfirm={handleRecipeAccept}
|
||||
onCancel={() => handleRecipeCancel()}
|
||||
recipeDetails={{
|
||||
title: recipeConfig?.title,
|
||||
description: recipeConfig?.description,
|
||||
instructions: recipeConfig?.instructions || undefined,
|
||||
title: recipe?.title,
|
||||
description: recipe?.description,
|
||||
instructions: recipe?.instructions || undefined,
|
||||
}}
|
||||
hasSecurityWarnings={hasSecurityWarnings}
|
||||
/>
|
||||
|
||||
@@ -81,7 +81,7 @@ interface ChatInputProps {
|
||||
};
|
||||
setIsGoosehintsModalOpen?: (isOpen: boolean) => void;
|
||||
disableAnimation?: boolean;
|
||||
recipeConfig?: Recipe | null;
|
||||
recipe?: Recipe | null;
|
||||
recipeAccepted?: boolean;
|
||||
initialPrompt?: string;
|
||||
toolCount: number;
|
||||
@@ -108,7 +108,7 @@ export default function ChatInput({
|
||||
disableAnimation = false,
|
||||
sessionCosts,
|
||||
setIsGoosehintsModalOpen,
|
||||
recipeConfig,
|
||||
recipe,
|
||||
recipeAccepted,
|
||||
initialPrompt,
|
||||
toolCount,
|
||||
@@ -318,7 +318,7 @@ export default function ChatInput({
|
||||
|
||||
useEffect(() => {
|
||||
// Only load draft once and if conditions are met
|
||||
if (!initialValue && !recipeConfig && !draftLoadedRef.current && chatContext) {
|
||||
if (!initialValue && !recipe && !draftLoadedRef.current && chatContext) {
|
||||
const draftText = chatContext.draft || '';
|
||||
|
||||
if (draftText) {
|
||||
@@ -329,7 +329,7 @@ export default function ChatInput({
|
||||
// Always mark as loaded after checking, regardless of whether we found a draft
|
||||
draftLoadedRef.current = true;
|
||||
}
|
||||
}, [chatContext, initialValue, recipeConfig]);
|
||||
}, [chatContext, initialValue, recipe]);
|
||||
|
||||
// Save draft when user types (debounced)
|
||||
const debouncedSaveDraft = useMemo(
|
||||
@@ -1624,7 +1624,7 @@ export default function ChatInput({
|
||||
dropdownRef={dropdownRef}
|
||||
setView={setView}
|
||||
alerts={alerts}
|
||||
recipeConfig={recipeConfig}
|
||||
recipe={recipe}
|
||||
hasMessages={messages.length > 0}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -76,13 +76,13 @@ export default function Pair({
|
||||
// Load a fresh chat session with new recipe reset behavior
|
||||
const newChat = await loadCurrentChat({
|
||||
resumeSessionId: undefined,
|
||||
recipeConfig: recipe,
|
||||
recipe: recipe,
|
||||
setAgentWaitingMessage,
|
||||
resetOptions: {
|
||||
resetSession: true,
|
||||
clearMessages: true,
|
||||
clearRecipeParameters: true,
|
||||
// Keep the new recipe from recipeConfig
|
||||
// Keep the new recipe from recipe
|
||||
},
|
||||
});
|
||||
|
||||
@@ -116,13 +116,13 @@ export default function Pair({
|
||||
// BUT only if we're resuming the same session (not starting a new chat)
|
||||
let finalChat = loadedChat;
|
||||
if (
|
||||
!loadedChat.recipeConfig &&
|
||||
currentChat?.recipeConfig &&
|
||||
!loadedChat.recipe &&
|
||||
currentChat?.recipe &&
|
||||
resumeSessionId === currentChat.sessionId
|
||||
) {
|
||||
finalChat = {
|
||||
...loadedChat,
|
||||
recipeConfig: currentChat.recipeConfig,
|
||||
recipe: currentChat.recipe,
|
||||
recipeParameters: currentChat.recipeParameters || null,
|
||||
};
|
||||
}
|
||||
@@ -171,7 +171,7 @@ export default function Pair({
|
||||
|
||||
const { initialPrompt: recipeInitialPrompt } = useRecipeManager(
|
||||
chat,
|
||||
recipe || chat.recipeConfig || null
|
||||
recipe || chat.recipe || null
|
||||
);
|
||||
|
||||
const handleMessageSubmit = () => {
|
||||
|
||||
@@ -28,7 +28,7 @@ export default function CreateEditRecipeModal({
|
||||
isCreateMode = false,
|
||||
}: CreateEditRecipeModalProps) {
|
||||
const { getExtensions } = useConfig();
|
||||
const [recipeConfig] = useState<Recipe | undefined>(config);
|
||||
const [recipe] = useState<Recipe | undefined>(config);
|
||||
|
||||
const getInitialValues = React.useCallback((): RecipeFormData => {
|
||||
if (config) {
|
||||
@@ -171,7 +171,7 @@ export default function CreateEditRecipeModal({
|
||||
}
|
||||
|
||||
return {
|
||||
...recipeConfig,
|
||||
...recipe,
|
||||
title,
|
||||
description,
|
||||
instructions,
|
||||
@@ -197,7 +197,7 @@ export default function CreateEditRecipeModal({
|
||||
.filter(Boolean) as ExtensionConfig[],
|
||||
};
|
||||
}, [
|
||||
recipeConfig,
|
||||
recipe,
|
||||
title,
|
||||
description,
|
||||
instructions,
|
||||
|
||||
@@ -25,7 +25,7 @@ interface ModelsBottomBarProps {
|
||||
dropdownRef: React.RefObject<HTMLDivElement>;
|
||||
setView: (view: View) => void;
|
||||
alerts: Alert[];
|
||||
recipeConfig?: Recipe | null;
|
||||
recipe?: Recipe | null;
|
||||
hasMessages?: boolean; // Add prop to know if there are messages to create a recipe from
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ export default function ModelsBottomBar({
|
||||
dropdownRef,
|
||||
setView,
|
||||
alerts,
|
||||
recipeConfig,
|
||||
recipe,
|
||||
hasMessages = false,
|
||||
}: ModelsBottomBarProps) {
|
||||
const {
|
||||
@@ -168,14 +168,14 @@ export default function ModelsBottomBar({
|
||||
|
||||
// Handle view recipe - open modal instead of navigating
|
||||
const handleViewRecipe = () => {
|
||||
if (recipeConfig) {
|
||||
if (recipe) {
|
||||
setShowViewRecipeModal(true);
|
||||
}
|
||||
};
|
||||
|
||||
// Handle save recipe - show save dialog
|
||||
const handleSaveRecipeClick = () => {
|
||||
if (recipeConfig) {
|
||||
if (recipe) {
|
||||
setShowSaveDialog(true);
|
||||
}
|
||||
};
|
||||
@@ -211,7 +211,7 @@ export default function ModelsBottomBar({
|
||||
</DropdownMenuItem>
|
||||
|
||||
{/* Recipe-specific menu items - only show when actively using a recipe */}
|
||||
{recipeConfig && (
|
||||
{recipe && (
|
||||
<>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem onClick={handleViewRecipe}>
|
||||
@@ -226,7 +226,7 @@ export default function ModelsBottomBar({
|
||||
)}
|
||||
|
||||
{/* Only show "Create a recipe from this session" when there are messages AND no recipe is currently active */}
|
||||
{hasMessages && !recipeConfig && (
|
||||
{hasMessages && !recipe && (
|
||||
<>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem
|
||||
@@ -256,20 +256,20 @@ export default function ModelsBottomBar({
|
||||
) : null}
|
||||
|
||||
{/* Save Recipe Dialog */}
|
||||
{showSaveDialog && recipeConfig && (
|
||||
{showSaveDialog && recipe && (
|
||||
<SaveRecipeDialog
|
||||
isOpen={showSaveDialog}
|
||||
onClose={() => setShowSaveDialog(false)}
|
||||
recipe={recipeConfig}
|
||||
recipe={recipe}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* View Recipe Modal */}
|
||||
{recipeConfig && (
|
||||
{recipe && (
|
||||
<CreateEditRecipeModal
|
||||
isOpen={showViewRecipeModal}
|
||||
onClose={() => setShowViewRecipeModal(false)}
|
||||
config={recipeConfig}
|
||||
config={recipe}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -58,7 +58,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
||||
title: DEFAULT_CHAT_TITLE,
|
||||
messages: [],
|
||||
messageHistoryIndex: 0,
|
||||
recipeConfig: null,
|
||||
recipe: null,
|
||||
recipeParameters: null,
|
||||
});
|
||||
clearDraft();
|
||||
@@ -67,7 +67,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
||||
const setRecipeConfig = (recipe: Recipe | null) => {
|
||||
setChat({
|
||||
...chat,
|
||||
recipeConfig: recipe,
|
||||
recipe: recipe,
|
||||
recipeParameters: null,
|
||||
});
|
||||
};
|
||||
@@ -75,7 +75,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
||||
const clearRecipeConfig = () => {
|
||||
setChat({
|
||||
...chat,
|
||||
recipeConfig: null,
|
||||
recipe: null,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ export function useAgentInitialization(): UseAgentInitializationReturn {
|
||||
: await startAgent({
|
||||
body: {
|
||||
working_dir: window.appConfig.get('GOOSE_WORKING_DIR') as string,
|
||||
recipe: recipeFromAppConfig ?? initContext.recipeConfig,
|
||||
recipe: recipeFromAppConfig ?? initContext.recipe,
|
||||
},
|
||||
throwOnError: true,
|
||||
});
|
||||
@@ -116,13 +116,13 @@ export function useAgentInitialization(): UseAgentInitializationReturn {
|
||||
// Initialize system and extensions with error boundary
|
||||
initContext.setAgentWaitingMessage('Extensions are loading');
|
||||
try {
|
||||
const recipeConfigForInit = initContext.recipeConfig || agentSession.recipe || undefined;
|
||||
const recipeForInit = initContext.recipe || agentSession.recipe || undefined;
|
||||
await initializeSystem(agentSession.id, provider as string, model as string, {
|
||||
getExtensions,
|
||||
addExtension,
|
||||
setIsExtensionsLoading: initContext.setIsExtensionsLoading,
|
||||
recipeParameters: agentSession.user_recipe_values,
|
||||
recipeConfig: recipeConfigForInit,
|
||||
recipe: recipeForInit,
|
||||
});
|
||||
} catch (error) {
|
||||
throw new AgentInitializationError(
|
||||
@@ -150,9 +150,9 @@ export function useAgentInitialization(): UseAgentInitializationReturn {
|
||||
messages = [];
|
||||
}
|
||||
|
||||
let recipeConfig = agentSession.recipe;
|
||||
let recipe = agentSession.recipe;
|
||||
if (resetOptions.clearRecipe) {
|
||||
recipeConfig = null;
|
||||
recipe = null;
|
||||
}
|
||||
|
||||
let recipeParameters = agentSession.user_recipe_values || null;
|
||||
@@ -162,10 +162,10 @@ export function useAgentInitialization(): UseAgentInitializationReturn {
|
||||
|
||||
const initChat: ChatType = {
|
||||
sessionId: agentSession.id,
|
||||
title: recipeConfig?.title || agentSession.description || 'New Session',
|
||||
title: recipe?.title || agentSession.description || 'New Session',
|
||||
messageHistoryIndex: 0,
|
||||
messages: messages,
|
||||
recipeConfig: recipeConfig,
|
||||
recipe: recipe,
|
||||
recipeParameters: recipeParameters,
|
||||
};
|
||||
|
||||
@@ -217,7 +217,7 @@ export function useAgentInitialization(): UseAgentInitializationReturn {
|
||||
title: agentSession.recipe?.title || agentSession.description,
|
||||
messageHistoryIndex: 0,
|
||||
messages: messages?.map(convertApiMessageToFrontendMessage),
|
||||
recipeConfig: agentSession.recipe,
|
||||
recipe: agentSession.recipe,
|
||||
recipeParameters: agentSession.user_recipe_values || null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -94,10 +94,10 @@ export const useChatEngine = ({
|
||||
body: {
|
||||
session_id: chat.sessionId,
|
||||
session_working_dir: window.appConfig.get('GOOSE_WORKING_DIR'),
|
||||
...(chat.recipeConfig?.title
|
||||
...(chat.recipe?.title
|
||||
? {
|
||||
recipe_name: chat.recipeConfig.title,
|
||||
recipe_version: chat.recipeConfig?.version ?? 'unknown',
|
||||
recipe_name: chat.recipe.title,
|
||||
recipe_version: chat.recipe?.version ?? 'unknown',
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useRecipeUI } from './useRecipeUI';
|
||||
* This is a transitional hook - long term plan is to eliminate it entirely
|
||||
* and use useRecipeState and useRecipeUI directly in components
|
||||
*/
|
||||
export const useRecipeManager = (chat: ChatType, recipeConfig?: Recipe | null) => {
|
||||
export const useRecipeManager = (chat: ChatType, recipe?: Recipe | null) => {
|
||||
const messagesRef = useRef(chat.messages);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -17,7 +17,7 @@ export const useRecipeManager = (chat: ChatType, recipeConfig?: Recipe | null) =
|
||||
}, [chat.messages]);
|
||||
|
||||
// Core recipe state and business logic
|
||||
const recipeState = useRecipeState(recipeConfig || chat.recipeConfig || null);
|
||||
const recipeState = useRecipeState(recipe || chat.recipe || null);
|
||||
|
||||
// UI-specific recipe interactions
|
||||
const recipeUI = useRecipeUI(
|
||||
@@ -43,7 +43,7 @@ export const useRecipeManager = (chat: ChatType, recipeConfig?: Recipe | null) =
|
||||
|
||||
return {
|
||||
// State from useRecipeState
|
||||
recipeConfig: recipeState.recipe,
|
||||
recipe: recipeState.recipe,
|
||||
recipeParameters: chat.recipeParameters,
|
||||
filteredParameters: recipeState.filteredParameters,
|
||||
initialPrompt: recipeState.getInitialPrompt(chat.recipeParameters || null),
|
||||
|
||||
@@ -111,8 +111,8 @@ type ElectronAPI = {
|
||||
getUpdateState: () => Promise<{ updateAvailable: boolean; latestVersion?: string } | null>;
|
||||
// Recipe warning functions
|
||||
closeWindow: () => void;
|
||||
hasAcceptedRecipeBefore: (recipeConfig: Recipe) => Promise<boolean>;
|
||||
recordRecipeHash: (recipeConfig: Recipe) => Promise<boolean>;
|
||||
hasAcceptedRecipeBefore: (recipe: Recipe) => Promise<boolean>;
|
||||
recordRecipeHash: (recipe: Recipe) => Promise<boolean>;
|
||||
openDirectoryInExplorer: (directoryPath: string) => Promise<boolean>;
|
||||
};
|
||||
|
||||
@@ -232,10 +232,9 @@ const electronAPI: ElectronAPI = {
|
||||
return ipcRenderer.invoke('get-update-state');
|
||||
},
|
||||
closeWindow: () => ipcRenderer.send('close-window'),
|
||||
hasAcceptedRecipeBefore: (recipeConfig: Recipe) =>
|
||||
ipcRenderer.invoke('has-accepted-recipe-before', recipeConfig),
|
||||
recordRecipeHash: (recipeConfig: Recipe) =>
|
||||
ipcRenderer.invoke('record-recipe-hash', recipeConfig),
|
||||
hasAcceptedRecipeBefore: (recipe: Recipe) =>
|
||||
ipcRenderer.invoke('has-accepted-recipe-before', recipe),
|
||||
recordRecipeHash: (recipe: Recipe) => ipcRenderer.invoke('record-recipe-hash', recipe),
|
||||
openDirectoryInExplorer: (directoryPath: string) =>
|
||||
ipcRenderer.invoke('open-directory-in-explorer', directoryPath),
|
||||
};
|
||||
|
||||
@@ -30,7 +30,7 @@ export interface ResetOptions {
|
||||
*/
|
||||
export interface InitializationContext {
|
||||
/** Recipe configuration to initialize with */
|
||||
recipeConfig?: Recipe;
|
||||
recipe?: Recipe;
|
||||
/** Session ID to resume from */
|
||||
resumeSessionId?: string;
|
||||
/** Callback to set waiting message during initialization */
|
||||
|
||||
@@ -6,6 +6,6 @@ export interface ChatType {
|
||||
title: string;
|
||||
messageHistoryIndex: number;
|
||||
messages: Message[];
|
||||
recipeConfig?: Recipe | null; // Add recipe configuration to chat state
|
||||
recipe?: Recipe | null; // Add recipe configuration to chat state
|
||||
recipeParameters?: Record<string, string> | null; // Add recipe parameters to chat state
|
||||
}
|
||||
|
||||
@@ -150,15 +150,15 @@ export const substituteParameters = (text: string, params: Record<string, string
|
||||
export const updateSystemPromptWithParameters = async (
|
||||
sessionId: string,
|
||||
recipeParameters: Record<string, string>,
|
||||
recipeConfig?: {
|
||||
recipe?: {
|
||||
instructions?: string | null;
|
||||
sub_recipes?: SubRecipe[] | null;
|
||||
parameters?: RecipeParameter[] | null;
|
||||
}
|
||||
): Promise<void> => {
|
||||
const subRecipes = recipeConfig?.sub_recipes;
|
||||
const subRecipes = recipe?.sub_recipes;
|
||||
try {
|
||||
const originalInstructions = recipeConfig?.instructions;
|
||||
const originalInstructions = recipe?.instructions;
|
||||
|
||||
if (!originalInstructions) {
|
||||
return;
|
||||
@@ -200,7 +200,7 @@ export const initializeSystem = async (
|
||||
addExtension?: (name: string, config: ExtensionConfig, enabled: boolean) => Promise<void>;
|
||||
setIsExtensionsLoading?: (loading: boolean) => void;
|
||||
recipeParameters?: Record<string, string> | null;
|
||||
recipeConfig?: Recipe;
|
||||
recipe?: Recipe;
|
||||
}
|
||||
) => {
|
||||
try {
|
||||
@@ -225,11 +225,11 @@ export const initializeSystem = async (
|
||||
console.log('This will not end well');
|
||||
}
|
||||
|
||||
// Get recipeConfig - prefer from options (session metadata) over app config
|
||||
const recipeConfig = options?.recipeConfig || window.appConfig?.get?.('recipe');
|
||||
const recipe_instructions = (recipeConfig as { instructions?: string })?.instructions;
|
||||
const responseConfig = (recipeConfig as { response?: { json_schema?: unknown } })?.response;
|
||||
const subRecipes = (recipeConfig as { sub_recipes?: SubRecipe[] })?.sub_recipes;
|
||||
// Get recipe - prefer from options (session metadata) over app config
|
||||
const recipe = options?.recipe || window.appConfig?.get?.('recipe');
|
||||
const recipe_instructions = (recipe as { instructions?: string })?.instructions;
|
||||
const responseConfig = (recipe as { response?: { json_schema?: unknown } })?.response;
|
||||
const subRecipes = (recipe as { sub_recipes?: SubRecipe[] })?.sub_recipes;
|
||||
const hasSubRecipes = subRecipes && subRecipes?.length > 0;
|
||||
const recipeParameters = options?.recipeParameters;
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import crypto from 'crypto';
|
||||
|
||||
function calculateRecipeHash(recipeConfig: unknown): string {
|
||||
function calculateRecipeHash(recipe: unknown): string {
|
||||
const hash = crypto.createHash('sha256');
|
||||
hash.update(JSON.stringify(recipeConfig));
|
||||
hash.update(JSON.stringify(recipe));
|
||||
return hash.digest('hex');
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ async function getRecipeHashesDir(): Promise<string> {
|
||||
return hashesDir;
|
||||
}
|
||||
|
||||
ipcMain.handle('has-accepted-recipe-before', async (_event, recipeConfig) => {
|
||||
const hash = calculateRecipeHash(recipeConfig);
|
||||
ipcMain.handle('has-accepted-recipe-before', async (_event, recipe) => {
|
||||
const hash = calculateRecipeHash(recipe);
|
||||
const hashFile = path.join(await getRecipeHashesDir(), `${hash}.hash`);
|
||||
try {
|
||||
await fs.access(hashFile);
|
||||
@@ -30,8 +30,8 @@ ipcMain.handle('has-accepted-recipe-before', async (_event, recipeConfig) => {
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('record-recipe-hash', async (_event, recipeConfig) => {
|
||||
const hash = calculateRecipeHash(recipeConfig);
|
||||
ipcMain.handle('record-recipe-hash', async (_event, recipe) => {
|
||||
const hash = calculateRecipeHash(recipe);
|
||||
const filePath = path.join(await getRecipeHashesDir(), `${hash}.hash`);
|
||||
const timestamp = new Date().toISOString();
|
||||
await fs.writeFile(filePath, timestamp);
|
||||
|
||||
Reference in New Issue
Block a user