diff --git a/ui/desktop/src/App.test.tsx b/ui/desktop/src/App.test.tsx
index ecc30beed8..d882de7bdd 100644
--- a/ui/desktop/src/App.test.tsx
+++ b/ui/desktop/src/App.test.tsx
@@ -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
diff --git a/ui/desktop/src/App.tsx b/ui/desktop/src/App.tsx
index 90e2b17804..1db019e694 100644
--- a/ui/desktop/src/App.tsx
+++ b/ui/desktop/src/App.tsx
@@ -297,7 +297,7 @@ export function AppInner() {
title: 'Pair Chat',
messages: [],
messageHistoryIndex: 0,
- recipeConfig: null,
+ recipe: null,
});
const { addExtension } = useConfig();
diff --git a/ui/desktop/src/components/BaseChat.tsx b/ui/desktop/src/components/BaseChat.tsx
index 2fbc879f71..59152c0b68 100644
--- a/ui/desktop/src/components/BaseChat.tsx
+++ b/ui/desktop/src/components/BaseChat.tsx
@@ -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 && (
{
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 && (
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 || {}}
/>
@@ -555,7 +547,7 @@ function BaseChatContent({
>
- ) : !recipeConfig && showPopularTopics ? (
+ ) : !recipe && showPopularTopics ? (
/* Show PopularChatTopics when no messages, no recipe, and showPopularTopics is true (Pair view) */
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}
/>
diff --git a/ui/desktop/src/components/ChatInput.tsx b/ui/desktop/src/components/ChatInput.tsx
index 2ed48b1d09..9d2d34722a 100644
--- a/ui/desktop/src/components/ChatInput.tsx
+++ b/ui/desktop/src/components/ChatInput.tsx
@@ -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}
/>
diff --git a/ui/desktop/src/components/pair.tsx b/ui/desktop/src/components/pair.tsx
index f1880e6dd9..6b60ae8e9d 100644
--- a/ui/desktop/src/components/pair.tsx
+++ b/ui/desktop/src/components/pair.tsx
@@ -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 = () => {
diff --git a/ui/desktop/src/components/recipes/CreateEditRecipeModal.tsx b/ui/desktop/src/components/recipes/CreateEditRecipeModal.tsx
index 356ed3a51b..e84e34a85e 100644
--- a/ui/desktop/src/components/recipes/CreateEditRecipeModal.tsx
+++ b/ui/desktop/src/components/recipes/CreateEditRecipeModal.tsx
@@ -28,7 +28,7 @@ export default function CreateEditRecipeModal({
isCreateMode = false,
}: CreateEditRecipeModalProps) {
const { getExtensions } = useConfig();
- const [recipeConfig] = useState(config);
+ const [recipe] = useState(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,
diff --git a/ui/desktop/src/components/settings/models/bottom_bar/ModelsBottomBar.tsx b/ui/desktop/src/components/settings/models/bottom_bar/ModelsBottomBar.tsx
index c44d6c6856..e058a2610b 100644
--- a/ui/desktop/src/components/settings/models/bottom_bar/ModelsBottomBar.tsx
+++ b/ui/desktop/src/components/settings/models/bottom_bar/ModelsBottomBar.tsx
@@ -25,7 +25,7 @@ interface ModelsBottomBarProps {
dropdownRef: React.RefObject;
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({
{/* Recipe-specific menu items - only show when actively using a recipe */}
- {recipeConfig && (
+ {recipe && (
<>
@@ -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 && (
<>
setShowSaveDialog(false)}
- recipe={recipeConfig}
+ recipe={recipe}
/>
)}
{/* View Recipe Modal */}
- {recipeConfig && (
+ {recipe && (
setShowViewRecipeModal(false)}
- config={recipeConfig}
+ config={recipe}
/>
)}
diff --git a/ui/desktop/src/contexts/ChatContext.tsx b/ui/desktop/src/contexts/ChatContext.tsx
index 0c7b672ee5..1bf71d3690 100644
--- a/ui/desktop/src/contexts/ChatContext.tsx
+++ b/ui/desktop/src/contexts/ChatContext.tsx
@@ -58,7 +58,7 @@ export const ChatProvider: React.FC = ({
title: DEFAULT_CHAT_TITLE,
messages: [],
messageHistoryIndex: 0,
- recipeConfig: null,
+ recipe: null,
recipeParameters: null,
});
clearDraft();
@@ -67,7 +67,7 @@ export const ChatProvider: React.FC = ({
const setRecipeConfig = (recipe: Recipe | null) => {
setChat({
...chat,
- recipeConfig: recipe,
+ recipe: recipe,
recipeParameters: null,
});
};
@@ -75,7 +75,7 @@ export const ChatProvider: React.FC = ({
const clearRecipeConfig = () => {
setChat({
...chat,
- recipeConfig: null,
+ recipe: null,
});
};
diff --git a/ui/desktop/src/hooks/useAgentInitialization.ts b/ui/desktop/src/hooks/useAgentInitialization.ts
index 526216072b..ed85ac64b2 100644
--- a/ui/desktop/src/hooks/useAgentInitialization.ts
+++ b/ui/desktop/src/hooks/useAgentInitialization.ts
@@ -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,
};
}
diff --git a/ui/desktop/src/hooks/useChatEngine.ts b/ui/desktop/src/hooks/useChatEngine.ts
index 6ef2e064c9..f0dd7fc381 100644
--- a/ui/desktop/src/hooks/useChatEngine.ts
+++ b/ui/desktop/src/hooks/useChatEngine.ts
@@ -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',
}
: {}),
},
diff --git a/ui/desktop/src/hooks/useRecipeManager.ts b/ui/desktop/src/hooks/useRecipeManager.ts
index d179858ba8..9d57c8f812 100644
--- a/ui/desktop/src/hooks/useRecipeManager.ts
+++ b/ui/desktop/src/hooks/useRecipeManager.ts
@@ -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),
diff --git a/ui/desktop/src/preload.ts b/ui/desktop/src/preload.ts
index 50fceda329..a577df3083 100644
--- a/ui/desktop/src/preload.ts
+++ b/ui/desktop/src/preload.ts
@@ -111,8 +111,8 @@ type ElectronAPI = {
getUpdateState: () => Promise<{ updateAvailable: boolean; latestVersion?: string } | null>;
// Recipe warning functions
closeWindow: () => void;
- hasAcceptedRecipeBefore: (recipeConfig: Recipe) => Promise;
- recordRecipeHash: (recipeConfig: Recipe) => Promise;
+ hasAcceptedRecipeBefore: (recipe: Recipe) => Promise;
+ recordRecipeHash: (recipe: Recipe) => Promise;
openDirectoryInExplorer: (directoryPath: string) => Promise;
};
@@ -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),
};
diff --git a/ui/desktop/src/types/agent.ts b/ui/desktop/src/types/agent.ts
index 94ad2f01e8..78ecea4328 100644
--- a/ui/desktop/src/types/agent.ts
+++ b/ui/desktop/src/types/agent.ts
@@ -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 */
diff --git a/ui/desktop/src/types/chat.ts b/ui/desktop/src/types/chat.ts
index c8a744a219..006e943ffb 100644
--- a/ui/desktop/src/types/chat.ts
+++ b/ui/desktop/src/types/chat.ts
@@ -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 | null; // Add recipe parameters to chat state
}
diff --git a/ui/desktop/src/utils/providerUtils.ts b/ui/desktop/src/utils/providerUtils.ts
index 86a49fbd7e..b05c77a130 100644
--- a/ui/desktop/src/utils/providerUtils.ts
+++ b/ui/desktop/src/utils/providerUtils.ts
@@ -150,15 +150,15 @@ export const substituteParameters = (text: string, params: Record,
- recipeConfig?: {
+ recipe?: {
instructions?: string | null;
sub_recipes?: SubRecipe[] | null;
parameters?: RecipeParameter[] | null;
}
): Promise => {
- 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;
setIsExtensionsLoading?: (loading: boolean) => void;
recipeParameters?: Record | 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;
diff --git a/ui/desktop/src/utils/recipeHash.ts b/ui/desktop/src/utils/recipeHash.ts
index c0b0e64561..ceafa204c1 100644
--- a/ui/desktop/src/utils/recipeHash.ts
+++ b/ui/desktop/src/utils/recipeHash.ts
@@ -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 {
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);