add headers to provider

This commit is contained in:
miloschwartz
2026-08-05 17:42:58 -04:00
parent 1f3fff4a9d
commit 3d7e322bf9
13 changed files with 271 additions and 11 deletions
@@ -21,6 +21,7 @@ import {
} from "@app/components/Settings";
import { StrategySelect } from "@app/components/StrategySelect";
import { SwitchInput } from "@app/components/SwitchInput";
import { HeadersInput } from "@app/components/HeadersInput";
import { Button } from "@app/components/ui/button";
import {
Form,
@@ -66,6 +67,7 @@ export default function AiProviderNetworkPage() {
const router = useRouter();
const t = useTranslations();
const [saveLoading, setSaveLoading] = useState(false);
const [headersValid, setHeadersValid] = useState(true);
const targetsFormRef = useRef<ProxyResourceTargetsFormHandle>(null);
const formSchema = useMemo(() => createAiProviderFormSchema(t), [t]);
@@ -79,6 +81,7 @@ export default function AiProviderNetworkPage() {
apiKey: "",
authType: (provider.authType as AiProviderAuthType) ?? "bearer",
routingMode: (provider.routingMode as "url" | "target") ?? "url",
headers: provider.headers ?? [],
skipTlsVerification: provider.skipTlsVerification,
enabled: provider.enabled
}
@@ -122,6 +125,7 @@ export default function AiProviderNetworkPage() {
apiKey: "",
authType: (updated.authType as AiProviderAuthType) ?? "bearer",
routingMode: (updated.routingMode as "url" | "target") ?? "url",
headers: updated.headers ?? [],
skipTlsVerification: updated.skipTlsVerification,
enabled: updated.enabled
});
@@ -310,6 +314,38 @@ export default function AiProviderNetworkPage() {
/>
</SettingsFormCell>
)}
<SettingsFormCell span="full">
<FormField
control={form.control}
name="headers"
render={({ field }) => (
<FormItem>
<FormLabel>
{t("customHeaders")}
</FormLabel>
<FormControl>
<HeadersInput
value={field.value}
onChange={
field.onChange
}
onValidityChange={
setHeadersValid
}
rows={4}
/>
</FormControl>
<FormDescription>
{t(
"aiProviderCustomHeadersDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
</SettingsFormCell>
</SettingsFormGrid>
</form>
</Form>
@@ -346,7 +382,7 @@ export default function AiProviderNetworkPage() {
<Button
type="submit"
loading={saveLoading}
disabled={saveLoading}
disabled={saveLoading || !headersValid}
form="ai-provider-network-form"
>
{t("saveSettings")}
@@ -25,6 +25,7 @@ import {
capabilityLabelKey
} from "@app/components/AiProviderCapabilitiesSelect";
import { AiProviderTypeSelect } from "@app/components/AiProviderTypeSelect";
import { HeadersInput } from "@app/components/HeadersInput";
import { StrategySelect } from "@app/components/StrategySelect";
import { SwitchInput } from "@app/components/SwitchInput";
import { Button } from "@app/components/ui/button";
@@ -68,6 +69,7 @@ export default function CreateAiProviderPage() {
const router = useRouter();
const t = useTranslations();
const [loading, setLoading] = useState(false);
const [headersValid, setHeadersValid] = useState(true);
const targetsRef = useRef<LocalTarget[]>([]);
const formSchema = useMemo(() => createAiProviderCreateFormSchema(t), [t]);
@@ -82,6 +84,7 @@ export default function CreateAiProviderPage() {
authType: defaultAuthTypeForProvider("openai"),
routingMode: "url",
capabilities: defaultCapabilitiesForProvider("openai"),
headers: [],
skipTlsVerification: false,
enabled: true
}
@@ -531,6 +534,38 @@ export default function CreateAiProviderPage() {
/>
</SettingsFormCell>
)}
<SettingsFormCell span="full">
<FormField
control={form.control}
name="headers"
render={({ field }) => (
<FormItem>
<FormLabel>
{t("customHeaders")}
</FormLabel>
<FormControl>
<HeadersInput
value={field.value}
onChange={
field.onChange
}
onValidityChange={
setHeadersValid
}
rows={4}
/>
</FormControl>
<FormDescription>
{t(
"aiProviderCustomHeadersDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
</SettingsFormCell>
</SettingsFormGrid>
</SettingsSectionForm>
@@ -663,7 +698,7 @@ export default function CreateAiProviderPage() {
<Button
type="button"
loading={loading}
disabled={loading}
disabled={loading || !headersValid}
onClick={() => {
form.handleSubmit(onSubmit)();
}}
+9 -1
View File
@@ -42,6 +42,10 @@ export function createAiProviderFormSchema(t: TranslateFn) {
authType: z.enum(AI_PROVIDER_AUTH_TYPES).optional().nullable(),
routingMode: z.enum(["url", "target"]).optional(),
capabilities: z.array(z.enum(AI_CAPABILITIES)).optional(),
headers: z
.array(z.object({ name: z.string(), value: z.string() }))
.nullable()
.optional(),
skipTlsVerification: z.boolean().optional(),
enabled: z.boolean().optional()
})
@@ -185,6 +189,8 @@ export function toAiProviderCreatePayload(values: AiProviderFormValues) {
authType: values.authType ?? "bearer",
capabilities:
values.type === "custom" ? (values.capabilities ?? []) : undefined,
headers:
values.headers && values.headers.length > 0 ? values.headers : null,
skipTlsVerification: values.skipTlsVerification,
enabled: values.enabled ?? true
};
@@ -226,7 +232,9 @@ export function toAiProviderNetworkPayload(values: AiProviderFormValues) {
return {
routingMode: full.routingMode,
upstreamUrl: full.upstreamUrl,
skipTlsVerification: full.skipTlsVerification
skipTlsVerification: full.skipTlsVerification,
headers:
values.headers && values.headers.length > 0 ? values.headers : null
};
}