| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- export const AZURE_OPENAI_API_VERSION = "2024-10-21"
- export function isAzureOpenAiEndpoint(endpoint: string): boolean {
- const trimmed = endpoint.trim()
- if (!trimmed) return false
- try {
- const url = new URL(/^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`)
- return url.hostname.toLowerCase().endsWith(".openai.azure.com")
- } catch {
- return /(^|\/\/)[^/?#]+\.openai\.azure\.com(?::\d+)?(?:[/?#]|$)/i.test(trimmed)
- }
- }
- interface AzureParsedEndpoint {
- resourceBase: string
- deployment: string
- apiVersion: string
- }
- /**
- * Parse an Azure resource URL the user may have pasted in any of the
- * common shapes (bare host, host + deployment path, full chat URL).
- * The deployment embedded in the path wins over `fallbackDeployment`.
- */
- function parseAzureOpenAiEndpoint(
- endpoint: string,
- fallbackDeployment: string,
- fallbackApiVersion: string,
- ): AzureParsedEndpoint | null {
- const trimmed = endpoint.trim()
- if (!isAzureOpenAiEndpoint(trimmed)) return null
- let apiVersion = (fallbackApiVersion.trim() || AZURE_OPENAI_API_VERSION)
- const qMatch = trimmed.match(/[?&]api-version=([^&]+)/i)
- if (qMatch) apiVersion = decodeURIComponent(qMatch[1])
- const withoutQuery = trimmed.split("?")[0].replace(/\/+$/, "")
- const withDeployment = withoutQuery.match(
- /^(https?:\/\/[^/]+\.openai\.azure\.com)\/openai\/deployments\/([^/]+)(?:\/chat\/completions)?$/i,
- )
- if (withDeployment) {
- return {
- resourceBase: withDeployment[1],
- deployment: decodeURIComponent(withDeployment[2]),
- apiVersion,
- }
- }
- const resourceOnly = withoutQuery.match(/^(https?:\/\/[^/]+\.openai\.azure\.com)(?:\/openai)?$/i)
- if (resourceOnly) {
- const deployment = fallbackDeployment.trim()
- if (!deployment) return null
- return {
- resourceBase: resourceOnly[1],
- deployment,
- apiVersion,
- }
- }
- return null
- }
- export function buildAzureOpenAiUrl(
- endpoint: string,
- deployment: string,
- apiVersion: string,
- ): string {
- const parsed = parseAzureOpenAiEndpoint(endpoint, deployment, apiVersion)
- if (!parsed) {
- const trimmed = endpoint.replace(/\/+$/, "")
- const version = encodeURIComponent(apiVersion.trim() || AZURE_OPENAI_API_VERSION)
- const deploymentPath = `/openai/deployments/${encodeURIComponent(deployment)}/chat/completions`
- return `${trimmed}${deploymentPath}?api-version=${version}`
- }
- const version = encodeURIComponent(parsed.apiVersion)
- const dep = encodeURIComponent(parsed.deployment)
- return `${parsed.resourceBase}/openai/deployments/${dep}/chat/completions?api-version=${version}`
- }
|