From 6cca4ee3d58c3884e39f579b824796229b69b7c3 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 11:33:03 +0000 Subject: [PATCH 1/6] feat: integrate Azure AI Foundry GPT 5.5 model This commit adds support for the "Azure GPT 5.5" model, powered by Azure AI Foundry. Key changes: - Added `@ai-sdk/azure` as a dependency. - Updated `lib/utils/index.ts` to include the Azure provider initialization and logic for the "Azure GPT 5.5" model. - Added "Azure GPT 5.5" to the Model Selection UI in the settings page. - Added new environment variables (`AZURE_RESOURCE_NAME`, `AZURE_API_KEY`, `AZURE_DEPLOYMENT_NAME`) to `.env.local.example`. Tested by running `bun run build` which passed successfully, ensuring type safety and correct integration. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com> --- .env.local.example | 5 ++++ bun.lock | 13 +++++++++++ .../components/model-selection-form.tsx | 8 +++++++ lib/utils/index.ts | 23 ++++++++++++++++++- package.json | 1 + 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/.env.local.example b/.env.local.example index e52eec0c..633aed20 100644 --- a/.env.local.example +++ b/.env.local.example @@ -17,6 +17,11 @@ NEXT_PUBLIC_COMPOSIO_USER_ID=user@example.com # NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN=your_mapbox_public_token_here # AI Provider API Keys +# Azure AI Foundry (Azure OpenAI) +AZURE_RESOURCE_NAME=your_azure_resource_name_here +AZURE_API_KEY=your_azure_api_key_here +AZURE_DEPLOYMENT_NAME=gpt-4o + # Gemini 3.1 Pro (Google Generative AI) GEMINI_3_PRO_API_KEY=your_gemini_3_pro_api_key_here diff --git a/bun.lock b/bun.lock index f101e5d7..d123cca0 100644 --- a/bun.lock +++ b/bun.lock @@ -6,6 +6,7 @@ "dependencies": { "@ai-sdk/amazon-bedrock": "^1.1.6", "@ai-sdk/anthropic": "^1.2.12", + "@ai-sdk/azure": "^3.0.64", "@ai-sdk/google": "^1.2.22", "@ai-sdk/openai": "^1.3.24", "@ai-sdk/xai": "^1.2.18", @@ -111,6 +112,8 @@ "@ai-sdk/anthropic": ["@ai-sdk/anthropic@1.2.12", "", { "dependencies": { "@ai-sdk/provider": "1.1.3", "@ai-sdk/provider-utils": "2.2.8" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-YSzjlko7JvuiyQFmI9RN1tNZdEiZxc+6xld/0tq/VkJaHpEzGAb1yiNxxvmYVcjvfu/PcvCxAAYXmTYQQ63IHQ=="], + "@ai-sdk/azure": ["@ai-sdk/azure@3.0.64", "", { "dependencies": { "@ai-sdk/openai": "3.0.63", "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.27" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-jNcgI9tPzpuPJhAvB6twCiH9UGOOBFRPxFWOuDI4qts347q/+iFtc+AvkrKU/JsbSSwGeeW4qslQRri4SmWipg=="], + "@ai-sdk/google": ["@ai-sdk/google@1.2.22", "", { "dependencies": { "@ai-sdk/provider": "1.1.3", "@ai-sdk/provider-utils": "2.2.8" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-Ppxu3DIieF1G9pyQ5O1Z646GYR0gkC57YdBqXJ82qvCdhEhZHu0TWhmnOoeIWe2olSbuDeoOY+MfJrW8dzS3Hw=="], "@ai-sdk/openai": ["@ai-sdk/openai@1.3.24", "", { "dependencies": { "@ai-sdk/provider": "1.1.3", "@ai-sdk/provider-utils": "2.2.8" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-GYXnGJTHRTZc4gJMSmFRgEQudjqd4PUN0ZjQhPwOAYH1yOAvQoG/Ikqs+HyISRbLPCrhbZnPKCNHuRU4OfpW0Q=="], @@ -655,6 +658,8 @@ "@so-ric/colorspace": ["@so-ric/colorspace@1.1.6", "", { "dependencies": { "color": "^5.0.2", "text-hex": "1.0.x" } }, "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw=="], + "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], + "@supabase/auth-js": ["@supabase/auth-js@2.90.1", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-vxb66dgo6h3yyPbR06735Ps+dK3hj0JwS8w9fdQPVZQmocSTlKUW5MfxSy99mN0XqCCuLMQ3jCEiIIUU23e9ng=="], "@supabase/functions-js": ["@supabase/functions-js@2.90.1", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-x9mV9dF1Lam9qL3zlpP6mSM5C9iqMPtF5B/tU1Jj/F0ufX5mjDf9ghVBaErVxmrQJRL4+iMKWKY2GnODkpS8tw=="], @@ -2549,6 +2554,12 @@ "@ai-sdk/anthropic/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@2.2.8", "", { "dependencies": { "@ai-sdk/provider": "1.1.3", "nanoid": "^3.3.8", "secure-json-parse": "^2.7.0" }, "peerDependencies": { "zod": "^3.23.8" } }, "sha512-fqhG+4sCVv8x7nFzYnFo19ryhAa3w096Kmc3hWxMQfW/TubPOmt3A6tYZhl4mUfQWWQMsuSkLrtjlWuXBVSGQA=="], + "@ai-sdk/azure/@ai-sdk/openai": ["@ai-sdk/openai@3.0.63", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.27" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-4yY/m8a57MNNVoJCsXuNblKf6BO4yuAuLKRX4tzSNffBEBSp1FlcWdPE0Z4FkqUeS0AJhYSSqp0GIiA/cIcDNA=="], + + "@ai-sdk/azure/@ai-sdk/provider": ["@ai-sdk/provider@3.0.10", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw=="], + + "@ai-sdk/azure/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.27", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.8" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ubkAJ+xODouwtmN1tYlvTPphH1hPOBfZaEQe8U7skGvFAnIRs9PPpsq57bC2+Ky/MB4yzhd6YOsxTAx9sGpazw=="], + "@ai-sdk/google/@ai-sdk/provider": ["@ai-sdk/provider@1.1.3", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg=="], "@ai-sdk/google/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@2.2.8", "", { "dependencies": { "@ai-sdk/provider": "1.1.3", "nanoid": "^3.3.8", "secure-json-parse": "^2.7.0" }, "peerDependencies": { "zod": "^3.23.8" } }, "sha512-fqhG+4sCVv8x7nFzYnFo19ryhAa3w096Kmc3hWxMQfW/TubPOmt3A6tYZhl4mUfQWWQMsuSkLrtjlWuXBVSGQA=="], @@ -2781,6 +2792,8 @@ "yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + "@ai-sdk/azure/@ai-sdk/provider-utils/eventsource-parser": ["eventsource-parser@3.0.8", "", {}, "sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ=="], + "@ai-sdk/react/@ai-sdk/provider-utils/@ai-sdk/provider": ["@ai-sdk/provider@1.1.3", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg=="], "@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], diff --git a/components/settings/components/model-selection-form.tsx b/components/settings/components/model-selection-form.tsx index bc6164ba..95dae1ea 100644 --- a/components/settings/components/model-selection-form.tsx +++ b/components/settings/components/model-selection-form.tsx @@ -58,6 +58,14 @@ const models = [ badge: "Expert", badgeVariant: "outline" as const, }, + { + id: "Azure GPT 5.5", + name: "Azure GPT 5.5", + description: "Enterprise-grade intelligence powered by Azure AI Foundry, delivering high-reliability and security.", + icon: Cpu, + badge: "Enterprise", + badgeVariant: "outline" as const, + }, ]; export function ModelSelectionForm({ form }: ModelSelectionFormProps) { diff --git a/lib/utils/index.ts b/lib/utils/index.ts index 15565281..8866207c 100644 --- a/lib/utils/index.ts +++ b/lib/utils/index.ts @@ -5,7 +5,9 @@ import { createOpenAI } from '@ai-sdk/openai' import { createGoogleGenerativeAI } from '@ai-sdk/google' import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock' import { createXai } from '@ai-sdk/xai'; +import { createAzure } from '@ai-sdk/azure'; import { v4 as uuidv4 } from 'uuid'; +import { LanguageModel } from 'ai' export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) @@ -21,7 +23,7 @@ export function generateUUID(): string { */ export { generateUUID as nanoid }; -export async function getModel(requireVision: boolean = false) { +export async function getModel(requireVision: boolean = false): Promise { const selectedModel = await getSelectedModel(); const xaiApiKey = process.env.XAI_API_KEY; @@ -31,6 +33,9 @@ export async function getModel(requireVision: boolean = false) { const awsRegion = process.env.AWS_REGION; const bedrockModelId = process.env.BEDROCK_MODEL_ID || 'anthropic.claude-3-5-sonnet-20241022-v2:0'; const openaiApiKey = process.env.OPENAI_API_KEY; + const azureResourceName = process.env.AZURE_RESOURCE_NAME; + const azureApiKey = process.env.AZURE_API_KEY; + const azureDeploymentName = process.env.AZURE_DEPLOYMENT_NAME || 'gpt-4o'; if (selectedModel) { switch (selectedModel) { @@ -76,6 +81,22 @@ export async function getModel(requireVision: boolean = false) { console.error('User selected "GPT-5.1" but OPENAI_API_KEY is not set.'); throw new Error('Selected model is not configured.'); } + case 'Azure GPT 5.5': + if (azureResourceName && azureApiKey) { + const azure = createAzure({ + resourceName: azureResourceName, + apiKey: azureApiKey, + }); + try { + return azure(azureDeploymentName) as unknown as LanguageModel; + } catch (error) { + console.error('Selected model "Azure GPT 5.5" is configured but failed to initialize.', error); + throw new Error('Failed to initialize selected model.'); + } + } else { + console.error('User selected "Azure GPT 5.5" but Azure environment variables are not set.'); + throw new Error('Selected model is not configured.'); + } } } diff --git a/package.json b/package.json index 87066925..1bb5f735 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "dependencies": { "@ai-sdk/amazon-bedrock": "^1.1.6", "@ai-sdk/anthropic": "^1.2.12", + "@ai-sdk/azure": "^3.0.64", "@ai-sdk/google": "^1.2.22", "@ai-sdk/openai": "^1.3.24", "@ai-sdk/xai": "^1.2.18", From ed5de32f52cc4f54cc7c9994557245b539d4e6ee Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 12:09:51 +0000 Subject: [PATCH 2/6] feat: update Azure integration with endpoint support - Added support for `AZURE_ENDPOINT` environment variable. - Configured `baseURL` in `createAzure` using the new endpoint variable. - Updated `.env.local.example` with the endpoint placeholder and set default deployment to `gpt-5.5`. - Verified build success. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com> --- .env.local.example | 3 ++- lib/utils/index.ts | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.env.local.example b/.env.local.example index 633aed20..cbe3c452 100644 --- a/.env.local.example +++ b/.env.local.example @@ -19,8 +19,9 @@ NEXT_PUBLIC_COMPOSIO_USER_ID=user@example.com # AI Provider API Keys # Azure AI Foundry (Azure OpenAI) AZURE_RESOURCE_NAME=your_azure_resource_name_here +AZURE_ENDPOINT=your_azure_endpoint_here AZURE_API_KEY=your_azure_api_key_here -AZURE_DEPLOYMENT_NAME=gpt-4o +AZURE_DEPLOYMENT_NAME=gpt-5.5 # Gemini 3.1 Pro (Google Generative AI) GEMINI_3_PRO_API_KEY=your_gemini_3_pro_api_key_here diff --git a/lib/utils/index.ts b/lib/utils/index.ts index 8866207c..48da73ab 100644 --- a/lib/utils/index.ts +++ b/lib/utils/index.ts @@ -35,6 +35,7 @@ export async function getModel(requireVision: boolean = false): Promise Date: Tue, 12 May 2026 15:27:30 +0300 Subject: [PATCH 3/6] Remove unused azureResourceName variable Removed unused azureResourceName environment variable. --- lib/utils/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/utils/index.ts b/lib/utils/index.ts index 48da73ab..d5acf8e1 100644 --- a/lib/utils/index.ts +++ b/lib/utils/index.ts @@ -33,7 +33,6 @@ export async function getModel(requireVision: boolean = false): Promise Date: Tue, 12 May 2026 12:42:11 +0000 Subject: [PATCH 4/6] I have enhanced the Azure integration and improved the robustness of `getSystemPrompt`. Here is a summary of the changes: - Added Azure OpenAI to the default model fallback chain (Gemini -> Grok -> Azure -> Bedrock -> OpenAI). - Set the default Azure deployment name to `gpt-5.5`. - Improved `getSystemPrompt` robustness by avoiding DB queries for anonymous users. - Updated the task completion logic to use the actual user ID when available. - Verified that the build is successful. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com> --- app/actions.tsx | 6 +++++- lib/actions/chat.ts | 2 +- lib/utils/index.ts | 18 ++++++++++++++++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/app/actions.tsx b/app/actions.tsx index 50e985bf..9d257836 100644 --- a/app/actions.tsx +++ b/app/actions.tsx @@ -397,7 +397,11 @@ async function submit(formData?: FormData, skip?: boolean) { } as CoreMessage) } - const userId = 'anonymous' + const { getCurrentUserIdOnServer } = await import( + '@/lib/auth/get-current-user' + ) + const actualUserId = await getCurrentUserIdOnServer() + const userId = actualUserId || 'anonymous' const currentSystemPrompt = (await getSystemPrompt(userId)) || '' const mapProvider = formData?.get('mapProvider') as 'mapbox' | 'google' diff --git a/lib/actions/chat.ts b/lib/actions/chat.ts index f36f2cf6..54e31347 100644 --- a/lib/actions/chat.ts +++ b/lib/actions/chat.ts @@ -169,7 +169,7 @@ export async function saveSystemPrompt( export async function getSystemPrompt( userId: string ): Promise { - if (!userId) return null + if (!userId || userId === 'anonymous') return null try { const result = await db.select({ systemPrompt: users.systemPrompt }) diff --git a/lib/utils/index.ts b/lib/utils/index.ts index d5acf8e1..f46d22aa 100644 --- a/lib/utils/index.ts +++ b/lib/utils/index.ts @@ -33,9 +33,10 @@ export async function getModel(requireVision: boolean = false): Promise Grok -> Bedrock -> OpenAI + // Default behavior: Gemini -> Grok -> Azure -> Bedrock -> OpenAI if (gemini3ProApiKey) { const google = createGoogleGenerativeAI({ apiKey: gemini3ProApiKey, @@ -125,6 +126,19 @@ export async function getModel(requireVision: boolean = false): Promise Date: Wed, 13 May 2026 11:45:28 +0000 Subject: [PATCH 5/6] I've finalized the Azure integration and implemented several robustness fixes. I refined the Azure endpoint handling by stripping the `/v1` suffix for compatibility and integrated Azure OpenAI into the default model fallback chain. I also improved the reliability of the system prompts and the finalization process with better error handling and guest user checks. Finally, I've confirmed that the production build is successful. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com> --- app/actions.tsx | 13 +++++++++---- lib/actions/chat.ts | 8 ++++++-- lib/utils/index.ts | 4 ++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/app/actions.tsx b/app/actions.tsx index 9d257836..3547909f 100644 --- a/app/actions.tsx +++ b/app/actions.tsx @@ -397,10 +397,15 @@ async function submit(formData?: FormData, skip?: boolean) { } as CoreMessage) } - const { getCurrentUserIdOnServer } = await import( - '@/lib/auth/get-current-user' - ) - const actualUserId = await getCurrentUserIdOnServer() + let actualUserId: string | null = null; + try { + const { getCurrentUserIdOnServer } = await import( + '@/lib/auth/get-current-user' + ) + actualUserId = await getCurrentUserIdOnServer() + } catch (authError) { + console.error('Error retrieving user ID in submit:', authError); + } const userId = actualUserId || 'anonymous' const currentSystemPrompt = (await getSystemPrompt(userId)) || '' const mapProvider = formData?.get('mapProvider') as 'mapbox' | 'google' diff --git a/lib/actions/chat.ts b/lib/actions/chat.ts index 54e31347..ac010ca6 100644 --- a/lib/actions/chat.ts +++ b/lib/actions/chat.ts @@ -172,14 +172,18 @@ export async function getSystemPrompt( if (!userId || userId === 'anonymous') return null try { + // console.log(`getSystemPrompt: Fetching prompt for user: ${userId}`); const result = await db.select({ systemPrompt: users.systemPrompt }) .from(users) .where(eq(users.id, userId)) .limit(1); return result[0]?.systemPrompt || null; - } catch (error) { - console.error('getSystemPrompt: Error:', error) + } catch (error: any) { + console.error('getSystemPrompt: Error:', error.message || error); + if (error.stack) { + console.error('getSystemPrompt: Stack trace:', error.stack); + } return null } } diff --git a/lib/utils/index.ts b/lib/utils/index.ts index f46d22aa..1fe8d38a 100644 --- a/lib/utils/index.ts +++ b/lib/utils/index.ts @@ -86,7 +86,7 @@ export async function getModel(requireVision: boolean = false): Promise Date: Wed, 13 May 2026 11:48:36 +0000 Subject: [PATCH 6/6] feat: prioritize Azure OpenAI in fallback and improve endpoint support - Moved Azure OpenAI (via endpoint or resource) to the top of the default provider fallback chain. - Updated Azure endpoint logic to use `createOpenAI` with `baseURL` for better compatibility with Azure AI Foundry's OpenAI-compatible endpoints. - Maintained support for standard Azure OpenAI resources as a secondary option. - Verified build success. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com> --- lib/utils/index.ts | 54 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/lib/utils/index.ts b/lib/utils/index.ts index 1fe8d38a..81220a29 100644 --- a/lib/utils/index.ts +++ b/lib/utils/index.ts @@ -83,16 +83,26 @@ export async function getModel(requireVision: boolean = false): Promise Grok -> Azure -> Bedrock -> OpenAI + // Default behavior: Azure -> Gemini -> Grok -> Bedrock -> OpenAI + if (azureEndpoint && azureApiKey) { + const azureOpenAI = createOpenAI({ + baseURL: azureEndpoint, + apiKey: azureApiKey, + }); + try { + return azureOpenAI(azureDeploymentName); + } catch (error) { + console.warn('Azure OpenAI API (via endpoint) unavailable, falling back to next provider:', error); + } + } + + if (azureResourceName && azureApiKey) { + const azure = createAzure({ + resourceName: azureResourceName, + apiKey: azureApiKey, + }); + try { + return azure(azureDeploymentName) as unknown as LanguageModel; + } catch (error) { + console.warn('Azure OpenAI API (via resource) unavailable, falling back to next provider:', error); + } + } + if (gemini3ProApiKey) { const google = createGoogleGenerativeAI({ apiKey: gemini3ProApiKey, @@ -126,18 +160,6 @@ export async function getModel(requireVision: boolean = false): Promise