fix(providers): complete custom openai-responses support (#436)

This commit is contained in:
Felix
2026-03-12 16:19:05 +08:00
committed by GitHub
Unverified
parent 272432783a
commit c0c8701cc3
13 changed files with 414 additions and 67 deletions

View File

@@ -26,16 +26,35 @@ type RuntimeProviderSyncContext = {
api: string;
};
function normalizeProviderBaseUrl(config: ProviderConfig, baseUrl?: string): string | undefined {
function normalizeProviderBaseUrl(
config: ProviderConfig,
baseUrl?: string,
apiProtocol?: string,
): string | undefined {
if (!baseUrl) {
return undefined;
}
const normalized = baseUrl.trim().replace(/\/+$/, '');
if (config.type === 'minimax-portal' || config.type === 'minimax-portal-cn') {
return baseUrl.replace(/\/v1$/, '').replace(/\/anthropic$/, '').replace(/\/$/, '') + '/anthropic';
return normalized.replace(/\/v1$/, '').replace(/\/anthropic$/, '').replace(/\/$/, '') + '/anthropic';
}
return baseUrl;
if (config.type === 'custom' || config.type === 'ollama') {
const protocol = apiProtocol || config.apiProtocol || 'openai-completions';
if (protocol === 'openai-responses') {
return normalized.replace(/\/responses?$/i, '');
}
if (protocol === 'openai-completions') {
return normalized.replace(/\/chat\/completions$/i, '');
}
if (protocol === 'anthropic-messages') {
return normalized.replace(/\/v1\/messages$/i, '').replace(/\/messages$/i, '');
}
}
return normalized;
}
function shouldUseExplicitDefaultOverride(config: ProviderConfig, runtimeProviderKey: string): boolean {
@@ -266,7 +285,7 @@ async function syncRuntimeProviderConfig(
context: RuntimeProviderSyncContext,
): Promise<void> {
await syncProviderConfigToOpenClaw(context.runtimeProviderKey, config.model, {
baseUrl: normalizeProviderBaseUrl(config, config.baseUrl || context.meta?.baseUrl),
baseUrl: normalizeProviderBaseUrl(config, config.baseUrl || context.meta?.baseUrl, context.api),
api: context.api,
apiKeyEnv: context.meta?.apiKeyEnv,
headers: context.meta?.headers,
@@ -289,7 +308,7 @@ async function syncCustomProviderAgentModel(
const modelId = config.model;
await updateAgentModelProvider(runtimeProviderKey, {
baseUrl: config.baseUrl,
baseUrl: normalizeProviderBaseUrl(config, config.baseUrl, config.apiProtocol || 'openai-completions'),
api: config.apiProtocol || 'openai-completions',
models: modelId ? [{ id: modelId, name: modelId }] : [],
apiKey: resolvedKey,
@@ -346,7 +365,7 @@ export async function syncUpdatedProviderToRuntime(
if (config.type !== 'custom') {
if (shouldUseExplicitDefaultOverride(config, ock)) {
await setOpenClawDefaultModelWithOverride(ock, modelOverride, {
baseUrl: normalizeProviderBaseUrl(config, config.baseUrl || context.meta?.baseUrl),
baseUrl: normalizeProviderBaseUrl(config, config.baseUrl || context.meta?.baseUrl, context.api),
api: context.api,
apiKeyEnv: context.meta?.apiKeyEnv,
headers: context.meta?.headers,
@@ -356,7 +375,7 @@ export async function syncUpdatedProviderToRuntime(
}
} else {
await setOpenClawDefaultModelWithOverride(ock, modelOverride, {
baseUrl: config.baseUrl,
baseUrl: normalizeProviderBaseUrl(config, config.baseUrl, config.apiProtocol || 'openai-completions'),
api: config.apiProtocol || 'openai-completions',
}, fallbackModels);
}
@@ -423,12 +442,16 @@ export async function syncDefaultProviderToRuntime(
if (provider.type === 'custom') {
await setOpenClawDefaultModelWithOverride(ock, modelOverride, {
baseUrl: provider.baseUrl,
baseUrl: normalizeProviderBaseUrl(provider, provider.baseUrl, provider.apiProtocol || 'openai-completions'),
api: provider.apiProtocol || 'openai-completions',
}, fallbackModels);
} else if (shouldUseExplicitDefaultOverride(provider, ock)) {
await setOpenClawDefaultModelWithOverride(ock, modelOverride, {
baseUrl: normalizeProviderBaseUrl(provider, provider.baseUrl || getProviderConfig(provider.type)?.baseUrl),
baseUrl: normalizeProviderBaseUrl(
provider,
provider.baseUrl || getProviderConfig(provider.type)?.baseUrl,
provider.apiProtocol || getProviderConfig(provider.type)?.api,
),
api: provider.apiProtocol || getProviderConfig(provider.type)?.api,
apiKeyEnv: getProviderConfig(provider.type)?.apiKeyEnv,
headers: getProviderConfig(provider.type)?.headers,
@@ -518,7 +541,7 @@ export async function syncDefaultProviderToRuntime(
) {
const modelId = provider.model;
await updateAgentModelProvider(ock, {
baseUrl: provider.baseUrl,
baseUrl: normalizeProviderBaseUrl(provider, provider.baseUrl, provider.apiProtocol || 'openai-completions'),
api: provider.apiProtocol || 'openai-completions',
models: modelId ? [{ id: modelId, name: modelId }] : [],
apiKey: providerKey,