mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-22 06:32:00 +00:00
xAI: normalize stale Grok transport to Responses
This commit is contained in:
committed by
Peter Steinberger
parent
f0ce658fbb
commit
2765fdc2dd
@@ -10,6 +10,14 @@ function isOpenAIApiBaseUrl(baseUrl?: string): boolean {
|
||||
return /^https?:\/\/api\.openai\.com(?:\/v1)?\/?$/i.test(trimmed);
|
||||
}
|
||||
|
||||
function isXaiApiBaseUrl(baseUrl?: string): boolean {
|
||||
const trimmed = baseUrl?.trim();
|
||||
if (!trimmed) {
|
||||
return false;
|
||||
}
|
||||
return /^https?:\/\/api\.x\.ai(?:\/v1)?\/?$/i.test(trimmed);
|
||||
}
|
||||
|
||||
function normalizeOpenAITransport(params: { provider: string; model: Model<Api> }): Model<Api> {
|
||||
if (normalizeProviderId(params.provider) !== "openai") {
|
||||
return params.model;
|
||||
@@ -29,11 +37,33 @@ function normalizeOpenAITransport(params: { provider: string; model: Model<Api>
|
||||
} as Model<Api>;
|
||||
}
|
||||
|
||||
function normalizeXaiTransport(params: { provider: string; model: Model<Api> }): Model<Api> {
|
||||
if (normalizeProviderId(params.provider) !== "xai") {
|
||||
return params.model;
|
||||
}
|
||||
|
||||
const useResponsesTransport =
|
||||
params.model.api === "openai-completions" &&
|
||||
(!params.model.baseUrl || isXaiApiBaseUrl(params.model.baseUrl));
|
||||
|
||||
if (!useResponsesTransport) {
|
||||
return params.model;
|
||||
}
|
||||
|
||||
return {
|
||||
...params.model,
|
||||
api: "openai-responses",
|
||||
} as Model<Api>;
|
||||
}
|
||||
|
||||
export function applyBuiltInResolvedProviderTransportNormalization(params: {
|
||||
provider: string;
|
||||
model: Model<Api>;
|
||||
}): Model<Api> {
|
||||
return normalizeOpenAITransport(params);
|
||||
return normalizeXaiTransport({
|
||||
...params,
|
||||
model: normalizeOpenAITransport(params),
|
||||
});
|
||||
}
|
||||
|
||||
export function normalizeResolvedProviderModel(params: {
|
||||
|
||||
@@ -1002,4 +1002,62 @@ describe("resolveModel", () => {
|
||||
baseUrl: "https://proxy.example.com/v1",
|
||||
});
|
||||
});
|
||||
|
||||
it("normalizes stale native xai completions transport to responses", () => {
|
||||
mockDiscoveredModel(discoverModels, {
|
||||
provider: "xai",
|
||||
modelId: "grok-4.20-beta-latest-reasoning",
|
||||
templateModel: buildForwardCompatTemplate({
|
||||
id: "grok-4.20-beta-latest-reasoning",
|
||||
name: "Grok 4.20 Beta Latest (Reasoning)",
|
||||
provider: "xai",
|
||||
api: "openai-completions",
|
||||
baseUrl: "https://api.x.ai/v1",
|
||||
}),
|
||||
});
|
||||
|
||||
const result = resolveModelForTest("xai", "grok-4.20-beta-latest-reasoning", "/tmp/agent");
|
||||
|
||||
expect(result.error).toBeUndefined();
|
||||
expect(result.model).toMatchObject({
|
||||
provider: "xai",
|
||||
id: "grok-4.20-beta-latest-reasoning",
|
||||
api: "openai-responses",
|
||||
baseUrl: "https://api.x.ai/v1",
|
||||
});
|
||||
});
|
||||
|
||||
it("normalizes stale native xai completions transport after plugin model normalization", () => {
|
||||
mockDiscoveredModel(discoverModels, {
|
||||
provider: "xai",
|
||||
modelId: "grok-4.20-beta-latest-reasoning",
|
||||
templateModel: buildForwardCompatTemplate({
|
||||
id: "grok-4.20-beta-latest-reasoning",
|
||||
name: "Grok 4.20 Beta Latest (Reasoning)",
|
||||
provider: "xai",
|
||||
api: "openai-completions",
|
||||
baseUrl: "https://api.x.ai/v1",
|
||||
}),
|
||||
});
|
||||
|
||||
const result = resolveModel("xai", "grok-4.20-beta-latest-reasoning", "/tmp/agent", undefined, {
|
||||
authStorage: { mocked: true } as never,
|
||||
modelRegistry: discoverModels({ mocked: true } as never, "/tmp/agent"),
|
||||
runtimeHooks: {
|
||||
buildProviderUnknownModelHintWithPlugin: () => undefined,
|
||||
prepareProviderDynamicModel: async () => {},
|
||||
runProviderDynamicModel: () => undefined,
|
||||
normalizeProviderResolvedModelWithPlugin: ({ provider, context }) =>
|
||||
provider === "xai" ? (context.model as never) : undefined,
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.error).toBeUndefined();
|
||||
expect(result.model).toMatchObject({
|
||||
provider: "xai",
|
||||
id: "grok-4.20-beta-latest-reasoning",
|
||||
api: "openai-responses",
|
||||
baseUrl: "https://api.x.ai/v1",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -122,12 +122,9 @@ function normalizeResolvedModel(params: {
|
||||
model: normalizedInputModel,
|
||||
},
|
||||
}) as Model<Api> | undefined;
|
||||
if (pluginNormalized) {
|
||||
return normalizeModelCompat(pluginNormalized);
|
||||
}
|
||||
return normalizeResolvedProviderModel({
|
||||
provider: params.provider,
|
||||
model: normalizedInputModel,
|
||||
model: pluginNormalized ?? normalizedInputModel,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user