feat: add requires_auth flag for custom providers without authentication (#6705)
Signed-off-by: rabi <ramishra@redhat.com>
This commit is contained in:
@@ -3480,7 +3480,6 @@
|
||||
"name",
|
||||
"engine",
|
||||
"display_name",
|
||||
"api_key_env",
|
||||
"base_url",
|
||||
"models"
|
||||
],
|
||||
@@ -3517,6 +3516,9 @@
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"requires_auth": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"supports_streaming": {
|
||||
"type": "boolean",
|
||||
"nullable": true
|
||||
@@ -6698,6 +6700,9 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"requires_auth": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"supports_streaming": {
|
||||
"type": "boolean",
|
||||
"nullable": true
|
||||
|
||||
@@ -154,7 +154,7 @@ export type CspMetadata = {
|
||||
};
|
||||
|
||||
export type DeclarativeProviderConfig = {
|
||||
api_key_env: string;
|
||||
api_key_env?: string;
|
||||
base_url: string;
|
||||
description?: string | null;
|
||||
display_name: string;
|
||||
@@ -164,6 +164,7 @@ export type DeclarativeProviderConfig = {
|
||||
} | null;
|
||||
models: Array<ModelInfo>;
|
||||
name: string;
|
||||
requires_auth?: boolean;
|
||||
supports_streaming?: boolean | null;
|
||||
timeout_seconds?: number | null;
|
||||
};
|
||||
@@ -1204,6 +1205,7 @@ export type UpdateCustomProviderRequest = {
|
||||
[key: string]: string;
|
||||
} | null;
|
||||
models: Array<string>;
|
||||
requires_auth?: boolean;
|
||||
supports_streaming?: boolean | null;
|
||||
};
|
||||
|
||||
|
||||
+42
-36
@@ -24,7 +24,7 @@ export default function CustomProviderForm({
|
||||
const [apiUrl, setApiUrl] = useState('');
|
||||
const [apiKey, setApiKey] = useState('');
|
||||
const [models, setModels] = useState('');
|
||||
const [isLocalModel, setIsLocalModel] = useState(false);
|
||||
const [noAuthRequired, setNoAuthRequired] = useState(false);
|
||||
const [supportsStreaming, setSupportsStreaming] = useState(true);
|
||||
const [validationErrors, setValidationErrors] = useState<Record<string, string>>({});
|
||||
|
||||
@@ -40,14 +40,13 @@ export default function CustomProviderForm({
|
||||
setApiUrl(initialData.api_url);
|
||||
setModels(initialData.models.join(', '));
|
||||
setSupportsStreaming(initialData.supports_streaming ?? true);
|
||||
setNoAuthRequired(!(initialData.requires_auth ?? true));
|
||||
}
|
||||
}, [initialData]);
|
||||
|
||||
const handleLocalModels = (checked: boolean) => {
|
||||
setIsLocalModel(checked);
|
||||
const handleNoAuthChange = (checked: boolean) => {
|
||||
setNoAuthRequired(!!checked);
|
||||
if (checked) {
|
||||
setApiKey('notrequired');
|
||||
} else {
|
||||
setApiKey('');
|
||||
}
|
||||
};
|
||||
@@ -58,7 +57,8 @@ export default function CustomProviderForm({
|
||||
const errors: Record<string, string> = {};
|
||||
if (!displayName) errors.displayName = 'Display name is required';
|
||||
if (!apiUrl) errors.apiUrl = 'API URL is required';
|
||||
if (!isLocalModel && !apiKey && !initialData) errors.apiKey = 'API key is required';
|
||||
const existingHadAuth = initialData && (initialData.requires_auth ?? true);
|
||||
if (!noAuthRequired && !apiKey && !existingHadAuth) errors.apiKey = 'API key is required';
|
||||
if (!models) errors.models = 'At least one model is required';
|
||||
|
||||
if (Object.keys(errors).length > 0) {
|
||||
@@ -78,6 +78,7 @@ export default function CustomProviderForm({
|
||||
api_key: apiKey,
|
||||
models: modelList,
|
||||
supports_streaming: supportsStreaming,
|
||||
requires_auth: !noAuthRequired,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -173,40 +174,45 @@ export default function CustomProviderForm({
|
||||
)}
|
||||
|
||||
<div>
|
||||
<label
|
||||
htmlFor="api-key"
|
||||
className="flex items-center text-sm font-medium text-textStandard mb-2"
|
||||
>
|
||||
API Key
|
||||
{!isLocalModel && !initialData && <span className="text-red-500 ml-1">*</span>}
|
||||
</label>
|
||||
<Input
|
||||
id="api-key"
|
||||
type="password"
|
||||
value={apiKey}
|
||||
onChange={(e) => setApiKey(e.target.value)}
|
||||
placeholder={initialData ? 'Leave blank to keep existing key' : 'Your API key'}
|
||||
aria-invalid={!!validationErrors.apiKey}
|
||||
aria-describedby={validationErrors.apiKey ? 'api-key-error' : undefined}
|
||||
className={validationErrors.apiKey ? 'border-red-500' : ''}
|
||||
disabled={isLocalModel}
|
||||
/>
|
||||
{validationErrors.apiKey && (
|
||||
<p id="api-key-error" className="text-red-500 text-sm mt-1">
|
||||
{validationErrors.apiKey}
|
||||
</p>
|
||||
)}
|
||||
<div className="flex items-center space-x-2 mb-2">
|
||||
<Checkbox
|
||||
id="no-auth-required"
|
||||
checked={noAuthRequired}
|
||||
onCheckedChange={handleNoAuthChange}
|
||||
/>
|
||||
<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>
|
||||
</div>
|
||||
|
||||
{!initialData && (
|
||||
<div className="flex items-center space-x-2 mt-2">
|
||||
<Checkbox id="local-model" checked={isLocalModel} onCheckedChange={handleLocalModels} />
|
||||
{!noAuthRequired && (
|
||||
<>
|
||||
<label
|
||||
htmlFor="local-model"
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 text-textSubtle"
|
||||
htmlFor="api-key"
|
||||
className="flex items-center text-sm font-medium text-textStandard mb-2"
|
||||
>
|
||||
This is a local model (no auth required)
|
||||
API Key
|
||||
{!initialData && <span className="text-red-500 ml-1">*</span>}
|
||||
</label>
|
||||
</div>
|
||||
<Input
|
||||
id="api-key"
|
||||
type="password"
|
||||
value={apiKey}
|
||||
onChange={(e) => setApiKey(e.target.value)}
|
||||
placeholder={initialData ? 'Leave blank to keep existing key' : 'Your API key'}
|
||||
aria-invalid={!!validationErrors.apiKey}
|
||||
aria-describedby={validationErrors.apiKey ? 'api-key-error' : undefined}
|
||||
className={validationErrors.apiKey ? 'border-red-500' : ''}
|
||||
/>
|
||||
{validationErrors.apiKey && (
|
||||
<p id="api-key-error" className="text-red-500 text-sm mt-1">
|
||||
{validationErrors.apiKey}
|
||||
</p>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{isEditable && (
|
||||
|
||||
Reference in New Issue
Block a user