Merge pull request 'fix: normalize API URL to prevent duplicate /chat/completions path' (#13) from feature-shadowAI into main
Reviewed-on: #13
This commit is contained in:
@@ -37,7 +37,12 @@ export async function callOpenAICompatible(params: AICallerParams): Promise<AICa
|
|||||||
const https = await import('https');
|
const https = await import('https');
|
||||||
|
|
||||||
const aiResult = await new Promise<{ status: number; body: string }>((resolve, reject) => {
|
const aiResult = await new Promise<{ status: number; body: string }>((resolve, reject) => {
|
||||||
const url = new URL(`${apiUrl}/chat/completions`);
|
// Normalize: strip trailing slash and /chat/completions if user included it
|
||||||
|
let baseUrl = apiUrl.replace(/\/+$/, '');
|
||||||
|
if (baseUrl.endsWith('/chat/completions')) {
|
||||||
|
baseUrl = baseUrl.slice(0, -'/chat/completions'.length);
|
||||||
|
}
|
||||||
|
const url = new URL(`${baseUrl}/chat/completions`);
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
hostname: url.hostname,
|
hostname: url.hostname,
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ function ModelSlotCard({ slot, model, isLoading }: { slot: string; model?: Shado
|
|||||||
</Group>
|
</Group>
|
||||||
<Divider />
|
<Divider />
|
||||||
<TextInput label="Display Name" placeholder="e.g. GPT-4o" value={name} onChange={(e) => setName(e.target.value)} size="sm" />
|
<TextInput label="Display Name" placeholder="e.g. GPT-4o" value={name} onChange={(e) => setName(e.target.value)} size="sm" />
|
||||||
<TextInput label="API URL" placeholder="https://api.openai.com/v1" value={apiUrl} onChange={(e) => setApiUrl(e.target.value)} size="sm" />
|
<TextInput label="API URL" description="Base URL only — /chat/completions is added automatically" placeholder="https://openrouter.ai/api/v1" value={apiUrl} onChange={(e) => setApiUrl(e.target.value)} size="sm" />
|
||||||
<PasswordInput label="API Key" placeholder="sk-..." value={apiKey} onChange={(e) => setApiKey(e.target.value)} size="sm" />
|
<PasswordInput label="API Key" placeholder="sk-..." value={apiKey} onChange={(e) => setApiKey(e.target.value)} size="sm" />
|
||||||
<TextInput label="Model Name" placeholder="gpt-4o" value={modelName} onChange={(e) => setModelName(e.target.value)} size="sm" />
|
<TextInput label="Model Name" placeholder="gpt-4o" value={modelName} onChange={(e) => setModelName(e.target.value)} size="sm" />
|
||||||
<Switch label="Active" checked={isActive} onChange={(e) => setIsActive(e.currentTarget.checked)} />
|
<Switch label="Active" checked={isActive} onChange={(e) => setIsActive(e.currentTarget.checked)} />
|
||||||
|
|||||||
Reference in New Issue
Block a user