Fix: Recipe Extensions Not Loading in Desktop (#6777)

This commit is contained in:
Zane
2026-01-28 18:39:13 -08:00
committed by GitHub
parent 66e4a1a43c
commit c8b02e0cc6
4 changed files with 19 additions and 16 deletions
@@ -81,12 +81,8 @@ export default function CreateEditRecipeModal({
const [copied, setCopied] = useState(false);
const [isSaving, setIsSaving] = useState(false);
// Initialize selected extensions for the recipe
const [recipeExtensions] = useState<ExtensionConfig[]>(() => {
if (recipe?.extensions) {
return recipe.extensions;
}
return [];
const [recipeExtensions] = useState<ExtensionConfig[] | undefined>(() => {
return recipe?.extensions ?? undefined;
});
// Reset form when recipe changes
@@ -132,6 +128,10 @@ export default function CreateEditRecipeModal({
}
}
const extensions = recipeExtensions?.map((extension) =>
'envs' in extension ? { ...extension, envs: undefined } : extension
) as ExtensionConfig[] | undefined;
return {
...recipe,
title,
@@ -141,10 +141,7 @@ export default function CreateEditRecipeModal({
prompt: prompt || undefined,
parameters: formattedParameters,
response: responseConfig,
// Strip envs to avoid leaking secrets
extensions: recipeExtensions.map((extension) =>
'envs' in extension ? { ...extension, envs: undefined } : extension
) as ExtensionConfig[],
extensions,
};
}, [
recipe,
@@ -156,7 +156,6 @@ export default function CreateRecipeFromSessionModal({
setIsCreating(true);
try {
// Create the recipe object from form data
const recipe: Recipe = {
title: formData.title,
description: formData.description,
@@ -181,7 +180,6 @@ export default function CreateRecipeFromSessionModal({
json_schema: JSON.parse(formData.jsonSchema),
}
: undefined,
extensions: [], // Will be populated based on current extensions
};
let recipeId = await saveRecipe(recipe, null);
@@ -32,7 +32,7 @@ import {
} from '../../api';
import ImportRecipeForm, { ImportRecipeButton } from './ImportRecipeForm';
import CreateEditRecipeModal from './CreateEditRecipeModal';
import { generateDeepLink, Recipe } from '../../recipe';
import { generateDeepLink, Recipe, stripEmptyExtensions } from '../../recipe';
import { useNavigation } from '../../hooks/useNavigation';
import { CronPicker } from '../schedule/CronPicker';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '../ui/dialog';
@@ -138,12 +138,12 @@ export default function RecipesView() {
}
};
const handleStartRecipeChat = async (recipe: Recipe, _recipeId: string) => {
const handleStartRecipeChat = async (recipe: Recipe) => {
try {
const newAgent = await startAgent({
body: {
working_dir: getInitialWorkingDir(),
recipe,
recipe: stripEmptyExtensions(recipe) as Recipe,
},
throwOnError: true,
});
@@ -506,7 +506,7 @@ export default function RecipesView() {
<Button
onClick={(e) => {
e.stopPropagation();
handleStartRecipeChat(recipe, recipeManifestResponse.id);
handleStartRecipeChat(recipe);
}}
size="sm"
className="h-8 w-8 p-0"
+8
View File
@@ -76,3 +76,11 @@ export async function generateDeepLink(recipe: Recipe): Promise<string> {
const encoded = await encodeRecipe(recipe);
return `goose://recipe?config=${encoded}`;
}
export function stripEmptyExtensions(recipe: Recipe): Recipe {
if (Array.isArray(recipe.extensions) && recipe.extensions.length === 0) {
const { extensions: _, ...rest } = recipe;
return rest as Recipe;
}
return recipe;
}