From 9ebbd8e99a4b06cd3df376881b359db034d8e29a Mon Sep 17 00:00:00 2001 From: SayanDeveloper Date: Wed, 3 Jul 2024 23:49:49 +0530 Subject: [PATCH 01/28] feat: internet search toggle in ui --- frontend/src/screens/dashboard/docsqa/index.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/frontend/src/screens/dashboard/docsqa/index.tsx b/frontend/src/screens/dashboard/docsqa/index.tsx index 3dec7d3f..5427a82d 100644 --- a/frontend/src/screens/dashboard/docsqa/index.tsx +++ b/frontend/src/screens/dashboard/docsqa/index.tsx @@ -83,6 +83,7 @@ const DocsQA = () => { const [retrieverConfig, setRetrieverConfig] = useState(defaultRetrieverConfig) const [promptTemplate, setPromptTemplate] = useState(defaultPrompt) const [isStreamEnabled, setIsStreamEnabled] = useState(false) + const [isInternetSearchEnabled, setIsInternetSearchEnabled] = useState(false) const { data: collections, isLoading: isCollectionsLoading } = useGetCollectionNamesQuery() @@ -150,6 +151,7 @@ const DocsQA = () => { retriever_name: selectedRetriever?.name ?? '', retriever_config: JSON.parse(retrieverConfig), prompt_template: promptTemplate, + internet_search_enabled: isInternetSearchEnabled, }, {} ) @@ -386,6 +388,13 @@ const DocsQA = () => { onChange={(e) => setIsStreamEnabled(e.target.checked)} /> +
+
Internet Search
+ setIsInternetSearchEnabled(e.target.checked)} + /> +
Prompt Template:
Date: Mon, 8 Jul 2024 18:25:36 +0530 Subject: [PATCH 02/28] added carbon loader --- .../modules/dataloaders/carbondataloader.py | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 backend/modules/dataloaders/carbondataloader.py diff --git a/backend/modules/dataloaders/carbondataloader.py b/backend/modules/dataloaders/carbondataloader.py new file mode 100644 index 00000000..77cb8423 --- /dev/null +++ b/backend/modules/dataloaders/carbondataloader.py @@ -0,0 +1,103 @@ +import os , requests +from carbondataloader import Carbon +import shutil +from typing import Dict, Iterator, List + +from backend.logger import logger +from backend.modules.dataloaders.loader import BaseDataLoader +from backend.types import DataIngestionMode, DataPoint, DataSource, LoadedDataPoint + + +api_key = os.get("") +customer_id = os.get("") + +def download_file(url, local_filename): + with requests.get(url, stream=True) as response: + response.raise_for_status() + with open(local_filename, 'wb') as local_file: + for chunk in response.iter_content(chunk_size=8192): + local_file.write(chunk) + return local_filename + +class CarbonDataLoader(BaseDataLoader): + """ + Load data from any source that carbon ai supports + """ + + def load_filtered_data( + self, + data_source: DataSource, + dest_dir: str, + previous_snapshot: Dict[str, str], + batch_size: int, + data_ingestion_mode: DataIngestionMode, + ) -> Iterator[List[LoadedDataPoint]]: + """ + + """ + carbon = Carbon(api_key=api_key,customer_id=customer_id) + + query_user_files_response = carbon.files.query_user_files( + pagination={ + "limit": 10, + "offset": 0, + }, + order_by="created_at", + order_dir="desc", + filters={ + "organization_user_data_source_id": [data_source.uri] + + }, + include_raw_file=True, + include_parsed_text_file=True, + include_additional_files=True, + ) + + for file in query_user_files_response.results: + url = file.presigned_url + filename = file.name + download_file(url, f"{dest_dir}/{filename}") + + + loaded_data_points: List[LoadedDataPoint] = [] + + for root, d_names, f_names in os.walk(dest_dir): + for f in f_names: + if f.startswith("."): + continue + full_path = os.path.join(root, f) + rel_path = os.path.relpath(full_path, dest_dir) + file_ext = os.path.splitext(f)[1] + logger.info( + f"full_path: {full_path}, rel_path: {rel_path}, file_ext: {file_ext}" + ) + data_point = DataPoint( + data_source_fqn=data_source.fqn, + data_point_uri=rel_path, + data_point_hash=str(os.lstat(full_path)), + local_filepath=full_path, + file_extension=file_ext, + ) + + # If the data ingestion mode is incremental, check if the data point already exists. + if ( + data_ingestion_mode == DataIngestionMode.INCREMENTAL + and previous_snapshot.get(data_point.data_point_fqn) + and previous_snapshot.get(data_point.data_point_fqn) + == data_point.data_point_hash + ): + continue + + loaded_data_points.append( + LoadedDataPoint( + data_point_hash=data_point.data_point_hash, + data_point_uri=data_point.data_point_uri, + data_source_fqn=data_point.data_source_fqn, + local_filepath=full_path, + file_extension=file_ext, + ) + ) + if len(loaded_data_points) >= batch_size: + yield loaded_data_points + loaded_data_points.clear() + yield loaded_data_points \ No newline at end of file From 00d9358bba417e4454cab1900077cd6ab4119178 Mon Sep 17 00:00:00 2001 From: Chirag Jain Date: Mon, 8 Jul 2024 18:48:27 +0530 Subject: [PATCH 03/28] Update requirements and refactor loader --- backend/modules/dataloaders/__init__.py | 7 +- .../modules/dataloaders/carbondataloader.py | 130 +++++++++--------- backend/requirements.txt | 4 + backend/settings.py | 3 + 4 files changed, 76 insertions(+), 68 deletions(-) diff --git a/backend/modules/dataloaders/__init__.py b/backend/modules/dataloaders/__init__.py index 409404bd..5a72d741 100644 --- a/backend/modules/dataloaders/__init__.py +++ b/backend/modules/dataloaders/__init__.py @@ -1,7 +1,6 @@ from backend.modules.dataloaders.githubloader import GithubLoader from backend.modules.dataloaders.loader import register_dataloader from backend.modules.dataloaders.localdirloader import LocalDirLoader -from backend.modules.dataloaders.truefoundryloader import TrueFoundryLoader from backend.modules.dataloaders.webloader import WebLoader from backend.settings import settings @@ -9,4 +8,10 @@ register_dataloader("web", WebLoader) register_dataloader("github", GithubLoader) if settings.TFY_API_KEY: + from backend.modules.dataloaders.truefoundryloader import TrueFoundryLoader + register_dataloader("truefoundry", TrueFoundryLoader) +if settings.CARBON_AI_API_KEY: + from backend.modules.dataloaders.carbondataloader import CarbonDataLoader + + register_dataloader("carbon", CarbonDataLoader) diff --git a/backend/modules/dataloaders/carbondataloader.py b/backend/modules/dataloaders/carbondataloader.py index 77cb8423..be066a8d 100644 --- a/backend/modules/dataloaders/carbondataloader.py +++ b/backend/modules/dataloaders/carbondataloader.py @@ -1,29 +1,28 @@ -import os , requests -from carbondataloader import Carbon -import shutil +import os from typing import Dict, Iterator, List +import requests +from carbon import Carbon + from backend.logger import logger from backend.modules.dataloaders.loader import BaseDataLoader +from backend.settings import settings from backend.types import DataIngestionMode, DataPoint, DataSource, LoadedDataPoint -api_key = os.get("") -customer_id = os.get("") - -def download_file(url, local_filename): - with requests.get(url, stream=True) as response: - response.raise_for_status() - with open(local_filename, 'wb') as local_file: - for chunk in response.iter_content(chunk_size=8192): - local_file.write(chunk) - return local_filename - class CarbonDataLoader(BaseDataLoader): """ - Load data from any source that carbon ai supports + Load data from any source that carbon ai supports """ - + + def _download_file(self, url: str, local_filepath: str, chunk_size: int = 8192): + with requests.get(url, stream=True) as response: + response.raise_for_status() + with open(local_filepath, "wb") as local_file: + for chunk in response.iter_content(chunk_size=chunk_size): + local_file.write(chunk) + return local_filepath + def load_filtered_data( self, data_source: DataSource, @@ -32,72 +31,69 @@ def load_filtered_data( batch_size: int, data_ingestion_mode: DataIngestionMode, ) -> Iterator[List[LoadedDataPoint]]: - """ - - """ - carbon = Carbon(api_key=api_key,customer_id=customer_id) + carbon = Carbon( + api_key=settings.CARBON_AI_API_KEY, + customer_id=settings.CARBON_AI_DEFAULT_CUSTOMER_ID, + ) query_user_files_response = carbon.files.query_user_files( pagination={ - "limit": 10, + "limit": 50, "offset": 0, }, order_by="created_at", order_dir="desc", - filters={ - "organization_user_data_source_id": [data_source.uri] - - }, + filters={"organization_user_data_source_id": [data_source.uri]}, include_raw_file=True, - include_parsed_text_file=True, - include_additional_files=True, + include_parsed_text_file=False, + include_additional_files=False, # TODO (chiragjn): Evaluate later ) + loaded_data_points: List[LoadedDataPoint] = [] + for file in query_user_files_response.results: url = file.presigned_url filename = file.name - download_file(url, f"{dest_dir}/{filename}") + file_id = file.external_file_id + _, file_extension = os.path.splitext(filename) + local_filepath = os.path.join(dest_dir, f"{file_id}-{filename}") + logger.debug( + f"Downloading file {filename} from {file.source} data source type to {local_filepath}" + ) + self._download_file(url=url, local_filepath=local_filepath) - - loaded_data_points: List[LoadedDataPoint] = [] + data_point_uri = f"{file.source}::{file.external_file_id}" + data_point_hash = ( + f"{file.source_created_at}::{file.file_statistics.file_size or 0}" + ) - for root, d_names, f_names in os.walk(dest_dir): - for f in f_names: - if f.startswith("."): - continue - full_path = os.path.join(root, f) - rel_path = os.path.relpath(full_path, dest_dir) - file_ext = os.path.splitext(f)[1] - logger.info( - f"full_path: {full_path}, rel_path: {rel_path}, file_ext: {file_ext}" - ) - data_point = DataPoint( - data_source_fqn=data_source.fqn, - data_point_uri=rel_path, - data_point_hash=str(os.lstat(full_path)), - local_filepath=full_path, - file_extension=file_ext, - ) + data_point = DataPoint( + data_source_fqn=data_source.fqn, + data_point_uri=data_point_uri, + data_point_hash=data_point_hash, + local_filepath=local_filepath, + file_extension=file_extension, + ) - # If the data ingestion mode is incremental, check if the data point already exists. - if ( - data_ingestion_mode == DataIngestionMode.INCREMENTAL - and previous_snapshot.get(data_point.data_point_fqn) - and previous_snapshot.get(data_point.data_point_fqn) - == data_point.data_point_hash - ): - continue + # If the data ingestion mode is incremental, check if the data point already exists. + if ( + data_ingestion_mode == DataIngestionMode.INCREMENTAL + and previous_snapshot.get(data_point.data_point_fqn) + and previous_snapshot.get(data_point.data_point_fqn) + == data_point.data_point_hash + ): + continue - loaded_data_points.append( - LoadedDataPoint( - data_point_hash=data_point.data_point_hash, - data_point_uri=data_point.data_point_uri, - data_source_fqn=data_point.data_source_fqn, - local_filepath=full_path, - file_extension=file_ext, - ) + loaded_data_points.append( + LoadedDataPoint( + data_point_hash=data_point.data_point_hash, + data_point_uri=data_point.data_point_uri, + data_source_fqn=data_point.data_source_fqn, + local_filepath=local_filepath, + file_extension=file_extension, ) - if len(loaded_data_points) >= batch_size: - yield loaded_data_points - loaded_data_points.clear() - yield loaded_data_points \ No newline at end of file + ) + if len(loaded_data_points) >= batch_size: + yield loaded_data_points + loaded_data_points.clear() + yield loaded_data_points diff --git a/backend/requirements.txt b/backend/requirements.txt index 38b63e5d..e1ab3d35 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -32,3 +32,7 @@ transformers==4.40.2 ### prisma prisma==0.13.1 + + +# carbon +carbon-python-sdk==0.2.11 diff --git a/backend/settings.py b/backend/settings.py index 58e6a555..e6b68871 100644 --- a/backend/settings.py +++ b/backend/settings.py @@ -31,6 +31,9 @@ class Config: # TODO: This will be removed in future releases - after fixing multimodal parser TFY_LLM_GATEWAY_URL: str = "" + CARBON_AI_API_KEY: str = "" + CARBON_AI_DEFAULT_CUSTOMER_ID: str = "" + @root_validator(pre=True) def _validate_values(cls, values): models_config_path = values.get("MODELS_CONFIG_PATH") From ecd705765e25f4b679128f3bf70004e7c5e9c4c0 Mon Sep 17 00:00:00 2001 From: Chirag Jain Date: Mon, 8 Jul 2024 19:03:44 +0530 Subject: [PATCH 04/28] Bumpy pydantic to v2 and update imports for older pydantic v1 usages --- backend/indexer/types.py | 2 +- backend/modules/dataloaders/carbondataloader.py | 2 +- backend/modules/query_controllers/example/types.py | 2 +- backend/modules/query_controllers/multimodal/types.py | 2 +- backend/requirements.txt | 2 +- backend/server/decorators.py | 2 +- backend/settings.py | 2 +- backend/types.py | 2 +- compose.env | 4 ++++ 9 files changed, 12 insertions(+), 8 deletions(-) diff --git a/backend/indexer/types.py b/backend/indexer/types.py index 84255950..7bdfc61e 100644 --- a/backend/indexer/types.py +++ b/backend/indexer/types.py @@ -1,4 +1,4 @@ -from pydantic import BaseModel, Field +from pydantic.v1 import BaseModel, Field from backend.types import DataIngestionMode, DataSource, EmbedderConfig, ParserConfig diff --git a/backend/modules/dataloaders/carbondataloader.py b/backend/modules/dataloaders/carbondataloader.py index be066a8d..056adb10 100644 --- a/backend/modules/dataloaders/carbondataloader.py +++ b/backend/modules/dataloaders/carbondataloader.py @@ -43,7 +43,7 @@ def load_filtered_data( }, order_by="created_at", order_dir="desc", - filters={"organization_user_data_source_id": [data_source.uri]}, + filters={"organization_user_data_source_id": [int(data_source.uri)]}, include_raw_file=True, include_parsed_text_file=False, include_additional_files=False, # TODO (chiragjn): Evaluate later diff --git a/backend/modules/query_controllers/example/types.py b/backend/modules/query_controllers/example/types.py index 0dbe2741..19da631a 100644 --- a/backend/modules/query_controllers/example/types.py +++ b/backend/modules/query_controllers/example/types.py @@ -1,6 +1,6 @@ from typing import Any, ClassVar, Collection, Dict, Optional -from pydantic import BaseModel, Field, root_validator, validator +from pydantic.v1 import BaseModel, Field, root_validator, validator from qdrant_client.models import Filter as QdrantFilter from backend.types import ModelConfig diff --git a/backend/modules/query_controllers/multimodal/types.py b/backend/modules/query_controllers/multimodal/types.py index 0dbe2741..19da631a 100644 --- a/backend/modules/query_controllers/multimodal/types.py +++ b/backend/modules/query_controllers/multimodal/types.py @@ -1,6 +1,6 @@ from typing import Any, ClassVar, Collection, Dict, Optional -from pydantic import BaseModel, Field, root_validator, validator +from pydantic.v1 import BaseModel, Field, root_validator, validator from qdrant_client.models import Filter as QdrantFilter from backend.types import ModelConfig diff --git a/backend/requirements.txt b/backend/requirements.txt index e1ab3d35..384d0270 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -9,7 +9,7 @@ uvicorn==0.23.2 fastapi==0.109.1 qdrant-client==1.9.0 python-dotenv==1.0.1 -pydantic==1.10.13 +pydantic==2.8.2 orjson==3.9.15 PyMuPDF==1.23.6 redis==5.0.1 diff --git a/backend/server/decorators.py b/backend/server/decorators.py index 2b17ff98..2b26614f 100644 --- a/backend/server/decorators.py +++ b/backend/server/decorators.py @@ -7,7 +7,7 @@ from typing import Any, Callable, List, Type, TypeVar, Union, get_type_hints from fastapi import APIRouter, Depends -from pydantic.typing import is_classvar +from pydantic.v1.typing import is_classvar from starlette.routing import Route, WebSocketRoute T = TypeVar("T") diff --git a/backend/settings.py b/backend/settings.py index e6b68871..45b29d34 100644 --- a/backend/settings.py +++ b/backend/settings.py @@ -1,7 +1,7 @@ import os from typing import Optional -from pydantic import BaseSettings, root_validator +from pydantic.v1 import BaseSettings, root_validator from backend.types import MetadataStoreConfig, VectorDBConfig diff --git a/backend/types.py b/backend/types.py index 3d92162e..eb483d3e 100644 --- a/backend/types.py +++ b/backend/types.py @@ -4,7 +4,7 @@ from enum import Enum from typing import Any, Dict, List, Literal, Optional -from pydantic import BaseModel, Field, constr, root_validator +from pydantic.v1 import BaseModel, Field, constr, root_validator from backend.constants import FQN_SEPARATOR diff --git a/compose.env b/compose.env index 9f7f4741..1eee6803 100644 --- a/compose.env +++ b/compose.env @@ -34,3 +34,7 @@ OPENAI_API_KEY= ## TFY VARS TFY_API_KEY= TFY_HOST= + + +CARBON_AI_API_KEY= +CARBON_AI_DEFAULT_CUSTOMER_ID= From 70e922307e98ef4df8a09ca791bf44201064986c Mon Sep 17 00:00:00 2001 From: Chirag Jain Date: Mon, 8 Jul 2024 20:09:44 +0530 Subject: [PATCH 05/28] make customer id part of uri --- .../modules/dataloaders/carbondataloader.py | 18 ++++++++++++++---- backend/settings.py | 1 - compose.env | 2 -- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/backend/modules/dataloaders/carbondataloader.py b/backend/modules/dataloaders/carbondataloader.py index 056adb10..9a0ebd15 100644 --- a/backend/modules/dataloaders/carbondataloader.py +++ b/backend/modules/dataloaders/carbondataloader.py @@ -12,7 +12,7 @@ class CarbonDataLoader(BaseDataLoader): """ - Load data from any source that carbon ai supports + Load data from variety of sources like Google Drive, Confluence, Notion and more """ def _download_file(self, url: str, local_filepath: str, chunk_size: int = 8192): @@ -31,9 +31,10 @@ def load_filtered_data( batch_size: int, data_ingestion_mode: DataIngestionMode, ) -> Iterator[List[LoadedDataPoint]]: + carbon_customer_id, carbon_data_source_id = data_source.uri.split("/") carbon = Carbon( api_key=settings.CARBON_AI_API_KEY, - customer_id=settings.CARBON_AI_DEFAULT_CUSTOMER_ID, + customer_id=carbon_customer_id, ) query_user_files_response = carbon.files.query_user_files( @@ -43,7 +44,7 @@ def load_filtered_data( }, order_by="created_at", order_dir="desc", - filters={"organization_user_data_source_id": [int(data_source.uri)]}, + filters={"organization_user_data_source_id": [int(carbon_data_source_id)]}, include_raw_file=True, include_parsed_text_file=False, include_additional_files=False, # TODO (chiragjn): Evaluate later @@ -57,7 +58,7 @@ def load_filtered_data( file_id = file.external_file_id _, file_extension = os.path.splitext(filename) local_filepath = os.path.join(dest_dir, f"{file_id}-{filename}") - logger.debug( + logger.info( f"Downloading file {filename} from {file.source} data source type to {local_filepath}" ) self._download_file(url=url, local_filepath=local_filepath) @@ -91,6 +92,15 @@ def load_filtered_data( data_source_fqn=data_point.data_source_fqn, local_filepath=local_filepath, file_extension=file_extension, + metadata={ + "data_source_type": file.source, + "id": file.id, + "external_file_id": file.external_file_id, + "filename": filename, + "file_format": file.file_statistics.file_format, + "mime_type": file.file_statistics.mime_type, + "created_at": file.source_created_at, + }, ) ) if len(loaded_data_points) >= batch_size: diff --git a/backend/settings.py b/backend/settings.py index 45b29d34..1dd61e85 100644 --- a/backend/settings.py +++ b/backend/settings.py @@ -32,7 +32,6 @@ class Config: TFY_LLM_GATEWAY_URL: str = "" CARBON_AI_API_KEY: str = "" - CARBON_AI_DEFAULT_CUSTOMER_ID: str = "" @root_validator(pre=True) def _validate_values(cls, values): diff --git a/compose.env b/compose.env index 1eee6803..55d03771 100644 --- a/compose.env +++ b/compose.env @@ -35,6 +35,4 @@ OPENAI_API_KEY= TFY_API_KEY= TFY_HOST= - CARBON_AI_API_KEY= -CARBON_AI_DEFAULT_CUSTOMER_ID= From 2d5599ed6d9fbba9471f951ef2a4d903fcf84ee5 Mon Sep 17 00:00:00 2001 From: Chirag Jain Date: Tue, 9 Jul 2024 00:22:03 +0530 Subject: [PATCH 06/28] remove carbon sdk and revert back to pydantic v1 --- backend/indexer/types.py | 2 +- .../modules/dataloaders/carbondataloader.py | 88 +++++++++++++++++-- .../query_controllers/example/types.py | 2 +- .../query_controllers/multimodal/types.py | 2 +- backend/requirements.txt | 8 +- backend/server/decorators.py | 2 +- backend/settings.py | 2 +- backend/types.py | 2 +- docker-compose.yaml | 1 + 9 files changed, 92 insertions(+), 17 deletions(-) diff --git a/backend/indexer/types.py b/backend/indexer/types.py index 7bdfc61e..84255950 100644 --- a/backend/indexer/types.py +++ b/backend/indexer/types.py @@ -1,4 +1,4 @@ -from pydantic.v1 import BaseModel, Field +from pydantic import BaseModel, Field from backend.types import DataIngestionMode, DataSource, EmbedderConfig, ParserConfig diff --git a/backend/modules/dataloaders/carbondataloader.py b/backend/modules/dataloaders/carbondataloader.py index 9a0ebd15..b25c5c1b 100644 --- a/backend/modules/dataloaders/carbondataloader.py +++ b/backend/modules/dataloaders/carbondataloader.py @@ -1,8 +1,8 @@ import os -from typing import Dict, Iterator, List +from typing import Any, Dict, Iterator, List, Optional import requests -from carbon import Carbon +from pydantic import BaseModel, Field from backend.logger import logger from backend.modules.dataloaders.loader import BaseDataLoader @@ -10,6 +10,84 @@ from backend.types import DataIngestionMode, DataPoint, DataSource, LoadedDataPoint +class _FileStatistics(BaseModel): + file_size: Optional[int] = None + mime_type: Optional[str] = None + file_format: Optional[str] = None + + +class _File(BaseModel): + id: int + name: str + presigned_url: Optional[str] = None + external_file_id: str + source: str + source_created_at: str + file_statistics: _FileStatistics = Field(default_factory=_FileStatistics) + + +class _UserFilesV2Response(BaseModel): + results: List[_File] + count: int + + +class _CarbonClient: + def __init__(self, api_key: str, customer_id: str): + self.api_key = api_key + self.customer_id = customer_id + + def _request(self, method: str, endpoint: str, **kwargs): + headers = { + "Authorization": f"Bearer {self.api_key}", + "customer-id": self.customer_id, + } + response = requests.request(method, endpoint, headers=headers, **kwargs) + response.raise_for_status() + return response.json() + + def query_user_files( + self, + pagination: Optional[Dict[str, int]] = None, + order_by: Optional[str] = None, + order_dir: Optional[str] = None, + filters: Optional[Dict[str, Any]] = None, + include_raw_file: Optional[Optional[bool]] = None, + include_parsed_text_file: Optional[Optional[bool]] = None, + include_additional_files: Optional[Optional[bool]] = None, + ) -> Iterator[_File]: + payload = {} + if pagination is not None: + payload["pagination"] = pagination + if order_by is not None: + payload["order_by"] = order_by + if order_dir is not None: + payload["order_dir"] = order_dir + if filters is not None: + payload["filters"] = filters + if include_raw_file is not None: + payload["include_raw_file"] = include_raw_file + if include_parsed_text_file is not None: + payload["include_parsed_text_file"] = include_parsed_text_file + if include_additional_files is not None: + payload["include_additional_files"] = include_additional_files + + total = -1 + count = 0 + + while total == -1 or count < total: + response = self._request( + "POST", "https://api.carbon.ai/user_files_v2", json=payload + ) + page = _UserFilesV2Response.parse_obj(response) + if total == -1: + total = page.count + for file in page.results: + # TODO (chiragjn): There can be an edge case here where file.file_metadata.is_folder = True + yield file + count += len(page.results) + payload["pagination"]["offset"] = count + + class CarbonDataLoader(BaseDataLoader): """ Load data from variety of sources like Google Drive, Confluence, Notion and more @@ -32,12 +110,12 @@ def load_filtered_data( data_ingestion_mode: DataIngestionMode, ) -> Iterator[List[LoadedDataPoint]]: carbon_customer_id, carbon_data_source_id = data_source.uri.split("/") - carbon = Carbon( + carbon = _CarbonClient( api_key=settings.CARBON_AI_API_KEY, customer_id=carbon_customer_id, ) - query_user_files_response = carbon.files.query_user_files( + user_files = carbon.query_user_files( pagination={ "limit": 50, "offset": 0, @@ -52,7 +130,7 @@ def load_filtered_data( loaded_data_points: List[LoadedDataPoint] = [] - for file in query_user_files_response.results: + for file in user_files: url = file.presigned_url filename = file.name file_id = file.external_file_id diff --git a/backend/modules/query_controllers/example/types.py b/backend/modules/query_controllers/example/types.py index 19da631a..7cc39d8d 100644 --- a/backend/modules/query_controllers/example/types.py +++ b/backend/modules/query_controllers/example/types.py @@ -1,6 +1,6 @@ from typing import Any, ClassVar, Collection, Dict, Optional -from pydantic.v1 import BaseModel, Field, root_validator, validator +from pydantic import BaseModel, Field, root_validator from qdrant_client.models import Filter as QdrantFilter from backend.types import ModelConfig diff --git a/backend/modules/query_controllers/multimodal/types.py b/backend/modules/query_controllers/multimodal/types.py index 19da631a..7cc39d8d 100644 --- a/backend/modules/query_controllers/multimodal/types.py +++ b/backend/modules/query_controllers/multimodal/types.py @@ -1,6 +1,6 @@ from typing import Any, ClassVar, Collection, Dict, Optional -from pydantic.v1 import BaseModel, Field, root_validator, validator +from pydantic import BaseModel, Field, root_validator from qdrant_client.models import Filter as QdrantFilter from backend.types import ModelConfig diff --git a/backend/requirements.txt b/backend/requirements.txt index 384d0270..0094a3de 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -9,12 +9,12 @@ uvicorn==0.23.2 fastapi==0.109.1 qdrant-client==1.9.0 python-dotenv==1.0.1 -pydantic==2.8.2 +pydantic>=1.0.0,<2.0.0 orjson==3.9.15 PyMuPDF==1.23.6 redis==5.0.1 beautifulsoup4==4.12.2 -truefoundry[ml]==0.2.4 +truefoundry[ml]==0.2.9 markdownify==0.11.6 gunicorn==22.0.0 markdown-crawler==0.0.8 @@ -32,7 +32,3 @@ transformers==4.40.2 ### prisma prisma==0.13.1 - - -# carbon -carbon-python-sdk==0.2.11 diff --git a/backend/server/decorators.py b/backend/server/decorators.py index 2b26614f..2b17ff98 100644 --- a/backend/server/decorators.py +++ b/backend/server/decorators.py @@ -7,7 +7,7 @@ from typing import Any, Callable, List, Type, TypeVar, Union, get_type_hints from fastapi import APIRouter, Depends -from pydantic.v1.typing import is_classvar +from pydantic.typing import is_classvar from starlette.routing import Route, WebSocketRoute T = TypeVar("T") diff --git a/backend/settings.py b/backend/settings.py index 1dd61e85..010e3b54 100644 --- a/backend/settings.py +++ b/backend/settings.py @@ -1,7 +1,7 @@ import os from typing import Optional -from pydantic.v1 import BaseSettings, root_validator +from pydantic import BaseSettings, root_validator from backend.types import MetadataStoreConfig, VectorDBConfig diff --git a/backend/types.py b/backend/types.py index eb483d3e..3d92162e 100644 --- a/backend/types.py +++ b/backend/types.py @@ -4,7 +4,7 @@ from enum import Enum from typing import Any, Dict, List, Literal, Optional -from pydantic.v1 import BaseModel, Field, constr, root_validator +from pydantic import BaseModel, Field, constr, root_validator from backend.constants import FQN_SEPARATOR diff --git a/docker-compose.yaml b/docker-compose.yaml index 859764c3..25ef3801 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -138,6 +138,7 @@ services: - TFY_API_KEY=${TFY_API_KEY} - TFY_HOST=${TFY_HOST} - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@cognita-db:5432/cognita-config + - CARBON_AI_API_KEY=${CARBON_AI_API_KEY} entrypoint: /bin/bash command: -c "set -e; prisma db push --schema ./backend/database/schema.prisma && uvicorn --host 0.0.0.0 --port 8000 backend.server.app:app --reload" networks: From b19342b10dda3472ea3df00dfcc0eff12ea01b85 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Tue, 9 Jul 2024 00:51:43 +0530 Subject: [PATCH 07/28] Added internet search for basic controller --- backend/modules/query_controllers/common.py | 41 +++++++++++++++++++ .../query_controllers/example/controller.py | 25 ++++++++++- .../query_controllers/example/payload.py | 12 ++++++ .../query_controllers/example/types.py | 4 ++ .../multimodal/controller.py | 10 +++++ .../query_controllers/multimodal/payload.py | 12 ++++++ .../query_controllers/multimodal/types.py | 4 ++ backend/settings.py | 2 + 8 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 backend/modules/query_controllers/common.py diff --git a/backend/modules/query_controllers/common.py b/backend/modules/query_controllers/common.py new file mode 100644 index 00000000..3d77d4d7 --- /dev/null +++ b/backend/modules/query_controllers/common.py @@ -0,0 +1,41 @@ +import requests + +from backend.settings import settings + + +def internet_search(query: str): + headers = { + "Accept": " application/json", + "X-Subscription-Token": f"{settings.BRAVE_API_KEY}", + } + + params = { + "q": f"{query}", + } + + # response = requests.get('https://api.search.brave.com/res/v1/web/search', params=params, headers=headers) + # response.raise_for_status() + # answer = response.json() + + answer = "DEMO ANSWER FROM INTERNET SEARCH" + return answer + + +def intent_summary_search(query: str): + headers = { + "Accept": "application/json", + # 'Accept-Encoding': 'gzip', + "X-Subscription-Token": f"{settings.BRAVE_API_KEY}", + } + + params = { + "q": f"{query}", + "summary": "1", + } + + # response = requests.get('https://api.search.brave.com/res/v1/web/search', params=params, headers=headers) + # response.raise_for_status() + # answer = response.json() + + answer = "DEMO ANSWER FROM INTENT SUMMARY SEARCH" + return answer diff --git a/backend/modules/query_controllers/example/controller.py b/backend/modules/query_controllers/example/controller.py index cbac7731..49eea57c 100644 --- a/backend/modules/query_controllers/example/controller.py +++ b/backend/modules/query_controllers/example/controller.py @@ -14,6 +14,10 @@ from backend.logger import logger from backend.modules.metadata_store.client import get_client from backend.modules.model_gateway.model_gateway import model_gateway +from backend.modules.query_controllers.common import ( + intent_summary_search, + internet_search, +) from backend.modules.query_controllers.example.payload import ( QUERY_WITH_CONTEXTUAL_COMPRESSION_MULTI_QUERY_RETRIEVER_SIMILARITY_PAYLOAD, QUERY_WITH_CONTEXTUAL_COMPRESSION_RETRIEVER_PAYLOAD, @@ -44,13 +48,24 @@ def _get_prompt_template(self, input_variables, template): """ return PromptTemplate(input_variables=input_variables, template=template) - def _format_docs(self, docs): + def _format_docs(self, docs, query, internet_search_enabled=False): formatted_docs = list() for doc in docs: doc.metadata.pop("image_b64", None) formatted_docs.append( {"page_content": doc.page_content, "metadata": doc.metadata} ) + + if internet_search_enabled: + # internet_search_results = internet_search(query) + intent_summary_results = intent_summary_search(query) + formatted_docs.append( + { + "page_content": f"{intent_summary_results}", + "metadata": {"source": "Intent Summary Search"}, + } + ) + return "\n\n".join([f"{doc['page_content']}" for doc in formatted_docs]) def _format_docs_for_stream(self, docs): @@ -208,6 +223,7 @@ async def answer( """ Sample answer method to answer the question using the context from the collection """ + logger.info(f"Request: {request.dict()}") try: # Get the vector store vector_store = await self._get_vector_store(request.collection_name) @@ -231,7 +247,12 @@ async def answer( # Using LCEL rag_chain_from_docs = ( RunnablePassthrough.assign( - context=(lambda x: self._format_docs(x["context"])) + # add internet search results to context + context=( + lambda x: self._format_docs( + x["context"], request.query, request.internet_search_enabled + ) + ) ) | QA_PROMPT | llm diff --git a/backend/modules/query_controllers/example/payload.py b/backend/modules/query_controllers/example/payload.py index df88f52c..d3f2de99 100644 --- a/backend/modules/query_controllers/example/payload.py +++ b/backend/modules/query_controllers/example/payload.py @@ -10,6 +10,7 @@ "retriever_name": "vectorstore", "retriever_config": {"search_type": "similarity", "search_kwargs": {"k": 5}}, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_VECTOR_STORE_RETRIEVER_PAYLOAD = { @@ -38,6 +39,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_VECTOR_STORE_RETRIEVER_MMR_PAYLOAD = { @@ -63,6 +65,7 @@ "search_kwargs": {"score_threshold": 0.7}, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_VECTOR_STORE_RETRIEVER_SIMILARITY_SCORE_PAYLOAD = { @@ -90,6 +93,7 @@ "search_kwargs": {"k": 10}, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_CONTEXTUAL_COMPRESSION_RETRIEVER_PAYLOAD = { @@ -121,6 +125,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_CONTEXTUAL_COMPRESSION_RETRIEVER_SEARCH_TYPE_MMR_PAYLOAD = { @@ -151,6 +156,7 @@ "search_kwargs": {"score_threshold": 0.7}, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_CONTEXTUAL_COMPRESSION_RETRIEVER_SEARCH_TYPE_SIMILARITY_WITH_SCORE_PAYLOAD = { @@ -183,6 +189,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_MULTI_QUERY_RETRIEVER_SIMILARITY_PAYLOAD = { @@ -217,6 +224,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_MULTI_QUERY_RETRIEVER_MMR_PAYLOAD = { @@ -247,6 +255,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_MULTI_QUERY_RETRIEVER_SIMILARITY_SCORE_PAYLOAD = { @@ -283,6 +292,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_CONTEXTUAL_COMPRESSION_MULTI_QUERY_RETRIEVER_MMR_PAYLOAD = { @@ -316,6 +326,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_CONTEXTUAL_COMPRESSION_MULTI_QUERY_RETRIEVER_SIMILARITY_PAYLOAD = { @@ -349,6 +360,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_CONTEXTUAL_COMPRESSION_MULTI_QUERY_RETRIEVER_SIMILARITY_SCORE_PAYLOAD = { diff --git a/backend/modules/query_controllers/example/types.py b/backend/modules/query_controllers/example/types.py index 0dbe2741..0170bbc8 100644 --- a/backend/modules/query_controllers/example/types.py +++ b/backend/modules/query_controllers/example/types.py @@ -126,6 +126,10 @@ class ExampleQueryInput(BaseModel): stream: Optional[bool] = Field(title="Stream the results", default=False) + internet_search_enabled: Optional[bool] = Field( + title="Enable internet search", default=False + ) + @root_validator() def validate_retriever_type(cls, values: Dict) -> Dict: retriever_name = values.get("retriever_name") diff --git a/backend/modules/query_controllers/multimodal/controller.py b/backend/modules/query_controllers/multimodal/controller.py index bc9f35b2..b2d22f36 100644 --- a/backend/modules/query_controllers/multimodal/controller.py +++ b/backend/modules/query_controllers/multimodal/controller.py @@ -14,6 +14,10 @@ from backend.logger import logger from backend.modules.metadata_store.client import get_client from backend.modules.model_gateway.model_gateway import model_gateway +from backend.modules.query_controllers.common import ( + intent_summary_search, + internet_search, +) from backend.modules.query_controllers.multimodal.payload import ( PROMPT, QUERY_WITH_CONTEXTUAL_COMPRESSION_MULTI_QUERY_RETRIEVER_SIMILARITY_PAYLOAD, @@ -254,6 +258,12 @@ async def answer( Sample answer method to answer the question using the context from the collection """ try: + if request.internet_search_enabled is True: + return { + "answer": "Internet search is not available for multimodal RAG yet", + "docs": [], + } + # Get the vector store vector_store = await self._get_vector_store(request.collection_name) diff --git a/backend/modules/query_controllers/multimodal/payload.py b/backend/modules/query_controllers/multimodal/payload.py index 8dd6eb70..bb1cbc25 100644 --- a/backend/modules/query_controllers/multimodal/payload.py +++ b/backend/modules/query_controllers/multimodal/payload.py @@ -10,6 +10,7 @@ "retriever_name": "vectorstore", "retriever_config": {"search_type": "similarity", "search_kwargs": {"k": 5}}, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_VECTOR_STORE_RETRIEVER_PAYLOAD = { @@ -38,6 +39,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_VECTOR_STORE_RETRIEVER_MMR_PAYLOAD = { @@ -63,6 +65,7 @@ "search_kwargs": {"score_threshold": 0.7}, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_VECTOR_STORE_RETRIEVER_SIMILARITY_SCORE_PAYLOAD = { @@ -90,6 +93,7 @@ "search_kwargs": {"k": 10}, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_CONTEXTUAL_COMPRESSION_RETRIEVER_PAYLOAD = { @@ -121,6 +125,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_CONTEXTUAL_COMPRESSION_RETRIEVER_SEARCH_TYPE_MMR_PAYLOAD = { @@ -151,6 +156,7 @@ "search_kwargs": {"score_threshold": 0.7}, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_CONTEXTUAL_COMPRESSION_RETRIEVER_SEARCH_TYPE_SIMILARITY_WITH_SCORE_PAYLOAD = { @@ -182,6 +188,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_MULTI_QUERY_RETRIEVER_SIMILARITY_PAYLOAD = { @@ -215,6 +222,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_MULTI_QUERY_RETRIEVER_MMR_PAYLOAD = { @@ -244,6 +252,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_MULTI_QUERY_RETRIEVER_SIMILARITY_SCORE_PAYLOAD = { @@ -280,6 +289,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_CONTEXTUAL_COMPRESSION_MULTI_QUERY_RETRIEVER_MMR_PAYLOAD = { @@ -312,6 +322,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_CONTEXTUAL_COMPRESSION_MULTI_QUERY_RETRIEVER_SIMILARITY_PAYLOAD = { @@ -344,6 +355,7 @@ }, }, "stream": False, + "internet_search_enabled": False, } QUERY_WITH_CONTEXTUAL_COMPRESSION_MULTI_QUERY_RETRIEVER_SIMILARITY_SCORE_PAYLOAD = { diff --git a/backend/modules/query_controllers/multimodal/types.py b/backend/modules/query_controllers/multimodal/types.py index 0dbe2741..0170bbc8 100644 --- a/backend/modules/query_controllers/multimodal/types.py +++ b/backend/modules/query_controllers/multimodal/types.py @@ -126,6 +126,10 @@ class ExampleQueryInput(BaseModel): stream: Optional[bool] = Field(title="Stream the results", default=False) + internet_search_enabled: Optional[bool] = Field( + title="Enable internet search", default=False + ) + @root_validator() def validate_retriever_type(cls, values: Dict) -> Dict: retriever_name = values.get("retriever_name") diff --git a/backend/settings.py b/backend/settings.py index 58e6a555..6b008320 100644 --- a/backend/settings.py +++ b/backend/settings.py @@ -31,6 +31,8 @@ class Config: # TODO: This will be removed in future releases - after fixing multimodal parser TFY_LLM_GATEWAY_URL: str = "" + BRAVE_API_KEY: str = "" + @root_validator(pre=True) def _validate_values(cls, values): models_config_path = values.get("MODELS_CONFIG_PATH") From 38c1a3bcd06e7421d4c91c919c8a1cfa9b31ca7b Mon Sep 17 00:00:00 2001 From: Chirag Jain Date: Tue, 9 Jul 2024 01:09:18 +0530 Subject: [PATCH 08/28] Add carbon api key as build arg --- backend/Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/Dockerfile b/backend/Dockerfile index b2a16f46..34459a0e 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -40,6 +40,9 @@ ENV MODELS_CONFIG_PATH=${MODELS_CONFIG_PATH} ARG INFINITY_API_KEY ENV INFINITY_API_KEY=${INFINITY_API_KEY} +ARG CARBON_AI_API_KEY +ENV CARBON_AI_API_KEY=${CARBON_AI_API_KEY} + # Copy the project files COPY . /app From 8a06513b9d247dcd08c3d8777105f67a433670b6 Mon Sep 17 00:00:00 2001 From: Chirag Jain Date: Tue, 9 Jul 2024 02:01:32 +0530 Subject: [PATCH 09/28] Bump truefoundry to fix list issue --- backend/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/requirements.txt b/backend/requirements.txt index 0094a3de..09dd39fb 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -14,7 +14,7 @@ orjson==3.9.15 PyMuPDF==1.23.6 redis==5.0.1 beautifulsoup4==4.12.2 -truefoundry[ml]==0.2.9 +truefoundry[ml]==0.2.10 markdownify==0.11.6 gunicorn==22.0.0 markdown-crawler==0.0.8 From 10d8b37bbaf1e5f9cd700924e2e9a37c6534dae8 Mon Sep 17 00:00:00 2001 From: sayan-truefoundry <136362719+sayan-truefoundry@users.noreply.github.com> Date: Tue, 9 Jul 2024 11:09:49 +0530 Subject: [PATCH 10/28] feat: carbon integration in UI (#271) --- frontend/Dockerfile | 4 + frontend/env.d.ts | 1 + frontend/package.json | 4 + frontend/src/assets/img/logos/logo.svg | 15 + .../dashboard/docsqa/NewDataSource.tsx | 695 +++++++++++------- frontend/src/stores/constants.ts | 1 + frontend/yarn.lock | 474 +++++++++++- 7 files changed, 906 insertions(+), 288 deletions(-) create mode 100644 frontend/src/assets/img/logos/logo.svg diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 84489597..dd9cb0b4 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -14,6 +14,7 @@ ARG VITE_DOCS_QA_STANDALONE_PATH ARG VITE_QA_FOUNDRY_URL ARG VITE_USE_LOCAL ARG VITE_GTAG_ID +ARG VITE_CARBON_API_KEY ENV VITE_USE_RELATIVE_BASE_URL=${VITE_USE_RELATIVE_BASE_URL} \ VITE_DOCS_QA_STANDALONE_PATH=${VITE_DOCS_QA_STANDALONE_PATH} RUN if [ -n "$VITE_QA_FOUNDRY_URL" ]; then \ @@ -25,6 +26,9 @@ RUN if [ -n "$VITE_USE_LOCAL" ]; then \ RUN if [ -n "$VITE_GTAG_ID" ]; then \ export VITE_GTAG_ID=${VITE_GTAG_ID}; \ fi +RUN if [ -n "$VITE_CARBON_API_KEY" ]; then \ + export VITE_CARBON_API_KEY=${VITE_CARBON_API_KEY}; \ + fi # Build the project RUN yarn build diff --git a/frontend/env.d.ts b/frontend/env.d.ts index 56863ae9..50a52138 100644 --- a/frontend/env.d.ts +++ b/frontend/env.d.ts @@ -46,6 +46,7 @@ declare interface ImportMetaEnv { readonly VITE_DOCS_QA_MAX_UPLOAD_SIZE_MB: string readonly VITE_USE_LOCAL: string readonly VITE_GTAG_ID: string + readonly VITE_CARBON_API_KEY: string // * Seeded by VITE readonly DEV: boolean readonly PROD: boolean diff --git a/frontend/package.json b/frontend/package.json index d17a0125..6d5274b4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -60,18 +60,22 @@ "@mui/material": "^5.5.0", "@mui/x-data-grid": "^6.19.6", "@mui/x-date-pickers": "^5.0.13", + "@radix-ui/react-dialog": "^1.1.1", "@reduxjs/toolkit": "^1.8.0", "@sentry/react": "^7.103.0", "@sentry/tracing": "^7.103.0", "async-mutex": "^0.3.2", "axios": "^1.6.0", + "carbon-connect": "^2.0.6", "classnames": "^2.3.1", "dayjs": "^1.11.0", "lodash": "^4.17.21", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-drag-drop-files": "^2.3.10", "react-error-boundary": "^3.1.4", "react-helmet-async": "^1.3.0", + "react-icons": "^5.2.1", "react-markdown": "^8.0.3", "react-promise-tracker": "^2.1.0", "react-redux": "^7.2.6", diff --git a/frontend/src/assets/img/logos/logo.svg b/frontend/src/assets/img/logos/logo.svg new file mode 100644 index 00000000..2bdde55d --- /dev/null +++ b/frontend/src/assets/img/logos/logo.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/frontend/src/screens/dashboard/docsqa/NewDataSource.tsx b/frontend/src/screens/dashboard/docsqa/NewDataSource.tsx index 059addef..705b2591 100644 --- a/frontend/src/screens/dashboard/docsqa/NewDataSource.tsx +++ b/frontend/src/screens/dashboard/docsqa/NewDataSource.tsx @@ -1,3 +1,6 @@ +import React, { useEffect, useState } from 'react' +import { MenuItem, Select } from '@mui/material' +import { startCase } from 'lodash' import { uploadArtifactFileWithSignedURI } from '@/api/truefoundry' import IconProvider from '@/components/assets/IconProvider' import Badge from '@/components/base/atoms/Badge' @@ -7,6 +10,7 @@ import Spinner from '@/components/base/atoms/Spinner' import { DarkTooltip } from '@/components/base/atoms/Tooltip' import notify from '@/components/base/molecules/Notify' import { + CARBON_API_KEY, DOCS_QA_MAX_UPLOAD_SIZE_MB, IS_LOCAL_DEVELOPMENT, } from '@/stores/constants' @@ -18,8 +22,11 @@ import { } from '@/stores/qafoundry' import { getFilePath, getUniqueFiles } from '@/utils/artifacts' import classNames from '@/utils/classNames' -import { MenuItem, Select } from '@mui/material' -import React, { useEffect, useState } from 'react' +import { CarbonConnect, EmbeddingGenerators } from 'carbon-connect' +import axios from 'axios' +import Logo from '@/assets/img/logos/logo.svg' + +const CUSTOMER_ID = 'cognita' const parseFileSize = (size: number) => { const units = ['B', 'Ki', 'Mi', 'Gi'] @@ -52,6 +59,10 @@ const NewDataSource = ({ open, onClose }: NewDataSourceProps) => { const [files, setFiles] = React.useState<{ id: string; file: File }[]>([]) const { data: dataLoaders, isLoading } = useGetDataLoadersQuery() + const [isCarbonConnectOpen, setIsCarbonConnectOpen] = useState(false) + const [dataSourceId, setDataSourceId] = useState('') + const dataSourceExternalId = React.useRef('') + const pattern = /^[a-z][a-z0-9-]*$/ const isValidUploadName = pattern.test(uploadName) @@ -154,7 +165,10 @@ const NewDataSource = ({ open, onClose }: NewDataSourceProps) => { } else { const res = await addDataSource({ type: selectedDataSourceType, - uri: dataSourceUri, + uri: + selectedDataSourceType === 'carbon' + ? `${CUSTOMER_ID}/${dataSourceId}` + : dataSourceUri, metadata: {}, }).unwrap() fqn = res.data_source?.fqn @@ -180,304 +194,429 @@ const NewDataSource = ({ open, onClose }: NewDataSourceProps) => { setIsSaving(false) } + const tokenFetcher = async () => { + const response = await axios.get( + 'https://api.carbon.ai/auth/v1/access_token', + { + headers: { + 'Content-Type': 'application/json', + 'customer-id': CUSTOMER_ID, + authorization: `Bearer ${CARBON_API_KEY}`, + }, + } + ) + return response.data + } + + const getDataSources = async () => { + const carbonAccessToken = window.sessionStorage.getItem( + 'carbon_access_token' + ) + const response = await axios.post( + 'https://api.carbon.ai/user_data_sources', + { + filters: { + source: 'GOOGLE_DRIVE', + }, + }, + { + headers: { + 'Content-Type': 'application/json', + Authorization: `token ${carbonAccessToken}`, + }, + } + ) + const filteredData = response.data.results.filter( + (res) => res.data_source_external_id === dataSourceExternalId.current + ) + if (filteredData.length === 0) return + setDataSourceId(filteredData[0].id) + return filteredData + } + + useEffect(() => { + const carbonAccessToken = window.sessionStorage.getItem( + 'carbon_access_token' + ) + if (carbonAccessToken) return + tokenFetcher() + .then((data) => { + window.sessionStorage.setItem('carbon_access_token', data.access_token) + }) + .catch((err) => {}) + }, []) + return ( - { - onClose() - resetForm() - }} - bodyClassName="p-0" - width="w-[65vw]" - > -
- {isSaving && ( -
-
- + <> + { + if (data?.action === 'UPDATE') { + const externalId = data?.data?.data_source_external_id + dataSourceExternalId.current = externalId ?? '' + getDataSources() + } + }} + primaryBackgroundColor="#F2F2F2" + primaryTextColor="#555555" + secondaryBackgroundColor="#f2f2f2" + secondaryTextColor="#000000" + allowMultipleFiles={true} + open={isCarbonConnectOpen} + setOpen={setIsCarbonConnectOpen} + chunkSize={1500} + zIndex={1500} + > + { + onClose() + resetForm() + }} + bodyClassName="z-2" + width="w-[65vw]" + > +
+ {isSaving && ( +
+
+ +
+

Data Source is being created...

-

Data Source is being created...

-
- )} -
- Create New Data Source -
-
-
- Documents that are uploaded will be accessible to the public. Please - do not upload any confidential or sensitive data. + )} +
+ Create New Data Source
-
-
-
- +
+
+ Documents that are uploaded will be accessible to the public. + Please do not upload any confidential or sensitive data.
- {selectedDataSourceType === 'localdir' ? ( - <> -
+
+
+
+ +
+ {selectedDataSourceType === 'localdir' ? ( + <> +
+ + setUploadName(e.target.value)} + /> + {uploadName && !isValidUploadName && ( +
+ +
+ Source name should only contain lowercase alphanumeric + character with hyphen! +
+
+ )} +
+ + + ) : selectedDataSourceType === 'carbon' ? ( +
+
+ ) : ( + <> setUploadName(e.target.value)} + placeholder={`${ + selectedDataSourceType === 'github' + ? 'Enter GitHub Repo URL' + : selectedDataSourceType === 'truefoundry' + ? 'Enter Data Source FQN' + : selectedDataSourceType === 'artifact' + ? 'Enter Artifact Version FQN' + : 'Enter Web URL' + }`} + value={dataSourceUri} + onChange={(e) => setDataSourceUri(e.target.value)} /> - {uploadName && !isValidUploadName && ( -
- -
- Source name should only contain lowercase alphanumeric - character with hyphen! -
-
+ + )} + {!!files.length && selectedDataSourceType === 'localdir' && ( +
- - - ) : ( - <> - - setDataSourceUri(e.target.value)} - /> - - )} - {!!files.length && selectedDataSourceType === 'localdir' && ( -
- - Selected Files ({files.length}){' '} - {uploadSizeMb > DOCS_QA_MAX_UPLOAD_SIZE_MB && ( - - Selected files total size cannot be more than{' '} - {DOCS_QA_MAX_UPLOAD_SIZE_MB} - MB - - )} - - -
    - {files.map(({ id, file }, idx) => ( -
  • -
    - {idx + 1}. -
    -
    - {file.name} + {files.map(({ id, file }, idx) => ( +
  • +
    + {idx + 1}. +
    +
    + {file.name} +
    + + +
    - - -
    -
- {isSaving ? ( -
+ {uploadedFileIds.includes(id) ? ( + + ) : ( + + )} +
+ ) : ( +
- ) : ( -
- )} + white + /> + )} + + ))} + +
+ )} +
+
+
+
-
-
-
- + + ) } diff --git a/frontend/src/stores/constants.ts b/frontend/src/stores/constants.ts index d7077ccb..fbf9a170 100644 --- a/frontend/src/stores/constants.ts +++ b/frontend/src/stores/constants.ts @@ -7,3 +7,4 @@ export const DOCS_QA_MAX_UPLOAD_SIZE_MB = parseInt( ) export const IS_LOCAL_DEVELOPMENT = import.meta.env.VITE_USE_LOCAL === 'true' export const GTAG_ID = import.meta.env.VITE_GTAG_ID +export const CARBON_API_KEY = import.meta.env.VITE_CARBON_API_KEY diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 45338ab7..36736048 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -24,6 +24,14 @@ "@babel/highlight" "^7.22.13" chalk "^2.4.2" +"@babel/code-frame@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" + integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== + dependencies: + "@babel/highlight" "^7.24.7" + picocolors "^1.0.0" + "@babel/compat-data@^7.17.7": version "7.17.7" resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.7.tgz" @@ -69,6 +77,16 @@ "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" +"@babel/generator@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.7.tgz#1654d01de20ad66b4b4d99c135471bc654c55e6d" + integrity sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA== + dependencies: + "@babel/types" "^7.24.7" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^2.5.1" + "@babel/helper-annotate-as-pure@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz" @@ -76,6 +94,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz#5373c7bc8366b12a033b4be1ac13a206c6656aab" + integrity sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg== + dependencies: + "@babel/types" "^7.24.7" + "@babel/helper-compilation-targets@^7.17.7": version "7.17.7" resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz" @@ -98,6 +123,13 @@ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== +"@babel/helper-environment-visitor@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz#4b31ba9551d1f90781ba83491dd59cf9b269f7d9" + integrity sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ== + dependencies: + "@babel/types" "^7.24.7" + "@babel/helper-function-name@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" @@ -106,6 +138,14 @@ "@babel/template" "^7.22.15" "@babel/types" "^7.23.0" +"@babel/helper-function-name@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz#75f1e1725742f39ac6584ee0b16d94513da38dd2" + integrity sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA== + dependencies: + "@babel/template" "^7.24.7" + "@babel/types" "^7.24.7" + "@babel/helper-hoist-variables@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" @@ -113,6 +153,21 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-hoist-variables@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz#b4ede1cde2fd89436397f30dc9376ee06b0f25ee" + integrity sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ== + dependencies: + "@babel/types" "^7.24.7" + +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.22.5": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b" + integrity sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz" @@ -139,6 +194,11 @@ resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz" integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== +"@babel/helper-plugin-utils@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz#98c84fe6fe3d0d3ae7bfc3a5e166a46844feb2a0" + integrity sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg== + "@babel/helper-simple-access@^7.17.7": version "7.17.7" resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz" @@ -160,11 +220,23 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-split-export-declaration@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz#83949436890e07fa3d6873c61a96e3bbf692d856" + integrity sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA== + dependencies: + "@babel/types" "^7.24.7" + "@babel/helper-string-parser@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== +"@babel/helper-string-parser@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz#4d2d0f14820ede3b9807ea5fc36dfc8cd7da07f2" + integrity sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg== + "@babel/helper-validator-identifier@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz" @@ -175,6 +247,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== +"@babel/helper-validator-identifier@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== + "@babel/helper-validator-option@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz" @@ -207,6 +284,16 @@ chalk "^2.4.2" js-tokens "^4.0.0" +"@babel/highlight@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" + integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== + dependencies: + "@babel/helper-validator-identifier" "^7.24.7" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + "@babel/parser@^7.16.7", "@babel/parser@^7.17.9": version "7.17.9" resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.17.9.tgz" @@ -222,6 +309,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== +"@babel/parser@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.7.tgz#9a5226f92f0c5c8ead550b750f5608e766c8ce85" + integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw== + "@babel/plugin-syntax-jsx@^7.12.13", "@babel/plugin-syntax-jsx@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz" @@ -229,6 +321,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-syntax-jsx@^7.22.5": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz#39a1fa4a7e3d3d7f34e2acc6be585b718d30e02d" + integrity sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-transform-react-jsx-development@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.7.tgz" @@ -301,6 +400,15 @@ "@babel/parser" "^7.22.15" "@babel/types" "^7.22.15" +"@babel/template@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.7.tgz#02efcee317d0609d2c07117cb70ef8fb17ab7315" + integrity sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/parser" "^7.24.7" + "@babel/types" "^7.24.7" + "@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" @@ -317,6 +425,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.24.7", "@babel/traverse@^7.4.5": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.7.tgz#de2b900163fa741721ba382163fe46a936c40cf5" + integrity sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.24.7" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-function-name" "^7.24.7" + "@babel/helper-hoist-variables" "^7.24.7" + "@babel/helper-split-export-declaration" "^7.24.7" + "@babel/parser" "^7.24.7" + "@babel/types" "^7.24.7" + debug "^4.3.1" + globals "^11.1.0" + "@babel/types@^7.16.7", "@babel/types@^7.17.0": version "7.17.0" resolved "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz" @@ -334,6 +458,15 @@ "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" +"@babel/types@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.7.tgz#6027fe12bc1aa724cd32ab113fb7f1988f1f66f2" + integrity sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q== + dependencies: + "@babel/helper-string-parser" "^7.24.7" + "@babel/helper-validator-identifier" "^7.24.7" + to-fast-properties "^2.0.0" + "@date-io/core@^2.15.0", "@date-io/core@^2.16.0": version "2.16.0" resolved "https://registry.yarnpkg.com/@date-io/core/-/core-2.16.0.tgz#7871bfc1d9bca9aa35ad444a239505589d0f22f6" @@ -412,6 +545,13 @@ resolved "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz" integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== +"@emotion/is-prop-valid@^1.1.0": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz#d4175076679c6a26faa92b03bb786f9e52612337" + integrity sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw== + dependencies: + "@emotion/memoize" "^0.8.1" + "@emotion/is-prop-valid@^1.1.2": version "1.1.2" resolved "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.1.2.tgz" @@ -436,6 +576,11 @@ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f" integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA== +"@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== + "@emotion/react@^11.8.1": version "11.9.0" resolved "https://registry.npmjs.org/@emotion/react/-/react-11.9.0.tgz" @@ -481,7 +626,12 @@ "@emotion/serialize" "^1.0.2" "@emotion/utils" "^1.1.0" -"@emotion/unitless@^0.7.5": +"@emotion/stylis@^0.8.4": + version "0.8.5" + resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" + integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== + +"@emotion/unitless@^0.7.4", "@emotion/unitless@^0.7.5": version "0.7.5" resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz" integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== @@ -626,6 +776,15 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/resolve-uri@^3.0.3": version "3.0.5" resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz" @@ -641,6 +800,11 @@ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.11" resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz" @@ -667,6 +831,14 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@jsdoc/salty@^0.2.1": version "0.2.7" resolved "https://registry.yarnpkg.com/@jsdoc/salty/-/salty-0.2.7.tgz#98ddce519fd95d7bee605a658fabf6e8cbf7556d" @@ -968,6 +1140,127 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== +"@radix-ui/primitive@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.1.0.tgz#42ef83b3b56dccad5d703ae8c42919a68798bbe2" + integrity sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA== + +"@radix-ui/react-compose-refs@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz#656432461fc8283d7b591dcf0d79152fae9ecc74" + integrity sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw== + +"@radix-ui/react-context@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.0.tgz#6df8d983546cfd1999c8512f3a8ad85a6e7fcee8" + integrity sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A== + +"@radix-ui/react-dialog@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz#4906507f7b4ad31e22d7dad69d9330c87c431d44" + integrity sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-dismissable-layer" "1.1.0" + "@radix-ui/react-focus-guards" "1.1.0" + "@radix-ui/react-focus-scope" "1.1.0" + "@radix-ui/react-id" "1.1.0" + "@radix-ui/react-portal" "1.1.1" + "@radix-ui/react-presence" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-slot" "1.1.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + aria-hidden "^1.1.1" + react-remove-scroll "2.5.7" + +"@radix-ui/react-dismissable-layer@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz#2cd0a49a732372513733754e6032d3fb7988834e" + integrity sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-callback-ref" "1.1.0" + "@radix-ui/react-use-escape-keydown" "1.1.0" + +"@radix-ui/react-focus-guards@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz#8e9abb472a9a394f59a1b45f3dd26cfe3fc6da13" + integrity sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw== + +"@radix-ui/react-focus-scope@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz#ebe2891a298e0a33ad34daab2aad8dea31caf0b2" + integrity sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA== + dependencies: + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-callback-ref" "1.1.0" + +"@radix-ui/react-id@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.1.0.tgz#de47339656594ad722eb87f94a6b25f9cffae0ed" + integrity sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA== + dependencies: + "@radix-ui/react-use-layout-effect" "1.1.0" + +"@radix-ui/react-portal@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.1.1.tgz#1957f1eb2e1aedfb4a5475bd6867d67b50b1d15f" + integrity sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g== + dependencies: + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-layout-effect" "1.1.0" + +"@radix-ui/react-presence@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.1.0.tgz#227d84d20ca6bfe7da97104b1a8b48a833bfb478" + integrity sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ== + dependencies: + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-use-layout-effect" "1.1.0" + +"@radix-ui/react-primitive@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz#fe05715faa9203a223ccc0be15dc44b9f9822884" + integrity sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw== + dependencies: + "@radix-ui/react-slot" "1.1.0" + +"@radix-ui/react-slot@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.1.0.tgz#7c5e48c36ef5496d97b08f1357bb26ed7c714b84" + integrity sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw== + dependencies: + "@radix-ui/react-compose-refs" "1.1.0" + +"@radix-ui/react-use-callback-ref@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz#bce938ca413675bc937944b0d01ef6f4a6dc5bf1" + integrity sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw== + +"@radix-ui/react-use-controllable-state@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz#1321446857bb786917df54c0d4d084877aab04b0" + integrity sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw== + dependencies: + "@radix-ui/react-use-callback-ref" "1.1.0" + +"@radix-ui/react-use-escape-keydown@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz#31a5b87c3b726504b74e05dac1edce7437b98754" + integrity sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw== + dependencies: + "@radix-ui/react-use-callback-ref" "1.1.0" + +"@radix-ui/react-use-layout-effect@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz#3c2c8ce04827b26a39e442ff4888d9212268bd27" + integrity sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w== + "@reduxjs/toolkit@^1.8.0": version "1.8.1" resolved "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.8.1.tgz" @@ -1499,6 +1792,13 @@ argparse@^2.0.1: resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +aria-hidden@^1.1.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.4.tgz#b78e383fdbc04d05762c78b4a25a501e736c4522" + integrity sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A== + dependencies: + tslib "^2.0.0" + aria-query@^4.2.2: version "4.2.2" resolved "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz" @@ -1648,6 +1948,17 @@ babel-plugin-macros@^2.6.1: cosmiconfig "^6.0.0" resolve "^1.12.0" +"babel-plugin-styled-components@>= 1.12.0": + version "2.1.4" + resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz#9a1f37c7f32ef927b4b008b529feb4a2c82b1092" + integrity sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.22.5" + lodash "^4.17.21" + picomatch "^2.3.1" + bail@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d" @@ -1761,11 +2072,29 @@ camelcase-css@^2.0.1: resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz" integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== +camelize@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3" + integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== + caniuse-lite@^1.0.30001317: version "1.0.30001418" resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz" integrity sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg== +carbon-connect-js@^0.0.23: + version "0.0.23" + resolved "https://registry.yarnpkg.com/carbon-connect-js/-/carbon-connect-js-0.0.23.tgz#685834fed77910cd74cf880d5523cfbeecea6497" + integrity sha512-xKOOBoIkd6TlIHD9LsHAY01Ibxn2w2k9oDJT1n0mWHEtuZ2Uw73f/PMl8up69vVvmDWPQ2lCEVwxlOIBCfkPrg== + +carbon-connect@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/carbon-connect/-/carbon-connect-2.0.6.tgz#48e75dfa7fc506eae99279e2cd3f5a530188c9d2" + integrity sha512-Vi5Ss4M1IZ3E7uXgL7tYzQvliuqfqPGEaZ8VqG/KMAk+Y702Nd383GzTxI3ru5v7wFEhBn7hQVYRlB1KVrpT7w== + dependencies: + carbon-connect-js "^0.0.23" + react-virtualized "^9.22.0" + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -1829,16 +2158,16 @@ cliui@^8.0.1: strip-ansi "^6.0.1" wrap-ansi "^7.0.0" +clsx@^1.0.4, clsx@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" + integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== + clsx@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz" integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== -clsx@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" - integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== - clsx@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb" @@ -1971,6 +2300,11 @@ cross-spawn@^7.0.1, cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" +css-color-keywords@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" + integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg== + css-selector-tokenizer@^0.8.0: version "0.8.0" resolved "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz" @@ -1979,6 +2313,15 @@ css-selector-tokenizer@^0.8.0: cssesc "^3.0.0" fastparse "^1.1.2" +css-to-react-native@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.2.0.tgz#cdd8099f71024e149e4f6fe17a7d46ecd55f1e32" + integrity sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ== + dependencies: + camelize "^1.0.0" + css-color-keywords "^1.0.0" + postcss-value-parser "^4.0.2" + cssesc@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" @@ -2049,6 +2392,13 @@ debug@^3.2.7: dependencies: ms "^2.1.1" +debug@^4.3.1: + version "4.3.5" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e" + integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== + dependencies: + ms "2.1.2" + decode-named-character-reference@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e" @@ -2092,6 +2442,11 @@ dequal@^2.0.0: resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.2.tgz#85ca22025e3a87e65ef75a7a437b35284a7e319d" integrity sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug== +detect-node-es@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493" + integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== + detective@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz" @@ -2137,7 +2492,7 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-helpers@^5.0.1: +dom-helpers@^5.0.1, dom-helpers@^5.1.3: version "5.2.1" resolved "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz" integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== @@ -2896,6 +3251,11 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: has-symbols "^1.0.3" hasown "^2.0.0" +get-nonce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" + integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== + get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" @@ -3133,7 +3493,7 @@ history@^5.2.0: dependencies: "@babel/runtime" "^7.7.6" -hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: +hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -4281,7 +4641,7 @@ postcss-selector-parser@^6.0.6, postcss-selector-parser@^6.0.9: cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-value-parser@^4.2.0: +postcss-value-parser@^4.0.2, postcss-value-parser@^4.2.0: version "4.2.0" resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== @@ -4456,6 +4816,14 @@ react-dom@^17.0.2: object-assign "^4.1.1" scheduler "^0.20.2" +react-drag-drop-files@^2.3.10: + version "2.3.10" + resolved "https://registry.yarnpkg.com/react-drag-drop-files/-/react-drag-drop-files-2.3.10.tgz#3f6ea316f8ad66a6f76b312cc4108c7c14065b06" + integrity sha512-Fv614W9+OtXFB5O+gjompTxQZLYGO7wJeT4paETGiXtiADB9yPOMGYD4A3PMCTY9Be874/wcpl+2dm3MvCIRzg== + dependencies: + prop-types "^15.7.2" + styled-components "^5.3.0" + react-error-boundary@^3.1.4: version "3.1.4" resolved "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz" @@ -4479,6 +4847,11 @@ react-helmet-async@^1.3.0: react-fast-compare "^3.2.0" shallowequal "^1.1.0" +react-icons@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.2.1.tgz#28c2040917b2a2eda639b0f797bff1888e018e4a" + integrity sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw== + react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" @@ -4494,6 +4867,11 @@ react-is@^18.0.0, react-is@^18.2.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== +react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + react-markdown@^8.0.3: version "8.0.3" resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-8.0.3.tgz#e8aba0d2f5a1b2124d476ee1fff9448a2f57e4b3" @@ -4537,6 +4915,25 @@ react-refresh@^0.11.0: resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz" integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== +react-remove-scroll-bar@^2.3.4: + version "2.3.6" + resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz#3e585e9d163be84a010180b18721e851ac81a29c" + integrity sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g== + dependencies: + react-style-singleton "^2.2.1" + tslib "^2.0.0" + +react-remove-scroll@2.5.7: + version "2.5.7" + resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz#15a1fd038e8497f65a695bf26a4a57970cac1ccb" + integrity sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA== + dependencies: + react-remove-scroll-bar "^2.3.4" + react-style-singleton "^2.2.1" + tslib "^2.1.0" + use-callback-ref "^1.3.0" + use-sidecar "^1.1.2" + react-router-dom@^6.2.2: version "6.3.0" resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz" @@ -4552,6 +4949,15 @@ react-router@6.3.0: dependencies: history "^5.2.0" +react-style-singleton@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4" + integrity sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g== + dependencies: + get-nonce "^1.0.0" + invariant "^2.2.4" + tslib "^2.0.0" + react-toastify@^8.2.0: version "8.2.0" resolved "https://registry.npmjs.org/react-toastify/-/react-toastify-8.2.0.tgz" @@ -4579,6 +4985,18 @@ react-transition-group@^4.4.5: loose-envify "^1.4.0" prop-types "^15.6.2" +react-virtualized@^9.22.0: + version "9.22.5" + resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.5.tgz#bfb96fed519de378b50d8c0064b92994b3b91620" + integrity sha512-YqQMRzlVANBv1L/7r63OHa2b0ZsAaDp1UhVNEdUaXI8A5u6hTpA5NYtUueLH2rFuY/27mTGIBl7ZhqFKzw18YQ== + dependencies: + "@babel/runtime" "^7.7.2" + clsx "^1.0.4" + dom-helpers "^5.1.3" + loose-envify "^1.4.0" + prop-types "^15.7.2" + react-lifecycles-compat "^3.0.4" + react@^17.0.2: version "17.0.2" resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz" @@ -5042,12 +5460,28 @@ style-to-object@^0.3.0: dependencies: inline-style-parser "0.1.1" +styled-components@^5.3.0: + version "5.3.11" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.11.tgz#9fda7bf1108e39bf3f3e612fcc18170dedcd57a8" + integrity sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/traverse" "^7.4.5" + "@emotion/is-prop-valid" "^1.1.0" + "@emotion/stylis" "^0.8.4" + "@emotion/unitless" "^0.7.4" + babel-plugin-styled-components ">= 1.12.0" + css-to-react-native "^3.0.0" + hoist-non-react-statics "^3.0.0" + shallowequal "^1.1.0" + supports-color "^5.5.0" + stylis@4.0.13: version "4.0.13" resolved "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz" integrity sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag== -supports-color@^5.3.0: +supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -5190,6 +5624,11 @@ tslib@^1.8.1: resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.0.0, tslib@^2.1.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0" + integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== + tslib@^2.3.1: version "2.6.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" @@ -5356,11 +5795,26 @@ url@0.10.3: punycode "1.3.2" querystring "0.2.0" +use-callback-ref@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.2.tgz#6134c7f6ff76e2be0b56c809b17a650c942b1693" + integrity sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA== + dependencies: + tslib "^2.0.0" + use-react-router-breadcrumbs@^3.1.0: version "3.2.0" resolved "https://registry.npmjs.org/use-react-router-breadcrumbs/-/use-react-router-breadcrumbs-3.2.0.tgz" integrity sha512-VAi1OnVvaC1JVnic2LOwMfMOPjL2Kw3aTPE2jCNPpFu25ZHeqmwr62DQZqkfiAOhOXXJrsfYaIJLu0IJbXNgXg== +use-sidecar@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2" + integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw== + dependencies: + detect-node-es "^1.1.0" + tslib "^2.0.0" + util-deprecate@^1.0.1, util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" From 36ab007171b5dac7731cd879465874478dcb07e2 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Tue, 9 Jul 2024 12:49:27 +0530 Subject: [PATCH 11/28] Added internet search functionality --- backend/Dockerfile | 3 + backend/modules/query_controllers/common.py | 46 ++++++--------- .../query_controllers/example/controller.py | 56 ++++++++++++------- .../multimodal/controller.py | 47 +++++++++++----- .../query_controllers/multimodal/payload.py | 2 +- backend/settings.py | 3 - docker-compose.yaml | 1 + 7 files changed, 90 insertions(+), 68 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index b2a16f46..0ba6cf98 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -40,6 +40,9 @@ ENV MODELS_CONFIG_PATH=${MODELS_CONFIG_PATH} ARG INFINITY_API_KEY ENV INFINITY_API_KEY=${INFINITY_API_KEY} +ARG BRAVE_API_KEY +ENV BRAVE_API_KEY=${BRAVE_API_KEY} + # Copy the project files COPY . /app diff --git a/backend/modules/query_controllers/common.py b/backend/modules/query_controllers/common.py index 3d77d4d7..4b3cc4a8 100644 --- a/backend/modules/query_controllers/common.py +++ b/backend/modules/query_controllers/common.py @@ -3,39 +3,25 @@ from backend.settings import settings -def internet_search(query: str): - headers = { - "Accept": " application/json", - "X-Subscription-Token": f"{settings.BRAVE_API_KEY}", - } - - params = { - "q": f"{query}", - } - - # response = requests.get('https://api.search.brave.com/res/v1/web/search', params=params, headers=headers) - # response.raise_for_status() - # answer = response.json() - - answer = "DEMO ANSWER FROM INTERNET SEARCH" - return answer - - def intent_summary_search(query: str): + url = f"https://api.search.brave.com/res/v1/web/search?q={query}&summary=1" + + payload = {} headers = { "Accept": "application/json", - # 'Accept-Encoding': 'gzip', + "Accept-Encoding": "gzip", "X-Subscription-Token": f"{settings.BRAVE_API_KEY}", } - params = { - "q": f"{query}", - "summary": "1", - } - - # response = requests.get('https://api.search.brave.com/res/v1/web/search', params=params, headers=headers) - # response.raise_for_status() - # answer = response.json() - - answer = "DEMO ANSWER FROM INTENT SUMMARY SEARCH" - return answer + response = requests.request("GET", url, headers=headers, data=payload) + answer = response.json() + + if "summarizer" in answer.keys(): + summary_query = answer["summarizer"]["key"] + url = ( + f"https://api.search.brave.com/res/v1/summarizer/search?key={summary_query}" + ) + response = requests.request("GET", url, headers=headers, data=payload) + answer = response.json()["summary"][0]["data"] + return answer + return "" diff --git a/backend/modules/query_controllers/example/controller.py b/backend/modules/query_controllers/example/controller.py index 49eea57c..e21b870e 100644 --- a/backend/modules/query_controllers/example/controller.py +++ b/backend/modules/query_controllers/example/controller.py @@ -6,18 +6,20 @@ from fastapi.responses import StreamingResponse from langchain.prompts import PromptTemplate from langchain.retrievers import ContextualCompressionRetriever, MultiQueryRetriever +from langchain.schema.document import Document from langchain.schema.vectorstore import VectorStoreRetriever from langchain_core.language_models.chat_models import BaseChatModel from langchain_core.output_parsers import StrOutputParser -from langchain_core.runnables import RunnableParallel, RunnablePassthrough +from langchain_core.runnables import ( + RunnableLambda, + RunnableParallel, + RunnablePassthrough, +) from backend.logger import logger from backend.modules.metadata_store.client import get_client from backend.modules.model_gateway.model_gateway import model_gateway -from backend.modules.query_controllers.common import ( - intent_summary_search, - internet_search, -) +from backend.modules.query_controllers.common import intent_summary_search from backend.modules.query_controllers.example.payload import ( QUERY_WITH_CONTEXTUAL_COMPRESSION_MULTI_QUERY_RETRIEVER_SIMILARITY_PAYLOAD, QUERY_WITH_CONTEXTUAL_COMPRESSION_RETRIEVER_PAYLOAD, @@ -27,10 +29,9 @@ GENERATION_TIMEOUT_SEC, ExampleQueryInput, ) - -# from backend.modules.rerankers.reranker_svc import InfinityRerankerSvc from backend.modules.vector_db.client import VECTOR_STORE_CLIENT from backend.server.decorators import post, query_controller +from backend.settings import settings from backend.types import Collection, ModelConfig EXAMPLES = { @@ -48,7 +49,7 @@ def _get_prompt_template(self, input_variables, template): """ return PromptTemplate(input_variables=input_variables, template=template) - def _format_docs(self, docs, query, internet_search_enabled=False): + def _format_docs(self, docs): formatted_docs = list() for doc in docs: doc.metadata.pop("image_b64", None) @@ -56,16 +57,6 @@ def _format_docs(self, docs, query, internet_search_enabled=False): {"page_content": doc.page_content, "metadata": doc.metadata} ) - if internet_search_enabled: - # internet_search_results = internet_search(query) - intent_summary_results = intent_summary_search(query) - formatted_docs.append( - { - "page_content": f"{intent_summary_results}", - "metadata": {"source": "Intent Summary Search"}, - } - ) - return "\n\n".join([f"{doc['page_content']}" for doc in formatted_docs]) def _format_docs_for_stream(self, docs): @@ -77,6 +68,22 @@ def _format_docs_for_stream(self, docs): ) return formatted_docs + def _internet_search(self, context): + logger.info("Using Internet search...") + if settings.BRAVE_API_KEY: + data_context, question = context["context"], context["question"] + intent_summary_results = intent_summary_search(question) + # insert internet search results into context at the beginning + data_context.insert( + 0, + Document( + page_content=intent_summary_results, + metadata={"_data_point_fqn": "internet::Internet"}, + ), + ) + context["context"] = data_context + return context + def _get_llm(self, model_configuration: ModelConfig, stream=False) -> BaseChatModel: """ Get the LLM @@ -250,7 +257,7 @@ async def answer( # add internet search results to context context=( lambda x: self._format_docs( - x["context"], request.query, request.internet_search_enabled + x["context"], ) ) ) @@ -261,7 +268,12 @@ async def answer( rag_chain_with_source = RunnableParallel( {"context": retriever, "question": RunnablePassthrough()} - ).assign(answer=rag_chain_from_docs) + ) + + if request.internet_search_enabled: + rag_chain_with_source = ( + rag_chain_with_source | self._internet_search + ).assign(answer=rag_chain_from_docs) if request.stream: return StreamingResponse( @@ -278,6 +290,10 @@ async def answer( # outputs = await setup_and_retrieval.ainvoke(request.query) # print(outputs) + # Retriever, internet search + # outputs = await (setup_and_retrieval | self.internet_search).ainvoke(request.query) + # print(outputs) + # Retriever and QA # outputs = await (setup_and_retrieval | QA_PROMPT).ainvoke(request.query) # print(outputs) diff --git a/backend/modules/query_controllers/multimodal/controller.py b/backend/modules/query_controllers/multimodal/controller.py index b2d22f36..45b2688b 100644 --- a/backend/modules/query_controllers/multimodal/controller.py +++ b/backend/modules/query_controllers/multimodal/controller.py @@ -6,6 +6,7 @@ from fastapi.responses import StreamingResponse from langchain.prompts import PromptTemplate from langchain.retrievers import ContextualCompressionRetriever, MultiQueryRetriever +from langchain.schema.document import Document from langchain.schema.vectorstore import VectorStoreRetriever from langchain_core.language_models.chat_models import BaseChatModel from langchain_core.messages import HumanMessage @@ -14,10 +15,7 @@ from backend.logger import logger from backend.modules.metadata_store.client import get_client from backend.modules.model_gateway.model_gateway import model_gateway -from backend.modules.query_controllers.common import ( - intent_summary_search, - internet_search, -) +from backend.modules.query_controllers.common import intent_summary_search from backend.modules.query_controllers.multimodal.payload import ( PROMPT, QUERY_WITH_CONTEXTUAL_COMPRESSION_MULTI_QUERY_RETRIEVER_SIMILARITY_PAYLOAD, @@ -30,6 +28,7 @@ ) from backend.modules.vector_db.client import VECTOR_STORE_CLIENT from backend.server.decorators import post, query_controller +from backend.settings import settings from backend.types import Collection, ModelConfig EXAMPLES = { @@ -65,6 +64,22 @@ def _format_docs_for_stream(self, docs): ) return formatted_docs + def _internet_search(self, context): + logger.info("Using Internet search...") + if settings.BRAVE_API_KEY: + data_context, question = context["context"], context["question"] + intent_summary_results = intent_summary_search(question) + # insert internet search results into context at the beginning + data_context.insert( + 0, + Document( + page_content=intent_summary_results, + metadata={"_data_point_fqn": "internet::Internet"}, + ), + ) + context["context"] = data_context + return context + def _get_llm(self, model_configuration: ModelConfig, stream=False) -> BaseChatModel: """ Get the LLM @@ -258,12 +273,6 @@ async def answer( Sample answer method to answer the question using the context from the collection """ try: - if request.internet_search_enabled is True: - return { - "answer": "Internet search is not available for multimodal RAG yet", - "docs": [], - } - # Get the vector store vector_store = await self._get_vector_store(request.collection_name) @@ -282,13 +291,23 @@ async def answer( logger.info(f"Using default prompt") prompt = PROMPT.format(question=request.query) - # Generate payload for VLM - images_set = set() - setup_and_retrieval = RunnableParallel( {"context": retriever, "question": RunnablePassthrough()} ) - outputs = await setup_and_retrieval.ainvoke(request.query) + + # Generate payload for VLM + images_set = set() + internet_search_result = "" + if request.internet_search_enabled: + outputs = await (setup_and_retrieval | self._internet_search).ainvoke( + request.query + ) + internet_search_result = outputs["context"][0].page_content + if request.internet_search_enabled: + prompt += f"\nContext: {internet_search_result}" + logger.info(f"Prompt: {prompt}") + else: + outputs = await setup_and_retrieval.ainvoke(request.query) if "context" in outputs: docs = outputs["context"] diff --git a/backend/modules/query_controllers/multimodal/payload.py b/backend/modules/query_controllers/multimodal/payload.py index bb1cbc25..0c5d4661 100644 --- a/backend/modules/query_controllers/multimodal/payload.py +++ b/backend/modules/query_controllers/multimodal/payload.py @@ -1,4 +1,4 @@ -PROMPT = "You are an AI assistant specialising in information retrieval. Answer the following question precisely by extracting the relavant information given in the images.\nQuestion: {question}" +PROMPT = "You are an AI assistant specialising in information retrieval. Answer the following question precisely by extracting the relevant information given in the images and context.\nQuestion: {question}" QUERY_WITH_VECTOR_STORE_RETRIEVER_SIMILARITY = { "collection_name": "finance", "query": "Explain key operating metrics of FY20", diff --git a/backend/settings.py b/backend/settings.py index 6b008320..999adede 100644 --- a/backend/settings.py +++ b/backend/settings.py @@ -28,9 +28,6 @@ class Config: LOG_LEVEL: str = "info" TFY_SERVICE_ROOT_PATH: str = "" - # TODO: This will be removed in future releases - after fixing multimodal parser - TFY_LLM_GATEWAY_URL: str = "" - BRAVE_API_KEY: str = "" @root_validator(pre=True) diff --git a/docker-compose.yaml b/docker-compose.yaml index 859764c3..b3cf09ae 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -137,6 +137,7 @@ services: - MODELS_CONFIG_PATH=${MODELS_CONFIG_PATH} - TFY_API_KEY=${TFY_API_KEY} - TFY_HOST=${TFY_HOST} + - BRAVE_API_KEY=${BRAVE_API_KEY} - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@cognita-db:5432/cognita-config entrypoint: /bin/bash command: -c "set -e; prisma db push --schema ./backend/database/schema.prisma && uvicorn --host 0.0.0.0 --port 8000 backend.server.app:app --reload" From 128e500d1823c3fcfeecfe0b4d3faa3329b55096 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Tue, 9 Jul 2024 14:08:22 +0530 Subject: [PATCH 12/28] Fixed example qcntrl --- backend/modules/query_controllers/example/controller.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/modules/query_controllers/example/controller.py b/backend/modules/query_controllers/example/controller.py index e21b870e..6de1fd5a 100644 --- a/backend/modules/query_controllers/example/controller.py +++ b/backend/modules/query_controllers/example/controller.py @@ -274,6 +274,10 @@ async def answer( rag_chain_with_source = ( rag_chain_with_source | self._internet_search ).assign(answer=rag_chain_from_docs) + else: + rag_chain_with_source = rag_chain_with_source.assign( + answer=rag_chain_from_docs + ) if request.stream: return StreamingResponse( From 3c252cdc9442ee70ccf9f7827522054be05cc6b9 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Tue, 9 Jul 2024 15:10:10 +0530 Subject: [PATCH 13/28] Added additional gateway models --- models_config.truefoundry.yaml | 46 ++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/models_config.truefoundry.yaml b/models_config.truefoundry.yaml index 421dda07..16c53cdf 100644 --- a/models_config.truefoundry.yaml +++ b/models_config.truefoundry.yaml @@ -1,24 +1,26 @@ model_providers: - - provider_name: truefoundry - api_format: openai - base_url: https://llm-gateway.truefoundry.com/api/inference/openai - api_key_env_var: TFY_API_KEY - llm_model_ids: - - "openai-main/gpt-4-turbo" - - "openai-main/gpt-3-5-turbo" - embedding_model_ids: - - "openai-main/text-embedding-ada-002" - reranking_model_ids: [] - default_headers: - "X-TFY-METADATA": '{"tfy_log_request": "true", "Custom-Metadata": "Cognita-LLM-Request"}' + - provider_name: truefoundry + api_format: openai + base_url: https://llm-gateway.truefoundry.com/api/inference/openai + api_key_env_var: TFY_API_KEY + llm_model_ids: + - "openai-main/gpt-4-turbo" + - "openai-main/gpt-3-5-turbo" + - "together-ai/llama-3-70b-chat-hf" + - "azure-openai/gpt-4" + embedding_model_ids: + - "openai-main/text-embedding-ada-002" + reranking_model_ids: [] + default_headers: + "X-TFY-METADATA": '{"tfy_log_request": "true", "Custom-Metadata": "Cognita-LLM-Request"}' - - provider_name: local-infinity - api_format: openai - base_url: https://infinity-svc-prod.truefoundry.com - api_key_env_var: INFINITY_API_KEY - llm_model_ids: [] - embedding_model_ids: - - "mixedbread-ai/mxbai-embed-large-v1" - reranking_model_ids: - - "mixedbread-ai/mxbai-rerank-xsmall-v1" - default_headers: {} + - provider_name: local-infinity + api_format: openai + base_url: https://infinity-svc-prod.truefoundry.com + api_key_env_var: INFINITY_API_KEY + llm_model_ids: [] + embedding_model_ids: + - "mixedbread-ai/mxbai-embed-large-v1" + reranking_model_ids: + - "mixedbread-ai/mxbai-rerank-xsmall-v1" + default_headers: {} From 81a3382221e3cf08e52cdfb15759b7c08251779c Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Mon, 15 Jul 2024 21:29:39 +0530 Subject: [PATCH 14/28] Fixed dockerfile --- backend/Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 451d5997..988eae6b 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -9,7 +9,6 @@ RUN python3 -m venv /virtualenvs/venv/ # Copy requirements.txt COPY backend/requirements.txt /tmp/requirements.txt COPY backend/vectordb.requirements.txt /tmp/vectordb.requirements.txt -COPY backend/parsers.requirements.txt /tmp/parsers.requirements.txt # Install Python packages RUN python3 -m pip install -U pip setuptools wheel && \ From 2e50222cfbb8e558be1db0fea170dc3409bc05d7 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Tue, 16 Jul 2024 15:25:50 +0530 Subject: [PATCH 15/28] Modified settings --- backend/settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/settings.py b/backend/settings.py index 514a39f2..056c1eda 100644 --- a/backend/settings.py +++ b/backend/settings.py @@ -32,9 +32,9 @@ class Config: CARBON_AI_API_KEY: str = "" - UNSTUCTURED_IO_URL: str = "" + UNSTRUCTURED_IO_URL: str = "" - UNSTUCTURED_IO_API_KEY: str = "" + UNSTRUCTURED_IO_API_KEY: str = "" @root_validator(pre=True) def _validate_values(cls, values): From ac9019feb68e7d67ceac82031da9c4ebbc092f6c Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Tue, 16 Jul 2024 15:57:44 +0530 Subject: [PATCH 16/28] Fixed unstructured variable names --- backend/modules/parsers/unstructured_io.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/modules/parsers/unstructured_io.py b/backend/modules/parsers/unstructured_io.py index 62c122d3..65e69eea 100644 --- a/backend/modules/parsers/unstructured_io.py +++ b/backend/modules/parsers/unstructured_io.py @@ -72,12 +72,12 @@ async def get_chunks(self, filepath: str, metadata: dict, *args, **kwargs): headers = { "accept": "application/json", } - if settings.UNSTUCTURED_IO_API_KEY: - headers["unstructured-api-key"] = settings.UNSTUCTURED_IO_API_KEY + if settings.UNSTRUCTURED_IO_API_KEY: + headers["unstructured-api-key"] = settings.UNSTRUCTURED_IO_API_KEY # Send POST request response = self.session.post( - settings.UNSTUCTURED_IO_URL.rstrip("/") + "/general/v0/general", + settings.UNSTRUCTURED_IO_URL.rstrip("/") + "/general/v0/general", headers=headers, files=files, data=data, From 6f08ffcd93d62d746eca406978abffed15243767 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Tue, 16 Jul 2024 22:07:41 +0530 Subject: [PATCH 17/28] Increased stream wait --- .../query_controllers/example/controller.py | 4 ++-- .../query_controllers/multimodal/controller.py | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/backend/modules/query_controllers/example/controller.py b/backend/modules/query_controllers/example/controller.py index 6de1fd5a..eed17c39 100644 --- a/backend/modules/query_controllers/example/controller.py +++ b/backend/modules/query_controllers/example/controller.py @@ -210,11 +210,11 @@ async def _stream_answer(self, rag_chain, query): yield json.dumps( {"docs": self._format_docs_for_stream(chunk["context"])} ) - await asyncio.sleep(0.1) + await asyncio.sleep(0.2) elif "answer" in chunk: # print("Answer: ", chunk['answer']) yield json.dumps({"answer": chunk["answer"]}) - await asyncio.sleep(0.1) + await asyncio.sleep(0.2) yield json.dumps({"end": ""}) except asyncio.TimeoutError: diff --git a/backend/modules/query_controllers/multimodal/controller.py b/backend/modules/query_controllers/multimodal/controller.py index 45b2688b..6dca214e 100644 --- a/backend/modules/query_controllers/multimodal/controller.py +++ b/backend/modules/query_controllers/multimodal/controller.py @@ -206,17 +206,17 @@ async def _stream_answer(self, rag_chain, query): if "question " in chunk: # print("Question: ", chunk['question']) yield json.dumps({"question": chunk["question"]}) - await asyncio.sleep(0.1) + await asyncio.sleep(0.2) elif "context" in chunk: # print("Context: ", self._format_docs_for_stream(chunk['context'])) yield json.dumps( {"docs": self._format_docs_for_stream(chunk["context"])} ) - await asyncio.sleep(0.1) + await asyncio.sleep(0.2) elif "answer" in chunk: # print("Answer: ", chunk['answer']) yield json.dumps({"answer": chunk["answer"]}) - await asyncio.sleep(0.1) + await asyncio.sleep(0.2) yield json.dumps({"end": ""}) except asyncio.TimeoutError: @@ -230,15 +230,15 @@ async def _stream_vlm_answer(self, llm, message_payload, docs): "docs": self._format_docs_for_stream(docs), } ) - await asyncio.sleep(0.1) + await asyncio.sleep(0.2) async for chunk in llm.astream(message_payload): yield json.dumps({"answer": chunk.content}) - await asyncio.sleep(0.1) + await asyncio.sleep(0.2) - await asyncio.sleep(0.1) + await asyncio.sleep(0.2) yield json.dumps({"end": ""}) - await asyncio.sleep(0.1) + await asyncio.sleep(0.2) except asyncio.TimeoutError: raise HTTPException(status_code=504, detail="Stream timed out") From 12ecdc06ac61ba425e43d3410c95273dc1a54fd8 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Wed, 17 Jul 2024 10:12:17 +0530 Subject: [PATCH 18/28] Increased sleep time --- .../modules/query_controllers/example/controller.py | 5 +++-- .../query_controllers/multimodal/controller.py | 13 ++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/backend/modules/query_controllers/example/controller.py b/backend/modules/query_controllers/example/controller.py index eed17c39..253993a2 100644 --- a/backend/modules/query_controllers/example/controller.py +++ b/backend/modules/query_controllers/example/controller.py @@ -210,13 +210,14 @@ async def _stream_answer(self, rag_chain, query): yield json.dumps( {"docs": self._format_docs_for_stream(chunk["context"])} ) - await asyncio.sleep(0.2) + await asyncio.sleep(0.5) elif "answer" in chunk: # print("Answer: ", chunk['answer']) yield json.dumps({"answer": chunk["answer"]}) - await asyncio.sleep(0.2) + await asyncio.sleep(0.5) yield json.dumps({"end": ""}) + await asyncio.sleep(0.5) except asyncio.TimeoutError: raise HTTPException(status_code=504, detail="Stream timed out") diff --git a/backend/modules/query_controllers/multimodal/controller.py b/backend/modules/query_controllers/multimodal/controller.py index 6dca214e..f09a4fd5 100644 --- a/backend/modules/query_controllers/multimodal/controller.py +++ b/backend/modules/query_controllers/multimodal/controller.py @@ -206,17 +206,17 @@ async def _stream_answer(self, rag_chain, query): if "question " in chunk: # print("Question: ", chunk['question']) yield json.dumps({"question": chunk["question"]}) - await asyncio.sleep(0.2) + await asyncio.sleep(0.5) elif "context" in chunk: # print("Context: ", self._format_docs_for_stream(chunk['context'])) yield json.dumps( {"docs": self._format_docs_for_stream(chunk["context"])} ) - await asyncio.sleep(0.2) + await asyncio.sleep(0.5) elif "answer" in chunk: # print("Answer: ", chunk['answer']) yield json.dumps({"answer": chunk["answer"]}) - await asyncio.sleep(0.2) + await asyncio.sleep(0.5) yield json.dumps({"end": ""}) except asyncio.TimeoutError: @@ -230,15 +230,14 @@ async def _stream_vlm_answer(self, llm, message_payload, docs): "docs": self._format_docs_for_stream(docs), } ) - await asyncio.sleep(0.2) + await asyncio.sleep(0.5) async for chunk in llm.astream(message_payload): yield json.dumps({"answer": chunk.content}) - await asyncio.sleep(0.2) + await asyncio.sleep(0.5) - await asyncio.sleep(0.2) yield json.dumps({"end": ""}) - await asyncio.sleep(0.2) + await asyncio.sleep(0.5) except asyncio.TimeoutError: raise HTTPException(status_code=504, detail="Stream timed out") From 69f4d74a5cfcb5d59a5ec414ec2972fb8fb7c895 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Wed, 17 Jul 2024 10:29:52 +0530 Subject: [PATCH 19/28] Different sleep times for stream --- .../modules/query_controllers/example/controller.py | 6 +++--- .../query_controllers/multimodal/controller.py | 13 +++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/backend/modules/query_controllers/example/controller.py b/backend/modules/query_controllers/example/controller.py index 253993a2..ae57517d 100644 --- a/backend/modules/query_controllers/example/controller.py +++ b/backend/modules/query_controllers/example/controller.py @@ -210,14 +210,14 @@ async def _stream_answer(self, rag_chain, query): yield json.dumps( {"docs": self._format_docs_for_stream(chunk["context"])} ) - await asyncio.sleep(0.5) + await asyncio.sleep(0.7) elif "answer" in chunk: # print("Answer: ", chunk['answer']) yield json.dumps({"answer": chunk["answer"]}) - await asyncio.sleep(0.5) + await asyncio.sleep(0.1) yield json.dumps({"end": ""}) - await asyncio.sleep(0.5) + await asyncio.sleep(0.2) except asyncio.TimeoutError: raise HTTPException(status_code=504, detail="Stream timed out") diff --git a/backend/modules/query_controllers/multimodal/controller.py b/backend/modules/query_controllers/multimodal/controller.py index f09a4fd5..caa5e562 100644 --- a/backend/modules/query_controllers/multimodal/controller.py +++ b/backend/modules/query_controllers/multimodal/controller.py @@ -206,19 +206,20 @@ async def _stream_answer(self, rag_chain, query): if "question " in chunk: # print("Question: ", chunk['question']) yield json.dumps({"question": chunk["question"]}) - await asyncio.sleep(0.5) + await asyncio.sleep(0.1) elif "context" in chunk: # print("Context: ", self._format_docs_for_stream(chunk['context'])) yield json.dumps( {"docs": self._format_docs_for_stream(chunk["context"])} ) - await asyncio.sleep(0.5) + await asyncio.sleep(0.7) elif "answer" in chunk: # print("Answer: ", chunk['answer']) yield json.dumps({"answer": chunk["answer"]}) - await asyncio.sleep(0.5) + await asyncio.sleep(0.1) yield json.dumps({"end": ""}) + await asyncio.sleep(0.2) except asyncio.TimeoutError: raise HTTPException(status_code=504, detail="Stream timed out") @@ -230,14 +231,14 @@ async def _stream_vlm_answer(self, llm, message_payload, docs): "docs": self._format_docs_for_stream(docs), } ) - await asyncio.sleep(0.5) + await asyncio.sleep(0.7) async for chunk in llm.astream(message_payload): yield json.dumps({"answer": chunk.content}) - await asyncio.sleep(0.5) + await asyncio.sleep(0.1) yield json.dumps({"end": ""}) - await asyncio.sleep(0.5) + await asyncio.sleep(0.2) except asyncio.TimeoutError: raise HTTPException(status_code=504, detail="Stream timed out") From 73f7b0f41bc8063b81cd41580c876118f18c3b51 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Wed, 17 Jul 2024 11:11:43 +0530 Subject: [PATCH 20/28] Set sleep time to 0.5 for stream --- .../query_controllers/example/controller.py | 6 +++--- .../query_controllers/multimodal/controller.py | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/backend/modules/query_controllers/example/controller.py b/backend/modules/query_controllers/example/controller.py index ae57517d..253993a2 100644 --- a/backend/modules/query_controllers/example/controller.py +++ b/backend/modules/query_controllers/example/controller.py @@ -210,14 +210,14 @@ async def _stream_answer(self, rag_chain, query): yield json.dumps( {"docs": self._format_docs_for_stream(chunk["context"])} ) - await asyncio.sleep(0.7) + await asyncio.sleep(0.5) elif "answer" in chunk: # print("Answer: ", chunk['answer']) yield json.dumps({"answer": chunk["answer"]}) - await asyncio.sleep(0.1) + await asyncio.sleep(0.5) yield json.dumps({"end": ""}) - await asyncio.sleep(0.2) + await asyncio.sleep(0.5) except asyncio.TimeoutError: raise HTTPException(status_code=504, detail="Stream timed out") diff --git a/backend/modules/query_controllers/multimodal/controller.py b/backend/modules/query_controllers/multimodal/controller.py index caa5e562..197b19d7 100644 --- a/backend/modules/query_controllers/multimodal/controller.py +++ b/backend/modules/query_controllers/multimodal/controller.py @@ -206,20 +206,20 @@ async def _stream_answer(self, rag_chain, query): if "question " in chunk: # print("Question: ", chunk['question']) yield json.dumps({"question": chunk["question"]}) - await asyncio.sleep(0.1) + await asyncio.sleep(0.5) elif "context" in chunk: # print("Context: ", self._format_docs_for_stream(chunk['context'])) yield json.dumps( {"docs": self._format_docs_for_stream(chunk["context"])} ) - await asyncio.sleep(0.7) + await asyncio.sleep(0.5) elif "answer" in chunk: # print("Answer: ", chunk['answer']) yield json.dumps({"answer": chunk["answer"]}) - await asyncio.sleep(0.1) + await asyncio.sleep(0.5) yield json.dumps({"end": ""}) - await asyncio.sleep(0.2) + await asyncio.sleep(0.5) except asyncio.TimeoutError: raise HTTPException(status_code=504, detail="Stream timed out") @@ -231,14 +231,14 @@ async def _stream_vlm_answer(self, llm, message_payload, docs): "docs": self._format_docs_for_stream(docs), } ) - await asyncio.sleep(0.7) + await asyncio.sleep(0.3) async for chunk in llm.astream(message_payload): yield json.dumps({"answer": chunk.content}) - await asyncio.sleep(0.1) + await asyncio.sleep(0.3) yield json.dumps({"end": ""}) - await asyncio.sleep(0.2) + await asyncio.sleep(0.3) except asyncio.TimeoutError: raise HTTPException(status_code=504, detail="Stream timed out") From 5820dcca618fc6a7078637c68bb7302dc19be9d3 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Wed, 17 Jul 2024 11:12:07 +0530 Subject: [PATCH 21/28] Set sleep time to 0.5 for stream --- backend/modules/query_controllers/multimodal/controller.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/modules/query_controllers/multimodal/controller.py b/backend/modules/query_controllers/multimodal/controller.py index 197b19d7..5379febc 100644 --- a/backend/modules/query_controllers/multimodal/controller.py +++ b/backend/modules/query_controllers/multimodal/controller.py @@ -231,14 +231,14 @@ async def _stream_vlm_answer(self, llm, message_payload, docs): "docs": self._format_docs_for_stream(docs), } ) - await asyncio.sleep(0.3) + await asyncio.sleep(0.5) async for chunk in llm.astream(message_payload): yield json.dumps({"answer": chunk.content}) - await asyncio.sleep(0.3) + await asyncio.sleep(0.5) yield json.dumps({"end": ""}) - await asyncio.sleep(0.3) + await asyncio.sleep(0.5) except asyncio.TimeoutError: raise HTTPException(status_code=504, detail="Stream timed out") From ee31d50b3e059d82ac2aa8123321649003b7fa31 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Thu, 18 Jul 2024 16:47:02 +0530 Subject: [PATCH 22/28] Skipping .truefoundry files --- backend/modules/dataloaders/truefoundryloader.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/modules/dataloaders/truefoundryloader.py b/backend/modules/dataloaders/truefoundryloader.py index bc97d50c..1d93ae87 100644 --- a/backend/modules/dataloaders/truefoundryloader.py +++ b/backend/modules/dataloaders/truefoundryloader.py @@ -82,6 +82,8 @@ def load_filtered_data( if f.startswith("."): continue full_path = os.path.join(root, f) + if ".truefoundry" in full_path: + continue logger.debug(f"Processing file: {full_path}") rel_path = os.path.relpath(full_path, dest_dir) file_ext = os.path.splitext(f)[1] From c7b86e8af6bb493e5d033fd7e18f3ee63210ce20 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Thu, 18 Jul 2024 17:13:12 +0530 Subject: [PATCH 23/28] Updated tf[ml] --- backend/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/requirements.txt b/backend/requirements.txt index 09dd39fb..6505a885 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -14,7 +14,7 @@ orjson==3.9.15 PyMuPDF==1.23.6 redis==5.0.1 beautifulsoup4==4.12.2 -truefoundry[ml]==0.2.10 +truefoundry[ml]==0.3.0rc4 markdownify==0.11.6 gunicorn==22.0.0 markdown-crawler==0.0.8 From 06a626ac8c737787c07d3a41e8176ef0171511a6 Mon Sep 17 00:00:00 2001 From: Chirag Jain Date: Thu, 18 Jul 2024 18:15:55 +0530 Subject: [PATCH 24/28] Drop component name entirely - directly pass the correct job fqn --- backend/indexer/indexer.py | 3 +-- backend/settings.py | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/backend/indexer/indexer.py b/backend/indexer/indexer.py index 33ec3729..d254c433 100644 --- a/backend/indexer/indexer.py +++ b/backend/indexer/indexer.py @@ -369,7 +369,7 @@ async def ingest_data(request: IngestDataToCollectionDto): ) created_data_ingestion_run.status = DataIngestionRunStatus.COMPLETED else: - if not settings.JOB_FQN or not settings.JOB_COMPONENT_NAME: + if not settings.JOB_FQN: logger.error( "Job FQN and Job Component Name are required to trigger the job" ) @@ -390,7 +390,6 @@ async def ingest_data(request: IngestDataToCollectionDto): ) trigger_job( application_fqn=settings.JOB_FQN, - component_name=settings.JOB_COMPONENT_NAME, params={ "collection_name": collection.name, "data_source_fqn": associated_data_source.data_source_fqn, diff --git a/backend/settings.py b/backend/settings.py index 056c1eda..9c0c4fca 100644 --- a/backend/settings.py +++ b/backend/settings.py @@ -23,7 +23,6 @@ class Config: TFY_HOST: str = "" TFY_API_KEY: str = "" JOB_FQN: str = "" - JOB_COMPONENT_NAME: str = "" LOG_LEVEL: str = "info" TFY_SERVICE_ROOT_PATH: str = "" From 7792293bd84fc029b4b113a00a8c9c31f1141a74 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Fri, 19 Jul 2024 15:01:42 +0530 Subject: [PATCH 25/28] Set timeout to 0.2 --- .../query_controllers/example/controller.py | 6 +++--- .../query_controllers/multimodal/controller.py | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/backend/modules/query_controllers/example/controller.py b/backend/modules/query_controllers/example/controller.py index 253993a2..4d440380 100644 --- a/backend/modules/query_controllers/example/controller.py +++ b/backend/modules/query_controllers/example/controller.py @@ -210,14 +210,14 @@ async def _stream_answer(self, rag_chain, query): yield json.dumps( {"docs": self._format_docs_for_stream(chunk["context"])} ) - await asyncio.sleep(0.5) + await asyncio.sleep(0.2) elif "answer" in chunk: # print("Answer: ", chunk['answer']) yield json.dumps({"answer": chunk["answer"]}) - await asyncio.sleep(0.5) + await asyncio.sleep(0.2) yield json.dumps({"end": ""}) - await asyncio.sleep(0.5) + await asyncio.sleep(0.2) except asyncio.TimeoutError: raise HTTPException(status_code=504, detail="Stream timed out") diff --git a/backend/modules/query_controllers/multimodal/controller.py b/backend/modules/query_controllers/multimodal/controller.py index 5379febc..36ec36a5 100644 --- a/backend/modules/query_controllers/multimodal/controller.py +++ b/backend/modules/query_controllers/multimodal/controller.py @@ -206,20 +206,20 @@ async def _stream_answer(self, rag_chain, query): if "question " in chunk: # print("Question: ", chunk['question']) yield json.dumps({"question": chunk["question"]}) - await asyncio.sleep(0.5) + await asyncio.sleep(0.2) elif "context" in chunk: # print("Context: ", self._format_docs_for_stream(chunk['context'])) yield json.dumps( {"docs": self._format_docs_for_stream(chunk["context"])} ) - await asyncio.sleep(0.5) + await asyncio.sleep(0.2) elif "answer" in chunk: # print("Answer: ", chunk['answer']) yield json.dumps({"answer": chunk["answer"]}) - await asyncio.sleep(0.5) + await asyncio.sleep(0.2) yield json.dumps({"end": ""}) - await asyncio.sleep(0.5) + await asyncio.sleep(0.2) except asyncio.TimeoutError: raise HTTPException(status_code=504, detail="Stream timed out") @@ -231,14 +231,14 @@ async def _stream_vlm_answer(self, llm, message_payload, docs): "docs": self._format_docs_for_stream(docs), } ) - await asyncio.sleep(0.5) + await asyncio.sleep(0.2) async for chunk in llm.astream(message_payload): yield json.dumps({"answer": chunk.content}) - await asyncio.sleep(0.5) + await asyncio.sleep(0.2) yield json.dumps({"end": ""}) - await asyncio.sleep(0.5) + await asyncio.sleep(0.2) except asyncio.TimeoutError: raise HTTPException(status_code=504, detail="Stream timed out") From 13a703469d2ea3c2ca956c5d179410f7e11c3c11 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Fri, 19 Jul 2024 16:40:06 +0530 Subject: [PATCH 26/28] modified sleep time --- backend/modules/query_controllers/example/controller.py | 2 +- backend/modules/query_controllers/multimodal/controller.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/modules/query_controllers/example/controller.py b/backend/modules/query_controllers/example/controller.py index 4d440380..5b36c4d0 100644 --- a/backend/modules/query_controllers/example/controller.py +++ b/backend/modules/query_controllers/example/controller.py @@ -210,7 +210,7 @@ async def _stream_answer(self, rag_chain, query): yield json.dumps( {"docs": self._format_docs_for_stream(chunk["context"])} ) - await asyncio.sleep(0.2) + await asyncio.sleep(0.5) elif "answer" in chunk: # print("Answer: ", chunk['answer']) yield json.dumps({"answer": chunk["answer"]}) diff --git a/backend/modules/query_controllers/multimodal/controller.py b/backend/modules/query_controllers/multimodal/controller.py index 36ec36a5..fb41e293 100644 --- a/backend/modules/query_controllers/multimodal/controller.py +++ b/backend/modules/query_controllers/multimodal/controller.py @@ -212,7 +212,7 @@ async def _stream_answer(self, rag_chain, query): yield json.dumps( {"docs": self._format_docs_for_stream(chunk["context"])} ) - await asyncio.sleep(0.2) + await asyncio.sleep(0.5) elif "answer" in chunk: # print("Answer: ", chunk['answer']) yield json.dumps({"answer": chunk["answer"]}) From bc4bd4297c0b0a5ba4c1d989bda2f51c244fe697 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Tue, 3 Sep 2024 10:12:01 +0530 Subject: [PATCH 27/28] Added relevance score --- backend/modules/query_controllers/example/controller.py | 1 + backend/modules/query_controllers/multimodal/controller.py | 1 + 2 files changed, 2 insertions(+) diff --git a/backend/modules/query_controllers/example/controller.py b/backend/modules/query_controllers/example/controller.py index cc5ce981..652f1047 100644 --- a/backend/modules/query_controllers/example/controller.py +++ b/backend/modules/query_controllers/example/controller.py @@ -56,6 +56,7 @@ class BasicRAGQueryController: "page_number", "pg_no", "source", + "relevance_score", ] def _get_prompt_template(self, input_variables, template): diff --git a/backend/modules/query_controllers/multimodal/controller.py b/backend/modules/query_controllers/multimodal/controller.py index c6f52b79..0ea6156f 100644 --- a/backend/modules/query_controllers/multimodal/controller.py +++ b/backend/modules/query_controllers/multimodal/controller.py @@ -51,6 +51,7 @@ class MultiModalRAGQueryController: "page_number", "pg_no", "source", + "relevance_score", ] def _get_prompt_template(self, input_variables, template): From ba1a0d8bd29479a9d4c0273fbdae10d6b47c41e0 Mon Sep 17 00:00:00 2001 From: Prathamesh Date: Fri, 6 Sep 2024 16:01:09 +0530 Subject: [PATCH 28/28] Added braveapi key in compose.env --- compose.env | 1 + 1 file changed, 1 insertion(+) diff --git a/compose.env b/compose.env index 5e23f5ae..1c516c7a 100644 --- a/compose.env +++ b/compose.env @@ -40,3 +40,4 @@ TFY_API_KEY= TFY_HOST= CARBON_AI_API_KEY= +BRAVE_API_KEY=