From fed093e830e055459a915d8217898375805c4d1c Mon Sep 17 00:00:00 2001 From: Dave Morris Date: Sun, 6 Aug 2023 14:52:31 -0500 Subject: [PATCH 01/10] potential fix for ChatVertexAI component bug --- src/backend/langflow/interface/initialize/loading.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/langflow/interface/initialize/loading.py b/src/backend/langflow/interface/initialize/loading.py index f52b2e56c..a9d0bce4d 100644 --- a/src/backend/langflow/interface/initialize/loading.py +++ b/src/backend/langflow/interface/initialize/loading.py @@ -139,7 +139,7 @@ def instantiate_llm(node_type, class_object, params: Dict): # This is a workaround so JinaChat works until streaming is implemented # if "openai_api_base" in params and "jina" in params["openai_api_base"]: # False if condition is True - if node_type == "VertexAI": + if "VertexAI" in node_type: return initialize_vertexai(class_object=class_object, params=params) # max_tokens sometimes is a string and should be an int if "max_tokens" in params: From c7635b5b7c464e63ddfc09d94059589c0b538f70 Mon Sep 17 00:00:00 2001 From: Dave Morris Date: Sun, 6 Aug 2023 14:53:37 -0500 Subject: [PATCH 02/10] Update config.yaml to enable ChatVertexAI --- src/backend/langflow/config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/langflow/config.yaml b/src/backend/langflow/config.yaml index 63e8cdf99..41627827a 100644 --- a/src/backend/langflow/config.yaml +++ b/src/backend/langflow/config.yaml @@ -127,9 +127,9 @@ llms: # There's a bug in this component deactivating until we get it sorted: _language_models.py", line 804, in send_message # is_blocked=safety_attributes.get("blocked", False), # AttributeError: 'list' object has no attribute 'get' - # ChatVertexAI: - # documentation: "https://python.langchain.com/docs/modules/model_io/models/chat/integrations/google_vertex_ai_palm" ### + ChatVertexAI: + documentation: "https://python.langchain.com/docs/modules/model_io/models/chat/integrations/google_vertex_ai_palm" memories: # https://github.com/supabase-community/supabase-py/issues/482 # ZepChatMessageHistory: From 8e8e97149a42b95a2df948fa02a4eb7d932f48c5 Mon Sep 17 00:00:00 2001 From: Dave Morris Date: Mon, 7 Aug 2023 08:19:37 -0500 Subject: [PATCH 03/10] Update docker-compose.yml to fix uvicorn factory path --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 961cd0e33..13d39e1f3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,7 @@ services: - "7860:7860" volumes: - ./:/app - command: bash -c "uvicorn --factory langflow.main:create_app --host 0.0.0.0 --port 7860 --reload" + command: bash -c "uvicorn --factory src.backend.langflow.main:create_app --host 0.0.0.0 --port 7860 --reload" frontend: build: From 50df00cd0d7287aa2282c544a2ea507b6a9babd3 Mon Sep 17 00:00:00 2001 From: Dave Morris Date: Mon, 7 Aug 2023 08:20:04 -0500 Subject: [PATCH 04/10] Update docker-compose.debug.yml to fix uvicorn factory path --- docker-compose.debug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index 25cddd9f7..6a9802e38 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -11,7 +11,7 @@ services: [ "sh", "-c", - "pip install debugpy -t /tmp && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 -m uvicorn --factory langflow.main:create_app --host 0.0.0.0 --port 7860 --reload", + "pip install debugpy -t /tmp && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 -m uvicorn --factory src.backend.langflow.main:create_app --host 0.0.0.0 --port 7860 --reload", ] ports: - 7860:7860 From 6386a321930ae3663c48c8f75d50bd95c6bd59a6 Mon Sep 17 00:00:00 2001 From: Dave Morris Date: Mon, 7 Aug 2023 08:20:34 -0500 Subject: [PATCH 05/10] Update dev.Dockerfile to fix uvicorn factory path --- dev.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev.Dockerfile b/dev.Dockerfile index 3fcc0803d..ed3631516 100644 --- a/dev.Dockerfile +++ b/dev.Dockerfile @@ -15,4 +15,4 @@ COPY ./ ./ # Install dependencies RUN poetry config virtualenvs.create false && poetry install --no-interaction --no-ansi -CMD ["uvicorn","--factory", "langflow.main:create_app", "--host", "0.0.0.0", "--port", "5003", "--reload", "log-level", "debug"] \ No newline at end of file +CMD ["uvicorn", "--factory", "src.backend.langflow.main:create_app", "--host", "0.0.0.0", "--port", "7860", "--reload", "--log-level", "debug"] From b54231e584a9ee0bebd49c951a3ae1f4e3f19677 Mon Sep 17 00:00:00 2001 From: Dave Morris Date: Mon, 7 Aug 2023 08:21:57 -0500 Subject: [PATCH 06/10] Update Dockerfile to fix uvicorn factory path --- src/backend/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/Dockerfile b/src/backend/Dockerfile index 13f2dc62e..d93227b4a 100644 --- a/src/backend/Dockerfile +++ b/src/backend/Dockerfile @@ -11,4 +11,5 @@ RUN rm *.whl EXPOSE 80 -CMD [ "uvicorn", "--host", "0.0.0.0", "--port", "80", "langflow.backend.app:app" ] +CMD [ "uvicorn", "--host", "0.0.0.0", "--port", "7860", "--factory", "langflow.main:create_app" ] + From bb2b8fbb3d2e837973f7002878444cd446dde699 Mon Sep 17 00:00:00 2001 From: Dave Morris Date: Tue, 8 Aug 2023 17:35:50 -0500 Subject: [PATCH 07/10] add support for VertexAIEmbeddings node --- .dockerignore | 1 + docs/docs/components/embeddings.mdx | 22 ++++++ docs/docs/components/llms.mdx | 22 ++++++ src/backend/Dockerfile | 1 - .../langflow/interface/initialize/loading.py | 8 ++- .../template/frontend_node/embeddings.py | 67 +++++++++++++++++++ src/frontend/src/utils/styleUtils.ts | 1 + src/frontend/vite.config.ts | 3 +- 8 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..0cafc1cde --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +.venv/ \ No newline at end of file diff --git a/docs/docs/components/embeddings.mdx b/docs/docs/components/embeddings.mdx index 644d91fee..5b134f08d 100644 --- a/docs/docs/components/embeddings.mdx +++ b/docs/docs/components/embeddings.mdx @@ -73,3 +73,25 @@ Used to load [OpenAI’s](https://openai.com/) embedding models. - **request_timeout:** Used to specify the maximum amount of time, in milliseconds, to wait for a response from the OpenAI API when generating embeddings for a given text. - **tiktoken_model_name:** Used to count the number of tokens in documents to constrain them to be under a certain limit. By default, when set to None, this will be the same as the embedding model name. + +--- + +### VertexAIEmbeddings + +Wrapper around [Google Vertex AI](https://cloud.google.com/vertex-ai) [Embeddings API](https://cloud.google.com/vertex-ai/docs/generative-ai/embeddings/get-text-embeddings). + +:::info +Vertex AI is a cloud computing platform offered by Google Cloud Platform (GCP). It provides access, management, and development of applications and services through global data centers. To use Vertex AI PaLM, you need to have the [google-cloud-aiplatform](https://pypi.org/project/google-cloud-aiplatform/) Python package installed and credentials configured for your environment. +::: + +- **credentials:** The default custom credentials (google.auth.credentials.Credentials) to use. +- **location:** The default location to use when making API calls – defaults to `us-central1`. +- **max_output_tokens:** Token limit determines the maximum amount of text output from one prompt – defaults to `128`. +- **model_name:** The name of the Vertex AI large language model – defaults to `text-bison`. +- **project:** The default GCP project to use when making Vertex API calls. +- **request_parallelism:** The amount of parallelism allowed for requests issued to VertexAI models – defaults to `5`. +- **temperature:** Tunes the degree of randomness in text generations. Should be a non-negative value – defaults to `0`. +- **top_k:** How the model selects tokens for output, the next token is selected from – defaults to `40`. +- **top_p:** Tokens are selected from most probable to least until the sum of their – defaults to `0.95`. +- **tuned_model_name:** The name of a tuned model. If provided, model_name is ignored. +- **verbose:** This parameter is used to control the level of detail in the output of the chain. When set to True, it will print out some internal states of the chain while it is being run, which can help debug and understand the chain's behavior. If set to False, it will suppress the verbose output – defaults to `False`. \ No newline at end of file diff --git a/docs/docs/components/llms.mdx b/docs/docs/components/llms.mdx index ccca8fdd4..088556d2f 100644 --- a/docs/docs/components/llms.mdx +++ b/docs/docs/components/llms.mdx @@ -185,6 +185,28 @@ Wrapper around [Google Vertex AI](https://cloud.google.com/vertex-ai) large lang Vertex AI is a cloud computing platform offered by Google Cloud Platform (GCP). It provides access, management, and development of applications and services through global data centers. To use Vertex AI PaLM, you need to have the [google-cloud-aiplatform](https://pypi.org/project/google-cloud-aiplatform/) Python package installed and credentials configured for your environment. ::: +- **credentials:** The default custom credentials (google.auth.credentials.Credentials) to use. +- **location:** The default location to use when making API calls – defaults to `us-central1`. +- **max_output_tokens:** Token limit determines the maximum amount of text output from one prompt – defaults to `128`. +- **model_name:** The name of the Vertex AI large language model – defaults to `text-bison`. +- **project:** The default GCP project to use when making Vertex API calls. +- **request_parallelism:** The amount of parallelism allowed for requests issued to VertexAI models – defaults to `5`. +- **temperature:** Tunes the degree of randomness in text generations. Should be a non-negative value – defaults to `0`. +- **top_k:** How the model selects tokens for output, the next token is selected from – defaults to `40`. +- **top_p:** Tokens are selected from most probable to least until the sum of their – defaults to `0.95`. +- **tuned_model_name:** The name of a tuned model. If provided, model_name is ignored. +- **verbose:** This parameter is used to control the level of detail in the output of the chain. When set to True, it will print out some internal states of the chain while it is being run, which can help debug and understand the chain's behavior. If set to False, it will suppress the verbose output – defaults to `False`. + +--- + +### ChatVertexAI + +Wrapper around [Google Vertex AI](https://cloud.google.com/vertex-ai) large language models. + +:::info +Vertex AI is a cloud computing platform offered by Google Cloud Platform (GCP). It provides access, management, and development of applications and services through global data centers. To use Vertex AI PaLM, you need to have the [google-cloud-aiplatform](https://pypi.org/project/google-cloud-aiplatform/) Python package installed and credentials configured for your environment. +::: + - **credentials:** The default custom credentials (google.auth.credentials.Credentials) to use. - **location:** The default location to use when making API calls – defaults to `us-central1`. - **max_output_tokens:** Token limit determines the maximum amount of text output from one prompt – defaults to `128`. diff --git a/src/backend/Dockerfile b/src/backend/Dockerfile index d93227b4a..8257d89b0 100644 --- a/src/backend/Dockerfile +++ b/src/backend/Dockerfile @@ -12,4 +12,3 @@ RUN rm *.whl EXPOSE 80 CMD [ "uvicorn", "--host", "0.0.0.0", "--port", "7860", "--factory", "langflow.main:create_app" ] - diff --git a/src/backend/langflow/interface/initialize/loading.py b/src/backend/langflow/interface/initialize/loading.py index 590fa4727..db876c76a 100644 --- a/src/backend/langflow/interface/initialize/loading.py +++ b/src/backend/langflow/interface/initialize/loading.py @@ -88,7 +88,7 @@ def instantiate_based_on_type(class_object, base_type, node_type, params): elif base_type == "toolkits": return instantiate_toolkit(node_type, class_object, params) elif base_type == "embeddings": - return instantiate_embedding(class_object, params) + return instantiate_embedding(node_type, class_object, params) elif base_type == "vectorstores": return instantiate_vectorstore(class_object, params) elif base_type == "documentloaders": @@ -258,9 +258,13 @@ def instantiate_toolkit(node_type, class_object: Type[BaseToolkit], params: Dict return loaded_toolkit -def instantiate_embedding(class_object, params: Dict): +def instantiate_embedding(node_type, class_object, params: Dict): params.pop("model", None) params.pop("headers", None) + + if "VertexAI" in node_type: + return initialize_vertexai(class_object=class_object, params=params) + try: return class_object(**params) except ValidationError: diff --git a/src/backend/langflow/template/frontend_node/embeddings.py b/src/backend/langflow/template/frontend_node/embeddings.py index d466b11a4..4e7e25112 100644 --- a/src/backend/langflow/template/frontend_node/embeddings.py +++ b/src/backend/langflow/template/frontend_node/embeddings.py @@ -5,6 +5,47 @@ from langflow.template.frontend_node.base import FrontendNode class EmbeddingFrontendNode(FrontendNode): + def add_extra_fields(self) -> None: + if "VertexAI" in self.template.type_name: + # Add credentials field which should of type file. + self.template.add_field( + TemplateField( + field_type="file", + required=False, + show=True, + name="credentials", + value="", + suffixes=[".json"], + file_types=["json"], + ) + ) + + @staticmethod + def format_vertex_field(field: TemplateField, name: str): + if "VertexAI" in name: + advanced_fields = [ + "verbose", + "top_p", + "top_k", + "max_output_tokens", + ] + if field.name in advanced_fields: + field.advanced = True + show_fields = [ + "verbose", + "project", + "location", + "credentials", + "max_output_tokens", + "model_name", + "temperature", + "top_p", + "top_k", + ] + + if field.name in show_fields: + field.show = True + @staticmethod def format_jina_fields(field: TemplateField): if "jina" in field.name: @@ -41,10 +82,36 @@ class EmbeddingFrontendNode(FrontendNode): @staticmethod def format_field(field: TemplateField, name: Optional[str] = None) -> None: FrontendNode.format_field(field, name) + if name and "vertex" in name.lower(): + EmbeddingFrontendNode.format_vertex_field(field, name) field.advanced = not field.required field.show = True if field.name == "headers": field.show = False + if field.name == "model_kwargs": + field.field_type = "code" + field.advanced = True + field.show = True + elif field.name in [ + "model_name", + "temperature", + "model_file", + "model_type", + "deployment_name", + "credentials", + ]: + field.advanced = False + field.show = True + if field.name == "credentials": + field.field_type = "file" + if name == "VertexAI" and field.name not in [ + "callbacks", + "client", + "stop", + "tags", + "cache", + ]: + field.show = True # Format Jina fields EmbeddingFrontendNode.format_jina_fields(field) diff --git a/src/frontend/src/utils/styleUtils.ts b/src/frontend/src/utils/styleUtils.ts index 42fbe8773..5b40e8c05 100644 --- a/src/frontend/src/utils/styleUtils.ts +++ b/src/frontend/src/utils/styleUtils.ts @@ -205,6 +205,7 @@ export const nodeIconsLucide = { SupabaseVectorStore: SupabaseIcon, VertexAI: VertexAIIcon, ChatVertexAI: VertexAIIcon, + VertexAIEmbeddings: VertexAIIcon, agents: Rocket, WikipediaAPIWrapper: SvgWikipedia, chains: Link, diff --git a/src/frontend/vite.config.ts b/src/frontend/vite.config.ts index f051c2eee..c361b7ea4 100644 --- a/src/frontend/vite.config.ts +++ b/src/frontend/vite.config.ts @@ -5,6 +5,7 @@ const apiRoutes = ["^/api/v1/", "/health"]; // Use environment variable to determine the target. const target = process.env.VITE_PROXY_TARGET || "http://127.0.0.1:7860"; +const port = process.env.VITE_PROXY_PORT || 3000; const proxyTargets = apiRoutes.reduce((proxyObj, route) => { proxyObj[route] = { @@ -22,7 +23,7 @@ export default defineConfig(() => { }, plugins: [react(), svgr()], server: { - port: 3000, + port: port, proxy: { ...proxyTargets, }, From aa20ae5a560c9ca025cde25e6c678425dd561848 Mon Sep 17 00:00:00 2001 From: Dave Morris Date: Tue, 8 Aug 2023 20:25:27 -0500 Subject: [PATCH 08/10] rename environment variable for vite server port --- src/frontend/vite.config.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/frontend/vite.config.ts b/src/frontend/vite.config.ts index c361b7ea4..d477ce539 100644 --- a/src/frontend/vite.config.ts +++ b/src/frontend/vite.config.ts @@ -5,7 +5,9 @@ const apiRoutes = ["^/api/v1/", "/health"]; // Use environment variable to determine the target. const target = process.env.VITE_PROXY_TARGET || "http://127.0.0.1:7860"; -const port = process.env.VITE_PROXY_PORT || 3000; + +// Use environment variable to determine the UI server port +const port = process.env.VITE_PORT || 3000; const proxyTargets = apiRoutes.reduce((proxyObj, route) => { proxyObj[route] = { From e922978f27c2f14e19793631da9db06d7d338bac Mon Sep 17 00:00:00 2001 From: Dave Morris Date: Wed, 9 Aug 2023 08:07:59 -0500 Subject: [PATCH 09/10] adding VertexAIEmbeddings into config.yaml --- src/backend/langflow/config.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backend/langflow/config.yaml b/src/backend/langflow/config.yaml index 41627827a..d25893c25 100644 --- a/src/backend/langflow/config.yaml +++ b/src/backend/langflow/config.yaml @@ -104,6 +104,8 @@ embeddings: documentation: "https://python.langchain.com/docs/modules/data_connection/text_embedding/integrations/sentence_transformers" CohereEmbeddings: documentation: "https://python.langchain.com/docs/modules/data_connection/text_embedding/integrations/cohere" + VertexAIEmbeddings: + documentation: "https://python.langchain.com/docs/modules/data_connection/text_embedding/integrations/google_vertex_ai_palm" llms: OpenAI: documentation: "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/openai" @@ -127,9 +129,9 @@ llms: # There's a bug in this component deactivating until we get it sorted: _language_models.py", line 804, in send_message # is_blocked=safety_attributes.get("blocked", False), # AttributeError: 'list' object has no attribute 'get' - ### ChatVertexAI: documentation: "https://python.langchain.com/docs/modules/model_io/models/chat/integrations/google_vertex_ai_palm" + ### memories: # https://github.com/supabase-community/supabase-py/issues/482 # ZepChatMessageHistory: From 97bf39143d619868fe88e9198457b731e19d8e94 Mon Sep 17 00:00:00 2001 From: Dave Morris Date: Wed, 9 Aug 2023 20:08:36 -0500 Subject: [PATCH 10/10] fix to allow running the backend on port 443 without https (wss protocol is required even without an SSL certificate) --- src/frontend/src/modals/formModal/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/modals/formModal/index.tsx b/src/frontend/src/modals/formModal/index.tsx index 81b15559c..89e7c687b 100644 --- a/src/frontend/src/modals/formModal/index.tsx +++ b/src/frontend/src/modals/formModal/index.tsx @@ -160,7 +160,7 @@ export default function FormModal({ } function getWebSocketUrl(chatId, isDevelopment = false) { - const isSecureProtocol = window.location.protocol === "https:"; + const isSecureProtocol = window.location.protocol === "https:" || window.location.port === "443"; const webSocketProtocol = isSecureProtocol ? "wss" : "ws"; const host = isDevelopment ? "localhost:7860" : window.location.host; const chatEndpoint = `/api/v1/chat/${chatId}`;