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
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ export const SwitchModelModal = ({
const [provider, setProvider] = useState<string | null>(
initialProvider || currentProvider || null
);
const [model, setModel] = useState<string>(currentModel || '');
// Only use currentModel if we're not switching to a different provider
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

thought this logic was worthy of a comment but can remove if people disagree

// Otherwise, let the auto-select logic pick an appropriate model for the new provider
const [model, setModel] = useState<string>(
initialProvider && initialProvider !== currentProvider ? '' : currentModel || ''
);
const [isCustomModel, setIsCustomModel] = useState(false);
const [validationErrors, setValidationErrors] = useState({
provider: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ function ProviderCards({
api_key: '',
models: editingProvider.config.models.map((m) => m.name),
supports_streaming: editingProvider.config.supports_streaming ?? true,
requires_auth: editingProvider.config.requires_auth ?? true,
};

const editable = editingProvider ? editingProvider.isEditable : true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Input } from '../../../../../ui/input';
import { Select } from '../../../../../ui/Select';
import { Button } from '../../../../../ui/button';
import { SecureStorageNotice } from '../SecureStorageNotice';
import { Checkbox } from '@radix-ui/themes';
import { UpdateCustomProviderRequest } from '../../../../../../api';

interface CustomProviderFormProps {
Expand All @@ -24,7 +23,7 @@ export default function CustomProviderForm({
const [apiUrl, setApiUrl] = useState('');
const [apiKey, setApiKey] = useState('');
const [models, setModels] = useState('');
const [noAuthRequired, setNoAuthRequired] = useState(false);
const [requiresApiKey, setRequiresApiKey] = useState(false);
const [supportsStreaming, setSupportsStreaming] = useState(true);
const [validationErrors, setValidationErrors] = useState<Record<string, string>>({});

Expand All @@ -40,13 +39,13 @@ export default function CustomProviderForm({
setApiUrl(initialData.api_url);
setModels(initialData.models.join(', '));
setSupportsStreaming(initialData.supports_streaming ?? true);
setNoAuthRequired(!(initialData.requires_auth ?? true));
setRequiresApiKey(initialData.requires_auth ?? true);
}
}, [initialData]);

const handleNoAuthChange = (checked: boolean) => {
setNoAuthRequired(!!checked);
if (checked) {
const handleRequiresApiKeyChange = (checked: boolean) => {
setRequiresApiKey(checked);
if (!checked) {
setApiKey('');
}
};
Expand All @@ -58,7 +57,7 @@ export default function CustomProviderForm({
if (!displayName) errors.displayName = 'Display name is required';
if (!apiUrl) errors.apiUrl = 'API URL is required';
const existingHadAuth = initialData && (initialData.requires_auth ?? true);
if (!noAuthRequired && !apiKey && !existingHadAuth) errors.apiKey = 'API key is required';
if (requiresApiKey && !apiKey && !existingHadAuth) errors.apiKey = 'API key is required';
if (!models) errors.models = 'At least one model is required';

if (Object.keys(errors).length > 0) {
Expand All @@ -78,7 +77,7 @@ export default function CustomProviderForm({
api_key: apiKey,
models: modelList,
supports_streaming: supportsStreaming,
requires_auth: !noAuthRequired,
requires_auth: requiresApiKey,
});
};

Expand Down Expand Up @@ -174,22 +173,25 @@ export default function CustomProviderForm({
)}

<div>
<div className="flex items-center space-x-2 mb-2">
<Checkbox
id="no-auth-required"
checked={noAuthRequired}
onCheckedChange={handleNoAuthChange}
<label className="block text-sm font-medium text-textStandard mb-2">Authentication</label>
<p className="text-sm text-textSubtle mb-3">
Local LLMs like Ollama typically don't require an API key.
</p>
<div className="flex items-center space-x-2">
<input
type="checkbox"
id="requires-api-key"
checked={requiresApiKey}
onChange={(e) => handleRequiresApiKeyChange(e.target.checked)}
className="rounded border-borderStandard"
/>
<label
htmlFor="no-auth-required"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 text-textSubtle"
>
No authentication required
<label htmlFor="requires-api-key" className="text-sm text-textSubtle">
This provider requires an API key
</label>
</div>

{!noAuthRequired && (
<>
{requiresApiKey && (
<div className="mt-3">
<label
htmlFor="api-key"
className="flex items-center text-sm font-medium text-textStandard mb-2"
Expand All @@ -212,7 +214,7 @@ export default function CustomProviderForm({
{validationErrors.apiKey}
</p>
)}
</>
</div>
)}
</div>
{isEditable && (
Expand Down Expand Up @@ -241,15 +243,14 @@ export default function CustomProviderForm({
)}
</div>
<div className="flex items-center space-x-2 mb-10">
<Checkbox
<input
type="checkbox"
id="supports-streaming"
checked={supportsStreaming}
onCheckedChange={(checked) => setSupportsStreaming(checked as boolean)}
onChange={(e) => setSupportsStreaming(e.target.checked)}
className="rounded border-borderStandard"
/>
<label
htmlFor="supports-streaming"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 text-textSubtle"
>
<label htmlFor="supports-streaming" className="text-sm text-textSubtle">
Provider supports streaming responses
</label>
</div>
Expand Down
Loading