From 8470f1cc1cfaf59439f0aa21767824546af8f798 Mon Sep 17 00:00:00 2001 From: Calvin Giles Date: Wed, 25 Sep 2024 09:48:42 +1200 Subject: [PATCH 01/16] Add VertexAI provider --- README.md | 8 ++- ai/providers/__init__.py | 9 ++- ai/providers/base_provider.py | 9 +-- ai/providers/vertexai.py | 111 ++++++++++++++++++++++++++++++++++ requirements.txt | 1 + 5 files changed, 128 insertions(+), 10 deletions(-) create mode 100644 ai/providers/vertexai.py diff --git a/README.md b/README.md index 07e396a..3e0643c 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,11 @@ Before you can run the app, you'll need to store some environment variables. export SLACK_BOT_TOKEN= export SLACK_APP_TOKEN= export OPENAI_API_KEY= -export ANTHROPIC_API_KEY= +export ANTHROPIC_API_KEY= +# For vertex, follow the quickstart to set up a project to run models: https://cloud.google.com/python/docs/reference/aiplatform/latest/index.html#quick-start +# If this is deployed into google cloud (app engine, cloud run etc) then this step is not needed. +export VERTEX_AI_ENABLED=true +gcloud auth application-default login ``` ### Setup Your Local Project @@ -128,4 +132,4 @@ Navigate to **OAuth & Permissions** in your app configuration and click **Add a ``` https://3cb89939.ngrok.io/slack/oauth_redirect -``` \ No newline at end of file +``` diff --git a/ai/providers/__init__.py b/ai/providers/__init__.py index 16ac2bb..630f557 100644 --- a/ai/providers/__init__.py +++ b/ai/providers/__init__.py @@ -1,5 +1,6 @@ from .anthropic import AnthropicAPI from .openai import OpenAI_API +from .vertexai import VertexAPI from ..ai_constants import DEFAULT_SYSTEM_CONTENT from state_store.get_user_state import get_user_state from typing import Optional, List @@ -21,7 +22,11 @@ def get_available_providers(): - return {**AnthropicAPI().get_models(), **OpenAI_API().get_models()} + return { + **AnthropicAPI().get_models(), + **OpenAI_API().get_models(), + **VertexAPI().get_models(), + } def _get_provider(provider_name: str): @@ -29,6 +34,8 @@ def _get_provider(provider_name: str): return OpenAI_API() elif provider_name.lower() == "anthropic": return AnthropicAPI() + elif provider_name.lower() == "vertexai": + return VertexAPI() else: raise ValueError(f"Unknown provider: {provider_name}") diff --git a/ai/providers/base_provider.py b/ai/providers/base_provider.py index 37a0326..f27625c 100644 --- a/ai/providers/base_provider.py +++ b/ai/providers/base_provider.py @@ -1,17 +1,12 @@ # A base class for API providers, defining the interface and common properties for subclasses. -class BaseAPIProvider: - MODELS = {} - - def __init__(self): - self.api_key: str - +class BaseAPIProvider(object): def set_model(self, model_name: str): raise NotImplementedError("Subclass must implement set_model") def get_models(self) -> dict: raise NotImplementedError("Subclass must implement get_model") - def generate_response(prompt: str) -> str: + def generate_response(self, prompt: str, system_content: str) -> str: raise NotImplementedError("Subclass must implement generate_response") diff --git a/ai/providers/vertexai.py b/ai/providers/vertexai.py new file mode 100644 index 0000000..d7202d4 --- /dev/null +++ b/ai/providers/vertexai.py @@ -0,0 +1,111 @@ +import google.api_core.exceptions + +from .base_provider import BaseAPIProvider +import os +import logging +import vertexai.generative_models + +logging.basicConfig(level=logging.ERROR) +logger = logging.getLogger(__name__) + + +class VertexAPI(BaseAPIProvider): + VERTEX_AI_PROVIDER = "VertexAI" + MODELS = { + "gemini-1.5-flash-001": { + "name": "Gemini 1.5 Flash 001", + "provider": VERTEX_AI_PROVIDER, + "max_tokens": 8192, + }, + "gemini-1.5-flash-002": { + "name": "Gemini 1.5 Flash 002", + "provider": VERTEX_AI_PROVIDER, + "max_tokens": 8192, + }, + "gemini-1.5-pro-002": { + "name": "Gemini 1.5 Pro 002", + "provider": VERTEX_AI_PROVIDER, + "max_tokens": 8192, + }, + "gemini-1.5-pro-001": { + "name": "Gemini 1.5 Pro 001", + "provider": VERTEX_AI_PROVIDER, + "max_tokens": 8192, + }, + "gemini-1.0-pro-002": { + "name": "Gemini 1.0 Pro 002", + "provider": VERTEX_AI_PROVIDER, + "max_tokens": 8192, + }, + "gemini-1.0-pro-001": { + "name": "Gemini 1.0 Pro 001", + "provider": VERTEX_AI_PROVIDER, + "max_tokens": 8192, + }, + "gemini-flash-experimental": { + "name": "Gemini Flash Experimental", + "provider": VERTEX_AI_PROVIDER, + "max_tokens": 8192, + }, + "gemini-pro-experimental": { + "name": "Gemini Pro Experimental", + "provider": VERTEX_AI_PROVIDER, + "max_tokens": 8192, + }, + "gemini-experimental": { + "name": "Gemini Pro Experimental", + "provider": VERTEX_AI_PROVIDER, + "max_tokens": 8192, + }, + } + + def __init__(self): + self.enabled = os.environ.get("VERTEX_AI_ENABLED", "").lower() in ["1", "true", "t", "yes", "y"] + vertexai.init(project=os.environ.get("GCP_PROJECT"), location=os.environ.get("GCP_LOCATION")) + + def set_model(self, model_name: str): + if model_name not in self.MODELS.keys(): + raise ValueError("Invalid model") + self.current_model = model_name + + def get_models(self) -> dict: + if self.enabled: + return self.MODELS + else: + return {} + + def generate_response(self, prompt: str, system_content: str) -> str: + try: + self.client = vertexai.generative_models.GenerativeModel( + model_name=self.current_model, + system_instruction=system_content, + generation_config={ + "max_output_tokens": self.MODELS[self.current_model]["max_tokens"], + }, + ) + response = self.client.generate_content( + contents=prompt, + ) + return "".join(part.text for part in response.candidates[0].content.parts) + + except google.api_core.exceptions.Unauthorized as e: + logger.error(f"Client is not Authorized. {e.reason}, {e.message}") + raise e + except google.api_core.exceptions.Forbidden as e: + logger.error(f"Client Forbidden. {e.reason}, {e.message}") + raise e + except google.api_core.exceptions.TooManyRequests as e: + logger.error(f"A 429 status code was received. {e.reason}, {e.message}") + raise e + except google.api_core.exceptions.ClientError as e: + logger.error(f"Client error: {e.reason}, {e.message}") + raise e + except google.api_core.exceptions.ServerError as e: + logger.error(f"Server error: {e.reason}, {e.message}") + raise e + except google.api_core.exceptions.GoogleAPICallError as e: + logger.error(f"Error: {e.reason}, {e.message}") + raise e + except google.api_core.exceptions.GoogleAPIError as e: + logger.error(f"Unknown error.") + raise e diff --git a/requirements.txt b/requirements.txt index 1e10a21..7957a7c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ black==24.8.0 slack-cli-hooks==0.0.2 openai==1.37.1 anthropic==0.32.0 +google-cloud-aiplatform==1.67.1 From cc568b51ea7ee2c9c0dbaa15b9bc95d1f7bb9f20 Mon Sep 17 00:00:00 2001 From: Calvin Giles Date: Wed, 25 Sep 2024 11:10:06 +1200 Subject: [PATCH 02/16] trigger From de4f9a2e276e8bda14ba756d380f71fe2530d665 Mon Sep 17 00:00:00 2001 From: Calvin Giles <2253836+calvingiles@users.noreply.github.com> Date: Wed, 25 Sep 2024 17:04:58 +1200 Subject: [PATCH 03/16] Update README.md --- README.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3e0643c..ea825ae 100644 --- a/README.md +++ b/README.md @@ -37,12 +37,21 @@ export SLACK_BOT_TOKEN= export SLACK_APP_TOKEN= export OPENAI_API_KEY= export ANTHROPIC_API_KEY= -# For vertex, follow the quickstart to set up a project to run models: https://cloud.google.com/python/docs/reference/aiplatform/latest/index.html#quick-start -# If this is deployed into google cloud (app engine, cloud run etc) then this step is not needed. -export VERTEX_AI_ENABLED=true +``` +##### Google Cloud Vertex AI Setup + +For vertex, follow the [quick-start](https://cloud.google.com/vertex-ai/generative-ai/docs/start/quickstarts/quickstart-multimodal#expandable-1) to set up a project to run models. + +To set up credentials for local development, you can use `gcloud` to creade application-default credentials: + +```zsh +export VERTEX_AI_PROJECT_ID= +export VERTEX_AI_LOCATION= gcloud auth application-default login ``` +If this is deployed into google cloud (app engine, cloud run etc) then running `gcloud` is not needed - but you will need to set `VERTEX_AI_PROJECT_ID`. + ### Setup Your Local Project ```zsh # Clone this project onto your machine From 0485f6a32fb2812739f015e5c871ffeb0dc1fa35 Mon Sep 17 00:00:00 2001 From: Calvin Giles <2253836+calvingiles@users.noreply.github.com> Date: Wed, 25 Sep 2024 17:06:04 +1200 Subject: [PATCH 04/16] Update vertexai.py --- ai/providers/vertexai.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ai/providers/vertexai.py b/ai/providers/vertexai.py index d7202d4..7cfe129 100644 --- a/ai/providers/vertexai.py +++ b/ai/providers/vertexai.py @@ -60,8 +60,8 @@ class VertexAPI(BaseAPIProvider): } def __init__(self): - self.enabled = os.environ.get("VERTEX_AI_ENABLED", "").lower() in ["1", "true", "t", "yes", "y"] - vertexai.init(project=os.environ.get("GCP_PROJECT"), location=os.environ.get("GCP_LOCATION")) + self.enabled = bool(os.environ.get("VERTEX_AI_PROJECT_ID", "")) + vertexai.init(project=os.environ.get("VERTEX_AI_PROJECT_ID"), location=os.environ.get("VERTEX_AI_LOCATION")) def set_model(self, model_name: str): if model_name not in self.MODELS.keys(): From e2171c128faec54cbb410298a3872141939a29ef Mon Sep 17 00:00:00 2001 From: Calvin Giles Date: Wed, 25 Sep 2024 19:27:15 +1200 Subject: [PATCH 05/16] Tidy up README --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ea825ae..870714c 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Before getting started, make sure you have a development workspace where you hav #### Prerequisites * To use the OpenAI and Anthropic models, you must have an account with sufficient credits. +* To use the Vertex models, you must have a [Google Cloud Provider project](https://cloud.google.com/vertex-ai/generative-ai/docs/start/quickstarts/quickstart-multimodal#expandable-1) with sufficient credits. #### Create a Slack App 1. Open [https://api.slack.com/apps/new](https://api.slack.com/apps/new) and choose "From an app manifest" @@ -102,10 +103,10 @@ Every incoming request is routed to a "listener". Inside this directory, we grou #### `ai/providers` -This module contains classes for communicating with different API providers, such as [Anthropic](https://www.anthropic.com/) and [OpenAI](https://openai.com/). To add your own LLM, create a new class for it using the `base_api.py` as an example, then update `get_available_apis.py` and `handle_response.py` to include and utilize your new class for API communication. +This module contains classes for communicating with different API providers, such as [Anthropic](https://www.anthropic.com/), [OpenAI](https://openai.com/) and [Vertex AI](cloud.google.com/vertex-ai). To add your own LLM, create a new class for it using the `base_api.py` as an example, then update `ai/providers/__init__.py` to include and utilize your new class for API communication. * `__init__.py`: -This file contains utility functions for handling responses from the provider APIs and retreiving available providers. +This file contains utility functions for handling responses from the provider APIs and retrieving available providers. ### `/state_store` From ea8744cc32379b25f91299c0901933d0eef95493 Mon Sep 17 00:00:00 2001 From: Calvin Giles Date: Wed, 25 Sep 2024 19:30:51 +1200 Subject: [PATCH 06/16] Only init vertex if the model is enabled --- ai/providers/vertexai.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ai/providers/vertexai.py b/ai/providers/vertexai.py index 7cfe129..effe0a3 100644 --- a/ai/providers/vertexai.py +++ b/ai/providers/vertexai.py @@ -61,7 +61,11 @@ class VertexAPI(BaseAPIProvider): def __init__(self): self.enabled = bool(os.environ.get("VERTEX_AI_PROJECT_ID", "")) - vertexai.init(project=os.environ.get("VERTEX_AI_PROJECT_ID"), location=os.environ.get("VERTEX_AI_LOCATION")) + if self.enabled: + vertexai.init( + project=os.environ.get("VERTEX_AI_PROJECT_ID"), + location=os.environ.get("VERTEX_AI_LOCATION"), + ) def set_model(self, model_name: str): if model_name not in self.MODELS.keys(): From 27f98f3e512c8cb026507e22dc4d7de682393937 Mon Sep 17 00:00:00 2001 From: "@zimeg" Date: Thu, 26 Sep 2024 14:49:22 -0700 Subject: [PATCH 07/16] docs: reference the vertex dashboard and additional credential instructions --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 870714c..bece5a9 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Before getting started, make sure you have a development workspace where you hav #### Prerequisites * To use the OpenAI and Anthropic models, you must have an account with sufficient credits. -* To use the Vertex models, you must have a [Google Cloud Provider project](https://cloud.google.com/vertex-ai/generative-ai/docs/start/quickstarts/quickstart-multimodal#expandable-1) with sufficient credits. +* To use the Vertex models, you must have [a Google Cloud Provider project](https://cloud.google.com/vertex-ai/generative-ai/docs/start/quickstarts/quickstart-multimodal#expandable-1) with sufficient credits. #### Create a Slack App 1. Open [https://api.slack.com/apps/new](https://api.slack.com/apps/new) and choose "From an app manifest" @@ -39,19 +39,19 @@ export SLACK_APP_TOKEN= export OPENAI_API_KEY= export ANTHROPIC_API_KEY= ``` + ##### Google Cloud Vertex AI Setup -For vertex, follow the [quick-start](https://cloud.google.com/vertex-ai/generative-ai/docs/start/quickstarts/quickstart-multimodal#expandable-1) to set up a project to run models. +To use Google Cloud Vertex AI, [follow this quick start](https://cloud.google.com/vertex-ai/generative-ai/docs/start/quickstarts/quickstart-multimodal#expandable-1) to create a project for sending requests to the Gemini API, then gather [Application Default Credentials](https://cloud.google.com/docs/authentication/provide-credentials-adc) with the strategy that matches your development environment. -To set up credentials for local development, you can use `gcloud` to creade application-default credentials: +Once your project and credentials are configured, export environment variables to select from Gemini models: ```zsh export VERTEX_AI_PROJECT_ID= export VERTEX_AI_LOCATION= -gcloud auth application-default login ``` -If this is deployed into google cloud (app engine, cloud run etc) then running `gcloud` is not needed - but you will need to set `VERTEX_AI_PROJECT_ID`. +The project location can be located under the **Region** on the [Vertex AI](https://console.cloud.google.com/vertex-ai) dashboard, as well as more details about available Gemini models. ### Setup Your Local Project ```zsh @@ -103,10 +103,10 @@ Every incoming request is routed to a "listener". Inside this directory, we grou #### `ai/providers` -This module contains classes for communicating with different API providers, such as [Anthropic](https://www.anthropic.com/), [OpenAI](https://openai.com/) and [Vertex AI](cloud.google.com/vertex-ai). To add your own LLM, create a new class for it using the `base_api.py` as an example, then update `ai/providers/__init__.py` to include and utilize your new class for API communication. +This module contains classes for communicating with different API providers, such as [Anthropic](https://www.anthropic.com/), [OpenAI](https://openai.com/), and [Vertex AI](cloud.google.com/vertex-ai). To add your own LLM, create a new class for it using the `base_api.py` as an example, then update `ai/providers/__init__.py` to include and utilize your new class for API communication. * `__init__.py`: -This file contains utility functions for handling responses from the provider APIs and retrieving available providers. +This file contains utility functions for handling responses from the provider APIs and retrieving available providers. ### `/state_store` From 380b11731a0f34a7fda30db11b05e2138cde4066 Mon Sep 17 00:00:00 2001 From: "@zimeg" Date: Thu, 26 Sep 2024 14:54:28 -0700 Subject: [PATCH 08/16] docs: reword a line about matching multiple development environments --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bece5a9..07999d0 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ export ANTHROPIC_API_KEY= ##### Google Cloud Vertex AI Setup -To use Google Cloud Vertex AI, [follow this quick start](https://cloud.google.com/vertex-ai/generative-ai/docs/start/quickstarts/quickstart-multimodal#expandable-1) to create a project for sending requests to the Gemini API, then gather [Application Default Credentials](https://cloud.google.com/docs/authentication/provide-credentials-adc) with the strategy that matches your development environment. +To use Google Cloud Vertex AI, [follow this quick start](https://cloud.google.com/vertex-ai/generative-ai/docs/start/quickstarts/quickstart-multimodal#expandable-1) to create a project for sending requests to the Gemini API, then gather [Application Default Credentials](https://cloud.google.com/docs/authentication/provide-credentials-adc) with the strategy to match your development environment. Once your project and credentials are configured, export environment variables to select from Gemini models: From 2077a67de56fd18711bf14954f5df2865f522e35 Mon Sep 17 00:00:00 2001 From: Calvin Giles Date: Fri, 27 Sep 2024 20:05:40 +1200 Subject: [PATCH 09/16] Fix pro-1.0-001 and strings --- ai/providers/vertexai.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/ai/providers/vertexai.py b/ai/providers/vertexai.py index effe0a3..650548d 100644 --- a/ai/providers/vertexai.py +++ b/ai/providers/vertexai.py @@ -16,46 +16,55 @@ class VertexAPI(BaseAPIProvider): "name": "Gemini 1.5 Flash 001", "provider": VERTEX_AI_PROVIDER, "max_tokens": 8192, + "system_instruction_supported": True, }, "gemini-1.5-flash-002": { "name": "Gemini 1.5 Flash 002", "provider": VERTEX_AI_PROVIDER, "max_tokens": 8192, + "system_instruction_supported": True, }, "gemini-1.5-pro-002": { "name": "Gemini 1.5 Pro 002", "provider": VERTEX_AI_PROVIDER, "max_tokens": 8192, + "system_instruction_supported": True, }, "gemini-1.5-pro-001": { "name": "Gemini 1.5 Pro 001", "provider": VERTEX_AI_PROVIDER, "max_tokens": 8192, + "system_instruction_supported": True, }, "gemini-1.0-pro-002": { "name": "Gemini 1.0 Pro 002", "provider": VERTEX_AI_PROVIDER, "max_tokens": 8192, + "system_instruction_supported": True, }, "gemini-1.0-pro-001": { "name": "Gemini 1.0 Pro 001", "provider": VERTEX_AI_PROVIDER, "max_tokens": 8192, + "system_instruction_supported": False, }, "gemini-flash-experimental": { "name": "Gemini Flash Experimental", "provider": VERTEX_AI_PROVIDER, "max_tokens": 8192, + "system_instruction_supported": True, }, "gemini-pro-experimental": { "name": "Gemini Pro Experimental", "provider": VERTEX_AI_PROVIDER, "max_tokens": 8192, + "system_instruction_supported": True, }, "gemini-experimental": { - "name": "Gemini Pro Experimental", + "name": "Gemini Experimental", "provider": VERTEX_AI_PROVIDER, "max_tokens": 8192, + "system_instruction_supported": True, }, } @@ -80,12 +89,20 @@ def get_models(self) -> dict: def generate_response(self, prompt: str, system_content: str) -> str: try: + if self.MODELS[self.current_model]["system_instruction_supported"]: + kwargs = dict( + system_instruction=system_content, + ) + else: + kwargs = dict() + prompt = system_content + "\n" + prompt + self.client = vertexai.generative_models.GenerativeModel( model_name=self.current_model, - system_instruction=system_content, generation_config={ "max_output_tokens": self.MODELS[self.current_model]["max_tokens"], }, + **kwargs, ) response = self.client.generate_content( contents=prompt, @@ -99,7 +116,7 @@ def generate_response(self, prompt: str, system_content: str) -> str: logger.error(f"Client Forbidden. {e.reason}, {e.message}") raise e except google.api_core.exceptions.TooManyRequests as e: - logger.error(f"A 429 status code was received. {e.reason}, {e.message}") + logger.error(f"Too many requests. {e.reason}, {e.message}") raise e except google.api_core.exceptions.ClientError as e: logger.error(f"Client error: {e.reason}, {e.message}") @@ -111,5 +128,5 @@ def generate_response(self, prompt: str, system_content: str) -> str: logger.error(f"Error: {e.reason}, {e.message}") raise e except google.api_core.exceptions.GoogleAPIError as e: - logger.error(f"Unknown error.") + logger.error(f"Unknown error. {e}") raise e From 8efc81e0dfc181f652956f244206db64ef703694 Mon Sep 17 00:00:00 2001 From: "@zimeg" Date: Fri, 27 Sep 2024 18:59:54 -0700 Subject: [PATCH 10/16] refactor: instantiate clients with explicit arguments and optional system instruction --- ai/providers/vertexai.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/ai/providers/vertexai.py b/ai/providers/vertexai.py index 650548d..04dfbf4 100644 --- a/ai/providers/vertexai.py +++ b/ai/providers/vertexai.py @@ -90,20 +90,21 @@ def get_models(self) -> dict: def generate_response(self, prompt: str, system_content: str) -> str: try: if self.MODELS[self.current_model]["system_instruction_supported"]: - kwargs = dict( - system_instruction=system_content, + self.client = vertexai.generative_models.GenerativeModel( + model_name=self.current_model, + generation_config={ + "max_output_tokens": self.MODELS[self.current_model]["max_tokens"], + }, + system_instruction=system_content ) else: - kwargs = dict() prompt = system_content + "\n" + prompt - - self.client = vertexai.generative_models.GenerativeModel( - model_name=self.current_model, - generation_config={ - "max_output_tokens": self.MODELS[self.current_model]["max_tokens"], - }, - **kwargs, - ) + self.client = vertexai.generative_models.GenerativeModel( + model_name=self.current_model, + generation_config={ + "max_output_tokens": self.MODELS[self.current_model]["max_tokens"], + }, + ) response = self.client.generate_content( contents=prompt, ) From 1cde9cbafb0d6f1990d69c2dd2d52ff52fe54ef8 Mon Sep 17 00:00:00 2001 From: "@zimeg" Date: Fri, 27 Sep 2024 19:00:36 -0700 Subject: [PATCH 11/16] style: order imports according to scoped alphabeticalizations --- ai/providers/vertexai.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ai/providers/vertexai.py b/ai/providers/vertexai.py index 04dfbf4..acdc64d 100644 --- a/ai/providers/vertexai.py +++ b/ai/providers/vertexai.py @@ -1,9 +1,10 @@ +import logging +import os + import google.api_core.exceptions +import vertexai.generative_models from .base_provider import BaseAPIProvider -import os -import logging -import vertexai.generative_models logging.basicConfig(level=logging.ERROR) logger = logging.getLogger(__name__) From cd44390ef656b3a6cb9b1a3b963c773163c3d119 Mon Sep 17 00:00:00 2001 From: "@zimeg" Date: Fri, 27 Sep 2024 19:02:38 -0700 Subject: [PATCH 12/16] fix: raise the not implemented error with the matching method name --- ai/providers/base_provider.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ai/providers/base_provider.py b/ai/providers/base_provider.py index f27625c..b94500a 100644 --- a/ai/providers/base_provider.py +++ b/ai/providers/base_provider.py @@ -6,7 +6,7 @@ def set_model(self, model_name: str): raise NotImplementedError("Subclass must implement set_model") def get_models(self) -> dict: - raise NotImplementedError("Subclass must implement get_model") + raise NotImplementedError("Subclass must implement get_models") def generate_response(self, prompt: str, system_content: str) -> str: raise NotImplementedError("Subclass must implement generate_response") From 8ec2ff7effa1c5d3ea5e752ca9f7bb4107b516b1 Mon Sep 17 00:00:00 2001 From: "@zimeg" Date: Fri, 27 Sep 2024 19:08:15 -0700 Subject: [PATCH 13/16] refactor: reorder provider selection and imports to follow the alphabet once more --- ai/providers/__init__.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/ai/providers/__init__.py b/ai/providers/__init__.py index 630f557..10944f9 100644 --- a/ai/providers/__init__.py +++ b/ai/providers/__init__.py @@ -1,9 +1,11 @@ +from typing import List, Optional + +from state_store.get_user_state import get_user_state + +from ..ai_constants import DEFAULT_SYSTEM_CONTENT from .anthropic import AnthropicAPI from .openai import OpenAI_API from .vertexai import VertexAPI -from ..ai_constants import DEFAULT_SYSTEM_CONTENT -from state_store.get_user_state import get_user_state -from typing import Optional, List """ New AI providers must be added below. @@ -30,10 +32,10 @@ def get_available_providers(): def _get_provider(provider_name: str): - if provider_name.lower() == "openai": - return OpenAI_API() - elif provider_name.lower() == "anthropic": + if provider_name.lower() == "anthropic": return AnthropicAPI() + elif provider_name.lower() == "openai": + return OpenAI_API() elif provider_name.lower() == "vertexai": return VertexAPI() else: From c7dad78304dc4bf96582d561f663a6ba8ec5acd6 Mon Sep 17 00:00:00 2001 From: "@zimeg" Date: Fri, 27 Sep 2024 19:09:01 -0700 Subject: [PATCH 14/16] style: include a trailing comma at the end of the system_instruction argument --- ai/providers/vertexai.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ai/providers/vertexai.py b/ai/providers/vertexai.py index acdc64d..e0a6708 100644 --- a/ai/providers/vertexai.py +++ b/ai/providers/vertexai.py @@ -96,7 +96,7 @@ def generate_response(self, prompt: str, system_content: str) -> str: generation_config={ "max_output_tokens": self.MODELS[self.current_model]["max_tokens"], }, - system_instruction=system_content + system_instruction=system_content, ) else: prompt = system_content + "\n" + prompt From 66c0e74be2b8094adf37d46fa0197b407d1b1bd2 Mon Sep 17 00:00:00 2001 From: "@zimeg" Date: Fri, 27 Sep 2024 19:21:56 -0700 Subject: [PATCH 15/16] refactor: override an undefined system instruction when supported as variables --- ai/providers/vertexai.py | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/ai/providers/vertexai.py b/ai/providers/vertexai.py index e0a6708..ea93045 100644 --- a/ai/providers/vertexai.py +++ b/ai/providers/vertexai.py @@ -90,22 +90,19 @@ def get_models(self) -> dict: def generate_response(self, prompt: str, system_content: str) -> str: try: + system_instruction = None if self.MODELS[self.current_model]["system_instruction_supported"]: - self.client = vertexai.generative_models.GenerativeModel( - model_name=self.current_model, - generation_config={ - "max_output_tokens": self.MODELS[self.current_model]["max_tokens"], - }, - system_instruction=system_content, - ) + system_instruction = system_content else: prompt = system_content + "\n" + prompt - self.client = vertexai.generative_models.GenerativeModel( - model_name=self.current_model, - generation_config={ - "max_output_tokens": self.MODELS[self.current_model]["max_tokens"], - }, - ) + + self.client = vertexai.generative_models.GenerativeModel( + model_name=self.current_model, + generation_config={ + "max_output_tokens": self.MODELS[self.current_model]["max_tokens"], + }, + system_instruction=system_instruction, + ) response = self.client.generate_content( contents=prompt, ) From 087ff282d520832a75c373acbe9b64753487c037 Mon Sep 17 00:00:00 2001 From: "@zimeg" Date: Fri, 27 Sep 2024 19:26:57 -0700 Subject: [PATCH 16/16] refactor: setup system instruction and adjust prompt before trying the client --- ai/providers/vertexai.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ai/providers/vertexai.py b/ai/providers/vertexai.py index ea93045..9813d6b 100644 --- a/ai/providers/vertexai.py +++ b/ai/providers/vertexai.py @@ -89,13 +89,13 @@ def get_models(self) -> dict: return {} def generate_response(self, prompt: str, system_content: str) -> str: - try: - system_instruction = None - if self.MODELS[self.current_model]["system_instruction_supported"]: - system_instruction = system_content - else: - prompt = system_content + "\n" + prompt + system_instruction = None + if self.MODELS[self.current_model]["system_instruction_supported"]: + system_instruction = system_content + else: + prompt = system_content + "\n" + prompt + try: self.client = vertexai.generative_models.GenerativeModel( model_name=self.current_model, generation_config={