mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-25 13:45:03 +08:00
feat: add provider user agent override
This commit is contained in:
@@ -138,6 +138,10 @@ interface ClaudeFormFieldsProps {
|
||||
// Full URL mode
|
||||
isFullUrl: boolean;
|
||||
onFullUrlChange: (value: boolean) => void;
|
||||
|
||||
// Local proxy User-Agent override
|
||||
customUserAgent: string;
|
||||
onCustomUserAgentChange: (value: string) => void;
|
||||
}
|
||||
|
||||
export function ClaudeFormFields({
|
||||
@@ -190,6 +194,8 @@ export function ClaudeFormFields({
|
||||
onApiKeyFieldChange,
|
||||
isFullUrl,
|
||||
onFullUrlChange,
|
||||
customUserAgent,
|
||||
onCustomUserAgentChange,
|
||||
}: ClaudeFormFieldsProps) {
|
||||
const { t } = useTranslation();
|
||||
const hasAnyAdvancedValue = !!(
|
||||
@@ -665,7 +671,30 @@ export function ClaudeFormFields({
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 高级选项(API 格式 + 认证字段 + 模型映射) */}
|
||||
{category !== "official" && (
|
||||
<div className="space-y-2">
|
||||
<FormLabel htmlFor="claude-custom-user-agent">
|
||||
{t("providerForm.customUserAgent", {
|
||||
defaultValue: "自定义 User-Agent",
|
||||
})}
|
||||
</FormLabel>
|
||||
<Input
|
||||
id="claude-custom-user-agent"
|
||||
type="text"
|
||||
value={customUserAgent}
|
||||
onChange={(e) => onCustomUserAgentChange(e.target.value)}
|
||||
placeholder="Mozilla/5.0 ..."
|
||||
autoComplete="off"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{t("providerForm.customUserAgentHint", {
|
||||
defaultValue:
|
||||
"仅在开启本地路由/代理接管后生效,会替换转发到供应商 API 请求中的 User-Agent。",
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{shouldShowModelSelector && (
|
||||
<Collapsible open={advancedExpanded} onOpenChange={setAdvancedExpanded}>
|
||||
<CollapsibleTrigger asChild>
|
||||
|
||||
@@ -72,6 +72,10 @@ interface CodexFormFieldsProps {
|
||||
|
||||
// Speed Test Endpoints
|
||||
speedTestEndpoints: EndpointCandidate[];
|
||||
|
||||
// Local proxy User-Agent override
|
||||
customUserAgent: string;
|
||||
onCustomUserAgentChange: (value: string) => void;
|
||||
}
|
||||
|
||||
type CodexCatalogRow = CodexCatalogModel & { rowId: string };
|
||||
@@ -128,6 +132,8 @@ export function CodexFormFields({
|
||||
catalogModels = [],
|
||||
onCatalogModelsChange,
|
||||
speedTestEndpoints,
|
||||
customUserAgent,
|
||||
onCustomUserAgentChange,
|
||||
}: CodexFormFieldsProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -582,6 +588,33 @@ export function CodexFormFields({
|
||||
onCustomEndpointsChange={onCustomEndpointsChange}
|
||||
/>
|
||||
)}
|
||||
|
||||
{category !== "official" && (
|
||||
<div className="space-y-2">
|
||||
<label
|
||||
htmlFor="codex-custom-user-agent"
|
||||
className="block text-sm font-medium text-foreground"
|
||||
>
|
||||
{t("providerForm.customUserAgent", {
|
||||
defaultValue: "自定义 User-Agent",
|
||||
})}
|
||||
</label>
|
||||
<Input
|
||||
id="codex-custom-user-agent"
|
||||
type="text"
|
||||
value={customUserAgent}
|
||||
onChange={(e) => onCustomUserAgentChange(e.target.value)}
|
||||
placeholder="Mozilla/5.0 ..."
|
||||
autoComplete="off"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{t("providerForm.customUserAgentHint", {
|
||||
defaultValue:
|
||||
"仅在开启本地路由/代理接管后生效,会替换转发到供应商 API 请求中的 User-Agent。",
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -355,6 +355,7 @@ function ProviderFormFull({
|
||||
),
|
||||
});
|
||||
setCodexChatReasoning(initialData?.meta?.codexChatReasoning ?? {});
|
||||
setCustomUserAgent(initialData?.meta?.customUserAgent ?? "");
|
||||
}, [appId, initialData, supportsFullUrl]);
|
||||
|
||||
const defaultValues: ProviderFormData = useMemo(
|
||||
@@ -509,6 +510,9 @@ function ProviderFormFull({
|
||||
useState<CodexChatReasoning>(
|
||||
() => initialData?.meta?.codexChatReasoning ?? {},
|
||||
);
|
||||
const [customUserAgent, setCustomUserAgent] = useState<string>(
|
||||
() => initialData?.meta?.customUserAgent ?? "",
|
||||
);
|
||||
|
||||
const {
|
||||
codexAuth,
|
||||
@@ -1386,6 +1390,10 @@ function ProviderFormFull({
|
||||
localCodexApiFormat === "openai_chat"
|
||||
? normalizeCodexChatReasoningForSave(codexChatReasoning)
|
||||
: undefined,
|
||||
customUserAgent:
|
||||
appId === "claude" || appId === "codex"
|
||||
? customUserAgent.trim() || undefined
|
||||
: undefined,
|
||||
testConfig: testConfig.enabled ? testConfig : undefined,
|
||||
costMultiplier: pricingConfig.enabled
|
||||
? pricingConfig.costMultiplier
|
||||
@@ -2009,6 +2017,8 @@ function ProviderFormFull({
|
||||
onApiKeyFieldChange={handleApiKeyFieldChange}
|
||||
isFullUrl={localIsFullUrl}
|
||||
onFullUrlChange={setLocalIsFullUrl}
|
||||
customUserAgent={customUserAgent}
|
||||
onCustomUserAgentChange={setCustomUserAgent}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -2041,6 +2051,8 @@ function ProviderFormFull({
|
||||
catalogModels={codexCatalogModels}
|
||||
onCatalogModelsChange={setCodexCatalogModels}
|
||||
speedTestEndpoints={speedTestEndpoints}
|
||||
customUserAgent={customUserAgent}
|
||||
onCustomUserAgentChange={setCustomUserAgent}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
@@ -219,6 +219,8 @@ export interface ProviderMeta {
|
||||
codexFastMode?: boolean;
|
||||
// Codex Responses -> Chat Completions reasoning capability metadata
|
||||
codexChatReasoning?: CodexChatReasoning;
|
||||
// Custom User-Agent for local proxy routing. Only applied by the local proxy.
|
||||
customUserAgent?: string;
|
||||
// 供应商类型(用于识别 Copilot 等特殊供应商)
|
||||
providerType?: string;
|
||||
// GitHub Copilot 关联账号 ID(旧字段,保留兼容读取)
|
||||
|
||||
Reference in New Issue
Block a user