fix(providers): complete custom openai-responses support (#436)
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user