Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions ui/desktop/src/components/recipes/CreateEditRecipeModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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>(() => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's great! I was about suggesting this too! You are quick :)

return recipe?.extensions ?? undefined;
});

// Reset form when recipe changes
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions ui/desktop/src/components/recipes/RecipesView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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,
});
Expand Down Expand Up @@ -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"
Expand Down
8 changes: 8 additions & 0 deletions ui/desktop/src/recipe/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Loading