Upload folder using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitignore +162 -0
- README.md +72 -12
- api/Dockerfile +13 -0
- api/main.py +19 -0
- api/requirements.txt +7 -0
- api/routes/__init__.py +0 -0
- api/routes/admin/__init__.py +0 -0
- api/routes/admin/chat_history.py +19 -0
- api/routes/admin/data_sources.py +57 -0
- api/routes/admin/embeddings.py +39 -0
- api/routes/admin/ui_settings.py +0 -0
- api/routes/admin/users.py +0 -0
- api/routes/admin/utils.py +30 -0
- api/routes/admin/vector_stores.py +31 -0
- api/routes/api.py +21 -0
- api/utils/embedchain.py +145 -0
- assets/add_data.png +0 -0
- assets/chat.png +0 -0
- assets/chat_history.png +0 -0
- assets/collection.png +0 -0
- assets/search.png +0 -0
- docker-compose.yml +30 -0
- embedchain.json +4 -0
- ui/.env.local +1 -0
- ui/.eslintrc.json +3 -0
- ui/.gitignore +32 -0
- ui/.next/app-build-manifest.json +40 -0
- ui/.next/build-manifest.json +30 -0
- ui/.next/cache/config.json +7 -0
- ui/.next/cache/webpack/client-development/0.pack.gz +3 -0
- ui/.next/cache/webpack/client-development/1.pack.gz +3 -0
- ui/.next/cache/webpack/client-development/10.pack.gz +3 -0
- ui/.next/cache/webpack/client-development/11.pack.gz +3 -0
- ui/.next/cache/webpack/client-development/2.pack.gz +3 -0
- ui/.next/cache/webpack/client-development/3.pack.gz +3 -0
- ui/.next/cache/webpack/client-development/4.pack.gz +3 -0
- ui/.next/cache/webpack/client-development/5.pack.gz +3 -0
- ui/.next/cache/webpack/client-development/6.pack.gz +3 -0
- ui/.next/cache/webpack/client-development/7.pack.gz +3 -0
- ui/.next/cache/webpack/client-development/8.pack.gz +3 -0
- ui/.next/cache/webpack/client-development/9.pack.gz +3 -0
- ui/.next/cache/webpack/client-development/index.pack.gz +3 -0
- ui/.next/cache/webpack/client-development/index.pack.gz.old +0 -0
- ui/.next/cache/webpack/server-development/0.pack.gz +3 -0
- ui/.next/cache/webpack/server-development/1.pack.gz +3 -0
- ui/.next/cache/webpack/server-development/10.pack.gz +3 -0
- ui/.next/cache/webpack/server-development/11.pack.gz +3 -0
- ui/.next/cache/webpack/server-development/12.pack.gz +3 -0
- ui/.next/cache/webpack/server-development/2.pack.gz +3 -0
- 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 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|