Junranl commited on
Commit
6e1a53e
·
verified ·
1 Parent(s): ce016b4

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitignore +162 -0
  2. README.md +72 -12
  3. api/Dockerfile +13 -0
  4. api/main.py +19 -0
  5. api/requirements.txt +7 -0
  6. api/routes/__init__.py +0 -0
  7. api/routes/admin/__init__.py +0 -0
  8. api/routes/admin/chat_history.py +19 -0
  9. api/routes/admin/data_sources.py +57 -0
  10. api/routes/admin/embeddings.py +39 -0
  11. api/routes/admin/ui_settings.py +0 -0
  12. api/routes/admin/users.py +0 -0
  13. api/routes/admin/utils.py +30 -0
  14. api/routes/admin/vector_stores.py +31 -0
  15. api/routes/api.py +21 -0
  16. api/utils/embedchain.py +145 -0
  17. assets/add_data.png +0 -0
  18. assets/chat.png +0 -0
  19. assets/chat_history.png +0 -0
  20. assets/collection.png +0 -0
  21. assets/search.png +0 -0
  22. docker-compose.yml +30 -0
  23. embedchain.json +4 -0
  24. ui/.env.local +1 -0
  25. ui/.eslintrc.json +3 -0
  26. ui/.gitignore +32 -0
  27. ui/.next/app-build-manifest.json +40 -0
  28. ui/.next/build-manifest.json +30 -0
  29. ui/.next/cache/config.json +7 -0
  30. ui/.next/cache/webpack/client-development/0.pack.gz +3 -0
  31. ui/.next/cache/webpack/client-development/1.pack.gz +3 -0
  32. ui/.next/cache/webpack/client-development/10.pack.gz +3 -0
  33. ui/.next/cache/webpack/client-development/11.pack.gz +3 -0
  34. ui/.next/cache/webpack/client-development/2.pack.gz +3 -0
  35. ui/.next/cache/webpack/client-development/3.pack.gz +3 -0
  36. ui/.next/cache/webpack/client-development/4.pack.gz +3 -0
  37. ui/.next/cache/webpack/client-development/5.pack.gz +3 -0
  38. ui/.next/cache/webpack/client-development/6.pack.gz +3 -0
  39. ui/.next/cache/webpack/client-development/7.pack.gz +3 -0
  40. ui/.next/cache/webpack/client-development/8.pack.gz +3 -0
  41. ui/.next/cache/webpack/client-development/9.pack.gz +3 -0
  42. ui/.next/cache/webpack/client-development/index.pack.gz +3 -0
  43. ui/.next/cache/webpack/client-development/index.pack.gz.old +0 -0
  44. ui/.next/cache/webpack/server-development/0.pack.gz +3 -0
  45. ui/.next/cache/webpack/server-development/1.pack.gz +3 -0
  46. ui/.next/cache/webpack/server-development/10.pack.gz +3 -0
  47. ui/.next/cache/webpack/server-development/11.pack.gz +3 -0
  48. ui/.next/cache/webpack/server-development/12.pack.gz +3 -0
  49. ui/.next/cache/webpack/server-development/2.pack.gz +3 -0
  50. ui/.next/cache/webpack/server-development/3.pack.gz +3 -0
.gitignore ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib64/
18
+ parts/
19
+ sdist/
20
+ var/
21
+ wheels/
22
+ share/python-wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+ MANIFEST
27
+
28
+ # PyInstaller
29
+ # Usually these files are written by a python script from a template
30
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
31
+ *.manifest
32
+ *.spec
33
+
34
+ # Installer logs
35
+ pip-log.txt
36
+ pip-delete-this-directory.txt
37
+
38
+ # Unit test / coverage reports
39
+ htmlcov/
40
+ .tox/
41
+ .nox/
42
+ .coverage
43
+ .coverage.*
44
+ .cache
45
+ nosetests.xml
46
+ coverage.xml
47
+ *.cover
48
+ *.py,cover
49
+ .hypothesis/
50
+ .pytest_cache/
51
+ cover/
52
+
53
+ # Translations
54
+ *.mo
55
+ *.pot
56
+
57
+ # Django stuff:
58
+ *.log
59
+ local_settings.py
60
+ db.sqlite3
61
+ db.sqlite3-journal
62
+
63
+ # Flask stuff:
64
+ instance/
65
+ .webassets-cache
66
+
67
+ # Scrapy stuff:
68
+ .scrapy
69
+
70
+ # Sphinx documentation
71
+ docs/_build/
72
+
73
+ # PyBuilder
74
+ .pybuilder/
75
+ target/
76
+
77
+ # Jupyter Notebook
78
+ .ipynb_checkpoints
79
+
80
+ # IPython
81
+ profile_default/
82
+ ipython_config.py
83
+
84
+ # pyenv
85
+ # For a library or package, you might want to ignore these files since the code is
86
+ # intended to run in multiple environments; otherwise, check them in:
87
+ # .python-version
88
+
89
+ # pipenv
90
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
91
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
92
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
93
+ # install all needed dependencies.
94
+ #Pipfile.lock
95
+
96
+ # poetry
97
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
98
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
99
+ # commonly ignored for libraries.
100
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
101
+ #poetry.lock
102
+
103
+ # pdm
104
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
105
+ #pdm.lock
106
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
107
+ # in version control.
108
+ # https://pdm.fming.dev/#use-with-ide
109
+ .pdm.toml
110
+
111
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
112
+ __pypackages__/
113
+
114
+ # Celery stuff
115
+ celerybeat-schedule
116
+ celerybeat.pid
117
+
118
+ # SageMath parsed files
119
+ *.sage.py
120
+
121
+ # Environments
122
+ .env
123
+ .venv
124
+ env/
125
+ venv/
126
+ ENV/
127
+ env.bak/
128
+ venv.bak/
129
+
130
+ # Spyder project settings
131
+ .spyderproject
132
+ .spyproject
133
+
134
+ # Rope project settings
135
+ .ropeproject
136
+
137
+ # mkdocs documentation
138
+ /site
139
+
140
+ # mypy
141
+ .mypy_cache/
142
+ .dmypy.json
143
+ dmypy.json
144
+
145
+ # Pyre type checker
146
+ .pyre/
147
+
148
+ # pytype static type analyzer
149
+ .pytype/
150
+
151
+ # Cython debug symbols
152
+ cython_debug/
153
+
154
+ .DS_Store
155
+ db/
156
+ backend/static
157
+ backend/media
158
+ backend/db.sqlite3
159
+
160
+ .terraform
161
+
162
+ db/
README.md CHANGED
@@ -1,12 +1,72 @@
1
- ---
2
- title: Rag Full
3
- emoji: 🚀
4
- colorFrom: pink
5
- colorTo: green
6
- sdk: gradio
7
- sdk_version: 4.43.0
8
- app_file: app.py
9
- pinned: false
10
- ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Embedchain Admin
2
+
3
+ Welcome to the Embedchain Admin repository. This toolkit helps you build a full-stack RAG (Retrieve, Append, Generate) application with a focus on simplicity and functionality, powered by Embedchain.
4
+
5
+ ## 🚀 Features
6
+
7
+ - **Chat Interface:** A clean and simple interface for messaging.
8
+ - **Streaming:** Supports live data streaming.
9
+ - **Citations:** Allows integration of citations within the chat.
10
+ - **Model Support:** Compatible with both proprietary and open-source models.
11
+ - **Admin Panel:**
12
+ - View chat history.
13
+ - Manage embeddings.
14
+ - Configure data sources through the UI.
15
+
16
+ ## Tech Stack
17
+
18
+ This project uses:
19
+
20
+ - FastAPI: For the backend, making it fast and easy to develop.
21
+ - NextJS: For the frontend, enabling responsive and dynamic web pages.
22
+ - Embedchain: Powers the core functionalities like chat and streaming.
23
+
24
+
25
+ ## Getting Started
26
+
27
+ To start using Embedchain Admin for your project, install python package using:
28
+
29
+ ```bash
30
+ pip install embedchain
31
+ ```
32
+
33
+ Now, if you use docker, you can simply run the following commands:
34
+
35
+ ### With docker
36
+ ```bash
37
+ ec create-app my-app --docker
38
+ cd my-app
39
+ ec start --docker
40
+ ```
41
+
42
+ ### Without docker
43
+
44
+ ```bash
45
+ ec create-app my-app
46
+ cd my-app
47
+ ec start
48
+ ```
49
+
50
+ You are all set now. Open http://localhost:3000 to view the chat UI.
51
+
52
+ ## Screenshots
53
+
54
+ ### Chat
55
+
56
+ <img src="assets/chat.png" height="600px" />
57
+
58
+ ### Search
59
+
60
+ <img src="assets/search.png" height="600px" />
61
+
62
+ ### Chat history
63
+
64
+ <img src="assets/chat_history.png" height="600px" />
65
+
66
+ ### Collections
67
+
68
+ <img src="assets/collection.png" height="600px" />
69
+
70
+ ### Data sources
71
+
72
+ <img src="assets/add_data.png" height="600px" />
api/Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY requirements.txt /app/
6
+
7
+ RUN pip install -r requirements.txt
8
+
9
+ COPY . /app
10
+
11
+ EXPOSE 8000
12
+
13
+ CMD ["python", "-m", "main"]
api/main.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import uvicorn
2
+ from dotenv import load_dotenv
3
+ from fastapi import FastAPI
4
+
5
+ from routes import api
6
+ from routes.admin import chat_history, data_sources, vector_stores
7
+
8
+ load_dotenv(".env")
9
+
10
+ app = FastAPI(title="Embedchain API")
11
+
12
+ app.include_router(api.router)
13
+ app.include_router(data_sources.router)
14
+ app.include_router(chat_history.router)
15
+ app.include_router(vector_stores.router)
16
+
17
+ if __name__ == "__main__":
18
+ uvicorn.run("main:app", host="0.0.0.0", port=8000, log_level="info",
19
+ reload=True, timeout_keep_alive=600)
api/requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ fastapi==0.108.0
2
+ uvicorn==0.25.0
3
+ embedchain
4
+ beautifulsoup4
5
+ sentence-transformers
6
+ langchain_huggingface
7
+ langchain_community
api/routes/__init__.py ADDED
File without changes
api/routes/admin/__init__.py ADDED
File without changes
api/routes/admin/chat_history.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from embedchain import App
2
+ from fastapi import APIRouter
3
+
4
+ from utils.embedchain import EC_APP_CONFIG
5
+
6
+ ec_app = App.from_config(config=EC_APP_CONFIG)
7
+
8
+ router = APIRouter()
9
+
10
+
11
+ @router.get("/api/v1/admin/chat_history")
12
+ async def get_all_chat_history():
13
+ chat_history = ec_app.llm.memory.get(
14
+ app_id=ec_app.config.id,
15
+ num_rounds=100,
16
+ display_format=True,
17
+ fetch_all=True,
18
+ )
19
+ return chat_history
api/routes/admin/data_sources.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from embedchain import App
2
+ from fastapi import APIRouter, Response, status
3
+ from pydantic import BaseModel
4
+
5
+ from routes.admin.utils import (set_env_variables, unset_env_variables,
6
+ validate_json)
7
+ from utils.embedchain import EC_APP_CONFIG
8
+
9
+ router = APIRouter()
10
+ ec_app = App.from_config(config=EC_APP_CONFIG)
11
+
12
+
13
+ class DataSourceModel(BaseModel):
14
+ dataType: str
15
+ dataValue: str
16
+ metadata: str
17
+ envVariables: str
18
+
19
+
20
+ @router.get("/api/v1/admin/data_sources")
21
+ async def get_all_data_sources():
22
+ data_sources = ec_app.get_data_sources()
23
+ response = data_sources
24
+ for i in response:
25
+ i.update({"app_id": ec_app.config.id})
26
+ return response
27
+
28
+
29
+ @router.post("/api/v1/admin/data_sources", status_code=201)
30
+ async def add_data_source(data_source: DataSourceModel, response: Response):
31
+ """
32
+ Adds a new source to the Embedchain app.
33
+ """
34
+ data_type = data_source.dataType
35
+ data_value = data_source.dataValue
36
+ metadata = data_source.metadata
37
+ env_variables = data_source.envVariables
38
+
39
+ # Validate json metadata
40
+ params = {"source": data_value, "data_type": data_type}
41
+ if metadata and not validate_json(metadata):
42
+ response.status_code = status.HTTP_400_BAD_REQUEST
43
+ return {"message": "Invalid metadata. Enter a valid JSON object."}
44
+
45
+ if env_variables and not validate_json(env_variables):
46
+ response.status_code = status.HTTP_400_BAD_REQUEST
47
+ return {"message": "Invalid environment variables. Enter a valid JSON object."}
48
+
49
+ try:
50
+ set_env_variables(env_variables)
51
+ ec_app.add(**params)
52
+ unset_env_variables(env_variables)
53
+ return {"message": f"Data of {data_type=} added successfully."}
54
+ except Exception as e:
55
+ message = f"An error occurred: Error message: {str(e)}." # noqa:E501
56
+ response.status_code = status.HTTP_400_BAD_REQUEST
57
+ return {"message": message}
api/routes/admin/embeddings.py ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import chromadb
2
+ from chromadb.config import Settings
3
+ from fastapi import APIRouter
4
+
5
+ router = APIRouter()
6
+
7
+
8
+ chroma_settings = Settings(
9
+ anonymized_telemetry=False,
10
+ persist_directory="db",
11
+ allow_reset=False,
12
+ is_persistent=True,
13
+ )
14
+ client = chromadb.Client(chroma_settings)
15
+
16
+
17
+ @router.get("/api/v1/admin/collections")
18
+ async def get_all_collections():
19
+ # Currently only works for ChromaDB but can be extended easily
20
+ # for other vector stores as well
21
+ collections = client.list_collections()
22
+ responses = [c.dict() for c in collections]
23
+ return responses
24
+
25
+
26
+ # TODO(deshraj): Add pagination and make this endpoint agnostic to the vector store
27
+ @router.get("/api/v1/admin/collections/chromadb/{collection_name}")
28
+ async def get_collection_details(collection_name: str):
29
+ collection = client.get_collection(collection_name)
30
+ collection_data = collection.get()
31
+ metadatas, documents = collection_data['metadatas'], collection_data['documents']
32
+ collated_data = []
33
+ for i in zip(metadatas, documents):
34
+ collated_data.append({
35
+ "metadata": i[0],
36
+ "document": i[1]
37
+ })
38
+ response = {"details": collection.model_dump(), "data": collated_data}
39
+ return response
api/routes/admin/ui_settings.py ADDED
File without changes
api/routes/admin/users.py ADDED
File without changes
api/routes/admin/utils.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+
4
+
5
+ def set_env_variables(env_variables: str):
6
+ if env_variables:
7
+ try:
8
+ env_variables = json.loads(env_variables)
9
+ for k, v in env_variables.items():
10
+ os.environ[k] = v
11
+ except Exception:
12
+ raise Exception("Invalid envVariables: Enter a valid JSON object.")
13
+
14
+
15
+ def unset_env_variables(env_variables: str):
16
+ if env_variables:
17
+ try:
18
+ env_variables = json.loads(env_variables)
19
+ for k, v in env_variables.items():
20
+ os.environ.pop(k)
21
+ except Exception:
22
+ raise Exception("Invalid envVariables: Enter a valid JSON object.")
23
+
24
+
25
+ def validate_json(json_string: str):
26
+ try:
27
+ json.loads(json_string)
28
+ return True
29
+ except Exception:
30
+ return False
api/routes/admin/vector_stores.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from embedchain import App
2
+ from fastapi import APIRouter
3
+
4
+ from utils.embedchain import EC_APP_CONFIG
5
+
6
+ router = APIRouter()
7
+ ec_app = App.from_config(config=EC_APP_CONFIG)
8
+
9
+
10
+ @router.get("/api/v1/admin/collections")
11
+ async def get_all_collections():
12
+ # Currently only works for ChromaDB but can be extended easily
13
+ # for other vector stores as well
14
+ collections = ec_app.db.client.list_collections()
15
+ responses = [c.dict() for c in collections]
16
+ return responses
17
+
18
+
19
+ @router.get("/api/v1/admin/collections/chromadb/{collection_name}")
20
+ async def get_collection_details(collection_name: str):
21
+ collection = ec_app.db.client.get_collection(collection_name)
22
+ collection_data = collection.get()
23
+ metadatas, documents = collection_data['metadatas'], collection_data['documents']
24
+ collated_data = []
25
+ for i in zip(metadatas, documents):
26
+ collated_data.append({
27
+ "metadata": i[0],
28
+ "document": i[1]
29
+ })
30
+ response = {"details": collection.dict(), "data": collated_data}
31
+ return response
api/routes/api.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, Query, responses
2
+ from fastapi.responses import StreamingResponse
3
+
4
+ from utils.embedchain import send_message
5
+
6
+ router = APIRouter()
7
+
8
+
9
+ @router.get("/api/v1/chat")
10
+ async def handle_chat(query: str, session_id: str = Query(None), number_documents: int = 1, citations: bool = True, stream: bool = True, model: str = "mistralai/Mixtral-8x7B-Instruct-v0.1"):
11
+ """
12
+ Handles a chat request to the Embedchain app.
13
+ Accepts 'query' and 'session_id' as query parameters.
14
+ """
15
+ generator = send_message(query, session_id, number_documents, citations, stream, model)
16
+ return StreamingResponse(generator)
17
+
18
+
19
+ @router.get("/")
20
+ async def root():
21
+ return responses.RedirectResponse(url="/docs")
api/utils/embedchain.py ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import json
3
+ import logging
4
+ import os
5
+ from typing import AsyncIterable
6
+
7
+ from embedchain import App
8
+ from embedchain.config import BaseLlmConfig
9
+ from langchain.callbacks.streaming_aiter import AsyncIteratorCallbackHandler
10
+ from langchain_community.chat_models.huggingface import ChatHuggingFace, HuggingFaceEndpoint
11
+ from langchain.schema import HumanMessage, SystemMessage
12
+
13
+ # App config using OpenAI gpt-3.5-turbo-1106 as LLM
14
+ '''
15
+ EC_APP_CONFIG = {
16
+ "app": {
17
+ "config": {
18
+ "id": "embedchain-demo-app",
19
+ }
20
+ },
21
+ "llm": {
22
+ "provider": "openai",
23
+ "config": {
24
+ "model": "gpt-3.5-turbo-1106",
25
+ }
26
+ },
27
+ 'vectordb': {
28
+ 'provider': 'chroma',
29
+ 'config': {
30
+ 'collection_name': 'rag-full',
31
+ 'dir': 'db',
32
+ 'allow_reset': True
33
+ }
34
+ }
35
+ }
36
+ '''
37
+ # Uncomment this configuration to use Mistral as LLM
38
+
39
+ EC_APP_CONFIG = {
40
+ "app": {
41
+ "config": {
42
+ "name": "embedchain-opensource-app"
43
+ }
44
+ },
45
+ "llm": {
46
+ "provider": "huggingface",
47
+ "config": {
48
+ "model": "mistralai/Mixtral-8x7B-Instruct-v0.1",
49
+ "temperature": 0.1,
50
+ "max_tokens": 250,
51
+ "top_p": 0.1
52
+ }
53
+ },
54
+ "embedder": {
55
+ "provider": "huggingface",
56
+ "config": {
57
+ "model": "sentence-transformers/all-mpnet-base-v2"
58
+ }
59
+ },
60
+ 'vectordb': {
61
+ 'provider': 'chroma',
62
+ 'config': {
63
+ 'collection_name': 'embedchain_store',
64
+ 'dir': 'db',
65
+ 'allow_reset': True
66
+ }
67
+ }
68
+
69
+ }
70
+
71
+
72
+
73
+ async def generate_sources_str(sources_metadata):
74
+ """Generate a string of unique source URLs from the sources metadata."""
75
+ seen_urls = set()
76
+ unique_sources = [source for source in sources_metadata if source['url'] not in seen_urls and not seen_urls.add(source['url'])]
77
+ sources_str = "<sources>\n" + "\n".join(json.dumps(source) for source in unique_sources) + "\n</sources>\n\n"
78
+ return sources_str
79
+
80
+
81
+ async def prepare_contexts_for_llm_query(ec_app, query, config, citations):
82
+ """Retrieve contexts from the database and prepare them for the LLM query."""
83
+ contexts = ec_app._retrieve_from_database(input_query=query, config=config, where={"app_id": ec_app.config.id}, citations=citations)
84
+ if citations and contexts and isinstance(contexts[0], tuple):
85
+ return [context[0] for context in contexts]
86
+ return contexts
87
+
88
+
89
+ async def generate_messages(ec_app, query, contexts_data_for_llm_query, config):
90
+ """Generate messages to be used in the LLM query."""
91
+ messages = []
92
+ if config.system_prompt:
93
+ messages.append(SystemMessage(content=config.system_prompt))
94
+ prompt = ec_app.llm.generate_prompt(query, contexts_data_for_llm_query)
95
+ messages.append(HumanMessage(content=prompt))
96
+ return messages
97
+
98
+
99
+ async def send_message(query, session_id, number_documents, citations, stream, model) -> AsyncIterable[str]:
100
+ ec_app = App.from_config(config=EC_APP_CONFIG)
101
+ context = ec_app.search(query, num_documents=number_documents)
102
+ sources_str = await generate_sources_str([c['metadata'] for c in context])
103
+
104
+ ec_app.llm.update_history(app_id=ec_app.config.id, session_id=session_id)
105
+ callback = AsyncIteratorCallbackHandler()
106
+ #config = BaseLlmConfig(model=model, stream=stream, callbacks=[callback], api_key=os.environ["OPENAI_API_KEY"])
107
+ config = BaseLlmConfig(model=model, stream=stream, callbacks=[callback], api_key=os.environ["HUGGINGFACE_ACCESS_TOKEN"])
108
+ contexts_data_for_llm_query = await prepare_contexts_for_llm_query(ec_app, query, config, citations)
109
+ messages = await generate_messages(ec_app, query, contexts_data_for_llm_query, config)
110
+
111
+ kwargs = {
112
+ "model": model,
113
+ "temperature": config.temperature,
114
+ "max_tokens": config.max_tokens,
115
+ "model_kwargs": {"top_p": config.top_p} if config.top_p else {},
116
+ "streaming": stream,
117
+ "callbacks": [callback],
118
+ "api_key": config.api_key,
119
+ "llm" : HuggingFaceEndpoint(
120
+ repo_id= model,
121
+ temperature= 0.1,
122
+ max_new_tokens= 250,
123
+ top_p= 0.1,
124
+ streaming= stream,
125
+ callbacks= [callback],
126
+ huggingfacehub_api_token= config.api_key
127
+ )
128
+ }
129
+
130
+
131
+ llm_task = asyncio.create_task(ChatHuggingFace(**kwargs).agenerate(messages=[messages]))
132
+
133
+ generated_answer = ""
134
+ try:
135
+ yield sources_str
136
+ async for token in callback.aiter():
137
+ yield token
138
+ generated_answer += token
139
+ except Exception as e:
140
+ logging.exception(f"Caught exception: {e}")
141
+ finally:
142
+ # add conversation in memory
143
+ ec_app.llm.add_history(ec_app.config.id, query, generated_answer, session_id=session_id)
144
+ callback.done.set()
145
+ await llm_task
assets/add_data.png ADDED
assets/chat.png ADDED
assets/chat_history.png ADDED
assets/collection.png ADDED
assets/search.png ADDED
docker-compose.yml ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: '3.9'
2
+
3
+ services:
4
+ frontend:
5
+ build:
6
+ context: ui/
7
+ dockerfile: Dockerfile
8
+ volumes:
9
+ - ./ui:/app
10
+ - /app/node_modules
11
+ ports:
12
+ - "3000:3000"
13
+ environment:
14
+ - NODE_ENV=development
15
+ - NEXT_PUBLIC_API_ENDPOINT=http://backend:8000
16
+ depends_on:
17
+ - backend
18
+
19
+ backend:
20
+ build:
21
+ context: api/
22
+ dockerfile: Dockerfile
23
+ volumes:
24
+ - ./api:/app
25
+ env_file:
26
+ - api/.env
27
+ ports:
28
+ - "8010:8000"
29
+ environment:
30
+ - PYTHONUNBUFFERED=1
embedchain.json ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ {
2
+ "name": "rag-full",
3
+ "provider": "hf/docker"
4
+ }
ui/.env.local ADDED
@@ -0,0 +1 @@
 
 
1
+ NEXT_PUBLIC_API_ENDPOINT=http://127.0.0.1:8000
ui/.eslintrc.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ {
2
+ "extends": "next/core-web-vitals"
3
+ }
ui/.gitignore ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+ # dependencies
4
+ /node_modules
5
+ /.pnp
6
+ .pnp.js
7
+
8
+ # testing
9
+ /coverage
10
+
11
+ # next.js
12
+ /.next/
13
+ /out/
14
+
15
+ # production
16
+ /build
17
+
18
+ # misc
19
+ .DS_Store
20
+ *.pem
21
+
22
+ # debug
23
+ npm-debug.log*
24
+ yarn-debug.log*
25
+ yarn-error.log*
26
+
27
+ # vercel
28
+ .vercel
29
+
30
+ # typescript
31
+ *.tsbuildinfo
32
+ next-env.d.ts
ui/.next/app-build-manifest.json ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "pages": {
3
+ "/layout": [
4
+ "static/chunks/webpack.js",
5
+ "static/chunks/main-app.js",
6
+ "static/css/app/layout.css",
7
+ "static/chunks/app/layout.js"
8
+ ],
9
+ "/page": [
10
+ "static/chunks/webpack.js",
11
+ "static/chunks/main-app.js",
12
+ "static/chunks/app/page.js"
13
+ ],
14
+ "/admin/data/add/page": [
15
+ "static/chunks/webpack.js",
16
+ "static/chunks/main-app.js",
17
+ "static/chunks/app/admin/data/add/page.js"
18
+ ],
19
+ "/admin/page": [
20
+ "static/chunks/webpack.js",
21
+ "static/chunks/main-app.js",
22
+ "static/chunks/app/admin/page.js"
23
+ ],
24
+ "/admin/collections/page": [
25
+ "static/chunks/webpack.js",
26
+ "static/chunks/main-app.js",
27
+ "static/chunks/app/admin/collections/page.js"
28
+ ],
29
+ "/admin/collections/[collection_name]/page": [
30
+ "static/chunks/webpack.js",
31
+ "static/chunks/main-app.js",
32
+ "static/chunks/app/admin/collections/[collection_name]/page.js"
33
+ ],
34
+ "/search/page": [
35
+ "static/chunks/webpack.js",
36
+ "static/chunks/main-app.js",
37
+ "static/chunks/app/search/page.js"
38
+ ]
39
+ }
40
+ }
ui/.next/build-manifest.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "polyfillFiles": [
3
+ "static/chunks/polyfills.js"
4
+ ],
5
+ "devFiles": [
6
+ "static/chunks/react-refresh.js"
7
+ ],
8
+ "ampDevFiles": [],
9
+ "lowPriorityFiles": [
10
+ "static/development/_buildManifest.js",
11
+ "static/development/_ssgManifest.js"
12
+ ],
13
+ "rootMainFiles": [
14
+ "static/chunks/webpack.js",
15
+ "static/chunks/main-app.js"
16
+ ],
17
+ "pages": {
18
+ "/_app": [
19
+ "static/chunks/webpack.js",
20
+ "static/chunks/main.js",
21
+ "static/chunks/pages/_app.js"
22
+ ],
23
+ "/_error": [
24
+ "static/chunks/webpack.js",
25
+ "static/chunks/main.js",
26
+ "static/chunks/pages/_error.js"
27
+ ]
28
+ },
29
+ "ampFirstPages": []
30
+ }
ui/.next/cache/config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "telemetry": {
3
+ "notifiedAt": "1725586628800",
4
+ "anonymousId": "7fee4018c383491a5cdd77e2ad22bdc6b6f9b84c0e20e89a45d74e247a1c960a",
5
+ "salt": "f4f5db81fcffcf37e540e3cadb3912e6"
6
+ }
7
+ }
ui/.next/cache/webpack/client-development/0.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:775bddb0187a17de0408560fd7a2d4ad919371165e8b12fe8dbaf2fcd7d45526
3
+ size 34926
ui/.next/cache/webpack/client-development/1.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cb1ad4428fbd7fbc1d75033f10ddd25f07e8f0b1786cd95d31a7ef69184e3f7d
3
+ size 5225
ui/.next/cache/webpack/client-development/10.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f4b074e86f670f62457f0dcc0c89e3b95f310c50baf063068c9d22982cf0de5b
3
+ size 25295
ui/.next/cache/webpack/client-development/11.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5f79907f1315a69281833eba6c496e0c4ff1f80fe14966dd888c7e9d686438c4
3
+ size 20220118
ui/.next/cache/webpack/client-development/2.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:62dacaf463018aeb80ec4d070e85281e1f33a6562cdcf20e8d27f18cd2b06699
3
+ size 12850129
ui/.next/cache/webpack/client-development/3.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c2525b4342fd65688be8cf43c65885a9b99e23599567ac3053641a9345bd5417
3
+ size 3470219
ui/.next/cache/webpack/client-development/4.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2e7e4913e696ce3ce2cd445f7990bb75260e0af84b0d6c918cced5db0deff849
3
+ size 5663055
ui/.next/cache/webpack/client-development/5.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f1ace2fc571a56956f9c113d955ec3f27a6670eac94dfdf5bb50fe7c82b7882e
3
+ size 25295
ui/.next/cache/webpack/client-development/6.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2eb11868b374a5af4449639f690a8a322bb1ff47cf87d7055dc517bed6cdcb32
3
+ size 20275597
ui/.next/cache/webpack/client-development/7.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ec6161cde66e0692243d81196015b4d643bf5099ec1bcd6df1f6930a8a79ba69
3
+ size 20273168
ui/.next/cache/webpack/client-development/8.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:89cd2bf85da9046850a60fba0c2fed2fad1e92f94db8242c46cb82c388730fca
3
+ size 3452068
ui/.next/cache/webpack/client-development/9.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:64e05b80dbc63f4c27a87b9bbfd1922efe0d830cea3a87cd21ccfdabd96632b9
3
+ size 5221
ui/.next/cache/webpack/client-development/index.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bce1b8a62578a00f598e0830555c61a4b90e37eb043e702e8a01792b8b292214
3
+ size 164080
ui/.next/cache/webpack/client-development/index.pack.gz.old ADDED
Binary file (141 kB). View file
 
ui/.next/cache/webpack/server-development/0.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9091fd71e15ca5e103e0ee4781e3f332156a26a01f486e7ee61d31181b229bea
3
+ size 4891
ui/.next/cache/webpack/server-development/1.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ae13ce75a1f9bbe401b041cb99eb8dd71d730242857d3885ec80a06fc72fc3b2
3
+ size 1464692
ui/.next/cache/webpack/server-development/10.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:081166452141f8326b638f292688283340a327e3bc1cbbf850cecb652ccb0b1f
3
+ size 8080043
ui/.next/cache/webpack/server-development/11.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cc8eb1eb0e85f0b7920b8a27ac883205e046bfa03849cc295cab6b185f1998d7
3
+ size 4762188
ui/.next/cache/webpack/server-development/12.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e4f6e3c151b86411b4c739f204be7f46190de4e38eaf4fb10c46d167c054ddbd
3
+ size 1664794
ui/.next/cache/webpack/server-development/2.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:29bc21168dcf72395a68069bc993c351441a8066501f72a1bdc13755d7b80fd1
3
+ size 11730
ui/.next/cache/webpack/server-development/3.pack.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:78792e57e3669703c8ca1a36cbf1bd31b89bad1bed6974936c765a0a457536f5
3
+ size 1949155