feat: add base path field to custom provider configuration (#7614)
Signed-off-by: sheikhlimon <sheikhlimon404@gmail.com>
This commit is contained in:
@@ -2015,6 +2015,17 @@ fn add_provider() -> anyhow::Result<()> {
|
|||||||
.initial_value(true)
|
.initial_value(true)
|
||||||
.interact()?;
|
.interact()?;
|
||||||
|
|
||||||
|
let base_path_input: String = cliclack::input("API base path (optional, press Enter to skip):")
|
||||||
|
.placeholder("e.g., v1/chat/completions or project_id/v1")
|
||||||
|
.required(false)
|
||||||
|
.interact()?;
|
||||||
|
|
||||||
|
let base_path = if base_path_input.trim().is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(base_path_input)
|
||||||
|
};
|
||||||
|
|
||||||
let headers = collect_custom_headers()?;
|
let headers = collect_custom_headers()?;
|
||||||
|
|
||||||
create_custom_provider(CreateCustomProviderParams {
|
create_custom_provider(CreateCustomProviderParams {
|
||||||
@@ -2027,7 +2038,7 @@ fn add_provider() -> anyhow::Result<()> {
|
|||||||
headers,
|
headers,
|
||||||
requires_auth,
|
requires_auth,
|
||||||
catalog_provider_id: None,
|
catalog_provider_id: None,
|
||||||
base_path: None,
|
base_path,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
cliclack::outro(format!("Custom provider added: {}", display_name))?;
|
cliclack::outro(format!("Custom provider added: {}", display_name))?;
|
||||||
|
|||||||
@@ -236,6 +236,7 @@ function ProviderCards({
|
|||||||
engine: editingProvider.config.engine,
|
engine: editingProvider.config.engine,
|
||||||
display_name: editingProvider.config.display_name,
|
display_name: editingProvider.config.display_name,
|
||||||
api_url: editingProvider.config.base_url,
|
api_url: editingProvider.config.base_url,
|
||||||
|
base_path: editingProvider.config.base_path ?? undefined,
|
||||||
api_key: '',
|
api_key: '',
|
||||||
models: editingProvider.config.models.map((m) => m.name),
|
models: editingProvider.config.models.map((m) => m.name),
|
||||||
supports_streaming: editingProvider.config.supports_streaming ?? true,
|
supports_streaming: editingProvider.config.supports_streaming ?? true,
|
||||||
|
|||||||
+27
-1
@@ -30,6 +30,7 @@ export default function CustomProviderForm({
|
|||||||
const [engine, setEngine] = useState('openai_compatible');
|
const [engine, setEngine] = useState('openai_compatible');
|
||||||
const [displayName, setDisplayName] = useState('');
|
const [displayName, setDisplayName] = useState('');
|
||||||
const [apiUrl, setApiUrl] = useState('');
|
const [apiUrl, setApiUrl] = useState('');
|
||||||
|
const [basePath, setBasePath] = useState('');
|
||||||
const [apiKey, setApiKey] = useState('');
|
const [apiKey, setApiKey] = useState('');
|
||||||
const [models, setModels] = useState('');
|
const [models, setModels] = useState('');
|
||||||
const [requiresAuth, setRequiresAuth] = useState(false);
|
const [requiresAuth, setRequiresAuth] = useState(false);
|
||||||
@@ -59,6 +60,7 @@ export default function CustomProviderForm({
|
|||||||
setEngine(engineMap[initialData.engine] || 'openai_compatible');
|
setEngine(engineMap[initialData.engine] || 'openai_compatible');
|
||||||
setDisplayName(initialData.display_name);
|
setDisplayName(initialData.display_name);
|
||||||
setApiUrl(initialData.api_url);
|
setApiUrl(initialData.api_url);
|
||||||
|
setBasePath(initialData.base_path ?? '');
|
||||||
setModels(initialData.models.join(', '));
|
setModels(initialData.models.join(', '));
|
||||||
setSupportsStreaming(initialData.supports_streaming ?? true);
|
setSupportsStreaming(initialData.supports_streaming ?? true);
|
||||||
setRequiresAuth(initialData.requires_auth ?? true);
|
setRequiresAuth(initialData.requires_auth ?? true);
|
||||||
@@ -81,6 +83,7 @@ export default function CustomProviderForm({
|
|||||||
// Prefill fields from template
|
// Prefill fields from template
|
||||||
setDisplayName(template.name);
|
setDisplayName(template.name);
|
||||||
setApiUrl(template.api_url);
|
setApiUrl(template.api_url);
|
||||||
|
setBasePath('');
|
||||||
setSupportsStreaming(template.supports_streaming);
|
setSupportsStreaming(template.supports_streaming);
|
||||||
setRequiresAuth(true);
|
setRequiresAuth(true);
|
||||||
|
|
||||||
@@ -101,6 +104,7 @@ export default function CustomProviderForm({
|
|||||||
setSelectedTemplate(null);
|
setSelectedTemplate(null);
|
||||||
setDisplayName('');
|
setDisplayName('');
|
||||||
setApiUrl('');
|
setApiUrl('');
|
||||||
|
setBasePath('');
|
||||||
setModels('');
|
setModels('');
|
||||||
setEngine('openai_compatible');
|
setEngine('openai_compatible');
|
||||||
setSupportsStreaming(true);
|
setSupportsStreaming(true);
|
||||||
@@ -233,6 +237,7 @@ export default function CustomProviderForm({
|
|||||||
requires_auth: requiresAuth,
|
requires_auth: requiresAuth,
|
||||||
headers: headersObject,
|
headers: headersObject,
|
||||||
catalog_provider_id: selectedTemplate?.id ?? initialData?.catalog_provider_id ?? undefined,
|
catalog_provider_id: selectedTemplate?.id ?? initialData?.catalog_provider_id ?? undefined,
|
||||||
|
base_path: basePath || undefined,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -438,7 +443,7 @@ export default function CustomProviderForm({
|
|||||||
id="api-url"
|
id="api-url"
|
||||||
value={apiUrl}
|
value={apiUrl}
|
||||||
onChange={(e) => setApiUrl(e.target.value)}
|
onChange={(e) => setApiUrl(e.target.value)}
|
||||||
placeholder="https://api.example.com/v1"
|
placeholder="https://api.example.com"
|
||||||
aria-invalid={!!validationErrors.apiUrl}
|
aria-invalid={!!validationErrors.apiUrl}
|
||||||
aria-describedby={validationErrors.apiUrl ? 'api-url-error' : undefined}
|
aria-describedby={validationErrors.apiUrl ? 'api-url-error' : undefined}
|
||||||
className={validationErrors.apiUrl ? 'border-red-500' : ''}
|
className={validationErrors.apiUrl ? 'border-red-500' : ''}
|
||||||
@@ -451,6 +456,27 @@ export default function CustomProviderForm({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Base Path */}
|
||||||
|
{isEditable && (
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
htmlFor="base-path"
|
||||||
|
className="flex items-center text-sm font-medium text-text-primary mb-2"
|
||||||
|
>
|
||||||
|
API Base Path (optional)
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
id="base-path"
|
||||||
|
value={basePath}
|
||||||
|
onChange={(e) => setBasePath(e.target.value)}
|
||||||
|
placeholder="e.g., v1/chat/completions or project_id/v1"
|
||||||
|
/>
|
||||||
|
<p className="text-xs text-textSubtle mt-1">
|
||||||
|
Override the default API path. Leave blank to use the provider's default path.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Authentication */}
|
{/* Authentication */}
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-text-primary mb-2">Authentication</label>
|
<label className="block text-sm font-medium text-text-primary mb-2">Authentication</label>
|
||||||
|
|||||||
Reference in New Issue
Block a user