diff --git a/crates/goose-server/src/routes/config_management.rs b/crates/goose-server/src/routes/config_management.rs
index a0caa8b3..1f45333f 100644
--- a/crates/goose-server/src/routes/config_management.rs
+++ b/crates/goose-server/src/routes/config_management.rs
@@ -123,7 +123,14 @@ pub async fn remove_config(
let config = Config::global();
- match config.delete(&query.key) {
+ // Check if the secret flag is true and call the appropriate method
+ let result = if query.is_secret {
+ config.delete_secret(&query.key)
+ } else {
+ config.delete(&query.key)
+ };
+
+ match result {
Ok(_) => Ok(Json(format!("Removed key {}", query.key))),
Err(_) => Err(StatusCode::NOT_FOUND),
}
diff --git a/ui/desktop/src/components/settings_v2/models/modelInterface.ts b/ui/desktop/src/components/settings_v2/models/modelInterface.ts
index d82017f0..4a397647 100644
--- a/ui/desktop/src/components/settings_v2/models/modelInterface.ts
+++ b/ui/desktop/src/components/settings_v2/models/modelInterface.ts
@@ -37,5 +37,5 @@ export async function getProviderMetadata(
if (!matches) {
throw Error(`No match for provider: ${providerName}`);
}
- return matches[0].metadata;
+ return matches.metadata;
}
diff --git a/ui/desktop/src/components/settings_v2/providers/ProviderGrid.tsx b/ui/desktop/src/components/settings_v2/providers/ProviderGrid.tsx
index b2b93548..9537ef0d 100644
--- a/ui/desktop/src/components/settings_v2/providers/ProviderGrid.tsx
+++ b/ui/desktop/src/components/settings_v2/providers/ProviderGrid.tsx
@@ -42,6 +42,21 @@ const ProviderCards = memo(function ProviderCards({
[openModal, refreshProviders]
);
+ const deleteProviderConfigViaModal = useCallback(
+ (provider: ProviderDetails) => {
+ openModal(provider, {
+ onDelete: () => {
+ // Only refresh if the function is provided
+ if (refreshProviders) {
+ refreshProviders();
+ }
+ },
+ formProps: {},
+ });
+ },
+ [openModal, refreshProviders]
+ );
+
// We don't need an intermediate function here
// Just pass the onProviderLaunch directly
@@ -52,6 +67,7 @@ const ProviderCards = memo(function ProviderCards({
key={provider.name}
provider={provider}
onConfigure={() => configureProviderViaModal(provider)}
+ onDelete={() => deleteProviderConfigViaModal(provider)}
onLaunch={() => onProviderLaunch(provider)}
isOnboarding={isOnboarding}
/>
@@ -87,6 +103,5 @@ export default memo(function ProviderGrid({
),
[providers, isOnboarding, refreshProviders, onProviderLaunch]
);
-
return
- Select an AI model provider to get started with goose. You’ll need to use API keys + Select an AI model provider to get started with goose. You'll need to use API keys generated by each provider which will be encrypted and stored locally. You can change your provider at any time in settings.
diff --git a/ui/desktop/src/components/settings_v2/providers/modal/ProviderConfiguationModal.tsx b/ui/desktop/src/components/settings_v2/providers/modal/ProviderConfiguationModal.tsx index 85fff361..f75127ec 100644 --- a/ui/desktop/src/components/settings_v2/providers/modal/ProviderConfiguationModal.tsx +++ b/ui/desktop/src/components/settings_v2/providers/modal/ProviderConfiguationModal.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import Modal from '../../../../components/Modal'; import ProviderSetupHeader from './subcomponents/ProviderSetupHeader'; import DefaultProviderSetupForm from './subcomponents/forms/DefaultProviderSetupForm'; @@ -10,6 +10,7 @@ import { DefaultSubmitHandler } from './subcomponents/handlers/DefaultSubmitHand import OllamaSubmitHandler from './subcomponents/handlers/OllamaSubmitHandler'; import OllamaForm from './subcomponents/forms/OllamaForm'; import { useConfig } from '../../../ConfigContext'; +import { AlertTriangle } from 'lucide-react'; const customSubmitHandlerMap = { provider_name: OllamaSubmitHandler, // example @@ -20,15 +21,31 @@ const customFormsMap = { }; export default function ProviderConfigurationModal() { - const { upsert } = useConfig(); const [validationErrors, setValidationErrors] = useState({}); + const { upsert, remove } = useConfig(); const { isOpen, currentProvider, modalProps, closeModal } = useProviderModal(); const [configValues, setConfigValues] = useState({}); + const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false); + + useEffect(() => { + if (isOpen && currentProvider) { + // Reset form state when the modal opens with a new provider + setConfigValues({}); + setValidationErrors({}); + setShowDeleteConfirmation(false); + } + }, [isOpen, currentProvider]); if (!isOpen || !currentProvider) return null; - const headerText = `Configure ${currentProvider.metadata.display_name}`; - const descriptionText = `Add your API key(s) for this provider to integrate into Goose`; + const isConfigured = currentProvider.is_configured; + const headerText = showDeleteConfirmation + ? `Delete configuration for ${currentProvider.metadata.display_name}` + : `Configure ${currentProvider.metadata.display_name}`; + + const descriptionText = showDeleteConfirmation + ? 'This will permanently delete the current provider configuration.' + : `Add your API key(s) for this provider to integrate into Goose`; const SubmitHandler = customSubmitHandlerMap[currentProvider.name] || DefaultSubmitHandler; const FormComponent = customFormsMap[currentProvider.name] || DefaultProviderSetupForm; @@ -80,6 +97,9 @@ export default function ProviderConfigurationModal() { }; const handleCancel = () => { + // Reset delete confirmation state + setShowDeleteConfirmation(false); + // Use custom cancel handler if provided if (modalProps.onCancel) { modalProps.onCancel(); @@ -88,30 +108,87 @@ export default function ProviderConfigurationModal() { closeModal(); }; + const handleDelete = () => { + setShowDeleteConfirmation(true); + }; + + const handleConfirmDelete = async () => { + try { + // Remove the provider configuration + // get the keys + const params = currentProvider.metadata.config_keys; + + // go through the keys are remove them + for (const param of params) { + console.log('param', param.name, 'secret', param.secret); + await remove(param.name, param.secret); + } + + // Call onDelete callback if provided + // This should trigger the refreshProviders function + if (modalProps.onDelete) { + modalProps.onDelete(currentProvider.name); + } + + // Reset the delete confirmation state before closing + setShowDeleteConfirmation(false); + + // Close the modal + // Close the modal after deletion and callback + closeModal(); + } catch (error) { + console.error('Failed to delete provider:', error); + // Keep modal open if there's an error + } + }; + // Function to determine which icon to display + const getModalIcon = () => { + if (showDeleteConfirmation) { + return+ Are you sure you want to delete the configuration parameters for {providerName}? This + action cannot be undone. +
+