From 8921b052524e3d012017e55cd647bc69c686ffd2 Mon Sep 17 00:00:00 2001 From: centdix <40307056+centdix@users.noreply.github.com> Date: Tue, 16 Dec 2025 14:45:13 +0100 Subject: [PATCH] fix(aichat): fix for azure responses api not available in some region (#7387) * fix completion fallback * cleaning * cache * cleaning * cleaning --- .../copilot/chat/AIChatManager.svelte.ts | 106 ++++++++++++------ 1 file changed, 74 insertions(+), 32 deletions(-) diff --git a/frontend/src/lib/components/copilot/chat/AIChatManager.svelte.ts b/frontend/src/lib/components/copilot/chat/AIChatManager.svelte.ts index 7a6a68c289..611dc4f2d3 100644 --- a/frontend/src/lib/components/copilot/chat/AIChatManager.svelte.ts +++ b/frontend/src/lib/components/copilot/chat/AIChatManager.svelte.ts @@ -71,6 +71,8 @@ class AIChatManager { historyManager = new HistoryManager() abortController: AbortController | undefined = undefined inlineAbortController: AbortController | undefined = undefined + // Flag to skip Responses API if it's not available (e.g., Azure region doesn't support it) + skipResponsesApi = false mode = $state(AIMode.NAVIGATOR) readonly isOpen = $derived(chatState.size > 0) @@ -421,9 +423,6 @@ class AIChatManager { const isOpenAI = model.provider === 'openai' || model.provider === 'azure_openai' const isAnthropic = model.provider === 'anthropic' - let completion: any - let parseFn: any - const messageParams = [ systemMessage, ...messages, @@ -433,40 +432,83 @@ class AIChatManager { // For OpenAI/Azure, try Responses API first, fallback to Completions API if (isOpenAI) { - try { - completion = await getOpenAIResponsesCompletion( - messageParams, - abortController, - toolDefs - ) - parseFn = parseOpenAIResponsesCompletion - } catch (err) { - console.warn('OpenAI Responses API failed, falling back to Completions API:', err) - completion = await getCompletion(messageParams, abortController, toolDefs, { + let useCompletionsApi = this.skipResponsesApi + if (!this.skipResponsesApi) { + try { + const completion = await getOpenAIResponsesCompletion( + messageParams, + abortController, + toolDefs + ) + const continueCompletion = await parseOpenAIResponsesCompletion( + completion, + callbacks, + messages, + addedMessages, + tools, + helpers + ) + if (!continueCompletion) { + break + } + } catch (err) { + console.warn('OpenAI Responses API failed, falling back to Completions API:', err) + // If the error indicates Responses API is not available in this region, skip it for future requests + const errorMessage = err instanceof Error ? err.message : String(err) + if (errorMessage.includes('Responses API is not enabled')) { + this.skipResponsesApi = true + } + useCompletionsApi = true + } + } + + // Use Completions API if Responses API is not available or failed + if (useCompletionsApi) { + const completion = await getCompletion(messageParams, abortController, toolDefs, { forceCompletions: true }) - parseFn = parseOpenAICompletion + const continueCompletion = await parseOpenAICompletion( + completion, + callbacks, + messages, + addedMessages, + tools, + helpers + ) + if (!continueCompletion) { + break + } } } else if (isAnthropic) { - completion = await getAnthropicCompletion(messageParams, abortController, toolDefs) - parseFn = parseAnthropicCompletion + const completion = await getAnthropicCompletion(messageParams, abortController, toolDefs) + if (completion) { + const continueCompletion = await parseAnthropicCompletion( + completion, + callbacks, + messages, + addedMessages, + tools, + helpers, + abortController + ) + if (!continueCompletion) { + break + } + } } else { - completion = await getCompletion(messageParams, abortController, toolDefs) - parseFn = parseOpenAICompletion - } - - if (completion) { - const continueCompletion = await parseFn( - completion as any, - callbacks, - messages, - addedMessages, - tools, - helpers, - isAnthropic ? abortController : undefined - ) - if (!continueCompletion) { - break + const completion = await getCompletion(messageParams, abortController, toolDefs) + if (completion) { + const continueCompletion = await parseOpenAICompletion( + completion, + callbacks, + messages, + addedMessages, + tools, + helpers + ) + if (!continueCompletion) { + break + } } } }