Browse Source

Add azure openai support

Saoud Rizwan 1 year ago
parent
commit
3ceb881de2
2 changed files with 18 additions and 6 deletions
  1. 16 5
      src/api/openai.ts
  2. 2 1
      src/utils/openai-format.ts

+ 16 - 5
src/api/openai.ts

@@ -1,5 +1,5 @@
 import { Anthropic } from "@anthropic-ai/sdk"
-import OpenAI from "openai"
+import OpenAI, { AzureOpenAI } from "openai"
 import { ApiHandler, ApiHandlerMessageResponse } from "."
 import { ApiHandlerOptions, ModelInfo, openAiModelInfoSaneDefaults } from "../shared/api"
 import { convertToAnthropicMessage, convertToOpenAiMessages } from "../utils/openai-format"
@@ -10,10 +10,21 @@ export class OpenAiHandler implements ApiHandler {
 
 	constructor(options: ApiHandlerOptions) {
 		this.options = options
-		this.client = new OpenAI({
-			baseURL: this.options.openAiBaseUrl,
-			apiKey: this.options.openAiApiKey,
-		})
+		// Azure API shape slightly differs from the core API shape: https://github.com/openai/openai-node?tab=readme-ov-file#microsoft-azure-openai
+		if (this.options.openAiBaseUrl?.toLowerCase().includes("azure.com")) {
+			this.client = new AzureOpenAI({
+				baseURL: this.options.openAiBaseUrl,
+				apiKey: this.options.openAiApiKey,
+				// https://learn.microsoft.com/en-us/azure/ai-services/openai/api-version-deprecation
+				// https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#api-specs
+				apiVersion: "2024-08-01-preview",
+			})
+		} else {
+			this.client = new OpenAI({
+				baseURL: this.options.openAiBaseUrl,
+				apiKey: this.options.openAiApiKey,
+			})
+		}
 	}
 
 	async createMessage(

+ 2 - 1
src/utils/openai-format.ts

@@ -65,6 +65,7 @@ export function convertToOpenAiMessages(
 				// I ran into an issue where if I gave feedback for one of many tool uses, the request would fail.
 				// "Messages following `tool_use` blocks must begin with a matching number of `tool_result` blocks."
 				// Therefore we need to send these images after the tool result messages
+				// NOTE: it's actually okay to have multiple user messages in a row, the model will treat them as a continuation of the same input (this way works better than combining them into one message, since the tool result specifically mentions (see following user message for image)
 				if (toolResultImages.length > 0) {
 					openAiMessages.push({
 						role: "user",
@@ -106,7 +107,7 @@ export function convertToOpenAiMessages(
 					{ nonToolMessages: [], toolMessages: [] }
 				)
 
-				// Process non-tool messages FIRST
+				// Process non-tool messages
 				let content: string | undefined
 				if (nonToolMessages.length > 0) {
 					content = nonToolMessages