Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ public static final class ChatModel {
public static final String OPENAI_RESPONSES_SETUP =
"org.apache.flink.agents.integrations.chatmodels.openai.OpenAIResponsesModelSetup";

// Azure OpenAI
public static final String AZURE_OPENAI_CONNECTION =
"org.apache.flink.agents.integrations.chatmodels.openai.AzureOpenAIChatModelConnection";
public static final String AZURE_OPENAI_SETUP =
"org.apache.flink.agents.integrations.chatmodels.openai.AzureOpenAIChatModelSetup";

// Python Wrapper
public static final String PYTHON_WRAPPER_CONNECTION =
"org.apache.flink.agents.api.chat.model.python.PythonChatModelConnection";
Expand Down
61 changes: 57 additions & 4 deletions docs/content/docs/development/chat_models.md
Original file line number Diff line number Diff line change
Expand Up @@ -390,10 +390,6 @@ Model availability and specifications may change. Always check the official Azur

Azure OpenAI provides access to OpenAI models (GPT-4, GPT-4o, etc.) through Azure's cloud infrastructure, using the same OpenAI SDK with Azure-specific authentication and endpoints. This offers enterprise security, compliance, and regional availability while using familiar OpenAI APIs.

{{< hint info >}}
Azure OpenAI is only supported in Python currently. To use Azure OpenAI from Java agents, see [Using Cross-Language Providers](#using-cross-language-providers).
{{< /hint >}}

{{< hint warning >}}
**Azure OpenAI vs Azure AI:** Azure OpenAI uses the OpenAI SDK to access OpenAI models (GPT-4, etc.) hosted on Azure. If you want to use other models like Llama, Mistral, or Phi deployed via Azure AI Studio, see [Azure AI](#azure-ai) instead.
{{< /hint >}}
Expand All @@ -420,6 +416,19 @@ Azure OpenAI is only supported in Python currently. To use Azure OpenAI from Jav

{{< /tab >}}

{{< tab "Java" >}}

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `api_key` | String | Required | Azure OpenAI API key for authentication |
| `api_version` | String | Required | Azure OpenAI REST API version (e.g., "2024-02-01"). See [API versions](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#rest-api-versioning) |
| `azure_endpoint` | String | Required | Azure OpenAI endpoint URL (e.g., `https://{resource-name}.openai.azure.com`) — either a direct Azure resource or a proxy/gateway URL that fronts an Azure OpenAI service |
| `timeout` | int | None | Timeout in seconds for API requests; must be greater than 0, otherwise ignored (SDK default applies) |
| `max_retries` | int | None | Maximum number of API retry attempts; must be non-negative, otherwise ignored (SDK default applies) |
| `azure_url_path_mode` | String | `"AUTO"` | Controls how the SDK constructs Azure OpenAI request URLs. One of `"AUTO"`, `"LEGACY"`, or `"UNIFIED"`. Custom gateways that proxy Azure OpenAI typically need `"LEGACY"` to force the `/openai/deployments/{model}` path |

{{< /tab >}}

{{< /tabs >}}

#### AzureOpenAIChatModelSetup Parameters
Expand All @@ -442,6 +451,22 @@ Azure OpenAI is only supported in Python currently. To use Azure OpenAI from Jav

{{< /tab >}}

{{< tab "Java" >}}

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `connection` | String | Required | Reference to connection method name |
| `model` | String | Required | Azure deployment name (not the underlying OpenAI model name) |
| `model_of_azure_deployment` | String | None | The underlying model name (e.g., 'gpt-4', 'gpt-4o'). Used solely for token metrics tracking |
| `prompt` | Prompt \| String | None | Prompt template or reference to prompt resource |
| `tools` | List<String> | None | List of tool names available to the model |
| `temperature` | double | None | Sampling temperature (0.0 to 2.0). Not supported by reasoning models |
| `max_tokens` | int | None | Maximum number of tokens to generate (must be greater than 0) |
| `logprobs` | boolean | `false` | Whether to return log probabilities of output tokens |
| `additional_kwargs` | Map<String, Object> | `{}` | Additional Azure OpenAI API parameters (forwarded to the OpenAI request body) |

{{< /tab >}}

{{< /tabs >}}

#### Usage Example
Expand Down Expand Up @@ -477,6 +502,34 @@ class MyAgent(Agent):
```
{{< /tab >}}

{{< tab "Java" >}}
```java
public class MyAgent extends Agent {
@ChatModelConnection
public static ResourceDescriptor azureOpenAIConnection() {
return ResourceDescriptor.Builder.newBuilder(ResourceName.ChatModel.AZURE_OPENAI_CONNECTION)
.addInitialArgument("api_key", "<your-api-key>")
.addInitialArgument("api_version", "2024-02-01")
.addInitialArgument("azure_endpoint", "https://your-resource.openai.azure.com")
.build();
}

@ChatModelSetup
public static ResourceDescriptor azureOpenAIChatModel() {
return ResourceDescriptor.Builder.newBuilder(ResourceName.ChatModel.AZURE_OPENAI_SETUP)
.addInitialArgument("connection", "azureOpenAIConnection")
.addInitialArgument("model", "my-gpt4-deployment") // Your Azure deployment name
.addInitialArgument("model_of_azure_deployment", "gpt-4") // Underlying model for metrics
.addInitialArgument("temperature", 0.3d)
.addInitialArgument("max_tokens", 1000)
.build();
}

...
}
```
{{< /tab >}}

{{< /tabs >}}

#### Available Models
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ public static ResourceDescriptor chatModelConnection() {
ResourceName.ChatModel.OPENAI_RESPONSES_CONNECTION)
.addInitialArgument("api_key", System.getenv().get("OPENAI_API_KEY"))
.build();
} else if (provider.equals("AZURE_OPENAI")) {
return ResourceDescriptor.Builder.newBuilder(
ResourceName.ChatModel.AZURE_OPENAI_CONNECTION)
.addInitialArgument("api_key", System.getenv().get("AZURE_OPENAI_API_KEY"))
.addInitialArgument(
"api_version", System.getenv().get("AZURE_OPENAI_API_VERSION"))
.addInitialArgument(
"azure_endpoint", System.getenv().get("AZURE_OPENAI_ENDPOINT"))
.addInitialArgument("azure_url_path_mode", "LEGACY")
.build();
} else if (provider.equals("ANTHROPIC")) {
String apiKey = System.getenv().get("ANTHROPIC_API_KEY");
return ResourceDescriptor.Builder.newBuilder(
Expand Down Expand Up @@ -150,6 +160,14 @@ public static ResourceDescriptor chatModel() {
"tools",
List.of("calculateBMI", "convertTemperature", "createRandomNumber"))
.build();
} else if (provider.equals("AZURE_OPENAI")) {
return ResourceDescriptor.Builder.newBuilder(ResourceName.ChatModel.AZURE_OPENAI_SETUP)
.addInitialArgument("connection", "chatModelConnection")
.addInitialArgument("model", System.getenv().get("AZURE_OPENAI_DEPLOYMENT"))
.addInitialArgument(
"tools",
List.of("calculateBMI", "convertTemperature", "createRandomNumber"))
.build();
} else {
throw new RuntimeException(String.format("Unknown model provider %s", provider));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.ArrayList;
Expand All @@ -41,7 +39,6 @@
* prompts.
*/
public class ChatModelIntegrationTest extends OllamaPreparationUtils {
private static final Logger LOG = LoggerFactory.getLogger(ChatModelIntegrationTest.class);

private static final String API_KEY = "_API_KEY";
private static final String OLLAMA = "OLLAMA";
Expand All @@ -53,7 +50,15 @@ public ChatModelIntegrationTest() throws IOException {
}

@ParameterizedTest()
@ValueSource(strings = {"ANTHROPIC", "AZURE", "OLLAMA", "OPENAI", "OPENAI_RESPONSES"})
@ValueSource(
strings = {
"ANTHROPIC",
"AZURE",
"AZURE_OPENAI",
"OLLAMA",
"OPENAI",
"OPENAI_RESPONSES"
})
public void testChatModeIntegration(String provider) throws Exception {
Assumptions.assumeTrue(
(OLLAMA.equals(provider) && ollamaReady)
Expand Down
Loading
Loading