From 640017edb80d87d6f5fea5e9874f22df0211f194 Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Sat, 24 Jan 2026 10:07:15 +0100 Subject: [PATCH 1/3] Support accessing Azure AI V1 API without api-version See https://learn.microsoft.com/en-us/azure/ai-foundry/openai/api-version-lifecycle#api-evolution --- README.md | 22 +++++++++++-------- .../com/openai/rest/AzureAIEndpoint.class.php | 11 ++++++++-- .../unittest/AzureAIEndpointTest.class.php | 17 ++++++++++++-- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index c6e211d..d10a656 100755 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ use util\cmd\Console; $ai= new OpenAIEndpoint('https://'.getenv('OPENAI_API_KEY').'@api.openai.com/v1'); Console::writeLine($ai->api('/responses')->invoke([ - 'model' => 'gpt-4o-mini', + 'model' => 'gpt-5.2', 'input' => $prompt, ])); ``` @@ -37,7 +37,7 @@ use util\cmd\Console; $ai= new OpenAIEndpoint('https://'.getenv('OPENAI_API_KEY').'@api.openai.com/v1'); $events= $ai->api('/responses')->stream([ - 'model' => 'gpt-4o-mini', + 'model' => 'gpt-5.2', 'input' => $prompt, ]); foreach ($events as $type => $value) { @@ -195,7 +195,7 @@ $functions= (new Functions())->register('weather', new Weather()); $ai= new OpenAIEndpoint('https://'.getenv('OPENAI_API_KEY').'@api.openai.com/v1'); $payload= [ - 'model' => 'gpt-4o-mini', + 'model' => 'gpt-5.2', 'tools' => new Tools($functions), 'input' => [['type' => 'message', 'role' => 'user', 'content' => $content]], ]; @@ -266,13 +266,17 @@ These endpoints differ slightly in how they are invoked, which is handled by the use com\openai\rest\AzureAIEndpoint; use util\cmd\Console; +// Using V1 API +$ai= new AzureAIEndpoint('https://'.getenv('AZUREAI_API_KEY').'@example.openai.azure.com/openai/v1'); + +// Using API version $ai= new AzureAIEndpoint( 'https://'.getenv('AZUREAI_API_KEY').'@example.openai.azure.com/openai/deployments/mini', - '2025-03-01-preview' + '2025-04-01-preview' ); Console::writeLine($ai->api('/responses')->invoke([ - 'model' => 'gpt-4o-mini', + 'model' => 'gpt-5.2', 'input' => $prompt, ])); ``` @@ -286,14 +290,14 @@ use com\openai\rest\{AzureAIEndpoint, Distributed, ByRemainingRequests}; use util\cmd\Console; $endpoints= [ - new AzureAIEndpoint('https://...@r1.openai.azure.com/openai/deployments/mini', '2024-02-01'), - new AzureAIEndpoint('https://...@r2.openai.azure.com/openai/deployments/mini', '2024-02-01'), + new AzureAIEndpoint('https://...@r1.openai.azure.com/openai/v1'), + new AzureAIEndpoint('https://...@r2.openai.azure.com/openai/v1'), ]; $ai= new Distributed($endpoints, new ByRemainingRequests()); Console::writeLine($ai->api('/responses')->invoke([ - 'model' => 'gpt-4o-mini', + 'model' => 'gpt-5.2', 'input' => $prompt, ])); foreach ($endpoints as $i => $endpoint) { @@ -362,7 +366,7 @@ use util\cmd\Console; $ai= new OpenAIEndpoint('https://'.getenv('OPENAI_API_KEY').'@api.openai.com/v1'); $flow= $ai->api('/chat/completions')->flow([ - 'model' => 'gpt-4o-mini', + 'model' => 'gpt-5.2', 'messages' => [['role' => 'user', 'content' => $prompt]], ]); foreach ($flow->deltas() as $type => $delta) { diff --git a/src/main/php/com/openai/rest/AzureAIEndpoint.class.php b/src/main/php/com/openai/rest/AzureAIEndpoint.class.php index d863c6c..e3e0ba8 100644 --- a/src/main/php/com/openai/rest/AzureAIEndpoint.class.php +++ b/src/main/php/com/openai/rest/AzureAIEndpoint.class.php @@ -30,14 +30,21 @@ public function __construct($arg, $version= null) { } } + /** @return string */ + private function versioned() { + return null === $this->version ? '' : '?api-version='.$this->version; + } + /** Returns an API */ public function api(string $path, array $segments= []): Api { return new Api( - $this->endpoint->resource(ltrim($path, '/').'?api-version='.$this->version, $segments), + $this->endpoint->resource(ltrim($path, '/').$this->versioned(), $segments), $this->rateLimit ); } /** @return string */ - public function toString() { return nameof($this).'(->'.$this->endpoint->base().'?api-version='.$this->version.')'; } + public function toString() { + return nameof($this).'(->'.$this->endpoint->base().$this->versioned().')'; + } } \ No newline at end of file diff --git a/src/test/php/com/openai/unittest/AzureAIEndpointTest.class.php b/src/test/php/com/openai/unittest/AzureAIEndpointTest.class.php index 9d15a3e..642f555 100644 --- a/src/test/php/com/openai/unittest/AzureAIEndpointTest.class.php +++ b/src/test/php/com/openai/unittest/AzureAIEndpointTest.class.php @@ -14,14 +14,19 @@ public function can_create() { $this->fixture(self::URI); } + #[Test] + public function no_version_by_default() { + Assert::null($this->fixture(self::URI)->version); + } + #[Test] public function version() { - Assert::equals('2024-02-01', $this->fixture(self::URI, '2024-02-01')->version); + Assert::equals('2025-04-01-preview', $this->fixture(self::URI, '2025-04-01-preview')->version); } #[Test] public function version_extracted_from_uri() { - Assert::equals('2024-02-01', $this->fixture(self::URI.'?api-version=2024-02-01')->version); + Assert::equals('2025-04-01-preview', $this->fixture(self::URI.'?api-version=2025-04-01-preview')->version); } #[Test] @@ -31,6 +36,14 @@ public function api_key_header_set() { #[Test] public function string_representation() { + Assert::equals( + 'com.openai.rest.AzureAIEndpoint(->https://test.openai.azure.com/openai/deployments/omni/)', + $this->fixture(self::URI)->toString() + ); + } + + #[Test] + public function string_representation_with_version() { Assert::equals( 'com.openai.rest.AzureAIEndpoint(->https://test.openai.azure.com/openai/deployments/omni/?api-version=2024-02-01)', $this->fixture(self::URI, '2024-02-01')->toString() From c75fdefb8b1ef29028560c1a5cf4fe619d73b216 Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Sat, 24 Jan 2026 10:08:55 +0100 Subject: [PATCH 2/3] Make deploymnent name in example consistent [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d10a656..c1fdd78 100755 --- a/README.md +++ b/README.md @@ -271,7 +271,7 @@ $ai= new AzureAIEndpoint('https://'.getenv('AZUREAI_API_KEY').'@example.openai.a // Using API version $ai= new AzureAIEndpoint( - 'https://'.getenv('AZUREAI_API_KEY').'@example.openai.azure.com/openai/deployments/mini', + 'https://'.getenv('AZUREAI_API_KEY').'@example.openai.azure.com/openai/deployments/gpt-5.2', '2025-04-01-preview' ); From a8ef49924b04dc4155a8511dc8cb555a4405a55a Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Sat, 24 Jan 2026 10:28:01 +0100 Subject: [PATCH 3/3] Add with() method to pass headers --- .../php/com/openai/rest/RestEndpoint.class.php | 12 ++++++++++++ .../unittest/AzureAIEndpointTest.class.php | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/main/php/com/openai/rest/RestEndpoint.class.php b/src/main/php/com/openai/rest/RestEndpoint.class.php index 0cc93c0..75a4270 100755 --- a/src/main/php/com/openai/rest/RestEndpoint.class.php +++ b/src/main/php/com/openai/rest/RestEndpoint.class.php @@ -31,6 +31,18 @@ public function __construct($endpoint) { /** Returns rate limit */ public function rateLimit(): RateLimit { return $this->rateLimit; } + /** + * Adds headers to be sent with every request + * + * @param string|[:string] $arg + * @param ?string $value + * @return self + */ + public function with($arg, $value= null) { + $this->endpoint->with($arg, $value); + return $this; + } + /** @return [:var] */ public function headers() { return $this->endpoint->headers(); } diff --git a/src/test/php/com/openai/unittest/AzureAIEndpointTest.class.php b/src/test/php/com/openai/unittest/AzureAIEndpointTest.class.php index 642f555..e9e0fef 100644 --- a/src/test/php/com/openai/unittest/AzureAIEndpointTest.class.php +++ b/src/test/php/com/openai/unittest/AzureAIEndpointTest.class.php @@ -34,6 +34,22 @@ public function api_key_header_set() { Assert::equals('1e51...', $this->fixture(self::URI)->headers()['API-Key']); } + #[Test] + public function additional_header() { + Assert::equals( + 'preview', + $this->fixture(self::URI)->with('aoai-evals', 'preview')->headers()['aoai-evals'] + ); + } + + #[Test] + public function additional_headers() { + Assert::equals( + 'preview', + $this->fixture(self::URI)->with(['aoai-evals' => 'preview'])->headers()['aoai-evals'] + ); + } + #[Test] public function string_representation() { Assert::equals(