From 2f9fd74a2cb376d1767251ac230cb97ae440f016 Mon Sep 17 00:00:00 2001 From: trojan-bumble-bee Date: Mon, 18 Nov 2024 21:10:06 +0000 Subject: [PATCH 1/3] feat(openai): add azure support --- gptcli/assistant.py | 3 +++ gptcli/config.py | 4 ++++ gptcli/gpt.py | 7 +++++++ gptcli/providers/openai.py | 10 ++++++++-- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/gptcli/assistant.py b/gptcli/assistant.py index d6932a0..6160f65 100644 --- a/gptcli/assistant.py +++ b/gptcli/assistant.py @@ -10,6 +10,7 @@ ModelOverrides, Message, ) +import gptcli from gptcli.providers.google import GoogleCompletionProvider from gptcli.providers.llama import LLaMACompletionProvider from gptcli.providers.openai import OpenAICompletionProvider @@ -83,6 +84,8 @@ def get_completion_provider(model: str) -> CompletionProvider: return CohereCompletionProvider() elif model.startswith("gemini"): return GoogleCompletionProvider() + elif gptcli.providers.openai.use_azure: + return OpenAICompletionProvider() else: raise ValueError(f"Unknown model: {model}") diff --git a/gptcli/config.py b/gptcli/config.py index a23753b..7337c99 100644 --- a/gptcli/config.py +++ b/gptcli/config.py @@ -21,6 +21,10 @@ class GptCliConfig: api_key: Optional[str] = os.environ.get("OPENAI_API_KEY") openai_api_key: Optional[str] = os.environ.get("OPENAI_API_KEY") openai_base_url: Optional[str] = os.environ.get("OPENAI_BASE_URL") + # When using azure open ai, set your assistant's model to your deployment + # name + openai_use_azure: bool = False + openai_azure_api_version: str = "2024-10-21" anthropic_api_key: Optional[str] = os.environ.get("ANTHROPIC_API_KEY") google_api_key: Optional[str] = os.environ.get("GOOGLE_API_KEY") cohere_api_key: Optional[str] = os.environ.get("COHERE_API_KEY") diff --git a/gptcli/gpt.py b/gptcli/gpt.py index 897694e..d8325bd 100755 --- a/gptcli/gpt.py +++ b/gptcli/gpt.py @@ -179,8 +179,15 @@ def main(): if config.openai_base_url: openai.base_url = config.openai_base_url + if config.openai_use_azure: + gptcli.providers.openai.use_azure = config.openai_use_azure + + if config.openai_azure_api_version: + openai.api_version = config.openai_azure_api_version + if config.api_key: openai.api_key = config.api_key + elif config.openai_api_key: openai.api_key = config.openai_api_key diff --git a/gptcli/providers/openai.py b/gptcli/providers/openai.py index 97574fa..2b181c5 100644 --- a/gptcli/providers/openai.py +++ b/gptcli/providers/openai.py @@ -1,7 +1,7 @@ import re from typing import Iterator, List, Optional, cast import openai -from openai import OpenAI +from openai import AzureOpenAI, OpenAI from openai.types.chat import ChatCompletionMessageParam from gptcli.completion import ( @@ -15,10 +15,16 @@ UsageEvent, ) +use_azure: bool = False class OpenAICompletionProvider(CompletionProvider): def __init__(self): - self.client = OpenAI(api_key=openai.api_key, base_url=openai.base_url) + if use_azure: + self.client = AzureOpenAI(api_key=openai.api_key, base_url=openai.base_url, api_version=openai.api_version) + else: + self.client = OpenAI(api_key=openai.api_key, base_url=openai.base_url) + + def complete( self, messages: List[Message], args: dict, stream: bool = False From b8425eec54872b51d2b6a50f31c4a8ebc634c3e3 Mon Sep 17 00:00:00 2001 From: trojan-bumble-bee Date: Mon, 18 Nov 2024 21:07:27 +0000 Subject: [PATCH 2/3] chore(openai): switch to using oai_azure prefix --- README.md | 2 ++ gptcli/assistant.py | 6 +++--- gptcli/config.py | 3 --- gptcli/gpt.py | 4 ---- gptcli/providers/azure_openai.py | 12 ++++++++++++ gptcli/providers/openai.py | 11 ++++------- 6 files changed, 21 insertions(+), 17 deletions(-) create mode 100644 gptcli/providers/azure_openai.py diff --git a/README.md b/README.md index 55d1316..63e8bb5 100644 --- a/README.md +++ b/README.md @@ -199,6 +199,8 @@ OPENAI_API_KEY=$TOGETHER_API_KEY OPENAI_BASE_URL=https://api.together.xyz/v1 gpt The prefix is stripped before sending the request to the API. +Similarly, use the `oai-azure:` model name prefix to use a model deployed via Azure Open AI. For example, `oai-azure:my-deployment-name`. + ## Other chat bots ### Anthropic Claude diff --git a/gptcli/assistant.py b/gptcli/assistant.py index 6160f65..82d44d1 100644 --- a/gptcli/assistant.py +++ b/gptcli/assistant.py @@ -10,12 +10,12 @@ ModelOverrides, Message, ) -import gptcli from gptcli.providers.google import GoogleCompletionProvider from gptcli.providers.llama import LLaMACompletionProvider from gptcli.providers.openai import OpenAICompletionProvider from gptcli.providers.anthropic import AnthropicCompletionProvider from gptcli.providers.cohere import CohereCompletionProvider +from gptcli.providers.azure_openai import AzureOpenAICompletionProvider class AssistantConfig(TypedDict, total=False): @@ -76,6 +76,8 @@ def get_completion_provider(model: str) -> CompletionProvider: or model.startswith("o1") ): return OpenAICompletionProvider() + elif model.startswith("oai-azure:"): + return AzureOpenAICompletionProvider() elif model.startswith("claude"): return AnthropicCompletionProvider() elif model.startswith("llama"): @@ -84,8 +86,6 @@ def get_completion_provider(model: str) -> CompletionProvider: return CohereCompletionProvider() elif model.startswith("gemini"): return GoogleCompletionProvider() - elif gptcli.providers.openai.use_azure: - return OpenAICompletionProvider() else: raise ValueError(f"Unknown model: {model}") diff --git a/gptcli/config.py b/gptcli/config.py index 7337c99..ce23e07 100644 --- a/gptcli/config.py +++ b/gptcli/config.py @@ -21,9 +21,6 @@ class GptCliConfig: api_key: Optional[str] = os.environ.get("OPENAI_API_KEY") openai_api_key: Optional[str] = os.environ.get("OPENAI_API_KEY") openai_base_url: Optional[str] = os.environ.get("OPENAI_BASE_URL") - # When using azure open ai, set your assistant's model to your deployment - # name - openai_use_azure: bool = False openai_azure_api_version: str = "2024-10-21" anthropic_api_key: Optional[str] = os.environ.get("ANTHROPIC_API_KEY") google_api_key: Optional[str] = os.environ.get("GOOGLE_API_KEY") diff --git a/gptcli/gpt.py b/gptcli/gpt.py index d8325bd..a5b0260 100755 --- a/gptcli/gpt.py +++ b/gptcli/gpt.py @@ -179,15 +179,11 @@ def main(): if config.openai_base_url: openai.base_url = config.openai_base_url - if config.openai_use_azure: - gptcli.providers.openai.use_azure = config.openai_use_azure - if config.openai_azure_api_version: openai.api_version = config.openai_azure_api_version if config.api_key: openai.api_key = config.api_key - elif config.openai_api_key: openai.api_key = config.openai_api_key diff --git a/gptcli/providers/azure_openai.py b/gptcli/providers/azure_openai.py new file mode 100644 index 0000000..281af2c --- /dev/null +++ b/gptcli/providers/azure_openai.py @@ -0,0 +1,12 @@ +import openai +from openai import AzureOpenAI +from gptcli.providers.openai import OpenAICompletionProvider + + +class AzureOpenAICompletionProvider(OpenAICompletionProvider): + def __init__(self): + self.client = AzureOpenAI( + api_key=openai.api_key, + base_url=openai.base_url, + api_version=openai.api_version, + ) diff --git a/gptcli/providers/openai.py b/gptcli/providers/openai.py index 2b181c5..14a8035 100644 --- a/gptcli/providers/openai.py +++ b/gptcli/providers/openai.py @@ -15,16 +15,10 @@ UsageEvent, ) -use_azure: bool = False class OpenAICompletionProvider(CompletionProvider): def __init__(self): - if use_azure: - self.client = AzureOpenAI(api_key=openai.api_key, base_url=openai.base_url, api_version=openai.api_version) - else: - self.client = OpenAI(api_key=openai.api_key, base_url=openai.base_url) - - + self.client = OpenAI(api_key=openai.api_key, base_url=openai.base_url) def complete( self, messages: List[Message], args: dict, stream: bool = False @@ -39,6 +33,9 @@ def complete( if model.startswith("oai-compat:"): model = model[len("oai-compat:") :] + if model.startswith("oai-azure:"): + model = model[len("oai-azure:") :] + try: if stream: response_iter = self.client.chat.completions.create( From 1b4cc141a849e04125002f899b4ba27ffa4a9afd Mon Sep 17 00:00:00 2001 From: trojan-bumble-bee Date: Mon, 18 Nov 2024 22:18:22 +0000 Subject: [PATCH 3/3] add super().__init__() --- gptcli/providers/azure_openai.py | 1 + 1 file changed, 1 insertion(+) diff --git a/gptcli/providers/azure_openai.py b/gptcli/providers/azure_openai.py index 281af2c..12648ac 100644 --- a/gptcli/providers/azure_openai.py +++ b/gptcli/providers/azure_openai.py @@ -5,6 +5,7 @@ class AzureOpenAICompletionProvider(OpenAICompletionProvider): def __init__(self): + super().__init__() self.client = AzureOpenAI( api_key=openai.api_key, base_url=openai.base_url,