fix(provider): preserve custom headers and add custom-provider User-Agent setting (#635)

This commit is contained in:
Felix
2026-03-23 16:45:57 +08:00
committed by GitHub
Unverified
parent 7b1e79ed7b
commit 4d75dc1e5f
15 changed files with 144 additions and 19 deletions

View File

@@ -294,7 +294,7 @@ async function syncRuntimeProviderConfig(
baseUrl: normalizeProviderBaseUrl(config, config.baseUrl || context.meta?.baseUrl, context.api),
api: context.api,
apiKeyEnv: context.meta?.apiKeyEnv,
headers: context.meta?.headers,
headers: config.headers ?? context.meta?.headers,
});
}
@@ -374,7 +374,7 @@ export async function syncUpdatedProviderToRuntime(
baseUrl: normalizeProviderBaseUrl(config, config.baseUrl || context.meta?.baseUrl, context.api),
api: context.api,
apiKeyEnv: context.meta?.apiKeyEnv,
headers: context.meta?.headers,
headers: config.headers ?? context.meta?.headers,
}, fallbackModels);
} else {
await setOpenClawDefaultModel(ock, modelOverride, fallbackModels);
@@ -383,6 +383,7 @@ export async function syncUpdatedProviderToRuntime(
await setOpenClawDefaultModelWithOverride(ock, modelOverride, {
baseUrl: normalizeProviderBaseUrl(config, config.baseUrl, config.apiProtocol || 'openai-completions'),
api: config.apiProtocol || 'openai-completions',
headers: config.headers,
}, fallbackModels);
}
}
@@ -451,6 +452,7 @@ export async function syncDefaultProviderToRuntime(
await setOpenClawDefaultModelWithOverride(ock, modelOverride, {
baseUrl: normalizeProviderBaseUrl(provider, provider.baseUrl, provider.apiProtocol || 'openai-completions'),
api: provider.apiProtocol || 'openai-completions',
headers: provider.headers,
}, fallbackModels);
} else if (shouldUseExplicitDefaultOverride(provider, ock)) {
await setOpenClawDefaultModelWithOverride(ock, modelOverride, {
@@ -461,7 +463,7 @@ export async function syncDefaultProviderToRuntime(
),
api: provider.apiProtocol || getProviderConfig(provider.type)?.api,
apiKeyEnv: getProviderConfig(provider.type)?.apiKeyEnv,
headers: getProviderConfig(provider.type)?.headers,
headers: provider.headers ?? getProviderConfig(provider.type)?.headers,
}, fallbackModels);
} else {
await setOpenClawDefaultModel(ock, modelOverride, fallbackModels);

View File

@@ -157,6 +157,9 @@ export class ProviderService {
authMode: definition?.defaultAuthMode ?? 'api_key',
baseUrl,
apiProtocol: definition?.providerConfig?.api,
headers: (entry.headers && typeof entry.headers === 'object'
? (entry.headers as Record<string, string>)
: undefined),
model,
enabled: true,
isDefault: false,

View File

@@ -30,6 +30,7 @@ export function providerConfigToAccount(
apiProtocol: config.apiProtocol || (config.type === 'custom' || config.type === 'ollama'
? 'openai-completions'
: getProviderDefinition(config.type)?.providerConfig?.api),
headers: config.headers,
model: config.model,
fallbackModels: config.fallbackModels,
fallbackAccountIds: config.fallbackProviderIds,
@@ -47,6 +48,7 @@ export function providerAccountToConfig(account: ProviderAccount): ProviderConfi
type: account.vendorId,
baseUrl: account.baseUrl,
apiProtocol: account.apiProtocol,
headers: account.headers,
model: account.model,
fallbackModels: account.fallbackModels,
fallbackProviderIds: account.fallbackAccountIds,

View File

@@ -55,6 +55,7 @@ export interface ProviderConfig {
type: ProviderType;
baseUrl?: string;
apiProtocol?: ProviderProtocol;
headers?: Record<string, string>;
model?: string;
fallbackModels?: string[];
fallbackProviderIds?: string[];
@@ -118,6 +119,7 @@ export interface ProviderAccount {
authMode: ProviderAuthMode;
baseUrl?: string;
apiProtocol?: ProviderProtocol;
headers?: Record<string, string>;
model?: string;
fallbackModels?: string[];
fallbackAccountIds?: string[];

View File

@@ -557,10 +557,12 @@ function upsertOpenClawProviderEntry(
models: mergeProviderModels(registryModels, existingModels, runtimeModels),
};
if (options.apiKeyEnv) nextProvider.apiKey = options.apiKeyEnv;
if (options.headers && Object.keys(options.headers).length > 0) {
nextProvider.headers = options.headers;
} else {
delete nextProvider.headers;
if (options.headers !== undefined) {
if (Object.keys(options.headers).length > 0) {
nextProvider.headers = options.headers;
} else {
delete nextProvider.headers;
}
}
if (options.authHeader !== undefined) {
nextProvider.authHeader = options.authHeader;

View File

@@ -34,6 +34,7 @@ export interface ProviderConfig {
type: ProviderType;
baseUrl?: string;
apiProtocol?: 'openai-completions' | 'openai-responses' | 'anthropic-messages';
headers?: Record<string, string>;
model?: string;
fallbackModels?: string[];
fallbackProviderIds?: string[];