File size: 5,853 Bytes
1390f29 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | #!/usr/bin/env python3
"""
Validate that the configured Azure OpenAI resource supports the Responses
API before enabling USE_RESPONSES_API=true (see .env.example and
agents/analyzer.py / agents/synthesis.py).
Responses API requires a specific minimum preview api-version and has
historically had narrower deployment/region availability than Chat
Completions -- this is a required go/no-go check, not an assumption
(this codebase has been burned before by unverified API-version
assumptions; see AZURE_API_VERSION_FIX.md and CLAUDE.md's version history).
Run: python scripts/validate_responses_api.py
"""
import os
import sys
from dotenv import load_dotenv
from openai import AzureOpenAI
load_dotenv()
# Ordered oldest -> newest. Azure OpenAI's own error message names the exact
# minimum version it requires, so this list only needs to bracket that value
# closely enough to report it -- it is not meant to be exhaustive.
CANDIDATE_VERSIONS = [
"2024-05-01-preview",
"2024-08-01-preview",
"2024-10-01-preview",
"2024-12-01-preview",
"2025-01-01-preview",
"2025-02-01-preview",
"2025-03-01-preview",
"2025-04-01-preview",
]
def _try_responses_call(client: AzureOpenAI, deployment: str) -> tuple[bool, str]:
try:
response = client.responses.create(
model=deployment,
instructions="You are a helpful assistant.",
input="Say hello in one word.",
max_output_tokens=20,
)
return True, response.output_text
except Exception as e:
return False, str(e)
def main() -> bool:
print("=" * 80)
print("Validating Azure OpenAI Responses API availability")
print("=" * 80)
print()
endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
api_key = os.getenv("AZURE_OPENAI_API_KEY")
deployment = os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME")
configured_version = os.getenv("AZURE_OPENAI_API_VERSION", "2024-02-01")
print(f"Endpoint: {endpoint}")
print(f"Deployment: {deployment}")
print(f"Currently configured AZURE_OPENAI_API_VERSION: {configured_version}")
print()
# Step 1: does the *currently configured* version work?
client = AzureOpenAI(api_key=api_key, api_version=configured_version, azure_endpoint=endpoint)
ok, detail = _try_responses_call(client, deployment)
if ok:
print(f"β
Responses API works with your CURRENT AZURE_OPENAI_API_VERSION ({configured_version}).")
print(f" Sample output: {detail!r}")
print()
print("Safe to set USE_RESPONSES_API=true without changing AZURE_OPENAI_API_VERSION.")
return True
print(f"β Responses API failed at your current API version ({configured_version}):")
print(f" {detail[:200]}")
print()
print("Probing newer API versions to find the minimum that works...")
print()
working_version = None
for v in CANDIDATE_VERSIONS:
client = AzureOpenAI(api_key=api_key, api_version=v, azure_endpoint=endpoint)
ok, detail = _try_responses_call(client, deployment)
status = "β
SUCCESS" if ok else "β failed"
print(f" {v}: {status}" + ("" if ok else f" ({detail[:120]})"))
if ok:
working_version = v
break
print()
if not working_version:
print("=" * 80)
print("β Responses API is NOT available on this resource/deployment/region")
print(" at any of the probed API versions.")
print(" USE_RESPONSES_API=true would fall back to Chat Completions on every")
print(" call (the code degrades gracefully), but that means no benefit from")
print(" enabling the flag -- leave it false until this is resolved with Azure.")
print("=" * 80)
return False
print("=" * 80)
print(f"β
Responses API works starting at api-version {working_version}")
print()
print("Before enabling USE_RESPONSES_API=true, also confirm the embeddings call")
print("(rag/embeddings.py) and Chat Completions fallback path still work if you")
print("bump AZURE_OPENAI_API_VERSION -- both currently read the same env var.")
print("=" * 80)
# Step 2: confirm embeddings and Chat Completions still work at the
# newer version, since rag/embeddings.py reads the SAME
# AZURE_OPENAI_API_VERSION env var (falls back to "2024-02-01" only if
# unset) -- bumping it for Responses API is a global change, not scoped
# to the analyzer/synthesis agents.
embedding_deployment = os.getenv("AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME")
client = AzureOpenAI(api_key=api_key, api_version=working_version, azure_endpoint=endpoint)
if embedding_deployment:
try:
resp = client.embeddings.create(input="test", model=embedding_deployment)
print(f"β
Embeddings still work at {working_version} (dim={len(resp.data[0].embedding)})")
except Exception as e:
print(f"β οΈ Embeddings FAILED at {working_version}: {str(e)[:150]}")
print(" Do not bump AZURE_OPENAI_API_VERSION globally without resolving this --")
print(" consider a separate api_version for rag/embeddings.py instead.")
try:
resp = client.chat.completions.create(
model=deployment,
messages=[{"role": "user", "content": "Say hi in one word."}],
temperature=0,
max_tokens=10,
)
print(f"β
Chat Completions fallback path still works at {working_version}")
except Exception as e:
print(f"β οΈ Chat Completions FAILED at {working_version}: {str(e)[:150]}")
print()
print(f"Next step: set AZURE_OPENAI_API_VERSION={working_version} in .env, then")
print("USE_RESPONSES_API=true.")
return True
if __name__ == "__main__":
success = main()
sys.exit(0 if success else 1)
|