





















@@ -963,15 +963,73 @@ function createOpenAICompletionsClient(
963963apiKey: string,
964964optionHeaders?: Record<string, string>,
965965) {
966+const clientConfig = buildOpenAICompletionsClientConfig(model, context, optionHeaders);
966967return new OpenAI({
967968 apiKey,
968-baseURL: model.baseUrl,
969+baseURL: clientConfig.baseURL,
969970dangerouslyAllowBrowser: true,
970-defaultHeaders: buildOpenAIClientHeaders(model, context, optionHeaders),
971+defaultHeaders: clientConfig.defaultHeaders,
972+defaultQuery: clientConfig.defaultQuery,
971973fetch: buildGuardedModelFetch(model),
972974});
973975}
974976977+function isAzureOpenAICompatibleHost(hostname: string): boolean {
978+return (
979+hostname.endsWith(".openai.azure.com") ||
980+hostname.endsWith(".services.ai.azure.com") ||
981+hostname.endsWith(".cognitiveservices.azure.com")
982+);
983+}
984+985+function buildOpenAICompletionsClientConfig(
986+model: Model<Api>,
987+context: Context,
988+optionHeaders?: Record<string, string>,
989+): {
990+baseURL: string;
991+defaultHeaders: Record<string, string>;
992+defaultQuery?: Record<string, string>;
993+} {
994+const headers = buildOpenAIClientHeaders(model, context, optionHeaders);
995+const defaultQuery: Record<string, string> = {};
996+let baseURL = model.baseUrl;
997+let isAzureHost = false;
998+999+try {
1000+const parsed = new URL(model.baseUrl);
1001+isAzureHost = isAzureOpenAICompatibleHost(parsed.hostname.toLowerCase());
1002+parsed.searchParams.forEach((value, key) => {
1003+if (value) {
1004+defaultQuery[key] = value;
1005+}
1006+});
1007+parsed.search = "";
1008+baseURL = parsed.toString().replace(/\/$/, "");
1009+} catch {
1010+// Keep the configured base URL unchanged; the OpenAI SDK will surface invalid URLs.
1011+}
1012+1013+if (isAzureHost) {
1014+const apiVersionHeader = Object.keys(headers).find(
1015+(key) => key.toLowerCase() === "api-version",
1016+);
1017+if (apiVersionHeader) {
1018+const apiVersion = headers[apiVersionHeader]?.trim();
1019+delete headers[apiVersionHeader];
1020+if (apiVersion && !defaultQuery["api-version"]) {
1021+defaultQuery["api-version"] = apiVersion;
1022+}
1023+}
1024+}
1025+1026+return {
1027+ baseURL,
1028+defaultHeaders: headers,
1029+defaultQuery: Object.keys(defaultQuery).length > 0 ? defaultQuery : undefined,
1030+};
1031+}
1032+9751033export function createOpenAICompletionsTransportStreamFn(): StreamFn {
9761034return (model, context, options) => {
9771035const eventStream = createAssistantMessageEventStream();
@@ -1577,5 +1635,6 @@ function mapStopReason(reason: string | null) {
15771635}
1578163615791637export const __testing = {
1638+ buildOpenAICompletionsClientConfig,
15801639 processOpenAICompletionsStream,
15811640};
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。