feat: add base path field to custom provider configuration (#7614)

Signed-off-by: sheikhlimon <sheikhlimon404@gmail.com>
This commit is contained in:
Sheikh Limon
2026-03-06 02:33:34 +06:00
committed by GitHub
parent 5f48087ba3
commit 2675a0bd74
3 changed files with 40 additions and 2 deletions
+12 -1
View File
@@ -2015,6 +2015,17 @@ fn add_provider() -> anyhow::Result<()> {
.initial_value(true)
.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()?;
create_custom_provider(CreateCustomProviderParams {
@@ -2027,7 +2038,7 @@ fn add_provider() -> anyhow::Result<()> {
headers,
requires_auth,
catalog_provider_id: None,
base_path: None,
base_path,
})?;
cliclack::outro(format!("Custom provider added: {}", display_name))?;
@@ -236,6 +236,7 @@ function ProviderCards({
engine: editingProvider.config.engine,
display_name: editingProvider.config.display_name,
api_url: editingProvider.config.base_url,
base_path: editingProvider.config.base_path ?? undefined,
api_key: '',
models: editingProvider.config.models.map((m) => m.name),
supports_streaming: editingProvider.config.supports_streaming ?? true,
@@ -30,6 +30,7 @@ export default function CustomProviderForm({
const [engine, setEngine] = useState('openai_compatible');
const [displayName, setDisplayName] = useState('');
const [apiUrl, setApiUrl] = useState('');
const [basePath, setBasePath] = useState('');
const [apiKey, setApiKey] = useState('');
const [models, setModels] = useState('');
const [requiresAuth, setRequiresAuth] = useState(false);
@@ -59,6 +60,7 @@ export default function CustomProviderForm({
setEngine(engineMap[initialData.engine] || 'openai_compatible');
setDisplayName(initialData.display_name);
setApiUrl(initialData.api_url);
setBasePath(initialData.base_path ?? '');
setModels(initialData.models.join(', '));
setSupportsStreaming(initialData.supports_streaming ?? true);
setRequiresAuth(initialData.requires_auth ?? true);
@@ -81,6 +83,7 @@ export default function CustomProviderForm({
// Prefill fields from template
setDisplayName(template.name);
setApiUrl(template.api_url);
setBasePath('');
setSupportsStreaming(template.supports_streaming);
setRequiresAuth(true);
@@ -101,6 +104,7 @@ export default function CustomProviderForm({
setSelectedTemplate(null);
setDisplayName('');
setApiUrl('');
setBasePath('');
setModels('');
setEngine('openai_compatible');
setSupportsStreaming(true);
@@ -233,6 +237,7 @@ export default function CustomProviderForm({
requires_auth: requiresAuth,
headers: headersObject,
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"
value={apiUrl}
onChange={(e) => setApiUrl(e.target.value)}
placeholder="https://api.example.com/v1"
placeholder="https://api.example.com"
aria-invalid={!!validationErrors.apiUrl}
aria-describedby={validationErrors.apiUrl ? 'api-url-error' : undefined}
className={validationErrors.apiUrl ? 'border-red-500' : ''}
@@ -451,6 +456,27 @@ export default function CustomProviderForm({
</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 */}
<div>
<label className="block text-sm font-medium text-text-primary mb-2">Authentication</label>