Compare commits

...

76 Commits

Author SHA1 Message Date
Deshraj Yadav f3553040bc [Bug fix] Fix chromadb issue on embedchain version 0.1.58 (#1151) 2024-01-09 23:45:42 +05:30
Christian Clauss 2b13984e11 README.md: Expand the acronym to help readers understand (#1148) 2024-01-09 23:08:16 +05:30
Sandra Serrano 0de9491c61 #1128 | Remove deprecated type hints from typing module (#1131) 2024-01-09 23:05:24 +05:30
Deshraj Yadav c9df7a2020 Documentation edits made through Mintlify web editor 2024-01-09 17:47:36 +05:30
Deshraj Yadav a7222e8c50 [Docs] Fix docs heading (#1150) 2024-01-09 17:44:20 +05:30
Deshraj Yadav 0373fa231c [Feature] Add support for vllm as llm source (#1149) 2024-01-09 17:38:53 +05:30
Deshraj Yadav 5f653e69ae Update version to 0.1.57 (#1146) 2024-01-09 02:12:31 +05:30
Sandra Serrano 2496ed133e [Bug fix] Fix typos, static methods and other sanity improvements in the package (#1129) 2024-01-09 00:17:46 +05:30
Madison Ebersole 62c0c52e31 Add support for Hugging Face Inference Endpoint as LLM (#1143) 2024-01-08 23:50:04 +05:30
Deven Patel e36198dcc2 [Docs] add slack ai in docs under examples tab (#1142)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2024-01-08 23:03:06 +05:30
Deshraj Yadav 5fa6221f91 Update documentation based on user feedback (#1141) 2024-01-08 11:07:24 +05:30
YusukeJustinNakajima f7696d1dc1 [Fix] Enhanced security for OpenAPI and JSON Loader Integration (#1122) 2024-01-08 11:07:03 +05:30
Christian Clauss 1878f8d4fc README.md: Fix typo (#1140) 2024-01-08 09:49:47 +05:30
Deshraj Yadav 6c69ddef9b Update package version to 0.1.56 (#1137) 2024-01-07 23:50:49 +05:30
Deshraj Yadav 0c45020d81 [Feature] Add support for docker in fullstack app (#1134) 2024-01-07 23:49:20 +05:30
Deven Patel 4dfce44c1a [BugFixes] slack loader (#1135)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2024-01-07 23:13:25 +05:30
Deven Patel 1b661bb2fd [Improvement] fix slack loader max_count (#1127)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2024-01-07 13:03:42 +05:30
Deven Patel 73e726f6e3 [Bug fix] quickfix custom configuration doc (#1125)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2024-01-07 11:00:35 +05:30
Deven Patel f58bbeffce [Bugfix] fix sadhguru example sources return logic (#1123)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2024-01-06 13:57:32 +05:30
Deven Patel 99261e5fb5 [Example] add example for nextjs app and discord/slack bots (#1111)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2024-01-05 22:36:58 +05:30
Deshraj Yadav b4a59d1bd5 [Feature] Update commands to run full stack app (#1118) 2024-01-05 15:58:59 +05:30
Deshraj Yadav 5c1f78879f [Misc] Minor fixes and refactor utils code (#1117) 2024-01-05 14:01:56 +05:30
Sandra Serrano 94ba82f2a2 #710 | Remove unused and deprecated app.count method (#1116) 2024-01-05 13:51:49 +05:30
Joe Sleiman b4ec14382b [Feature] Google Drive Folder support as a data source (#1106) 2024-01-05 11:46:01 +05:30
Ikko Eltociear Ashimine 38ad57a22c Update full-stack.mdx (#1115) 2024-01-05 11:27:48 +05:30
Deshraj Yadav 60bbc180ba Add support for ec runserver command (#1112) 2024-01-04 15:59:43 +05:30
Taranjeet Singh a67d902b85 Fix top_p value bug in quickstart example in docs (#1110) 2024-01-04 00:41:14 +05:30
Deven Patel ae2e9cb890 [Bugfix] fix cache session id in chat method (#1107)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2024-01-03 13:51:11 +05:30
Deven Patel 1976d38b25 [Bugfix] fix chat pdf streamlit example (#1108)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2024-01-03 13:46:44 +05:30
Deshraj Yadav f5e3410e9a Update docs for session_id (#1105) 2024-01-03 01:14:47 +05:30
Taranjeet Singh 2f6ba642c7 feat: Add private ai example (#1101) 2024-01-02 19:18:25 +05:30
Taranjeet Singh dd9b72dc62 Bump version to 0.1.51 (#1100) 2024-01-02 18:08:18 +05:30
Taranjeet Singh dd258c14b5 feat: Make gpt4all work offline. (#1099) 2024-01-02 17:46:08 +05:30
Deven Patel 295cd3fac6 [Updates] Update GPTCache configuration/docs (#1098)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2024-01-02 17:32:48 +05:30
Sidharth Mohanty c62663f2e4 Add GPT4Vision Image loader (#1089)
Co-authored-by: Deshraj Yadav <deshrajdry@gmail.com>
2024-01-02 03:57:23 +05:30
Taranjeet Singh 367d6b70e2 Update docs and side navbar. (#1097) 2024-01-02 00:18:57 +05:30
Taranjeet Singh 27236bd1b2 Improve docs. (#1096) 2024-01-01 23:22:43 +05:30
Deven Patel 6a82eb4287 [Docs] update search docs (#1093)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2024-01-01 22:32:27 +05:30
Logie bd88fe3980 fix: typo when import helpers.json_serializable on rss_feed files (#1095) 2024-01-01 21:38:41 +05:30
Deven Patel 4f70fea6df [BugFix] search method in app (#1092)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2023-12-31 23:58:17 +05:30
Sidharth Mohanty aee5bbb44b [Refactor] Update dependencies and loaders (#1062) 2023-12-30 20:52:20 +05:30
Deven Patel a304ded500 [Bugfix] fix config validation for google llm config (#1088)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2023-12-30 16:25:41 +05:30
Deshraj Yadav a54dde0509 [Bug Fix] Handle chat sessions properly during app.chat() calls (#1084) 2023-12-30 15:36:24 +05:30
Taranjeet Singh 52b4577d3b Update links, code and description (#1087) 2023-12-30 15:32:16 +05:30
Taranjeet Singh e199f57279 Fix light mode logo (#1083) 2023-12-30 15:16:48 +05:30
Taranjeet Singh dec12b33a6 Update dark mode logo (#1082) 2023-12-30 15:14:14 +05:30
Deven Patel 04daa1b206 [Feature] Add support for GPTCache (#1065) 2023-12-30 14:51:48 +05:30
Deven Patel a7e1520d08 [Improvements] update docs (#1079)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2023-12-30 13:39:38 +05:30
Deshraj Yadav 9e2b232c13 Update version to 0.1.47 (#1077) 2023-12-30 00:16:31 +05:30
Sidharth Mohanty 404e73af77 [Feature] Add Dropbox loader (#1073)
Co-authored-by: Deshraj Yadav <deshrajdry@gmail.com>
2023-12-29 23:22:25 +05:30
Sidharth Mohanty a544b4d3ff Load local text files of any kind - code, txts, json etc (#1076) 2023-12-29 22:26:24 +05:30
Sidharth Mohanty 6df63d9ca7 Update notebooks to use dict instead of yaml and remove dataloaders (#1075) 2023-12-29 21:57:46 +05:30
Deshraj Yadav 904baac153 Update version to 0.1.46 (#1074) 2023-12-29 17:01:11 +05:30
Deven Patel a926bcc640 [Refactor] Converge Pipeline and App classes (#1021)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2023-12-29 16:52:41 +05:30
Deven Patel c0aafd38c9 [Feature] Return score when doing search in vectorDB (#1060)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2023-12-29 15:56:12 +05:30
Deven Patel 19d80914df [Improvement] return all the metadata when citations flag is True (#1059)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2023-12-29 14:48:41 +05:30
Sidharth Mohanty d9d529987e Migrate from template to prompt arg while keeping backward compatibility (#1066) 2023-12-28 23:36:33 +05:30
Deven Patel 12e6eaf802 [Docs] add docs for youtube channel (#1072)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2023-12-28 21:08:48 +05:30
Taranjeet Singh 7a026ea282 Fix link in github issue bug template (#1068) 2023-12-28 20:06:53 +05:30
Taranjeet Singh 97dc90169b docs: Update framework desc & link (#1067) 2023-12-28 19:39:22 +05:30
Sidharth Mohanty 64c02f374a Add cards for gradio and hf (#1061) 2023-12-28 09:03:31 +05:30
Sukkrit Sharma 6c1ea7799e [Feature] Add support for Together AI API (#1058) 2023-12-25 18:36:20 +05:30
Deshraj Yadav 6be29f5bed [Bug Fix] Fix FileExistsError when using Embedchain in multithreading setting (#1056) 2023-12-24 16:33:53 +05:30
Deven Patel 68737da7a2 [Update] update readme (#1054)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2023-12-23 16:38:32 +05:30
Deven Patel da388b679f [Chat PDF] update chat pdf logic (#1053)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2023-12-23 16:13:48 +05:30
Sidharth Mohanty 11f0d719f5 Provide openai-key support from config (#1052) 2023-12-23 14:42:18 +05:30
Deshraj Yadav e90673ae5b Added Dev Container Folder 2023-12-23 12:55:39 +05:30
Deven Patel f055028c6b [Bugfix] fix chat PDF dependencies (#1051)
Co-authored-by: Deven Patel <deven298@yahoo.com>
2023-12-23 12:21:03 +05:30
Prikshit 106a338371 Add local file path support to SitemapLoader (#954) 2023-12-23 10:56:33 +05:30
Deven Patel 9fe80c5cca [App Deployment] create chat with PDF app (#1049)
Co-authored-by: Deven Patel <deven298@yahoo.com>
Co-authored-by: Deshraj Yadav <deshrajdry@gmail.com>
2023-12-22 19:53:10 +05:30
Deshraj Yadav 050706e95e Update poetry.lock file (#1048) 2023-12-22 19:48:27 +05:30
Sidharth Mohanty 6d2389de1c [fix] streamlit app init by caching it (#1047) 2023-12-22 12:03:45 +05:30
Dhravya Shah dd97fad5a4 Fix: indents in yaml file (#1046) 2023-12-22 10:56:40 +05:30
Sukkrit Sharma 0f73ba9677 Added Support for Ollama for local model inference. (#1045)
Co-authored-by: Deshraj Yadav <deshraj@gatech.edu>
2023-12-22 05:10:00 +05:30
Sidharth Mohanty 210fe9bb80 [new] add gradio and hf spaces deployments (#1042) 2023-12-22 00:00:55 +05:30
Sidharth Mohanty ec8549d0e1 [fix] dot file and docs (#1044) 2023-12-21 18:50:12 +05:30
260 changed files with 6038 additions and 3461 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ body:
- type: markdown
attributes:
value: >
#### Before submitting a bug, please make sure the issue hasn't been already addressed by searching through [the existing and past issues](https://github.com/gventuri/pandas-ai/issues?q=is%3Aissue+sort%3Acreated-desc+).
#### Before submitting a bug, please make sure the issue hasn't been already addressed by searching through [the existing and past issues](https://github.com/embedchain/embedchain/issues?q=is%3Aissue+sort%3Acreated-desc+).
- type: textarea
attributes:
label: 🐛 Describe the bug
+3
View File
@@ -175,3 +175,6 @@ notebooks/*.yaml
.ipynb_checkpoints/
!configs/*.yaml
# cache db
*.db
+15 -8
View File
@@ -13,17 +13,17 @@
<a href="https://pepy.tech/project/embedchain">
<img src="https://static.pepy.tech/badge/embedchain" alt="Downloads">
</a>
<a href="https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw">
<a href="https://embedchain.ai/slack">
<img src="https://img.shields.io/badge/slack-embedchain-brightgreen.svg?logo=slack" alt="Slack">
</a>
<a href="https://discord.gg/CUU9FPhRNt">
<a href="https://embedchain.ai/discord">
<img src="https://dcbadge.vercel.app/api/server/6PzXDgEjG5?style=flat" alt="Discord">
</a>
<a href="https://twitter.com/embedchain">
<img src="https://img.shields.io/twitter/follow/embedchain" alt="Twitter">
</a>
<a href="https://colab.research.google.com/drive/138lMWhENGeEu7Q1-6lNbNTHGLZXBBz_B?usp=sharing">
<img src="https://camo.githubusercontent.com/84f0493939e0c4de4e6dbe113251b4bfb5353e57134ffd9fcab6b8714514d4d1/68747470733a2f2f636f6c61622e72657365617263682e676f6f676c652e636f6d2f6173736574732f636f6c61622d62616467652e737667" alt="Open in Colab">
<img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open in Colab">
</a>
<a href="https://codecov.io/gh/embedchain/embedchain">
<img src="https://codecov.io/gh/embedchain/embedchain/graph/badge.svg?token=EMRRHZXW1Q" alt="codecov">
@@ -39,16 +39,21 @@
Embedchain is an Open Source RAG Framework that makes it easy to create and deploy AI apps. At its core, Embedchain follows the design principle of being *"Conventional but Configurable"* to serve both software engineers and machine learning engineers.
Embedchain streamlines the creation of RAG applications, offering a seamless process for managing various types of unstructured data. It efficiently segments data into manageable chunks, generates relevant embeddings, and stores them in a vector database for optimized retrieval. With a suite of diverse APIs, it enables users to extract contextual information, find precise answers, or engage in interactive chat conversations, all tailored to their own data.
Embedchain streamlines the creation of Retrieval-Augmented Generation (RAG) applications, offering a seamless process for managing various types of unstructured data. It efficiently segments data into manageable chunks, generates relevant embeddings, and stores them in a vector database for optimized retrieval. With a suite of diverse APIs, it enables users to extract contextual information, find precise answers, or engage in interactive chat conversations, all tailored to their own data.
## 🔧 Quick install
### Python API
```bash
pip install embedchain
```
## 🔍 Usage and Demo
## ✨ Live demo
Checkout the [Chat with PDF](https://embedchain.ai/demo/chat-pdf) live demo we created using Embedchain. You can find the source code [here](https://github.com/embedchain/embedchain/tree/main/examples/chat-pdf).
## 🔍 Usage
<!-- Demo GIF or Image -->
<p align="center">
@@ -76,7 +81,7 @@ elon_bot.query("How many companies does Elon Musk run and name those?")
You can also try it in your browser with Google Colab:
[![Open in Colab](https://camo.githubusercontent.com/84f0493939e0c4de4e6dbe113251b4bfb5353e57134ffd9fcab6b8714514d4d1/68747470733a2f2f636f6c61622e72657365617263682e676f6f676c652e636f6d2f6173736574732f636f6c61622d62616467652e737667)](https://colab.research.google.com/drive/17ON1LPonnXAtLaZEebnOktstB_1cJJmh?usp=sharing)
[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/17ON1LPonnXAtLaZEebnOktstB_1cJJmh?usp=sharing)
## 📖 Documentation
Comprehensive guides and API documentation are available to help you get the most out of Embedchain:
@@ -88,7 +93,9 @@ Comprehensive guides and API documentation are available to help you get the mos
## 🔗 Join the Community
Connect with fellow developers and users by joining our [Slack Workspace](https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw) or [Discord Community](https://discord.gg/CUU9FPhRNt). Dive into discussions, ask questions, and share your experiences.
* Connect with fellow developers by joining our [Slack Community](https://embedchain.ai/slack) or [Discord Community](https://embedchain.ai/discord).
* Dive into [GitHub Discussions](https://github.com/embedchain/embedchain/discussions), ask questions, or share your experiences.
## 🤝 Schedule a 1-on-1 Session
@@ -116,7 +123,7 @@ If you utilize this repository, please consider citing it with:
```
@misc{embedchain,
author = {Taranjeet Singh, Deshraj Yadav},
title = {Embedchain: Data platform for LLMs - load, index, retrieve, and sync any unstructured data},
title = {Embedchain: The Open Source RAG Framework},
year = {2023},
publisher = {GitHub},
journal = {GitHub repository},
-1
View File
@@ -1,7 +1,6 @@
app:
config:
id: 'my-app'
collection_name: 'my-app'
llm:
provider: openai
+1 -1
View File
@@ -15,7 +15,7 @@ llm:
max_tokens: 1000
top_p: 1
stream: false
template: |
prompt: |
Use the following pieces of context to answer the query at the end.
If you don't know the answer, just say that you don't know, don't try to make up an answer.
+12
View File
@@ -0,0 +1,12 @@
llm:
provider: ollama
config:
model: 'llama2'
temperature: 0.5
top_p: 1
stream: true
embedder:
provider: huggingface
config:
model: 'BAAI/bge-small-en-v1.5'
-1
View File
@@ -1,7 +1,6 @@
app:
config:
id: 'open-source-app'
collection_name: 'open-source-app'
collect_metrics: false
llm:
+6
View File
@@ -0,0 +1,6 @@
llm:
provider: together
config:
model: mistralai/Mixtral-8x7B-Instruct-v0.1
temperature: 0.5
max_tokens: 1000
+14
View File
@@ -0,0 +1,14 @@
llm:
provider: vllm
config:
model: 'meta-llama/Llama-2-70b-hf'
temperature: 0.5
top_p: 1
top_k: 10
stream: true
trust_remote_code: true
embedder:
provider: huggingface
config:
model: 'BAAI/bge-small-en-v1.5'
+57 -11
View File
@@ -25,7 +25,8 @@ llm:
max_tokens: 1000
top_p: 1
stream: false
template: |
api_key: sk-xxx
prompt: |
Use the following pieces of context to answer the query at the end.
If you don't know the answer, just say that you don't know, don't try to make up an answer.
@@ -48,12 +49,21 @@ embedder:
provider: openai
config:
model: 'text-embedding-ada-002'
api_key: sk-xxx
chunker:
chunk_size: 2000
chunk_overlap: 100
length_function: 'len'
min_chunk_size: 0
cache:
similarity_evaluation:
strategy: distance
max_distance: 1.0
config:
similarity_threshold: 0.8
auto_flush: 50
```
```json config.json
@@ -71,8 +81,9 @@ chunker:
"max_tokens": 1000,
"top_p": 1,
"stream": false,
"template": "Use the following pieces of context to answer the query at the end.\nIf you don't know the answer, just say that you don't know, don't try to make up an answer.\n$context\n\nQuery: $query\n\nHelpful Answer:",
"system_prompt": "Act as William Shakespeare. Answer the following questions in the style of William Shakespeare."
"prompt": "Use the following pieces of context to answer the query at the end.\nIf you don't know the answer, just say that you don't know, don't try to make up an answer.\n$context\n\nQuery: $query\n\nHelpful Answer:",
"system_prompt": "Act as William Shakespeare. Answer the following questions in the style of William Shakespeare.",
"api_key": "sk-xxx"
}
},
"vectordb": {
@@ -86,7 +97,8 @@ chunker:
"embedder": {
"provider": "openai",
"config": {
"model": "text-embedding-ada-002"
"model": "text-embedding-ada-002",
"api_key": "sk-xxx"
}
},
"chunker": {
@@ -94,7 +106,17 @@ chunker:
"chunk_overlap": 100,
"length_function": "len",
"min_chunk_size": 0
}
},
"cache": {
"similarity_evaluation": {
"strategy": "distance",
"max_distance": 1.0,
},
"config": {
"similarity_threshold": 0.8,
"auto_flush": 50,
},
},
}
```
@@ -113,14 +135,15 @@ config = {
'max_tokens': 1000,
'top_p': 1,
'stream': False,
'template': (
'prompt': (
"Use the following pieces of context to answer the query at the end.\n"
"If you don't know the answer, just say that you don't know, don't try to make up an answer.\n"
"$context\n\nQuery: $query\n\nHelpful Answer:"
),
'system_prompt': (
"Act as William Shakespeare. Answer the following questions in the style of William Shakespeare."
)
),
'api_key': 'sk-xxx'
}
},
'vectordb': {
@@ -134,7 +157,8 @@ config = {
'embedder': {
'provider': 'openai',
'config': {
'model': 'text-embedding-ada-002'
'model': 'text-embedding-ada-002',
'api_key': 'sk-xxx'
}
},
'chunker': {
@@ -142,7 +166,17 @@ config = {
'chunk_overlap': 100,
'length_function': 'len',
'min_chunk_size': 0
}
},
'cache': {
'similarity_evaluation': {
'strategy': 'distance',
'max_distance': 1.0,
},
'config': {
'similarity_threshold': 0.8,
'auto_flush': 50,
},
},
}
```
</CodeGroup>
@@ -164,10 +198,11 @@ Alright, let's dive into what each key means in the yaml config above:
- `max_tokens` (Integer): Controls how many tokens are used in the response.
- `top_p` (Float): Controls the diversity of word selection. A higher value (closer to 1) makes word selection more diverse.
- `stream` (Boolean): Controls if the response is streamed back to the user (set to false).
- `template` (String): A custom template for the prompt that the model uses to generate responses.
- `prompt` (String): A prompt for the model to follow when generating responses, requires `$context` and `$query` variables.
- `system_prompt` (String): A system prompt for the model to follow when generating responses, in this case, it's set to the style of William Shakespeare.
- `stream` (Boolean): Controls if the response is streamed back to the user (set to false).
- `number_documents` (Integer): Number of documents to pull from the vectordb as context, defaults to 1
- `api_key` (String): The API key for the language model.
3. `vectordb` Section:
- `provider` (String): The provider for the vector database, set to 'chroma'. You can find the full list of vector database providers in [our docs](/components/vector-databases).
- `config`:
@@ -179,12 +214,23 @@ Alright, let's dive into what each key means in the yaml config above:
- `provider` (String): The provider for the embedder, set to 'openai'. You can find the full list of embedding model providers in [our docs](/components/embedding-models).
- `config`:
- `model` (String): The specific model used for text embedding, 'text-embedding-ada-002'.
- `api_key` (String): The API key for the embedding model.
5. `chunker` Section:
- `chunk_size` (Integer): The size of each chunk of text that is sent to the language model.
- `chunk_overlap` (Integer): The amount of overlap between each chunk of text.
- `length_function` (String): The function used to calculate the length of each chunk of text. In this case, it's set to 'len'. You can also use any function import directly as a string here.
- `min_chunk_size` (Integer): The minimum size of each chunk of text that is sent to the language model. Must be less than `chunk_size`, and greater than `chunk_overlap`.
6. `cache` Section: (Optional)
- `similarity_evaluation` (Optional): The config for similarity evaluation strategy. If not provided, the default `distance` based similarity evaluation strategy is used.
- `strategy` (String): The strategy to use for similarity evaluation. Currently, only `distance` and `exact` based similarity evaluation is supported. Defaults to `distance`.
- `max_distance` (Float): The bound of maximum distance. Defaults to `1.0`.
- `positive` (Boolean): If the larger distance indicates more similar of two entities, set it `True`, otherwise `False`. Defaults to `False`.
- `config` (Optional): The config for initializing the cache. If not provided, sensible default values are used as mentioned below.
- `similarity_threshold` (Float): The threshold for similarity evaluation. Defaults to `0.8`.
- `auto_flush` (Integer): The number of queries after which the cache is flushed. Defaults to `20`.
<Note>
If you provide a cache section, the app will automatically configure and use a cache to store the results of the language model. This is useful if you want to speed up the response time and save inference cost of your app.
</Note>
If you have questions about the configuration above, please feel free to reach out to us using one of the following methods:
<Snippet file="get-help.mdx" />
+2 -2
View File
@@ -21,7 +21,7 @@ title: '📊 add'
### Load data from webpage
```python Code example
from embedchain import Pipeline as App
from embedchain import App
app = App()
app.add("https://www.forbes.com/profile/elon-musk")
@@ -32,7 +32,7 @@ app.add("https://www.forbes.com/profile/elon-musk")
### Load data from sitemap
```python Code example
from embedchain import Pipeline as App
from embedchain import App
app = App()
app.add("https://python.langchain.com/sitemap.xml", data_type="sitemap")
+45 -11
View File
@@ -18,6 +18,9 @@ title: '💬 chat'
<ParamField path="where" type="dict" optional>
A dictionary of key-value pairs to filter the chunks from the vector database. Defaults to `None`
</ParamField>
<ParamField path="session_id" type="str" optional>
Session ID of the chat. This can be used to maintain chat history of different user sessions. Default value: `default`
</ParamField>
<ParamField path="citations" type="bool" optional>
Return citations along with the LLM answer. Defaults to `False`
</ParamField>
@@ -36,7 +39,7 @@ title: '💬 chat'
If you want to get the answer to question and return both answer and citations, use the following code snippet:
```python With Citations
from embedchain import Pipeline as App
from embedchain import App
# Initialize app
app = App()
@@ -53,27 +56,39 @@ print(sources)
# [
# (
# 'Elon Musk PROFILEElon MuskCEO, Tesla$247.1B$2.3B (0.96%)Real Time Net Worthas of 12/7/23 ...',
# 'https://www.forbes.com/profile/elon-musk',
# '4651b266--4aa78839fe97'
# {
# 'url': 'https://www.forbes.com/profile/elon-musk',
# 'score': 0.89,
# ...
# }
# ),
# (
# '74% of the company, which is now called X.Wealth HistoryHOVER TO REVEAL NET WORTH BY YEARForbes ...',
# 'https://www.forbes.com/profile/elon-musk',
# '4651b266--4aa78839fe97'
# {
# 'url': 'https://www.forbes.com/profile/elon-musk',
# 'score': 0.81,
# ...
# }
# ),
# (
# 'founded in 2002, is worth nearly $150 billion after a $750 million tender offer in June 2023 ...',
# 'https://www.forbes.com/profile/elon-musk',
# '4651b266--4aa78839fe97'
# {
# 'url': 'https://www.forbes.com/profile/elon-musk',
# 'score': 0.73,
# ...
# }
# )
# ]
```
<Note>
When `citations=True`, note that the returned `sources` are a list of tuples where each tuple has three elements (in the following order):
When `citations=True`, note that the returned `sources` are a list of tuples where each tuple has two elements (in the following order):
1. source chunk
2. link of the source document
3. document id (used for book keeping purposes)
2. dictionary with metadata about the source chunk
- `url`: url of the source
- `doc_id`: document id (used for book keeping purposes)
- `score`: score of the source chunk with respect to the question
- other metadata you might have added at the time of adding the source
</Note>
@@ -82,7 +97,7 @@ When `citations=True`, note that the returned `sources` are a list of tuples whe
If you just want to return answers and don't want to return citations, you can use the following example:
```python Without Citations
from embedchain import Pipeline as App
from embedchain import App
# Initialize app
app = App()
@@ -95,3 +110,22 @@ answer = app.chat("What is the net worth of Elon?")
print(answer)
# Answer: The net worth of Elon Musk is $221.9 billion.
```
### With session id
If you want to maintain chat sessions for different users, you can simply pass the `session_id` keyword argument. See the example below:
```python With session id
from embedchain import App
app = App()
app.add("https://www.forbes.com/profile/elon-musk")
# Chat on your data using `.chat()`
app.chat("What is the net worth of Elon Musk?", session_id="user1")
# 'The net worth of Elon Musk is $250.8 billion.'
app.chat("What is the net worth of Bill Gates?", session_id="user2")
# "I don't know the current net worth of Bill Gates."
app.chat("What was my last question", session_id="user1")
# 'Your last question was "What is the net worth of Elon Musk?"'
```
+1 -1
View File
@@ -7,7 +7,7 @@ title: 🗑 delete
## Usage
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
+1 -1
View File
@@ -9,7 +9,7 @@ The `deploy()` method not only deploys your pipeline but also efficiently manage
## Usage
```python
from embedchain import Pipeline as App
from embedchain import App
# Initialize app
app = App()
+4 -4
View File
@@ -41,7 +41,7 @@ You can create an embedchain pipeline instance using the following methods:
### Default setting
```python Code Example
from embedchain import Pipeline as App
from embedchain import App
app = App()
```
@@ -49,7 +49,7 @@ app = App()
### Python Dict
```python Code Example
from embedchain import Pipeline as App
from embedchain import App
config_dict = {
'llm': {
@@ -76,7 +76,7 @@ app = App.from_config(config=config_dict)
<CodeGroup>
```python main.py
from embedchain import Pipeline as App
from embedchain import App
# load llm configuration from config.yaml file
app = App.from_config(config_path="config.yaml")
@@ -103,7 +103,7 @@ embedder:
<CodeGroup>
```python main.py
from embedchain import Pipeline as App
from embedchain import App
# load llm configuration from config.json file
app = App.from_config(config_path="config.json")
+23 -11
View File
@@ -36,7 +36,7 @@ title: '❓ query'
If you want to get the answer to question and return both answer and citations, use the following code snippet:
```python With Citations
from embedchain import Pipeline as App
from embedchain import App
# Initialize app
app = App()
@@ -53,27 +53,39 @@ print(sources)
# [
# (
# 'Elon Musk PROFILEElon MuskCEO, Tesla$247.1B$2.3B (0.96%)Real Time Net Worthas of 12/7/23 ...',
# 'https://www.forbes.com/profile/elon-musk',
# '4651b266--4aa78839fe97'
# {
# 'url': 'https://www.forbes.com/profile/elon-musk',
# 'score': 0.89,
# ...
# }
# ),
# (
# '74% of the company, which is now called X.Wealth HistoryHOVER TO REVEAL NET WORTH BY YEARForbes ...',
# 'https://www.forbes.com/profile/elon-musk',
# '4651b266--4aa78839fe97'
# {
# 'url': 'https://www.forbes.com/profile/elon-musk',
# 'score': 0.81,
# ...
# }
# ),
# (
# 'founded in 2002, is worth nearly $150 billion after a $750 million tender offer in June 2023 ...',
# 'https://www.forbes.com/profile/elon-musk',
# '4651b266--4aa78839fe97'
# {
# 'url': 'https://www.forbes.com/profile/elon-musk',
# 'score': 0.73,
# ...
# }
# )
# ]
```
<Note>
When `citations=True`, note that the returned `sources` are a list of tuples where each tuple has three elements (in the following order):
When `citations=True`, note that the returned `sources` are a list of tuples where each tuple has two elements (in the following order):
1. source chunk
2. link of the source document
3. document id (used for book keeping purposes)
2. dictionary with metadata about the source chunk
- `url`: url of the source
- `doc_id`: document id (used for book keeping purposes)
- `score`: score of the source chunk with respect to the question
- other metadata you might have added at the time of adding the source
</Note>
### Without citations
@@ -81,7 +93,7 @@ When `citations=True`, note that the returned `sources` are a list of tuples whe
If you just want to return answers and don't want to return citations, you can use the following example:
```python Without Citations
from embedchain import Pipeline as App
from embedchain import App
# Initialize app
app = App()
+1 -1
View File
@@ -7,7 +7,7 @@ title: 🔄 reset
## Usage
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
app.add("https://www.forbes.com/profile/elon-musk")
+13 -7
View File
@@ -24,7 +24,7 @@ title: '🔍 search'
Refer to the following example on how to use the search api:
```python Code example
from embedchain import Pipeline as App
from embedchain import App
# Initialize app
app = App()
@@ -38,14 +38,20 @@ print(context)
# Context:
# [
# {
# 'context': 'Elon Musk PROFILEElon MuskCEO, Tesla$221.9BReal Time Net Worthas of 10/29/23Reflects change since 5 pm ET of prior trading day. 1 in the world todayPhoto by Martin Schoeller for ForbesAbout Elon MuskElon Musk cofounded six companies, including electric car maker Tesla, rocket producer SpaceX and tunneling startup Boring Company.He owns about 21% of Tesla between stock and options, but has pledged more than half his shares as collateral for personal loans of up to $3.5 billion.SpaceX, founded in',
# 'source': 'https://www.forbes.com/profile/elon-musk',
# 'document_id': 'some_document_id'
# 'context': 'Elon Musk PROFILEElon MuskCEO, Tesla$221.9BReal Time Net Worth ...',
# 'metadata': {
# 'source': 'https://www.forbes.com/profile/elon-musk',
# 'document_id': 'some_document_id',
# 'score': 0.404,
# }
# },
# {
# 'context': 'company, which is now called X.Wealth HistoryHOVER TO REVEAL NET WORTH BY YEARForbes Lists 1Forbes 400 (2023)The Richest Person In Every State (2023) 2Billionaires (2023) 1Innovative Leaders (2019) 25Powerful People (2018) 12Richest In Tech (2017)Global Game Changers (2016)More ListsPersonal StatsAge52Source of WealthTesla, SpaceX, Self MadeSelf-Made Score8Philanthropy Score1ResidenceAustin, TexasCitizenshipUnited StatesMarital StatusSingleChildren11EducationBachelor of Arts/Science, University',
# 'source': 'https://www.forbes.com/profile/elon-musk',
# 'document_id': 'some_document_id'
# 'context': 'company, which is now called X.Wealth HistoryHOVER TO REVEAL NET WORTH ...',
# 'metadata': {
# 'source': 'https://www.forbes.com/profile/elon-musk',
# 'document_id': 'some_document_id',
# 'score': 0.435,
# }
# }
# ]
```
+1 -1
View File
@@ -5,7 +5,7 @@ title: "🐝 Beehiiv"
To add any Beehiiv data sources to your app, just add the base url as the source and set the data_type to `beehiiv`.
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
+19 -10
View File
@@ -2,18 +2,27 @@
title: '📊 CSV'
---
To add any csv file, use the data_type as `csv`. `csv` allows remote urls and conventional file paths. Headers are included for each line, so if you have an `age` column, `18` will be added as `age: 18`. Eg:
You can load any csv file from your local file system or through a URL. Headers are included for each line, so if you have an `age` column, `18` will be added as `age: 18`.
## Usage
### Load from a local file
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
app.add('https://people.sc.fsu.edu/~jburkardt/data/csv/airtravel.csv', data_type="csv")
# Or add using the local file path
# app.add('/path/to/file.csv', data_type="csv")
app.query("Summarize the air travel data")
# Answer: The air travel data shows the number of flights for the months of July in the years 1958, 1959, and 1960. In July 1958, there were 491 flights, in July 1959 there were 548 flights, and in July 1960 there were 622 flights.
app.add('/path/to/file.csv', data_type='csv')
```
Note: There is a size limit allowed for csv file beyond which it can throw error. This limit is set by the LLMs. Please consider chunking large csv files into smaller csv files.
### Load from URL
```python
from embedchain import App
app = App()
app.add('https://people.sc.fsu.edu/~jburkardt/data/csv/airtravel.csv', data_type="csv")
```
<Note>
There is a size limit allowed for csv file beyond which it can throw error. This limit is set by the LLMs. Please consider chunking large csv files into smaller csv files.
</Note>
+2 -2
View File
@@ -5,7 +5,7 @@ title: '⚙️ Custom'
When we say "custom", we mean that you can customize the loader and chunker to your needs. This is done by passing a custom loader and chunker to the `add` method.
```python
from embedchain import Pipeline as App
from embedchain import App
import your_loader
import your_chunker
@@ -27,7 +27,7 @@ app.add("source", data_type="custom", loader=loader, chunker=chunker)
Example:
```python
from embedchain import Pipeline as App
from embedchain import App
from embedchain.loaders.github import GithubLoader
app = App()
@@ -35,7 +35,7 @@ Default behavior is to create a persistent vector db in the directory **./db**.
Create a local index:
```python
from embedchain import Pipeline as App
from embedchain import App
naval_chat_bot = App()
naval_chat_bot.add("https://www.youtube.com/watch?v=3qHkcs3kG44")
@@ -45,7 +45,7 @@ naval_chat_bot.add("https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Alma
You can reuse the local index with the same code, but without adding new documents:
```python
from embedchain import Pipeline as App
from embedchain import App
naval_chat_bot = App()
print(naval_chat_bot.query("What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?"))
@@ -56,7 +56,7 @@ print(naval_chat_bot.query("What unique capacity does Naval argue humans possess
You can reset the app by simply calling the `reset` method. This will delete the vector database and all other app related files.
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
app.add("https://www.youtube.com/watch?v=3qHkcs3kG44")
+3 -3
View File
@@ -1,5 +1,5 @@
---
title: '📁 Directory'
title: '📁 Directory/Folder'
---
To use an entire directory as data source, just add `data_type` as `directory` and pass in the path of the local directory.
@@ -8,7 +8,7 @@ To use an entire directory as data source, just add `data_type` as `directory` a
```python
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ["OPENAI_API_KEY"] = "sk-xxx"
@@ -23,7 +23,7 @@ print(response)
```python
import os
from embedchain import Pipeline as App
from embedchain import App
from embedchain.loaders.directory_loader import DirectoryLoader
os.environ["OPENAI_API_KEY"] = "sk-xxx"
+1 -1
View File
@@ -12,7 +12,7 @@ To add any Discord channel messages to your app, just add the `channel_id` as th
```python
import os
from embedchain import Pipeline as App
from embedchain import App
# add your discord "BOT" token
os.environ["DISCORD_TOKEN"] = "xxx"
+3 -3
View File
@@ -1,14 +1,14 @@
---
title: '📚 Code documentation'
title: '📚 Code Docs website'
---
To add any code documentation website as a loader, use the data_type as `docs_site`. Eg:
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
app.add("https://docs.embedchain.ai/", data_type="docs_site")
app.query("What is Embedchain?")
# Answer: Embedchain is a platform that utilizes various components, including paid/proprietary ones, to provide what is believed to be the best configuration available. It uses LLM (Language Model) providers such as OpenAI, Anthpropic, Vertex_AI, GPT4ALL, Azure_OpenAI, LLAMA2, JINA, and COHERE. Embedchain allows users to import and utilize these LLM providers for their applications.'
# Answer: Embedchain is a platform that utilizes various components, including paid/proprietary ones, to provide what is believed to be the best configuration available. It uses LLM (Language Model) providers such as OpenAI, Anthpropic, Vertex_AI, GPT4ALL, Azure_OpenAI, LLAMA2, JINA, Ollama, Together and COHERE. Embedchain allows users to import and utilize these LLM providers for their applications.'
```
+1 -1
View File
@@ -7,7 +7,7 @@ title: '📄 Docx file'
To add any doc/docx file, use the data_type as `docx`. `docx` allows remote urls and conventional file paths. Eg:
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
app.add('https://example.com/content/intro.docx', data_type="docx")
+27
View File
@@ -0,0 +1,27 @@
---
title: '💾 Dropbox'
---
To load folders or files from your Dropbox account, configure the `data_type` parameter as `dropbox` and specify the path to the desired file or folder, starting from the root directory of your Dropbox account.
For Dropbox access, an **access token** is required. Obtain this token by visiting [Dropbox Developer Apps](https://www.dropbox.com/developers/apps). There, create a new app and generate an access token for it.
Ensure your app has the following settings activated:
- In the Permissions section, enable `files.content.read` and `files.metadata.read`.
```python
import os
from embedchain import Pipeline as App
os.environ["DROPBOX_ACCESS_TOKEN"] = "sl.xxx"
os.environ["OPENAI_API_KEY"] = "sk-xxx"
app = App()
# any path from the root of your dropbox account, you can leave it "" for the root folder
app.add("/test", data_type="dropbox")
print(app.query("Which two celebrities are mentioned here?"))
# The two celebrities mentioned in the given context are Elon Musk and Jeff Bezos.
```
+1 -1
View File
@@ -24,7 +24,7 @@ To use this you need to save `credentials.json` in the directory from where you
12. Put the `.json` file in your current directory and rename it to `credentials.json`
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
@@ -0,0 +1,28 @@
---
title: 'Google Drive'
---
To use GoogleDriveLoader you must install the extra dependencies with `pip install --upgrade embedchain[googledrive]`.
The data_type must be `google_drive`. Otherwise, it will be considered a regular web page.
Google Drive requires the setup of credentials. This can be done by following the steps below:
1. Go to the [Google Cloud Console](https://console.cloud.google.com/apis/credentials).
2. Create a project if you don't have one already.
3. Enable the [Google Drive API](https://console.cloud.google.com/flows/enableapi?apiid=drive.googleapis.com)
4. [Authorize credentials for desktop app](https://developers.google.com/drive/api/quickstart/python#authorize_credentials_for_a_desktop_application)
5. When done, you will be able to download the credentials in `json` format. Rename the downloaded file to `credentials.json` and save it in `~/.credentials/credentials.json`
6. Set the environment variable `GOOGLE_APPLICATION_CREDENTIALS=~/.credentials/credentials.json`
The first time you use the loader, you will be prompted to enter your Google account credentials.
```python
from embedchain import Pipeline as App
app = App()
url = "https://drive.google.com/drive/u/0/folders/xxx-xxx"
app.add(url, data_type="google_drive")
```
+45
View File
@@ -0,0 +1,45 @@
---
title: "🖼️ Image"
---
To use an image as data source, just add `data_type` as `image` and pass in the path of the image (local or hosted).
We use [GPT4 Vision](https://platform.openai.com/docs/guides/vision) to generate meaning of the image using a custom prompt, and then use the generated text as the data source.
You would require an OpenAI API key with access to `gpt-4-vision-preview` model to use this feature.
### Without customization
```python
import os
from embedchain import App
os.environ["OPENAI_API_KEY"] = "sk-xxx"
app = App()
app.add("./Elon-Musk.webp", data_type="image")
response = app.query("Describe the man in the image.")
print(response)
# Answer: The man in the image is dressed in formal attire, wearing a dark suit jacket and a white collared shirt. He has short hair and is standing. He appears to be gazing off to the side with a reflective expression. The background is dark with faint, warm-toned vertical lines, possibly from a lit environment behind the individual or reflections. The overall atmosphere is somewhat moody and introspective.
```
### Customization
```python
import os
from embedchain import App
from embedchain.loaders.image import ImageLoader
image_loader = ImageLoader(
max_tokens=100,
api_key="sk-xxx",
prompt="Is the person looking wealthy? Structure your thoughts around what you see in the image.",
)
app = App()
app.add("./Elon-Musk.webp", data_type="image", loader=image_loader)
response = app.query("Describe the man in the image.")
print(response)
# Answer: The man in the image appears to be well-dressed in a suit and shirt, suggesting that he may be in a professional or formal setting. His composed demeanor and confident posture further indicate a sense of self-assurance. Based on these visual cues, one could infer that the man may have a certain level of economic or social status, possibly indicating wealth or professional success.
```
+1 -1
View File
@@ -21,7 +21,7 @@ If you would like to add other data structures (e.g. list, dict etc.), convert i
<CodeGroup>
```python python
from embedchain import Pipeline as App
from embedchain import App
app = App()
+1 -1
View File
@@ -5,7 +5,7 @@ title: '📝 Mdx file'
To add any `.mdx` file to your app, use the data_type (first argument to `.add()` method) as `mdx`. Note that this supports support mdx file present on machine, so this should be a file path. Eg:
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
app.add('path/to/file.mdx', data_type='mdx')
+1 -1
View File
@@ -8,7 +8,7 @@ To load a notion page, use the data_type as `notion`. Since it is hard to automa
The next argument must **end** with the `notion page id`. The id is a 32-character string. Eg:
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
+1 -1
View File
@@ -5,7 +5,7 @@ title: 🙌 OpenAPI
To add any OpenAPI spec yaml file (currently the json file will be detected as JSON data type), use the data_type as 'openapi'. 'openapi' allows remote urls and conventional file paths.
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
+12 -9
View File
@@ -8,28 +8,31 @@ Embedchain comes with built-in support for various data sources. We handle the c
<Card title="📰 PDF file" href="/components/data-sources/pdf-file"></Card>
<Card title="📊 CSV file" href="/components/data-sources/csv"></Card>
<Card title="📃 JSON file" href="/components/data-sources/json"></Card>
<Card title="📺 Youtube" href="/components/data-sources/youtube-video"></Card>
<Card title="📝 Text" href="/components/data-sources/text"></Card>
<Card title="📚 Documentation website" href="/components/data-sources/docs-site"></Card>
<Card title="📄 DOCX file" href="/components/data-sources/docx"></Card>
<Card title="📁 Directory/ Folder" href="/components/data-sources/directory"></Card>
<Card title="🌐 HTML Web page" href="/components/data-sources/web-page"></Card>
<Card title="📽️ Youtube Channel" href="/components/data-sources/youtube-channel"></Card>
<Card title="📺 Youtube Video" href="/components/data-sources/youtube-video"></Card>
<Card title="📚 Docs website" href="/components/data-sources/docs-site"></Card>
<Card title="📝 MDX file" href="/components/data-sources/mdx"></Card>
<Card title="📄 DOCX file" href="/components/data-sources/docx"></Card>
<Card title="📓 Notion" href="/components/data-sources/notion"></Card>
<Card title="❓💬 Q&A pair" href="/components/data-sources/qna"></Card>
<Card title="🗺️ Sitemap" href="/components/data-sources/sitemap"></Card>
<Card title="🌐 Web page" href="/components/data-sources/web-page"></Card>
<Card title="🧾 XML file" href="/components/data-sources/xml"></Card>
<Card title="❓💬 Q&A pair" href="/components/data-sources/qna"></Card>
<Card title="🙌 OpenAPI" href="/components/data-sources/openapi"></Card>
<Card title="📬 Gmail" href="/components/data-sources/gmail"></Card>
<Card title="📝 Github" href="/components/data-sources/github"></Card>
<Card title="🐘 Postgres" href="/components/data-sources/postgres"></Card>
<Card title="🐬 MySQL" href="/components/data-sources/mysql"></Card>
<Card title="🤖 Slack" href="/components/data-sources/slack"></Card>
<Card title="🗨️ Discourse" href="/components/data-sources/discourse"></Card>
<Card title="💬 Discord" href="/components/data-sources/discord"></Card>
<Card title="📝 Github" href="/components/data-sources/github"></Card>
<Card title="⚙️ Custom" href="/components/data-sources/custom"></Card>
<Card title="🗨️ Discourse" href="/components/data-sources/discourse"></Card>
<Card title="📝 Substack" href="/components/data-sources/substack"></Card>
<Card title="🐝 Beehiiv" href="/components/data-sources/beehiiv"></Card>
<Card title="📁 Directory" href="/components/data-sources/directory"></Card>
<Card title="💾 Dropbox" href="/components/data-sources/dropbox"></Card>
<Card title="🖼️ Image" href="/components/data-sources/image"></Card>
<Card title="⚙️ Custom" href="/components/data-sources/custom"></Card>
</CardGroup>
<br/ >
+43 -10
View File
@@ -1,17 +1,50 @@
---
title: '📰 PDF file'
title: '📰 PDF'
---
To add any pdf file, use the data_type as `pdf_file`. Eg:
You can load any pdf file from your local file system or through a URL.
```python
from embedchain import Pipeline as App
## Setup
Install the following packages for loading youtube videos which help in transcription.
app = App()
app.add('https://arxiv.org/pdf/1706.03762.pdf', data_type='pdf_file')
app.query("What is the paper 'attention is all you need' about?")
# Answer: The paper "Attention Is All You Need" proposes a new network architecture called the Transformer, which is based solely on attention mechanisms. It suggests moving away from complex recurrent or convolutional neural networks and instead using attention mechanisms to connect the encoder and decoder in sequence transduction models.
```bash
pip install pytube youtube-transcript-api
```
Note that we do not support password protected pdfs.
## Usage
### Load from a local file
```python
from embedchain import App
app = App()
app.add('/path/to/file.pdf', data_type='pdf_file')
```
### Load from URL
```python
from embedchain import App
app = App()
app.add('https://arxiv.org/pdf/1706.03762.pdf', data_type='pdf_file')
app.query("What is the paper 'attention is all you need' about?", citations=True)
# Answer: The paper "Attention Is All You Need" proposes a new network architecture called the Transformer, which is based solely on attention mechanisms. It suggests that complex recurrent or convolutional neural networks can be replaced with a simpler architecture that connects the encoder and decoder through attention. The paper discusses how this approach can improve sequence transduction models, such as neural machine translation.
# Contexts:
# [
# (
# 'Provided proper attribution is ...',
# {
# 'page': 0,
# 'url': 'https://arxiv.org/pdf/1706.03762.pdf',
# 'score': 0.3676220203221626,
# ...
# }
# ),
# ]
```
We also store the page number under the key `page` with each chunk that helps understand where the answer is coming from. You can fetch the `page` key while during retrieval (refer to the example given above).
<Note>
Note that we do not support password protected pdf files.
</Note>
+1 -1
View File
@@ -5,7 +5,7 @@ title: '❓💬 Queston and answer pair'
QnA pair is a local data type. To supply your own QnA pair, use the data_type as `qna_pair` and enter a tuple. Eg:
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
+1 -1
View File
@@ -5,7 +5,7 @@ title: '🗺️ Sitemap'
Add all web pages from an xml-sitemap. Filters non-text files. Use the data_type as `sitemap`. Eg:
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
+1 -1
View File
@@ -16,7 +16,7 @@ This will automatically retrieve data from the workspace associated with the use
```python
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ["SLACK_USER_TOKEN"] = "xoxp-xxx"
app = App()
+1 -1
View File
@@ -5,7 +5,7 @@ title: "📝 Substack"
To add any Substack data sources to your app, just add the main base url as the source and set the data_type to `substack`.
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
+1 -1
View File
@@ -7,7 +7,7 @@ title: '📝 Text'
Text is a local data type. To supply your own text, use the data_type as `text` and enter a string. The text is not processed, this can be very versatile. Eg:
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
+2 -2
View File
@@ -1,11 +1,11 @@
---
title: '🌐 Web page'
title: '🌐 HTML Web page'
---
To add any web page, use the data_type as `web_page`. Eg:
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
+1 -1
View File
@@ -7,7 +7,7 @@ title: '🧾 XML file'
To add any xml file, use the data_type as `xml`. Eg:
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
@@ -0,0 +1,20 @@
---
title: '📽️ Youtube Channel'
---
To add all the videos from a youtube channel to your app, use the data_type as `youtube_channel`.
<Note>
Make sure you have all the required packages installed before using this data type. You can install them by running the following command in your terminal.
```bash
pip install -u "embedchain[youtube]"
```
</Note>
```python
from embedchain import App
app = App()
app.add("@channel_name", data_type="youtube_channel")
```
@@ -1,12 +1,11 @@
---
title: '📺 Youtube'
title: '📺 Youtube Video'
---
To add any youtube video to your app, use the data_type (first argument to `.add()` method) as `youtube_video`. Eg:
To add any youtube video to your app, use the data_type as `youtube_video`. Eg:
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
app.add('a_valid_youtube_url_here', data_type='youtube_video')
+6 -6
View File
@@ -25,7 +25,7 @@ Once you have obtained the key, you can use it like this:
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ['OPENAI_API_KEY'] = 'xxx'
@@ -52,7 +52,7 @@ To use Google AI embedding function, you have to set the `GOOGLE_API_KEY` enviro
<CodeGroup>
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ["GOOGLE_API_KEY"] = "xxx"
@@ -81,7 +81,7 @@ To use Azure OpenAI embedding model, you have to set some of the azure openai re
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ["OPENAI_API_TYPE"] = "azure"
os.environ["AZURE_OPENAI_ENDPOINT"] = "https://xxx.openai.azure.com/"
@@ -119,7 +119,7 @@ GPT4All supports generating high quality embeddings of arbitrary length document
<CodeGroup>
```python main.py
from embedchain import Pipeline as App
from embedchain import App
# load embedding model configuration from config.yaml file
app = App.from_config(config_path="config.yaml")
@@ -148,7 +148,7 @@ Hugging Face supports generating embeddings of arbitrary length documents of tex
<CodeGroup>
```python main.py
from embedchain import Pipeline as App
from embedchain import App
# load embedding model configuration from config.yaml file
app = App.from_config(config_path="config.yaml")
@@ -179,7 +179,7 @@ Embedchain supports Google's VertexAI embeddings model through a simple interfac
<CodeGroup>
```python main.py
from embedchain import Pipeline as App
from embedchain import App
# load embedding model configuration from config.yaml file
app = App.from_config(config_path="config.yaml")
+12
View File
@@ -0,0 +1,12 @@
---
title: 🧩 Introduction
---
## Overview
You can configure following components
* [Data Source](/components/data-sources/overview)
* [LLM](/components/llms)
* [Embedding Model](/components/embedding-models)
* [Vector Database](/components/vector-databases)
+151 -14
View File
@@ -12,6 +12,9 @@ Embedchain comes with built-in support for various popular large language models
<Card title="Azure OpenAI" href="#azure-openai"></Card>
<Card title="Anthropic" href="#anthropic"></Card>
<Card title="Cohere" href="#cohere"></Card>
<Card title="Together" href="#together"></Card>
<Card title="Ollama" href="#ollama"></Card>
<Card title="vLLM" href="#vllm"></Card>
<Card title="GPT4All" href="#gpt4all"></Card>
<Card title="JinaChat" href="#jinachat"></Card>
<Card title="Hugging Face" href="#hugging-face"></Card>
@@ -27,7 +30,7 @@ Once you have obtained the key, you can use it like this:
```python
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ['OPENAI_API_KEY'] = 'xxx'
@@ -42,7 +45,7 @@ If you are looking to configure the different parameters of the LLM, you can do
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ['OPENAI_API_KEY'] = 'xxx'
@@ -69,7 +72,7 @@ Examples:
<Accordion title="Using Pydantic Models">
```python
import os
from embedchain import Pipeline as App
from embedchain import App
from embedchain.llm.openai import OpenAILlm
import requests
from pydantic import BaseModel, Field, ValidationError, field_validator
@@ -121,7 +124,7 @@ print(result)
<Accordion title="Using OpenAI JSON schema">
```python
import os
from embedchain import Pipeline as App
from embedchain import App
from embedchain.llm.openai import OpenAILlm
import requests
from pydantic import BaseModel, Field, ValidationError, field_validator
@@ -156,7 +159,7 @@ print(result)
<Accordion title="Using actual python functions">
```python
import os
from embedchain import Pipeline as App
from embedchain import App
from embedchain.llm.openai import OpenAILlm
import requests
from pydantic import BaseModel, Field, ValidationError, field_validator
@@ -190,7 +193,7 @@ To use Google AI model, you have to set the `GOOGLE_API_KEY` environment variabl
<CodeGroup>
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ["GOOGLE_API_KEY"] = "xxx"
@@ -233,7 +236,7 @@ To use Azure OpenAI model, you have to set some of the azure openai related envi
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ["OPENAI_API_TYPE"] = "azure"
os.environ["OPENAI_API_BASE"] = "https://xxx.openai.azure.com/"
@@ -272,7 +275,7 @@ To use anthropic's model, please set the `ANTHROPIC_API_KEY` which you find on t
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ["ANTHROPIC_API_KEY"] = "xxx"
@@ -309,7 +312,7 @@ Once you have the API key, you are all set to use it with Embedchain.
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ["COHERE_API_KEY"] = "xxx"
@@ -329,6 +332,97 @@ llm:
</CodeGroup>
## Together
Install related dependencies using the following command:
```bash
pip install --upgrade 'embedchain[together]'
```
Set the `TOGETHER_API_KEY` as environment variable which you can find on their [Account settings page](https://api.together.xyz/settings/api-keys).
Once you have the API key, you are all set to use it with Embedchain.
<CodeGroup>
```python main.py
import os
from embedchain import App
os.environ["TOGETHER_API_KEY"] = "xxx"
# load llm configuration from config.yaml file
app = App.from_config(config_path="config.yaml")
```
```yaml config.yaml
llm:
provider: together
config:
model: togethercomputer/RedPajama-INCITE-7B-Base
temperature: 0.5
max_tokens: 1000
top_p: 1
```
</CodeGroup>
## Ollama
Setup Ollama using https://github.com/jmorganca/ollama
<CodeGroup>
```python main.py
import os
from embedchain import App
# load llm configuration from config.yaml file
app = App.from_config(config_path="config.yaml")
```
```yaml config.yaml
llm:
provider: ollama
config:
model: 'llama2'
temperature: 0.5
top_p: 1
stream: true
```
</CodeGroup>
## vLLM
Setup vLLM by following instructions given in [their docs](https://docs.vllm.ai/en/latest/getting_started/installation.html).
<CodeGroup>
```python main.py
import os
from embedchain import App
# load llm configuration from config.yaml file
app = App.from_config(config_path="config.yaml")
```
```yaml config.yaml
llm:
provider: vllm
config:
model: 'meta-llama/Llama-2-70b-hf'
temperature: 0.5
top_p: 1
top_k: 10
stream: true
trust_remote_code: true
```
</CodeGroup>
## GPT4ALL
Install related dependencies using the following command:
@@ -342,7 +436,7 @@ GPT4all is a free-to-use, locally running, privacy-aware chatbot. No GPU or inte
<CodeGroup>
```python main.py
from embedchain import Pipeline as App
from embedchain import App
# load llm configuration from config.yaml file
app = App.from_config(config_path="config.yaml")
@@ -374,7 +468,7 @@ Once you have the key, load the app using the config yaml file:
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ["JINACHAT_API_KEY"] = "xxx"
# load llm configuration from config.yaml file
@@ -410,7 +504,7 @@ Once you have the token, load the app using the config yaml file:
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ["HUGGINGFACE_ACCESS_TOKEN"] = "xxx"
@@ -430,6 +524,49 @@ llm:
```
</CodeGroup>
### Custom Endpoints
You can also use [Hugging Face Inference Endpoints](https://huggingface.co/docs/inference-endpoints/index#-inference-endpoints) to access custom endpoints. First, set the `HUGGINGFACE_ACCESS_TOKEN` as above.
Then, load the app using the config yaml file:
<CodeGroup>
```python main.py
import os
from embedchain import App
os.environ["HUGGINGFACE_ACCESS_TOKEN"] = "xxx"
# load llm configuration from config.yaml file
app = App.from_config(config_path="config.yaml")
```
```yaml config.yaml
llm:
provider: huggingface
config:
endpoint: https://api-inference.huggingface.co/models/gpt2 # replace with your personal endpoint
```
</CodeGroup>
If your endpoint requires additional parameters, you can pass them in the `model_kwargs` field:
```
llm:
provider: huggingface
config:
endpoint: <YOUR_ENDPOINT_URL_HERE>
model_kwargs:
max_new_tokens: 100
temperature: 0.5
```
Currently only supports `text-generation` and `text2text-generation` for now [[ref](https://api.python.langchain.com/en/latest/llms/langchain_community.llms.huggingface_endpoint.HuggingFaceEndpoint.html?highlight=huggingfaceendpoint#)].
See langchain's [hugging face endpoint](https://python.langchain.com/docs/integrations/chat/huggingface#huggingfaceendpoint) for more information.
## Llama2
Llama2 is integrated through [Replicate](https://replicate.com/). Set `REPLICATE_API_TOKEN` in environment variable which you can obtain from [their platform](https://replicate.com/account/api-tokens).
@@ -440,7 +577,7 @@ Once you have the token, load the app using the config yaml file:
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ["REPLICATE_API_TOKEN"] = "xxx"
@@ -467,7 +604,7 @@ Setup Google Cloud Platform application credentials by following the instruction
<CodeGroup>
```python main.py
from embedchain import Pipeline as App
from embedchain import App
# load llm configuration from config.yaml file
app = App.from_config(config_path="config.yaml")
+7 -7
View File
@@ -22,7 +22,7 @@ Utilizing a vector database alongside Embedchain is a seamless process. All you
<CodeGroup>
```python main.py
from embedchain import Pipeline as App
from embedchain import App
# load chroma configuration from yaml file
app = App.from_config(config_path="config1.yaml")
@@ -67,7 +67,7 @@ You can authorize the connection to Elasticsearch by providing either `basic_aut
<CodeGroup>
```python main.py
from embedchain import Pipeline as App
from embedchain import App
# load elasticsearch configuration from yaml file
app = App.from_config(config_path="config.yaml")
@@ -97,7 +97,7 @@ pip install --upgrade 'embedchain[opensearch]'
<CodeGroup>
```python main.py
from embedchain import Pipeline as App
from embedchain import App
# load opensearch configuration from yaml file
app = App.from_config(config_path="config.yaml")
@@ -133,7 +133,7 @@ Set the Zilliz environment variables `ZILLIZ_CLOUD_URI` and `ZILLIZ_CLOUD_TOKEN`
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ['ZILLIZ_CLOUD_URI'] = 'https://xxx.zillizcloud.com'
os.environ['ZILLIZ_CLOUD_TOKEN'] = 'xxx'
@@ -172,7 +172,7 @@ In order to use Pinecone as vector database, set the environment variables `PINE
<CodeGroup>
```python main.py
from embedchain import Pipeline as App
from embedchain import App
# load pinecone configuration from yaml file
app = App.from_config(config_path="config.yaml")
@@ -195,7 +195,7 @@ In order to use Qdrant as a vector database, set the environment variables `QDRA
<CodeGroup>
```python main.py
from embedchain import Pipeline as App
from embedchain import App
# load qdrant configuration from yaml file
app = App.from_config(config_path="config.yaml")
@@ -215,7 +215,7 @@ In order to use Weaviate as a vector database, set the environment variables `WE
<CodeGroup>
```python main.py
from embedchain import Pipeline as App
from embedchain import App
# load weaviate configuration from yaml file
app = App.from_config(config_path="config.yaml")
+2 -2
View File
@@ -27,7 +27,7 @@ make lint format
### Authors
- Taranjeet Singh ([@taranjeetio](https://twitter.com/taranjeetio))
- Deshraj Yadav ([@deshrajdry](https://twitter.com/taranjeetio))
- Deshraj Yadav ([@deshrajdry](https://twitter.com/deshrajdry))
### Citation
@@ -36,7 +36,7 @@ If you utilize this repository, please consider citing it with:
```
@misc{embedchain,
author = {Taranjeet Singh, Deshraj Yadav},
title = {Embechain: Data platform for LLMs - Load, index, retrieve and sync any unstructured data},
title = {Embechain: The Open Source RAG Framework},
year = {2023},
publisher = {GitHub},
journal = {GitHub repository},
+38
View File
@@ -0,0 +1,38 @@
---
title: 'Embedchain.ai'
description: 'Deploy your RAG application to embedchain.ai platform'
---
## Deploy on Embedchain Platform
Embedchain enables developers to deploy their LLM-powered apps in production using the [Embedchain platform](https://app.embedchain.ai). The platform offers free access to context on your data through its REST API. Once the pipeline is deployed, you can update your data sources anytime after deployment.
See the example below on how to use the deploy your app (for free):
```python
from embedchain import App
# Initialize app
app = App()
# Add data source
app.add("https://www.forbes.com/profile/elon-musk")
# Deploy your pipeline to Embedchain Platform
app.deploy()
# 🔑 Enter your Embedchain API key. You can find the API key at https://app.embedchain.ai/settings/keys/
# ec-xxxxxx
# 🛠️ Creating pipeline on the platform...
# 🎉🎉🎉 Pipeline created successfully! View your pipeline: https://app.embedchain.ai/pipelines/xxxxx
# 🛠️ Adding data to your pipeline...
# ✅ Data of type: web_page, value: https://www.forbes.com/profile/elon-musk added successfully.
```
## Seeking help?
If you run into issues with deployment, please feel free to reach out to us via any of the following methods:
<Snippet file="get-help.mdx" />
+59
View File
@@ -0,0 +1,59 @@
---
title: 'Gradio.app'
description: 'Deploy your RAG application to gradio.app platform'
---
Embedchain offers a Streamlit template to facilitate the development of RAG chatbot applications in just three easy steps.
Follow the instructions given below to deploy your first application quickly:
## Step-1: Create RAG app
We provide a command line utility called `ec` in embedchain that inherits the template for `gradio.app` platform and help you deploy the app. Follow the instructions to create a gradio.app app using the template provided:
```bash Install embedchain
pip install embedchain
```
```bash Create application
mkdir my-rag-app
ec create --template=gradio.app
```
This will generate a directory structure like this:
```bash
├── app.py
├── embedchain.json
└── requirements.txt
```
Feel free to edit the files as required.
- `app.py`: Contains API app code
- `embedchain.json`: Contains embedchain specific configuration for deployment (you don't need to configure this)
- `requirements.txt`: Contains python dependencies for your application
## Step-2: Test app locally
You can run the app locally by simply doing:
```bash Run locally
pip install -r requirements.txt
ec dev
```
## Step-3: Deploy to gradio.app
```bash Deploy to gradio.app
ec deploy
```
This will run `gradio deploy` which will prompt you questions and deploy your app directly to huggingface spaces.
<img src="/images/gradio_app.png" alt="gradio app" />
## Seeking help?
If you run into issues with deployment, please feel free to reach out to us via any of the following methods:
<Snippet file="get-help.mdx" />
+103
View File
@@ -0,0 +1,103 @@
---
title: 'Huggingface.co'
description: 'Deploy your RAG application to huggingface.co platform'
---
With Embedchain, you can directly host your apps in just three steps to huggingface spaces where you can view and deploy your app to the world.
We support two types of deployment to huggingface spaces:
<CardGroup cols={2}>
<Card title="" href="#using-streamlit-io">
Streamlit.io
</Card>
<Card title="" href="#using-gradio-app">
Gradio.app
</Card>
</CardGroup>
## Using streamlit.io
### Step 1: Create a new RAG app
Create a new RAG app using the following command:
```bash
mkdir my-rag-app
ec create --template=hf/streamlit.io # inside my-rag-app directory
```
When you run this for the first time, you'll be asked to login to huggingface.co. Once you login, you'll need to create a **write** token. You can create a write token by going to [huggingface.co settings](https://huggingface.co/settings/token). Once you create a token, you'll be asked to enter the token in the terminal.
This will also create an `embedchain.json` file in your app directory. Add a `name` key into the `embedchain.json` file. This will be the "repo-name" of your app in huggingface spaces.
```json embedchain.json
{
"name": "my-rag-app",
"provider": "hf/streamlit.io"
}
```
### Step-2: Test app locally
You can run the app locally by simply doing:
```bash Run locally
pip install -r requirements.txt
ec dev
```
### Step-3: Deploy to huggingface spaces
```bash Deploy to huggingface spaces
ec deploy
```
This will deploy your app to huggingface spaces. You can view your app at `https://huggingface.co/spaces/<your-username>/my-rag-app`. This will get prompted in the terminal once the app is deployed.
## Using gradio.app
Similar to streamlit.io, you can deploy your app to gradio.app in just three steps.
### Step 1: Create a new RAG app
Create a new RAG app using the following command:
```bash
mkdir my-rag-app
ec create --template=hf/gradio.app # inside my-rag-app directory
```
When you run this for the first time, you'll be asked to login to huggingface.co. Once you login, you'll need to create a **write** token. You can create a write token by going to [huggingface.co settings](https://huggingface.co/settings/token). Once you create a token, you'll be asked to enter the token in the terminal.
This will also create an `embedchain.json` file in your app directory. Add a `name` key into the `embedchain.json` file. This will be the "repo-name" of your app in huggingface spaces.
```json embedchain.json
{
"name": "my-rag-app",
"provider": "hf/gradio.app"
}
```
### Step-2: Test app locally
You can run the app locally by simply doing:
```bash Run locally
pip install -r requirements.txt
ec dev
```
### Step-3: Deploy to huggingface spaces
```bash Deploy to huggingface spaces
ec deploy
```
This will deploy your app to huggingface spaces. You can view your app at `https://huggingface.co/spaces/<your-username>/my-rag-app`. This will get prompted in the terminal once the app is deployed.
## Seeking help?
If you run into issues with deployment, please feel free to reach out to us via any of the following methods:
<Snippet file="get-help.mdx" />
+32
View File
@@ -0,0 +1,32 @@
### Embedchain Chat with PDF App
You can easily create and deploy your own `chat-pdf` App using Embedchain.
Here are few simple steps for you to create and deploy your app:
1. Fork the embedchain repo from [Github](https://github.com/embedchain/embedchain).
<Note>
If you run into problems with forking, please refer to [github docs](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo) for forking a repo.
</Note>
2. Navigate to `chat-pdf` example app from your forked repo:
```bash
cd <your_fork_repo>/examples/chat-pdf
```
3. Run your app in development environment with simple commands
```bash
pip install -r requirements.txt
ec dev
```
Feel free to improve our simple `chat-pdf` streamlit app and create pull request to showcase your app [here](https://docs.embedchain.ai/examples/showcase)
4. You can easily deploy your app using Streamlit interface
Connect your Github account with Streamlit and refer this [guide](https://docs.streamlit.io/streamlit-community-cloud/deploy-your-app) to deploy your app.
You can also use the deploy button from your streamlit website you see when running `ec dev` command.
+124
View File
@@ -0,0 +1,124 @@
Fork the Embedchain repo on [Github](https://github.com/embedchain/embedchain) to create your own NextJS discord and slack bot powered by Embedchain.
If you run into problems with forking, please refer to [github docs](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo) for forking a repo.
We will work from the `examples/nextjs` folder so change your current working directory by running the command - `cd <your_forked_repo>/examples/nextjs`
# Installation
First, lets start by install all the required packages and dependencies.
- Install all the required python packages by running ```pip install -r requirements.txt```
- We will use [Fly.io](https://fly.io/) to deploy our embedchain app, discord and slack bot. Follow the step one to install [Fly.io CLI](https://docs.embedchain.ai/deployment/fly_io#step-1-install-flyctl-command-line)
# Developement
## Embedchain App
First, we need an Embedchain app powered with the knowledge of NextJS. We have already created an embedchain app using FastAPI in `ec_app` folder for you. Feel free to ingest data of your choice to power the App.
<Note>
Navigate to `ec_app` folder and create `.env` file in this folder and set your OpenAI API key as shown in `.env.example` file. If you want to use other open-source models, feel free to use the app config in `app.py`. More details for using custom configuration for Embedchain app is [available here](https://docs.embedchain.ai/api-reference/advanced/configuration).
</Note>
Before running the ec commands to develope the app, open `fly.toml` file and update the `name` variable to something unique. This is important as `fly.io` requires users to provide a globally unique deployment app names.
Now, we need to launch this application with fly.io. You can see your app on [fly.io dashboard](https://fly.io/dashboard). Run the following command to launch your app on fly.io:
```bash
fly launch --no-deploy
```
To run the app in development, run the following command:
```bash
ec dev
```
Run `ec deploy` to deploy your app on Fly.io. Once you deploy your app, save the endpoint on which our discord and slack bot will send requests.
## Discord bot
For discord bot, you will need to create the bot on discord developer portal and get the discord bot token and your discord bot name.
While keeping in mind the following note, create the discord bot by following the instructions from our [discord bot docs](https://docs.embedchain.ai/examples/discord_bot) and get discord bot token.
<Note>
You do not need to set `OPENAI_API_KEY` to run this discord bot. Follow the remaining instructions to create a discord bot app. We recommend you to give the following sets of bot permissions to run the discord bot without errors:
```
(General Permissions)
Read Message/View Channels
(Text Permissions)
Send Messages
Create Public Thread
Create Private Thread
Send Messages in Thread
Manage Threads
Embed Links
Read Message History
```
</Note>
Once you have your discord bot token and discord app name. Navigate to `nextjs_discord` folder and create `.env` file and define your discord bot token, discord bot name and endpoint of your embedchain app as shown in `.env.example` file.
To run the app in development:
```bash
python app.py
```
Before deploying the app, open `fly.toml` file and update the `name` variable to something unique. This is important as `fly.io` requires users to provide a globally unique deployment app names.
Now, we need to launch this application with fly.io. You can see your app on [fly.io dashboard](https://fly.io/dashboard). Run the following command to launch your app on fly.io:
```bash
fly launch --no-deploy
```
Run `ec deploy` to deploy your app on Fly.io. Once you deploy your app, your discord bot will be live!
## Slack bot
For Slack bot, you will need to create the bot on slack developer portal and get the slack bot token and slack app token.
### Setup
- Create a workspace on Slack if you don't have one already by clicking [here](https://slack.com/intl/en-in/).
- Create a new App on your Slack account by going [here](https://api.slack.com/apps).
- Select `From Scratch`, then enter the Bot Name and select your workspace.
- Go to `App Credentials` section on the `Basic Information` tab from the left sidebar, create your app token and save it in your `.env` file as `SLACK_APP_TOKEN`.
- Go to `Socket Mode` tab from the left sidebar and enable the socket mode to listen to slack message from your workspace.
- (Optional) Under the `App Home` tab you can change your App display name and default name.
- Navigate to `Event Subscription` tab, and enable the event subscription so that we can listen to slack events.
- Once you enable the event subscription, you will need to subscribe to bot events to authorize the bot to listen to app mention events of the bot. Do that by tapping on `Add Bot User Event` button and select `app_mention`.
- On the left Sidebar, go to `OAuth and Permissions` and add the following scopes under `Bot Token Scopes`:
```text
app_mentions:read
channels:history
channels:read
chat:write
emoji:read
reactions:write
reactions:read
```
- Now select the option `Install to Workspace` and after it's done, copy the `Bot User OAuth Token` and set it in your `.env` file as `SLACK_BOT_TOKEN`.
Once you have your slack bot token and slack app token. Navigate to `nextjs_slack` folder and create `.env` file and define your slack bot token, slack app token and endpoint of your embedchain app as shown in `.env.example` file.
To run the app in development:
```bash
python app.py
```
Before deploying the app, open `fly.toml` file and update the `name` variable to something unique. This is important as `fly.io` requires users to provide a globally unique deployment app names.
Now, we need to launch this application with fly.io. You can see your app on [fly.io dashboard](https://fly.io/dashboard). Run the following command to launch your app on fly.io:
```bash
fly launch --no-deploy
```
Run `ec deploy` to deploy your app on Fly.io. Once you deploy your app, your slack bot will be live!
+8
View File
@@ -44,6 +44,14 @@ Get started with Embedchain by trying out the examples below. You can run the ex
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/cohere.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" noZoom alt="Open In Colab"/></a></td>
<td className="align-middle"><a target="_blank" href="https://replit.com/@taranjeetio/cohere#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
<tr>
<td className="align-middle">Together</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/together.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" noZoom alt="Open In Colab"/></a></td>
</tr>
<tr>
<td className="align-middle">Ollama</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/ollama.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" noZoom alt="Open In Colab"/></a></td>
</tr>
<tr>
<td className="align-middle">Hugging Face</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/hugging_face_hub.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" noZoom alt="Open In Colab"/></a></td>
+2 -1
View File
@@ -37,7 +37,7 @@ llm:
max_tokens: 1000
top_p: 1
stream: false
template: |
prompt: |
Use the following pieces of context to answer the query at the end.
If you don't know the answer, just say that you don't know, don't try to make up an answer.
@@ -81,6 +81,7 @@ curl --request POST \
| `OPENAI_API_BASE` | Azure OpenAI |
| `OPENAI_API_VERSION` | Azure OpenAI |
| `COHERE_API_KEY` | Cohere |
| `TOGETHER_API_KEY` | Together |
| `ANTHROPIC_API_KEY` | Anthropic |
| `JINACHAT_API_KEY` | Jina |
| `HUGGINGFACE_ACCESS_TOKEN` | Huggingface |
+67
View File
@@ -0,0 +1,67 @@
[Embedchain Examples Repo](https://github.com/embedchain/examples) contains code on how to build your own Slack AI to chat with the unstructured data lying in your slack channels.
![Slack AI Demo](/images/slack-ai.png)
## Getting started
Create a Slack AI involves 3 steps
* Create slack user
* Set environment variables
* Run the app locally
### Step 1: Create Slack user token
Follow the steps given below to fetch your slack user token to get data through Slack APIs:
1. Create a workspace on Slack if you don’t have one already by clicking [here](https://slack.com/intl/en-in/).
2. Create a new App on your Slack account by going [here](https://api.slack.com/apps).
3. Select `From Scratch`, then enter the App Name and select your workspace.
4. Navigate to `OAuth & Permissions` tab from the left sidebar and go to the `scopes` section. Add the following scopes under `User Token Scopes`:
```
# Following scopes are needed for reading channel history
channels:history
channels:read
# Following scopes are needed to fetch list of channels from slack
groups:read
mpim:read
im:read
```
5. Click on the `Install to Workspace` button under `OAuth Tokens for Your Workspace` section in the same page and install the app in your slack workspace.
6. After installing the app you will see the `User OAuth Token`, save that token as you will need to configure it as `SLACK_USER_TOKEN` for this demo.
### Step 2: Set environment variables
Navigate to `api` folder and set your `HUGGINGFACE_ACCESS_TOKEN` and `SLACK_USER_TOKEN` in `.env.example` file. Then rename the `.env.example` file to `.env`.
<Note>
By default, we use `Mixtral` model from Hugging Face. However, if you prefer to use OpenAI model, then set `OPENAI_API_KEY` instead of `HUGGINGFACE_ACCESS_TOKEN` along with `SLACK_USER_TOKEN` in `.env` file, and update the code in `api/utils/app.py` file to use OpenAI model instead of Hugging Face model.
</Note>
### Step 3: Run app locally
Follow the instructions given below to run app locally based on your development setup (with docker or without docker):
#### With docker
```bash
docker-compose build
ec start --docker
```
#### Without docker
```bash
ec install-reqs
ec start
```
Finally, you will have the Slack AI frontend running on http://localhost:3000. You can also access the REST APIs on http://localhost:8000.
## Credits
This demo was built using the Embedchain's [full stack demo template](https://docs.embedchain.ai/get-started/full-stack). Follow the instructions [given here](https://docs.embedchain.ai/get-started/full-stack) to create your own full stack RAG application.
+3 -43
View File
@@ -10,51 +10,11 @@ After successfully setting up and testing your RAG app locally, the next step is
<Card title="Modal.com" href="/deployment/modal_com"></Card>
<Card title="Render.com" href="/deployment/render_com"></Card>
<Card title="Streamlit.io" href="/deployment/streamlit_io"></Card>
<Card title="Embedchain Platform" href="#option-1-deploy-on-embedchain-platform"></Card>
<Card title="Self-hosting" href="#option-2-self-hosting"></Card>
<Card title="Gradio.app" href="/deployment/gradio_app"></Card>
<Card title="Huggingface.co" href="/deployment/huggingface_spaces"></Card>
<Card title="Embedchain.ai" href="/deployment/embedchain_ai"></Card>
</CardGroup>
## Deploy on Embedchain Platform
Embedchain enables developers to deploy their LLM-powered apps in production using the [Embedchain platform](https://app.embedchain.ai). The platform offers free access to context on your data through its REST API. Once the pipeline is deployed, you can update your data sources anytime after deployment.
See the example below on how to use the deploy your app (for free):
```python
from embedchain import Pipeline as App
# Initialize app
app = App()
# Add data source
app.add("https://www.forbes.com/profile/elon-musk")
# Deploy your pipeline to Embedchain Platform
app.deploy()
# 🔑 Enter your Embedchain API key. You can find the API key at https://app.embedchain.ai/settings/keys/
# ec-xxxxxx
# 🛠️ Creating pipeline on the platform...
# 🎉🎉🎉 Pipeline created successfully! View your pipeline: https://app.embedchain.ai/pipelines/xxxxx
# 🛠️ Adding data to your pipeline...
# ✅ Data of type: web_page, value: https://www.forbes.com/profile/elon-musk added successfully.
```
## Self-hosting
You can also deploy Embedchain as a self-hosted service using the dockerized REST API service that we provide. Please follow the [guide here](/examples/rest-api) on how to use the REST API service. Here are some tutorials on how to deploy a containerized application to different platforms like AWS, GCP, Azure etc:
- [Fly.io](/deployment/fly_io)
- [Render.com](https://render.com/docs/deploy-an-image)
- [Huggingface Spaces](https://huggingface.co/new-space)
- [AWS EKS](https://docs.aws.amazon.com/eks/latest/userguide/sample-deployment.html)
- [AWS ECS](https://docs.aws.amazon.com/codecatalyst/latest/userguide/deploy-tut-ecs.html)
- [Google GKE](https://cloud.google.com/kubernetes-engine/docs/tutorials/hello-app)
- [Azure App Service](https://learn.microsoft.com/en-us/training/modules/deploy-run-container-app-service/)
## Seeking help?
If you run into issues with deployment, please feel free to reach out to us via any of the following methods:
+7 -7
View File
@@ -11,7 +11,7 @@ Use the model provided on huggingface: `mistralai/Mistral-7B-v0.1`
<CodeGroup>
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ["HUGGINGFACE_ACCESS_TOKEN"] = "hf_your_token"
@@ -40,7 +40,7 @@ Use the model `gpt-4-turbo` provided my openai.
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ['OPENAI_API_KEY'] = 'xxx'
@@ -65,7 +65,7 @@ llm:
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ['OPENAI_API_KEY'] = 'xxx'
@@ -90,7 +90,7 @@ llm:
<CodeGroup>
```python main.py
from embedchain import Pipeline as App
from embedchain import App
# load llm configuration from opensource.yaml file
app = App.from_config(config_path="opensource.yaml")
@@ -131,7 +131,7 @@ llm:
```python main.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
@@ -149,7 +149,7 @@ response = app.query("What is the net worth of Elon Musk?")
Set up the app by adding an `id` in the config file. This keeps the data for future use. You can include this `id` in the yaml config or input it directly in `config` dict.
```python app1.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
@@ -167,7 +167,7 @@ response = app.query("What is the net worth of Elon Musk?")
```
```python app2.py
import os
from embedchain import Pipeline as App
from embedchain import App
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
+62
View File
@@ -0,0 +1,62 @@
---
title: '💻 Full stack'
---
Get started with full-stack RAG applications using Embedchain's easy-to-use CLI tool. Set up everything with just a few commands, whether you prefer Docker or not.
## Prerequisites
Choose your setup method:
### Without Docker
Ensure these are installed:
- Embedchain python package (`pip install embedchain`)
- [Node.js](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) and [Yarn](https://classic.yarnpkg.com/lang/en/docs/install/)
### With Docker
Install Docker from [Docker's official website](https://docs.docker.com/engine/install/).
## Quick Start Guide
### Setting Up
For the purpose of the demo, you have to set `OPENAI_API_KEY` to start with but you can choose any llm by changing the configuration easily.
### Installation Commands
<CodeGroup>
```bash without docker
ec create-app my-app
cd my-app
ec start
```
```bash with docker
ec create-app my-app --docker
cd my-app
ec start --docker
```
</CodeGroup>
### What Happens Next?
1. Embedchain fetches a full stack template (FastAPI backend, Next.JS frontend).
2. Installs required components.
3. Launches both frontend and backend servers.
### See It In Action
Open http://localhost:3000 to view the chat UI.
![full stack example](/images/fullstack.png)
### Admin Panel
Check out the Embedchain admin panel to see the document chunks for your RAG application.
![full stack chunks](/images/fullstack-chunks.png)
+71 -73
View File
@@ -1,85 +1,83 @@
---
title: '⚡ Quickstart'
description: '💡 Start building ChatGPT like apps in a minute on your own data'
description: '💡 Create a RAG app on your own data in a minute'
---
Install python package:
## Installation
First install the Python package:
```bash
pip install embedchain
```
Creating an app involves 3 steps:
Once you have installed the package, depending upon your preference you can either use:
<Steps>
<Step title="⚙️ Import app instance">
```python
from embedchain import Pipeline as App
app = App()
```
<Accordion title="Customize your app by a simple YAML config" icon="gear-complex">
Embedchain provides a wide range of options to customize your app. You can customize the model, data sources, and much more.
Explore the custom configurations [here](https://docs.embedchain.ai/advanced/configuration).
<CodeGroup>
```python yaml_app.py
from embedchain import Pipeline as App
app = App.from_config(config_path="config.yaml")
```
```python json_app.py
from embedchain import Pipeline as App
app = App.from_config(config_path="config.json")
```
```python app.py
from embedchain import Pipeline as App
config = {} # Add your config here
app = App.from_config(config=config)
```
</CodeGroup>
</Accordion>
</Step>
<Step title="🗃️ Add data sources">
```python
app.add("https://en.wikipedia.org/wiki/Elon_Musk")
app.add("https://www.forbes.com/profile/elon-musk")
# app.add("path/to/file/elon_musk.pdf")
```
<Accordion title="Embedchain supports adding data from many data sources." icon="files">
Embedchain supports adding data from many data sources including web pages, PDFs, databases, and more.
Explore the list of supported [data sources](https://docs.embedchain.ai/data-sources/overview).
</Accordion>
</Step>
<Step title="💬 Ask questions, chat, or search through your data with ease">
```python
app.query("What is the net worth of Elon Musk today?")
# Answer: The net worth of Elon Musk today is $258.7 billion.
```
<hr />
<Accordion title="Want to chat with your app?" icon="face-thinking">
Embedchain provides a wide range of features to interact with your app. You can chat with your app, ask questions, search through your data, and much more.
```python
app.chat("How many companies does Elon Musk run? Name those")
# Answer: Elon Musk runs 3 companies: Tesla, SpaceX, and Neuralink.
app.chat("What is his net worth today?")
# Answer: The net worth of Elon Musk today is $258.7 billion.
```
To learn about other features, click [here](https://docs.embedchain.ai/get-started/introduction)
</Accordion>
</Step>
<Step title="🚀 Seamlessly launch your App on the Embedchain Platform!">
```python
app.deploy()
# 🔑 Enter your Embedchain API key. You can find the API key at https://app.embedchain.ai/settings/keys/
# ec-xxxxxx
<CardGroup cols={2}>
<Card title="Open Source Models" icon="osi" href="#open-source-models">
This includes Open source LLMs like Mistral, Llama, etc.<br/>
Free to use, and runs locally on your machine.
</Card>
<Card title="Paid Models" icon="dollar-sign" href="#paid-models" color="#4A154B">
This includes paid LLMs like GPT 4, Claude, etc.<br/>
Cost money and are accessible via an API.
</Card>
</CardGroup>
# 🛠️ Creating pipeline on the platform...
# 🎉🎉🎉 Pipeline created successfully! View your pipeline: https://app.embedchain.ai/pipelines/xxxxx
## Open Source Models
# 🛠️ Adding data to your pipeline...
# ✅ Data of type: web_page, value: https://www.forbes.com/profile/elon-musk added successfully.
```
<Accordion title="Share your app with others" icon="laptop-mobile">
You can now share your app with others from our platform.
Access your app on our [platform](https://app.embedchain.ai/).
</Accordion>
</Step>
</Steps>
This section gives a quickstart example of using Mistral as the Open source LLM and Sentence transformers as the Open source embedding model. These models are free and run mostly on your local machine.
We are using Mistral hosted at Hugging Face, so will you need a Hugging Face token to run this example. Its *free* and you can create one [here](https://huggingface.co/docs/hub/security-tokens).
<CodeGroup>
```python quickstart.py
import os
# replace this with your HF key
os.environ["HUGGINGFACE_ACCESS_TOKEN"] = "hf_xxxx"
from embedchain import App
app = App.from_config("mistral.yaml")
app.add("https://www.forbes.com/profile/elon-musk")
app.add("https://en.wikipedia.org/wiki/Elon_Musk")
app.query("What is the net worth of Elon Musk today?")
# Answer: The net worth of Elon Musk today is $258.7 billion.
```
```yaml mistral.yaml
llm:
provider: huggingface
config:
model: 'mistralai/Mistral-7B-v0.1'
top_p: 0.5
embedder:
provider: huggingface
config:
model: 'sentence-transformers/all-mpnet-base-v2'
```
</CodeGroup>
## Paid Models
In this section, we will use both LLM and embedding model from OpenAI.
```python quickstart.py
import os
# replace this with your OpenAI key
os.environ["OPENAI_API_KEY"] = "sk-xxxx"
from embedchain import App
app = App()
app.add("https://www.forbes.com/profile/elon-musk")
app.add("https://en.wikipedia.org/wiki/Elon_Musk")
app.query("What is the net worth of Elon Musk today?")
# Answer: The net worth of Elon Musk today is $258.7 billion.
```
# Next Steps
Now that you have created your first app, you can follow any of the links:
* [Introduction](/get-started/introduction)
* [Customization](/components/introduction)
* [Use cases](/use-cases/introduction)
* [Deployment](/get-started/deployment)
Binary file not shown.

After

Width:  |  Height:  |  Size: 758 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

+1 -1
View File
@@ -21,7 +21,7 @@ Create a new file called `app.py` and add the following code:
```python
import chainlit as cl
from embedchain import Pipeline as App
from embedchain import App
import os
+1 -1
View File
@@ -39,7 +39,7 @@ os.environ['LANGCHAIN_PROJECT] = <your-project>
```python
from embedchain import Pipeline as App
from embedchain import App
app = App()
app.add("https://en.wikipedia.org/wiki/Elon_Musk")
+13 -13
View File
@@ -17,7 +17,7 @@ pip install embedchain streamlit
<Tab title="app.py">
```python
import os
from embedchain import Pipeline as App
from embedchain import App
import streamlit as st
with st.sidebar:
@@ -85,22 +85,22 @@ pip install embedchain streamlit
<Tab title="config.yaml">
```yaml
app:
config:
name: 'mistral-streamlit-app'
config:
name: 'mistral-streamlit-app'
llm:
provider: huggingface
config:
model: 'mistralai/Mixtral-8x7B-Instruct-v0.1'
temperature: 0.1
max_tokens: 250
top_p: 0.1
stream: true
provider: huggingface
config:
model: 'mistralai/Mixtral-8x7B-Instruct-v0.1'
temperature: 0.1
max_tokens: 250
top_p: 0.1
stream: true
embedder:
provider: huggingface
config:
model: 'sentence-transformers/all-mpnet-base-v2'
provider: huggingface
config:
model: 'sentence-transformers/all-mpnet-base-v2'
```
</Tab>
</Tabs>
+10
View File
@@ -0,0 +1,10 @@
<svg width="1371" height="249" viewBox="0 0 1371 249" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M66.248 1V248.8H158.996V210.214H120.41V148.264H158.996V101.89H120.41V39.94H158.996V1H66.248ZM169.655 1V248.8H223.817V124.9L246.827 248.8H262.403L285.767 124.9V248.8H339.929V1H277.979L254.615 148.264L231.251 1H169.655ZM404.661 210.214V148.264H412.449C416.697 148.264 419.883 151.804 419.883 156.052V202.426C419.883 206.674 416.697 210.214 412.449 210.214H404.661ZM443.955 125.254L443.247 124.9C460.239 124.9 474.399 111.094 474.399 94.102V32.152C474.399 15.16 460.239 1 443.247 1H350.499V248.8H443.247C460.239 248.8 474.399 234.994 474.399 218.002V156.052C474.399 139.06 460.947 125.608 443.955 125.254ZM412.449 101.89H404.661V39.94H412.449C416.697 39.94 419.883 43.48 419.883 47.728V94.102C419.883 98.35 416.697 101.89 412.449 101.89ZM577.421 1H484.673V248.8H577.421V210.214H538.835V148.264H577.421V101.89H538.835V39.94H577.421V1ZM642.242 210.214V39.94H649.676C654.278 39.94 657.464 43.48 657.464 47.728V202.426C657.464 206.674 654.278 210.214 649.676 210.214H642.242ZM711.98 218.002V32.152C711.98 15.16 697.82 1 680.828 1H588.08V248.8H680.828C697.82 248.8 711.98 234.994 711.98 218.002ZM88 164.8H70V182.8H88V164.8Z" fill="white"/>
<rect x="17" y="164.8" width="18" height="18" fill="white"/>
<rect y="141.8" width="11" height="18" fill="white"/>
<rect x="26" y="64.7998" width="30" height="30" fill="white"/>
<rect x="1334.52" y="90.3779" width="26.6955" height="26.6955" fill="white"/>
<rect x="1360.32" y="133.091" width="10.6782" height="16.0173" fill="white"/>
<rect x="1334.52" y="148.219" width="16.0173" height="16.0173" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M723 217.646V31.2444C723 14.202 736.847 0 753.889 0H816.023C833.066 0 847.268 14.202 847.268 31.2444V85.5672H792.59V46.8667C792.59 42.6061 789.394 39.0556 784.779 39.0556C780.518 39.0556 777.323 42.6061 777.323 46.8667V202.024C777.323 206.284 780.518 209.835 784.779 209.835C789.394 209.835 792.59 206.284 792.59 202.024V163.323H847.268V217.646C847.268 234.688 833.066 248.535 816.023 248.535H753.889C736.847 248.535 723 234.688 723 217.646ZM856.144 248.535V0H910.467V101.189H925.734V0H980.057V248.535H925.734V147.701H910.467V248.535H856.144ZM1066.34 248.535L1062.79 209.835H1039.36L1035.45 248.535H988.941L1019.83 0H1081.96L1113.21 248.535H1066.34ZM1043.62 163.323H1058.18L1050.72 85.5672L1043.62 163.323ZM1176.06 248.535H1121.74V0H1176.06V248.535ZM1184.84 248.535V0H1239.17L1262.24 124.268V0H1308.76V75.2506H1302.48V101.946H1308.76V153.557H1294.47V169.575H1308.76V248.535H1254.43L1231.35 124.268V248.535H1184.84Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

+10 -23
View File
@@ -1,24 +1,11 @@
<svg width="1161" height="212" viewBox="0 0 1161 212" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1010.3 212V0H1056.64L1076.33 106V0H1116V212H1069.66L1049.98 106V212H1010.3Z" fill="white"/>
<path d="M1001.3 212H954.958V0H1001.3V212Z" fill="white"/>
<path d="M906.196 212L903.167 178.989H883.179L879.847 212H840.173L866.522 0H919.522L946.173 212H906.196ZM886.813 139.314H899.23L892.87 72.9886L886.813 139.314Z" fill="white"/>
<path d="M725.385 212V0H771.722V86.3143H784.745V0H831.082V212H784.745V125.989H771.722V212H725.385Z" fill="white"/>
<path d="M610.298 185.651V26.6514C610.298 12.1143 622.109 0 636.646 0H689.646C704.183 0 716.298 12.1143 716.298 26.6514V72.9886H669.658V39.9771C669.658 36.3429 666.932 33.3143 662.995 33.3143C659.36 33.3143 656.635 36.3429 656.635 39.9771V172.326C656.635 175.96 659.36 178.989 662.995 178.989C666.932 178.989 669.658 175.96 669.658 172.326V139.314H716.298V185.651C716.298 200.189 704.183 212 689.646 212H636.646C622.109 212 610.298 200.189 610.298 185.651Z" fill="white"/>
<path d="M541.841 33.3143V178.989H548.201C552.138 178.989 554.864 175.96 554.864 172.326V39.9771C554.864 36.3429 552.138 33.3143 548.201 33.3143H541.841ZM601.504 26.6514V185.651C601.504 200.189 589.389 212 574.852 212H495.504V0H574.852C589.389 0 601.504 12.1143 601.504 26.6514Z" fill="white"/>
<path d="M407.037 212V0H486.385V33.3143H453.374V86.3143H486.385V125.989H453.374V178.989H486.385V212H407.037Z" fill="white"/>
<path d="M338.587 125.989V178.989H345.249C348.884 178.989 351.609 175.96 351.609 172.326V132.651C351.609 129.017 348.884 125.989 345.249 125.989H338.587ZM371.598 106L372.204 106.303C386.741 106.606 398.249 118.114 398.249 132.651V185.651C398.249 200.189 386.135 212 371.598 212H292.249V0H371.598C386.135 0 398.249 12.1143 398.249 26.6514V79.6514C398.249 94.1886 386.135 106 371.598 106ZM338.587 86.3143H345.249C348.884 86.3143 351.609 83.2857 351.609 79.6514V39.9771C351.609 36.3429 348.884 33.3143 345.249 33.3143H338.587V86.3143Z" fill="white"/>
<path d="M137.532 212V0H190.23L210.218 125.989L230.207 0H283.207V212H236.87V106L216.881 212H203.555L183.87 106V212H137.532Z" fill="white"/>
<path d="M49.0637 212V0H128.412V33.3143H95.4008V86.3143H128.412V125.989H95.4008V178.989H128.412V212H49.0637Z" fill="white"/>
<rect x="1125.62" y="65.6279" width="25.2381" height="25.238" fill="white"/>
<path d="M1150.86 106H1160.95V121.143H1150.86V106Z" fill="white"/>
<rect x="1125.62" y="121.118" width="15.1428" height="15.1429" fill="white"/>
<rect x="1095.33" y="50.5068" width="25.2381" height="25.238" fill="#010312"/>
<rect x="1105.43" y="111.022" width="15.1428" height="15.1429" fill="#010312"/>
<rect x="1085.23" y="126.23" width="15.1428" height="15.1429" fill="#010312"/>
<rect x="42.9069" y="55.4932" width="10.0952" height="25.238" fill="#010312"/>
<rect x="45.4301" y="121.118" width="10.0952" height="20.1904" fill="#010312"/>
<rect x="22.7124" y="55.5215" width="25.2381" height="25.238" fill="white"/>
<path d="M0 121.148H10.0952V136.291H0V121.148Z" fill="white"/>
<rect x="15.1404" y="141.375" width="15.1428" height="15.1429" fill="white"/>
<rect x="60.5702" y="141.375" width="15.1428" height="15.1429" fill="#010312"/>
<svg width="2052" height="549" viewBox="0 0 2052 549" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="2052" height="549" fill="#2A2B4C"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M406.248 151V398.8H498.996V360.214H460.41V298.264H498.996V251.89H460.41V189.94H498.996V151H406.248ZM509.655 151V398.8H563.817V274.9L586.827 398.8H602.403L625.767 274.9V398.8H679.929V151H617.979L594.615 298.264L571.251 151H509.655ZM744.661 360.214V298.264H752.449C756.697 298.264 759.883 301.804 759.883 306.052V352.426C759.883 356.674 756.697 360.214 752.449 360.214H744.661ZM783.955 275.254L783.247 274.9C800.239 274.9 814.399 261.094 814.399 244.102V182.152C814.399 165.16 800.239 151 783.247 151H690.499V398.8H783.247C800.239 398.8 814.399 384.994 814.399 368.002V306.052C814.399 289.06 800.947 275.608 783.955 275.254ZM752.449 251.89H744.661V189.94H752.449C756.697 189.94 759.883 193.48 759.883 197.728V244.102C759.883 248.35 756.697 251.89 752.449 251.89ZM917.421 151H824.673V398.8H917.421V360.214H878.835V298.264H917.421V251.89H878.835V189.94H917.421V151ZM982.242 360.214V189.94H989.676C994.278 189.94 997.464 193.48 997.464 197.728V352.426C997.464 356.674 994.278 360.214 989.676 360.214H982.242ZM1051.98 368.002V182.152C1051.98 165.16 1037.82 151 1020.83 151H928.08V398.8H1020.83C1037.82 398.8 1051.98 384.994 1051.98 368.002ZM428 314.8H410V332.8H428V314.8Z" fill="white"/>
<rect x="357" y="314.8" width="18" height="18" fill="white"/>
<rect x="340" y="291.8" width="11" height="18" fill="white"/>
<rect x="366" y="214.8" width="30" height="30" fill="white"/>
<rect x="1674.52" y="240.378" width="26.6955" height="26.6955" fill="white"/>
<rect x="1700.32" y="283.091" width="10.6782" height="16.0173" fill="white"/>
<rect x="1674.52" y="298.218" width="16.0173" height="16.0173" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M1063 367.646V181.244C1063 164.202 1076.85 150 1093.89 150H1156.02C1173.07 150 1187.27 164.202 1187.27 181.244V235.567H1132.59V196.867C1132.59 192.606 1129.39 189.056 1124.78 189.056C1120.52 189.056 1117.32 192.606 1117.32 196.867V352.024C1117.32 356.284 1120.52 359.835 1124.78 359.835C1129.39 359.835 1132.59 356.284 1132.59 352.024V313.323H1187.27V367.646C1187.27 384.688 1173.07 398.535 1156.02 398.535H1093.89C1076.85 398.535 1063 384.688 1063 367.646ZM1196.14 398.535V150H1250.47V251.189H1265.73V150H1320.06V398.535H1265.73V297.701H1250.47V398.535H1196.14ZM1406.34 398.535L1402.79 359.835H1379.36L1375.45 398.535H1328.94L1359.83 150H1421.96L1453.21 398.535H1406.34ZM1383.62 313.323H1398.18L1390.72 235.567L1383.62 313.323ZM1516.06 398.535H1461.74V150H1516.06V398.535ZM1524.84 398.535V150H1579.17L1602.24 274.268V150H1648.76V225.251H1642.48V251.946H1648.76V303.557H1634.47V319.575H1648.76V398.535H1594.43L1571.35 274.268V398.535H1524.84Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

+10
View File
@@ -0,0 +1,10 @@
<svg width="1371" height="249" viewBox="0 0 1371 249" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M66.248 1V248.8H158.996V210.214H120.41V148.264H158.996V101.89H120.41V39.94H158.996V1H66.248ZM169.655 1V248.8H223.817V124.9L246.827 248.8H262.403L285.767 124.9V248.8H339.929V1H277.979L254.615 148.264L231.251 1H169.655ZM404.661 210.214V148.264H412.449C416.697 148.264 419.883 151.804 419.883 156.052V202.426C419.883 206.674 416.697 210.214 412.449 210.214H404.661ZM443.955 125.254L443.247 124.9C460.239 124.9 474.399 111.094 474.399 94.102V32.152C474.399 15.16 460.239 1 443.247 1H350.499V248.8H443.247C460.239 248.8 474.399 234.994 474.399 218.002V156.052C474.399 139.06 460.947 125.608 443.955 125.254ZM412.449 101.89H404.661V39.94H412.449C416.697 39.94 419.883 43.48 419.883 47.728V94.102C419.883 98.35 416.697 101.89 412.449 101.89ZM577.421 1H484.673V248.8H577.421V210.214H538.835V148.264H577.421V101.89H538.835V39.94H577.421V1ZM642.242 210.214V39.94H649.676C654.278 39.94 657.464 43.48 657.464 47.728V202.426C657.464 206.674 654.278 210.214 649.676 210.214H642.242ZM711.98 218.002V32.152C711.98 15.16 697.82 1 680.828 1H588.08V248.8H680.828C697.82 248.8 711.98 234.994 711.98 218.002ZM88 164.8H70V182.8H88V164.8Z" fill="#2A2B4C"/>
<rect x="17" y="164.8" width="18" height="18" fill="#2A2B4C"/>
<rect y="141.8" width="11" height="18" fill="#2A2B4C"/>
<rect x="26" y="64.7998" width="30" height="30" fill="#2A2B4C"/>
<rect x="1334.52" y="90.3779" width="26.6955" height="26.6955" fill="#2A2B4C"/>
<rect x="1360.32" y="133.091" width="10.6782" height="16.0173" fill="#2A2B4C"/>
<rect x="1334.52" y="148.219" width="16.0173" height="16.0173" fill="#2A2B4C"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M723 217.646V31.2444C723 14.202 736.847 0 753.889 0H816.023C833.066 0 847.268 14.202 847.268 31.2444V85.5672H792.59V46.8667C792.59 42.6061 789.394 39.0556 784.779 39.0556C780.518 39.0556 777.323 42.6061 777.323 46.8667V202.024C777.323 206.284 780.518 209.835 784.779 209.835C789.394 209.835 792.59 206.284 792.59 202.024V163.323H847.268V217.646C847.268 234.688 833.066 248.535 816.023 248.535H753.889C736.847 248.535 723 234.688 723 217.646ZM856.144 248.535V0H910.467V101.189H925.734V0H980.057V248.535H925.734V147.701H910.467V248.535H856.144ZM1066.34 248.535L1062.79 209.835H1039.36L1035.45 248.535H988.941L1019.83 0H1081.96L1113.21 248.535H1066.34ZM1043.62 163.323H1058.18L1050.72 85.5672L1043.62 163.323ZM1176.06 248.535H1121.74V0H1176.06V248.535ZM1184.84 248.535V0H1239.17L1262.24 124.268V0H1308.76V75.2506H1302.48V101.946H1308.76V153.557H1294.47V169.575H1308.76V248.535H1254.43L1231.35 124.268V248.535H1184.84Z" fill="#2A2B4C"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

+10 -23
View File
@@ -1,24 +1,11 @@
<svg width="1161" height="212" viewBox="0 0 1161 212" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1010.3 212V0H1056.64L1076.33 106V0H1116V212H1069.66L1049.98 106V212H1010.3Z" fill="#010312"/>
<path d="M1001.3 212H954.958V0H1001.3V212Z" fill="#010312"/>
<path d="M906.196 212L903.167 178.989H883.179L879.847 212H840.173L866.522 0H919.522L946.173 212H906.196ZM886.813 139.314H899.23L892.87 72.9886L886.813 139.314Z" fill="#010312"/>
<path d="M725.385 212V0H771.722V86.3143H784.745V0H831.082V212H784.745V125.989H771.722V212H725.385Z" fill="#010312"/>
<path d="M610.298 185.651V26.6514C610.298 12.1143 622.109 0 636.646 0H689.646C704.183 0 716.298 12.1143 716.298 26.6514V72.9886H669.658V39.9771C669.658 36.3429 666.932 33.3143 662.995 33.3143C659.36 33.3143 656.635 36.3429 656.635 39.9771V172.326C656.635 175.96 659.36 178.989 662.995 178.989C666.932 178.989 669.658 175.96 669.658 172.326V139.314H716.298V185.651C716.298 200.189 704.183 212 689.646 212H636.646C622.109 212 610.298 200.189 610.298 185.651Z" fill="#010312"/>
<path d="M541.841 33.3143V178.989H548.201C552.138 178.989 554.864 175.96 554.864 172.326V39.9771C554.864 36.3429 552.138 33.3143 548.201 33.3143H541.841ZM601.504 26.6514V185.651C601.504 200.189 589.389 212 574.852 212H495.504V0H574.852C589.389 0 601.504 12.1143 601.504 26.6514Z" fill="#010312"/>
<path d="M407.037 212V0H486.385V33.3143H453.374V86.3143H486.385V125.989H453.374V178.989H486.385V212H407.037Z" fill="#010312"/>
<path d="M338.587 125.989V178.989H345.249C348.884 178.989 351.609 175.96 351.609 172.326V132.651C351.609 129.017 348.884 125.989 345.249 125.989H338.587ZM371.598 106L372.204 106.303C386.741 106.606 398.249 118.114 398.249 132.651V185.651C398.249 200.189 386.135 212 371.598 212H292.249V0H371.598C386.135 0 398.249 12.1143 398.249 26.6514V79.6514C398.249 94.1886 386.135 106 371.598 106ZM338.587 86.3143H345.249C348.884 86.3143 351.609 83.2857 351.609 79.6514V39.9771C351.609 36.3429 348.884 33.3143 345.249 33.3143H338.587V86.3143Z" fill="#010312"/>
<path d="M137.532 212V0H190.23L210.218 125.989L230.207 0H283.207V212H236.87V106L216.881 212H203.555L183.87 106V212H137.532Z" fill="#010312"/>
<path d="M49.0637 212V0H128.412V33.3143H95.4008V86.3143H128.412V125.989H95.4008V178.989H128.412V212H49.0637Z" fill="#010312"/>
<rect x="1125.62" y="65.6279" width="25.2381" height="25.238" fill="#010312"/>
<path d="M1150.86 106H1160.95V121.143H1150.86V106Z" fill="#010312"/>
<rect x="1125.62" y="121.118" width="15.1428" height="15.1429" fill="#010312"/>
<rect x="1095.33" y="50.5068" width="25.2381" height="25.238" fill="white"/>
<rect x="1105.43" y="111.022" width="15.1428" height="15.1429" fill="white"/>
<rect x="1085.23" y="126.23" width="15.1428" height="15.1429" fill="white"/>
<rect x="42.9069" y="55.4932" width="10.0952" height="25.238" fill="white"/>
<rect x="45.4301" y="121.118" width="10.0952" height="20.1904" fill="white"/>
<rect x="22.7124" y="55.5215" width="25.2381" height="25.238" fill="#010312"/>
<path d="M0 121.148H10.0952V136.291H0V121.148Z" fill="#010312"/>
<rect x="15.1404" y="141.375" width="15.1428" height="15.1429" fill="#010312"/>
<rect x="60.5702" y="141.375" width="15.1428" height="15.1429" fill="white"/>
<svg width="2052" height="549" viewBox="0 0 2052 549" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="2052" height="549" fill="#2A2B4C"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M406.248 151V398.8H498.996V360.214H460.41V298.264H498.996V251.89H460.41V189.94H498.996V151H406.248ZM509.655 151V398.8H563.817V274.9L586.827 398.8H602.403L625.767 274.9V398.8H679.929V151H617.979L594.615 298.264L571.251 151H509.655ZM744.661 360.214V298.264H752.449C756.697 298.264 759.883 301.804 759.883 306.052V352.426C759.883 356.674 756.697 360.214 752.449 360.214H744.661ZM783.955 275.254L783.247 274.9C800.239 274.9 814.399 261.094 814.399 244.102V182.152C814.399 165.16 800.239 151 783.247 151H690.499V398.8H783.247C800.239 398.8 814.399 384.994 814.399 368.002V306.052C814.399 289.06 800.947 275.608 783.955 275.254ZM752.449 251.89H744.661V189.94H752.449C756.697 189.94 759.883 193.48 759.883 197.728V244.102C759.883 248.35 756.697 251.89 752.449 251.89ZM917.421 151H824.673V398.8H917.421V360.214H878.835V298.264H917.421V251.89H878.835V189.94H917.421V151ZM982.242 360.214V189.94H989.676C994.278 189.94 997.464 193.48 997.464 197.728V352.426C997.464 356.674 994.278 360.214 989.676 360.214H982.242ZM1051.98 368.002V182.152C1051.98 165.16 1037.82 151 1020.83 151H928.08V398.8H1020.83C1037.82 398.8 1051.98 384.994 1051.98 368.002ZM428 314.8H410V332.8H428V314.8Z" fill="white"/>
<rect x="357" y="314.8" width="18" height="18" fill="white"/>
<rect x="340" y="291.8" width="11" height="18" fill="white"/>
<rect x="366" y="214.8" width="30" height="30" fill="white"/>
<rect x="1674.52" y="240.378" width="26.6955" height="26.6955" fill="white"/>
<rect x="1700.32" y="283.091" width="10.6782" height="16.0173" fill="white"/>
<rect x="1674.52" y="298.218" width="16.0173" height="16.0173" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M1063 367.646V181.244C1063 164.202 1076.85 150 1093.89 150H1156.02C1173.07 150 1187.27 164.202 1187.27 181.244V235.567H1132.59V196.867C1132.59 192.606 1129.39 189.056 1124.78 189.056C1120.52 189.056 1117.32 192.606 1117.32 196.867V352.024C1117.32 356.284 1120.52 359.835 1124.78 359.835C1129.39 359.835 1132.59 356.284 1132.59 352.024V313.323H1187.27V367.646C1187.27 384.688 1173.07 398.535 1156.02 398.535H1093.89C1076.85 398.535 1063 384.688 1063 367.646ZM1196.14 398.535V150H1250.47V251.189H1265.73V150H1320.06V398.535H1265.73V297.701H1250.47V398.535H1196.14ZM1406.34 398.535L1402.79 359.835H1379.36L1375.45 398.535H1328.94L1359.83 150H1421.96L1453.21 398.535H1406.34ZM1383.62 313.323H1398.18L1390.72 235.567L1383.62 313.323ZM1516.06 398.535H1461.74V150H1516.06V398.535ZM1524.84 398.535V150H1579.17L1602.24 274.268V150H1648.76V225.251H1642.48V251.946H1648.76V303.557H1634.47V319.575H1648.76V398.535H1594.43L1571.35 274.268V398.535H1524.84Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

+52 -38
View File
@@ -2,8 +2,8 @@
"$schema": "https://mintlify.com/schema.json",
"name": "Embedchain",
"logo": {
"dark": "/logo/dark.svg",
"light": "/logo/light.svg",
"dark": "/logo/dark-rt.svg",
"light": "/logo/light-rt.svg",
"href": "https://github.com/embedchain/embedchain"
},
"favicon": "/favicon.png",
@@ -41,16 +41,6 @@
"name": "Talk to founders",
"icon": "calendar",
"url": "https://cal.com/taranjeetio/ec"
},
{
"name": "Join our slack",
"icon": "slack",
"url": "https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw"
},
{
"name": "Join our discord",
"icon": "discord",
"url": "https://discord.gg/CUU9FPhRNt"
}
],
"topbarLinks": [
@@ -61,7 +51,7 @@
],
"topbarCtaButton": {
"name": "Join our slack",
"url": "https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw"
"url": "https://embedchain.ai/slack"
},
"primaryTab": {
"name": "Documentation"
@@ -70,32 +60,24 @@
{
"group": "Get Started",
"pages": [
"get-started/introduction",
"get-started/quickstart",
"get-started/introduction",
"get-started/faq",
"get-started/full-stack",
{
"group": "🔗 Integrations",
"group": "🔗 Integrations",
"pages": [
"integration/langsmith",
"integration/chainlit",
"integration/streamlit-mistral"
]
},
"get-started/faq"
]
},
{
"group": "Deployment",
"pages": [
"get-started/deployment",
"deployment/fly_io",
"deployment/modal_com",
"deployment/render_com",
"deployment/streamlit_io"
}
]
},
{
"group": "Use cases",
"pages": [
"use-cases/introduction",
"use-cases/chatbots",
"use-cases/question-answering",
"use-cases/semantic-search"
@@ -104,31 +86,44 @@
{
"group": "Components",
"pages": [
"components/introduction",
{
"group": "Data sources",
"pages": [
"components/data-sources/overview",
{
"group": "Data types",
"pages": [
"components/data-sources/pdf-file",
"components/data-sources/csv",
"components/data-sources/json",
"components/data-sources/docs-site",
"components/data-sources/docx",
"components/data-sources/mdx",
"components/data-sources/notion",
"components/data-sources/pdf-file",
"components/data-sources/qna",
"components/data-sources/sitemap",
"components/data-sources/text",
"components/data-sources/directory",
"components/data-sources/web-page",
"components/data-sources/openapi",
"components/data-sources/youtube-channel",
"components/data-sources/youtube-video",
"components/data-sources/docs-site",
"components/data-sources/mdx",
"components/data-sources/docx",
"components/data-sources/notion",
"components/data-sources/sitemap",
"components/data-sources/xml",
"components/data-sources/qna",
"components/data-sources/openapi",
"components/data-sources/gmail",
"components/data-sources/github",
"components/data-sources/postgres",
"components/data-sources/mysql",
"components/data-sources/slack",
"components/data-sources/discord",
"components/data-sources/discourse",
"components/data-sources/substack",
"components/data-sources/discord",
"components/data-sources/beehiiv",
"components/data-sources/directory"
"components/data-sources/directory",
"components/data-sources/dropbox",
"components/data-sources/image",
"components/data-sources/custom"
]
},
"components/data-sources/data-type-handling"
@@ -139,6 +134,19 @@
"components/embedding-models"
]
},
{
"group": "Deployment",
"pages": [
"get-started/deployment",
"deployment/fly_io",
"deployment/modal_com",
"deployment/render_com",
"deployment/streamlit_io",
"deployment/gradio_app",
"deployment/huggingface_spaces",
"deployment/embedchain_ai"
]
},
{
"group": "Community",
"pages": [
@@ -148,6 +156,7 @@
{
"group": "Examples",
"pages": [
"examples/chat-with-PDF",
"examples/notebooks-and-replits",
{
"group": "REST API Service",
@@ -165,7 +174,9 @@
},
"examples/full_stack",
"examples/openai-assistant",
"examples/opensource-assistant"
"examples/opensource-assistant",
"examples/nextjs-assistant",
"examples/slack-AI"
]
},
{
@@ -235,6 +246,9 @@
"posthog": {
"apiKey": "phc_PHQDA5KwztijnSojsxJ2c1DuJd52QCzJzT2xnSGvjN2",
"apiHost": "https://app.embedchain.ai/ingest"
},
"ga4": {
"measurementId": "G-4QK7FJE6T3"
}
},
"feedback": {
+1 -1
View File
@@ -1,5 +1,5 @@
---
title: 'Chatbots'
title: '🤖 Chatbots'
---
Chatbots, especially those powered by Large Language Models (LLMs), have a wide range of use cases, significantly enhancing various aspects of business, education, and personal assistance. Here are some key applications:
+11
View File
@@ -0,0 +1,11 @@
---
title: 🧱 Introduction
---
## Overview
You can use embedchain to create the following usecases:
* [Chatbots](/use-cases/chatbots)
* [Question Answering](/use-cases/question-answering)
* [Semantic Search](/use-cases/semantic-search)
+2 -2
View File
@@ -1,5 +1,5 @@
---
title: 'Question Answering'
title: '❓ Question Answering'
---
Utilizing large language models (LLMs) for question answering is a transformative application, bringing significant benefits to various real-world situations. Embedchain extensively supports tasks related to question answering, including summarization, content creation, language translation, and data analysis. The versatility of question answering with LLMs enables solutions for numerous practical applications such as:
@@ -24,7 +24,7 @@ Quickly create a RAG pipeline to answer queries about the [Next.JS Framework](ht
First, let's create your RAG pipeline. Open your Python environment and enter:
```python Create pipeline
from embedchain import Pipeline as App
from embedchain import App
app = App()
```
+17 -7
View File
@@ -1,3 +1,7 @@
---
title: '🔍 Semantic Search'
---
Semantic searching, which involves understanding the intent and contextual meaning behind search queries, is yet another popular use-case of RAG. It has several popular use cases across various domains:
- **Information Retrieval**: Enhances search accuracy in databases and websites
@@ -19,7 +23,7 @@ Embedchain offers a simple yet customizable `search()` API that you can use for
First, let's create your RAG pipeline. Open your Python environment and enter:
```python Create pipeline
from embedchain import Pipeline as App
from embedchain import App
app = App()
```
@@ -48,18 +52,24 @@ app.search("Summarize the features of Next.js 14?")
[
{
'context': 'Next.js 14 | Next.jsBack to BlogThursday, October 26th 2023Next.js 14Posted byLee Robinson@leeerobTim Neutkens@timneutkensAs we announced at Next.js Conf, Next.js 14 is our most focused release with: Turbopack: 5,000 tests passing for App & Pages Router 53% faster local server startup 94% faster code updates with Fast Refresh Server Actions (Stable): Progressively enhanced mutations Integrated with caching & revalidating Simple function calls, or works natively with forms Partial Prerendering',
'source': 'https://nextjs.org/blog/next-14',
'document_id': '6c8d1a7b-ea34-4927-8823-daa29dcfc5af--b83edb69b8fc7e442ff8ca311b48510e6c80bf00caa806b3a6acb34e1bcdd5d5'
'metadata': {
'source': 'https://nextjs.org/blog/next-14',
'document_id': '6c8d1a7b-ea34-4927-8823-daa29dcfc5af--b83edb69b8fc7e442ff8ca311b48510e6c80bf00caa806b3a6acb34e1bcdd5d5'
}
},
{
'context': 'Next.js 13.3 | Next.jsBack to BlogThursday, April 6th 2023Next.js 13.3Posted byDelba de Oliveira@delba_oliveiraTim Neutkens@timneutkensNext.js 13.3 adds popular community-requested features, including: File-Based Metadata API: Dynamically generate sitemaps, robots, favicons, and more. Dynamic Open Graph Images: Generate OG images using JSX, HTML, and CSS. Static Export for App Router: Static / Single-Page Application (SPA) support for Server Components. Parallel Routes and Interception: Advanced',
'source': 'https://nextjs.org/blog/next-13-3',
'document_id': '6c8d1a7b-ea34-4927-8823-daa29dcfc5af--b83edb69b8fc7e442ff8ca311b48510e6c80bf00caa806b3a6acb34e1bcdd5d5'
'metadata': {
'source': 'https://nextjs.org/blog/next-13-3',
'document_id': '6c8d1a7b-ea34-4927-8823-daa29dcfc5af--b83edb69b8fc7e442ff8ca311b48510e6c80bf00caa806b3a6acb34e1bcdd5d5'
}
},
{
'context': 'Upgrading: Version 14 | Next.js MenuUsing App RouterFeatures available in /appApp Router.UpgradingVersion 14Version 14 Upgrading from 13 to 14 To update to Next.js version 14, run the following command using your preferred package manager: Terminalnpm i next@latest react@latest react-dom@latest eslint-config-next@latest Terminalyarn add next@latest react@latest react-dom@latest eslint-config-next@latest Terminalpnpm up next react react-dom eslint-config-next -latest Terminalbun add next@latest',
'source': 'https://nextjs.org/docs/app/building-your-application/upgrading/version-14',
'document_id': '6c8d1a7b-ea34-4927-8823-daa29dcfc5af--b83edb69b8fc7e442ff8ca311b48510e6c80bf00caa806b3a6acb34e1bcdd5d5'
'metadata': {
'source': 'https://nextjs.org/docs/app/building-your-application/upgrading/version-14',
'document_id': '6c8d1a7b-ea34-4927-8823-daa29dcfc5af--b83edb69b8fc7e442ff8ca311b48510e6c80bf00caa806b3a6acb34e1bcdd5d5'
}
}
]
```
+1 -1
View File
@@ -178,7 +178,7 @@ await app.addLocal("qna_pair", ["Question", "Answer"]);
## Testing
Before you consume valueable tokens, you should make sure that the embedding you have done works and that it's receiving the correct document from the database.
Before you consume valuable tokens, you should make sure that the embedding you have done works and that it's receiving the correct document from the database.
For this you can use the `dryRun` method.
+1 -2
View File
@@ -2,10 +2,9 @@ import importlib.metadata
__version__ = importlib.metadata.version(__package__ or __name__)
from embedchain.apps.app import App # noqa: F401
from embedchain.app import App # noqa: F401
from embedchain.client import Client # noqa: F401
from embedchain.pipeline import Pipeline # noqa: F401
from embedchain.vectordb.chroma import ChromaDB # noqa: F401
# Setup the user directory if doesn't exist already
Client.setup_dir()
+457
View File
@@ -0,0 +1,457 @@
import ast
import json
import logging
import os
import sqlite3
import uuid
from typing import Any, Optional
import requests
import yaml
from embedchain.cache import (Config, ExactMatchEvaluation,
SearchDistanceEvaluation, cache,
gptcache_data_manager, gptcache_pre_function)
from embedchain.client import Client
from embedchain.config import AppConfig, CacheConfig, ChunkerConfig
from embedchain.constants import SQLITE_PATH
from embedchain.embedchain import EmbedChain
from embedchain.embedder.base import BaseEmbedder
from embedchain.embedder.openai import OpenAIEmbedder
from embedchain.factory import EmbedderFactory, LlmFactory, VectorDBFactory
from embedchain.helpers.json_serializable import register_deserializable
from embedchain.llm.base import BaseLlm
from embedchain.llm.openai import OpenAILlm
from embedchain.telemetry.posthog import AnonymousTelemetry
from embedchain.utils.misc import validate_config
from embedchain.vectordb.base import BaseVectorDB
from embedchain.vectordb.chroma import ChromaDB
# Set up the user directory if it doesn't exist already
Client.setup_dir()
@register_deserializable
class App(EmbedChain):
"""
EmbedChain App lets you create a LLM powered app for your unstructured
data by defining your chosen data source, embedding model,
and vector database.
"""
def __init__(
self,
id: str = None,
name: str = None,
config: AppConfig = None,
db: BaseVectorDB = None,
embedding_model: BaseEmbedder = None,
llm: BaseLlm = None,
config_data: dict = None,
log_level=logging.WARN,
auto_deploy: bool = False,
chunker: ChunkerConfig = None,
cache_config: CacheConfig = None,
):
"""
Initialize a new `App` instance.
:param config: Configuration for the pipeline, defaults to None
:type config: AppConfig, optional
:param db: The database to use for storing and retrieving embeddings, defaults to None
:type db: BaseVectorDB, optional
:param embedding_model: The embedding model used to calculate embeddings, defaults to None
:type embedding_model: BaseEmbedder, optional
:param llm: The LLM model used to calculate embeddings, defaults to None
:type llm: BaseLlm, optional
:param config_data: Config dictionary, defaults to None
:type config_data: dict, optional
:param log_level: Log level to use, defaults to logging.WARN
:type log_level: int, optional
:param auto_deploy: Whether to deploy the pipeline automatically, defaults to False
:type auto_deploy: bool, optional
:raises Exception: If an error occurs while creating the pipeline
"""
if id and config_data:
raise Exception("Cannot provide both id and config. Please provide only one of them.")
if id and name:
raise Exception("Cannot provide both id and name. Please provide only one of them.")
if name and config:
raise Exception("Cannot provide both name and config. Please provide only one of them.")
logging.basicConfig(level=log_level, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
self.logger = logging.getLogger(__name__)
self.auto_deploy = auto_deploy
# Store the dict config as an attribute to be able to send it
self.config_data = config_data if (config_data and validate_config(config_data)) else None
self.client = None
# pipeline_id from the backend
self.id = None
self.chunker = None
if chunker:
self.chunker = ChunkerConfig(**chunker)
self.cache_config = cache_config
self.config = config or AppConfig()
self.name = self.config.name
self.config.id = self.local_id = str(uuid.uuid4()) if self.config.id is None else self.config.id
if id is not None:
# Init client first since user is trying to fetch the pipeline
# details from the platform
self._init_client()
pipeline_details = self._get_pipeline(id)
self.config.id = self.local_id = pipeline_details["metadata"]["local_id"]
self.id = id
if name is not None:
self.name = name
self.embedding_model = embedding_model or OpenAIEmbedder()
self.db = db or ChromaDB()
self.llm = llm or OpenAILlm()
self._init_db()
# If cache_config is provided, initializing the cache ...
if self.cache_config is not None:
self._init_cache()
# Send anonymous telemetry
self._telemetry_props = {"class": self.__class__.__name__}
self.telemetry = AnonymousTelemetry(enabled=self.config.collect_metrics)
# Establish a connection to the SQLite database
self.connection = sqlite3.connect(SQLITE_PATH, check_same_thread=False)
self.cursor = self.connection.cursor()
# Create the 'data_sources' table if it doesn't exist
self.cursor.execute(
"""
CREATE TABLE IF NOT EXISTS data_sources (
pipeline_id TEXT,
hash TEXT,
type TEXT,
value TEXT,
metadata TEXT,
is_uploaded INTEGER DEFAULT 0,
PRIMARY KEY (pipeline_id, hash)
)
"""
)
self.connection.commit()
# Send anonymous telemetry
self.telemetry.capture(event_name="init", properties=self._telemetry_props)
self.user_asks = []
if self.auto_deploy:
self.deploy()
def _init_db(self):
"""
Initialize the database.
"""
self.db._set_embedder(self.embedding_model)
self.db._initialize()
self.db.set_collection_name(self.db.config.collection_name)
def _init_cache(self):
if self.cache_config.similarity_eval_config.strategy == "exact":
similarity_eval_func = ExactMatchEvaluation()
else:
similarity_eval_func = SearchDistanceEvaluation(
max_distance=self.cache_config.similarity_eval_config.max_distance,
positive=self.cache_config.similarity_eval_config.positive,
)
cache.init(
pre_embedding_func=gptcache_pre_function,
embedding_func=self.embedding_model.to_embeddings,
data_manager=gptcache_data_manager(vector_dimension=self.embedding_model.vector_dimension),
similarity_evaluation=similarity_eval_func,
config=Config(**self.cache_config.init_config.as_dict()),
)
def _init_client(self):
"""
Initialize the client.
"""
config = Client.load_config()
if config.get("api_key"):
self.client = Client()
else:
api_key = input(
"🔑 Enter your Embedchain API key. You can find the API key at https://app.embedchain.ai/settings/keys/ \n" # noqa: E501
)
self.client = Client(api_key=api_key)
def _get_pipeline(self, id):
"""
Get existing pipeline
"""
print("🛠️ Fetching pipeline details from the platform...")
url = f"{self.client.host}/api/v1/pipelines/{id}/cli/"
r = requests.get(
url,
headers={"Authorization": f"Token {self.client.api_key}"},
)
if r.status_code == 404:
raise Exception(f"❌ Pipeline with id {id} not found!")
print(
f"🎉 Pipeline loaded successfully! Pipeline url: https://app.embedchain.ai/pipelines/{r.json()['id']}\n" # noqa: E501
)
return r.json()
def _create_pipeline(self):
"""
Create a pipeline on the platform.
"""
print("🛠️ Creating pipeline on the platform...")
# self.config_data is a dict. Pass it inside the key 'yaml_config' to the backend
payload = {
"yaml_config": json.dumps(self.config_data),
"name": self.name,
"local_id": self.local_id,
}
url = f"{self.client.host}/api/v1/pipelines/cli/create/"
r = requests.post(
url,
json=payload,
headers={"Authorization": f"Token {self.client.api_key}"},
)
if r.status_code not in [200, 201]:
raise Exception(f"❌ Error occurred while creating pipeline. API response: {r.text}")
if r.status_code == 200:
print(
f"🎉🎉🎉 Existing pipeline found! View your pipeline: https://app.embedchain.ai/pipelines/{r.json()['id']}\n" # noqa: E501
) # noqa: E501
elif r.status_code == 201:
print(
f"🎉🎉🎉 Pipeline created successfully! View your pipeline: https://app.embedchain.ai/pipelines/{r.json()['id']}\n" # noqa: E501
)
return r.json()
def _get_presigned_url(self, data_type, data_value):
payload = {"data_type": data_type, "data_value": data_value}
r = requests.post(
f"{self.client.host}/api/v1/pipelines/{self.id}/cli/presigned_url/",
json=payload,
headers={"Authorization": f"Token {self.client.api_key}"},
)
r.raise_for_status()
return r.json()
def search(self, query, num_documents=3):
"""
Search for similar documents related to the query in the vector database.
"""
# Send anonymous telemetry
self.telemetry.capture(event_name="search", properties=self._telemetry_props)
# TODO: Search will call the endpoint rather than fetching the data from the db itself when deploy=True.
if self.id is None:
where = {"app_id": self.local_id}
context = self.db.query(
query,
n_results=num_documents,
where=where,
citations=True,
)
result = []
for c in context:
result.append({"context": c[0], "metadata": c[1]})
return result
else:
# Make API call to the backend to get the results
NotImplementedError("Search is not implemented yet for the prod mode.")
def _upload_file_to_presigned_url(self, presigned_url, file_path):
try:
with open(file_path, "rb") as file:
response = requests.put(presigned_url, data=file)
response.raise_for_status()
return response.status_code == 200
except Exception as e:
self.logger.exception(f"Error occurred during file upload: {str(e)}")
print("❌ Error occurred during file upload!")
return False
def _upload_data_to_pipeline(self, data_type, data_value, metadata=None):
payload = {
"data_type": data_type,
"data_value": data_value,
"metadata": metadata,
}
try:
self._send_api_request(f"/api/v1/pipelines/{self.id}/cli/add/", payload)
# print the local file path if user tries to upload a local file
printed_value = metadata.get("file_path") if metadata.get("file_path") else data_value
print(f"✅ Data of type: {data_type}, value: {printed_value} added successfully.")
except Exception as e:
print(f"❌ Error occurred during data upload for type {data_type}!. Error: {str(e)}")
def _send_api_request(self, endpoint, payload):
url = f"{self.client.host}{endpoint}"
headers = {"Authorization": f"Token {self.client.api_key}"}
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
return response
def _process_and_upload_data(self, data_hash, data_type, data_value):
if os.path.isabs(data_value):
presigned_url_data = self._get_presigned_url(data_type, data_value)
presigned_url = presigned_url_data["presigned_url"]
s3_key = presigned_url_data["s3_key"]
if self._upload_file_to_presigned_url(presigned_url, file_path=data_value):
metadata = {"file_path": data_value, "s3_key": s3_key}
data_value = presigned_url
else:
self.logger.error(f"File upload failed for hash: {data_hash}")
return False
else:
if data_type == "qna_pair":
data_value = list(ast.literal_eval(data_value))
metadata = {}
try:
self._upload_data_to_pipeline(data_type, data_value, metadata)
self._mark_data_as_uploaded(data_hash)
return True
except Exception:
print(f"❌ Error occurred during data upload for hash {data_hash}!")
return False
def _mark_data_as_uploaded(self, data_hash):
self.cursor.execute(
"UPDATE data_sources SET is_uploaded = 1 WHERE hash = ? AND pipeline_id = ?",
(data_hash, self.local_id),
)
self.connection.commit()
def get_data_sources(self):
db_data = self.cursor.execute("SELECT * FROM data_sources WHERE pipeline_id = ?", (self.local_id,)).fetchall()
data_sources = []
for data in db_data:
data_sources.append({"data_type": data[2], "data_value": data[3], "metadata": data[4]})
return data_sources
def deploy(self):
if self.client is None:
self._init_client()
pipeline_data = self._create_pipeline()
self.id = pipeline_data["id"]
results = self.cursor.execute(
"SELECT * FROM data_sources WHERE pipeline_id = ? AND is_uploaded = 0", (self.local_id,) # noqa:E501
).fetchall()
if len(results) > 0:
print("🛠️ Adding data to your pipeline...")
for result in results:
data_hash, data_type, data_value = result[1], result[2], result[3]
self._process_and_upload_data(data_hash, data_type, data_value)
# Send anonymous telemetry
self.telemetry.capture(event_name="deploy", properties=self._telemetry_props)
@classmethod
def from_config(
cls,
config_path: Optional[str] = None,
config: Optional[dict[str, Any]] = None,
auto_deploy: bool = False,
yaml_path: Optional[str] = None,
):
"""
Instantiate a Pipeline object from a configuration.
:param config_path: Path to the YAML or JSON configuration file.
:type config_path: Optional[str]
:param config: A dictionary containing the configuration.
:type config: Optional[dict[str, Any]]
:param auto_deploy: Whether to deploy the pipeline automatically, defaults to False
:type auto_deploy: bool, optional
:param yaml_path: (Deprecated) Path to the YAML configuration file. Use config_path instead.
:type yaml_path: Optional[str]
:return: An instance of the Pipeline class.
:rtype: Pipeline
"""
# Backward compatibility for yaml_path
if yaml_path and not config_path:
config_path = yaml_path
if config_path and config:
raise ValueError("Please provide only one of config_path or config.")
config_data = None
if config_path:
file_extension = os.path.splitext(config_path)[1]
with open(config_path, "r") as file:
if file_extension in [".yaml", ".yml"]:
config_data = yaml.safe_load(file)
elif file_extension == ".json":
config_data = json.load(file)
else:
raise ValueError("config_path must be a path to a YAML or JSON file.")
elif config and isinstance(config, dict):
config_data = config
else:
logging.error(
"Please provide either a config file path (YAML or JSON) or a config dictionary. Falling back to defaults because no config is provided.", # noqa: E501
)
config_data = {}
try:
validate_config(config_data)
except Exception as e:
raise Exception(f"Error occurred while validating the config. Error: {str(e)}")
app_config_data = config_data.get("app", {}).get("config", {})
db_config_data = config_data.get("vectordb", {})
embedding_model_config_data = config_data.get("embedding_model", config_data.get("embedder", {}))
llm_config_data = config_data.get("llm", {})
chunker_config_data = config_data.get("chunker", {})
cache_config_data = config_data.get("cache", None)
app_config = AppConfig(**app_config_data)
db_provider = db_config_data.get("provider", "chroma")
db = VectorDBFactory.create(db_provider, db_config_data.get("config", {}))
if llm_config_data:
llm_provider = llm_config_data.get("provider", "openai")
llm = LlmFactory.create(llm_provider, llm_config_data.get("config", {}))
else:
llm = None
embedding_model_provider = embedding_model_config_data.get("provider", "openai")
embedding_model = EmbedderFactory.create(
embedding_model_provider, embedding_model_config_data.get("config", {})
)
if cache_config_data is not None:
cache_config = CacheConfig.from_config(cache_config_data)
else:
cache_config = None
# Send anonymous telemetry
event_properties = {"init_type": "config_data"}
AnonymousTelemetry().capture(event_name="init", properties=event_properties)
return cls(
config=app_config,
llm=llm,
db=db,
embedding_model=embedding_model,
config_data=config_data,
auto_deploy=auto_deploy,
chunker=chunker_config_data,
cache_config=cache_config,
)
-157
View File
@@ -1,157 +0,0 @@
from typing import Optional
import yaml
from embedchain.config import (AppConfig, BaseEmbedderConfig, BaseLlmConfig,
ChunkerConfig)
from embedchain.config.vectordb.base import BaseVectorDbConfig
from embedchain.embedchain import EmbedChain
from embedchain.embedder.base import BaseEmbedder
from embedchain.embedder.openai import OpenAIEmbedder
from embedchain.factory import EmbedderFactory, LlmFactory, VectorDBFactory
from embedchain.helpers.json_serializable import register_deserializable
from embedchain.llm.base import BaseLlm
from embedchain.llm.openai import OpenAILlm
from embedchain.utils import validate_config
from embedchain.vectordb.base import BaseVectorDB
from embedchain.vectordb.chroma import ChromaDB
@register_deserializable
class App(EmbedChain):
"""
The EmbedChain app in it's simplest and most straightforward form.
An opinionated choice of LLM, vector database and embedding model.
Methods:
add(source, data_type): adds the data from the given URL to the vector db.
query(query): finds answer to the given query using vector database and LLM.
chat(query): finds answer to the given query using vector database and LLM, with conversation history.
"""
def __init__(
self,
config: Optional[AppConfig] = None,
llm: BaseLlm = None,
llm_config: Optional[BaseLlmConfig] = None,
db: BaseVectorDB = None,
db_config: Optional[BaseVectorDbConfig] = None,
embedder: BaseEmbedder = None,
embedder_config: Optional[BaseEmbedderConfig] = None,
system_prompt: Optional[str] = None,
chunker: Optional[ChunkerConfig] = None,
):
"""
Initialize a new `App` instance.
:param config: Config for the app instance., defaults to None
:type config: Optional[AppConfig], optional
:param llm: LLM Class instance. example: `from embedchain.llm.openai import OpenAILlm`, defaults to OpenAiLlm
:type llm: BaseLlm, optional
:param llm_config: Allows you to configure the LLM, e.g. how many documents to return,
example: `from embedchain.config import BaseLlmConfig`, defaults to None
:type llm_config: Optional[BaseLlmConfig], optional
:param db: The database to use for storing and retrieving embeddings,
example: `from embedchain.vectordb.chroma_db import ChromaDb`, defaults to ChromaDb
:type db: BaseVectorDB, optional
:param db_config: Allows you to configure the vector database,
example: `from embedchain.config import ChromaDbConfig`, defaults to None
:type db_config: Optional[BaseVectorDbConfig], optional
:param embedder: The embedder (embedding model and function) use to calculate embeddings.
example: `from embedchain.embedder.gpt4all_embedder import GPT4AllEmbedder`, defaults to OpenAIEmbedder
:type embedder: BaseEmbedder, optional
:param embedder_config: Allows you to configure the Embedder.
example: `from embedchain.config import BaseEmbedderConfig`, defaults to None
:type embedder_config: Optional[BaseEmbedderConfig], optional
:param system_prompt: System prompt that will be provided to the LLM as such, defaults to None
:type system_prompt: Optional[str], optional
:raises TypeError: LLM, database or embedder or their config is not a valid class instance.
"""
# Type check configs
if config and not isinstance(config, AppConfig):
raise TypeError(
"Config is not a `AppConfig` instance. "
"Please make sure the type is right and that you are passing an instance."
)
if llm_config and not isinstance(llm_config, BaseLlmConfig):
raise TypeError(
"`llm_config` is not a `BaseLlmConfig` instance. "
"Please make sure the type is right and that you are passing an instance."
)
if db_config and not isinstance(db_config, BaseVectorDbConfig):
raise TypeError(
"`db_config` is not a `BaseVectorDbConfig` instance. "
"Please make sure the type is right and that you are passing an instance."
)
if embedder_config and not isinstance(embedder_config, BaseEmbedderConfig):
raise TypeError(
"`embedder_config` is not a `BaseEmbedderConfig` instance. "
"Please make sure the type is right and that you are passing an instance."
)
# Assign defaults
if config is None:
config = AppConfig()
if llm is None:
llm = OpenAILlm(config=llm_config)
if db is None:
db = ChromaDB(config=db_config)
if embedder is None:
embedder = OpenAIEmbedder(config=embedder_config)
self.chunker = None
if chunker:
self.chunker = ChunkerConfig(**chunker)
# Type check assignments
if not isinstance(llm, BaseLlm):
raise TypeError(
"LLM is not a `BaseLlm` instance. "
"Please make sure the type is right and that you are passing an instance."
)
if not isinstance(db, BaseVectorDB):
raise TypeError(
"Database is not a `BaseVectorDB` instance. "
"Please make sure the type is right and that you are passing an instance."
)
if not isinstance(embedder, BaseEmbedder):
raise TypeError(
"Embedder is not a `BaseEmbedder` instance. "
"Please make sure the type is right and that you are passing an instance."
)
super().__init__(config, llm=llm, db=db, embedder=embedder, system_prompt=system_prompt)
@classmethod
def from_config(cls, yaml_path: str):
"""
Instantiate an App object from a YAML configuration file.
:param yaml_path: Path to the YAML configuration file.
:type yaml_path: str
:return: An instance of the App class.
:rtype: App
"""
with open(yaml_path, "r") as file:
config_data = yaml.safe_load(file)
try:
validate_config(config_data)
except Exception as e:
raise Exception(f"❌ Error occurred while validating the YAML config. Error: {str(e)}")
app_config_data = config_data.get("app", {})
llm_config_data = config_data.get("llm", {})
db_config_data = config_data.get("vectordb", {})
embedding_model_config_data = config_data.get("embedding_model", config_data.get("embedder", {}))
chunker_config_data = config_data.get("chunker", {})
app_config = AppConfig(**app_config_data.get("config", {}))
llm_provider = llm_config_data.get("provider", "openai")
llm = LlmFactory.create(llm_provider, llm_config_data.get("config", {}))
db_provider = db_config_data.get("provider", "chroma")
db = VectorDBFactory.create(db_provider, db_config_data.get("config", {}))
embedder_provider = embedding_model_config_data.get("provider", "openai")
embedder = EmbedderFactory.create(embedder_provider, embedding_model_config_data.get("config", {}))
return cls(config=app_config, llm=llm, db=db, embedder=embedder, chunker=chunker_config_data)
+3 -3
View File
@@ -1,7 +1,7 @@
from typing import Any
from embedchain import Pipeline as App
from embedchain.config import AddConfig, BaseLlmConfig, PipelineConfig
from embedchain import App
from embedchain.config import AddConfig, AppConfig, BaseLlmConfig
from embedchain.embedder.openai import OpenAIEmbedder
from embedchain.helpers.json_serializable import (JSONSerializable,
register_deserializable)
@@ -12,7 +12,7 @@ from embedchain.vectordb.chroma import ChromaDB
@register_deserializable
class BaseBot(JSONSerializable):
def __init__(self):
self.app = App(config=PipelineConfig(), llm=OpenAILlm(), db=ChromaDB(), embedding_model=OpenAIEmbedder())
self.app = App(config=AppConfig(), llm=OpenAILlm(), db=ChromaDB(), embedding_model=OpenAIEmbedder())
def add(self, data: Any, config: AddConfig = None):
"""
+3 -3
View File
@@ -1,7 +1,7 @@
import argparse
import logging
import os
from typing import List, Optional
from typing import Optional
from embedchain.helpers.json_serializable import register_deserializable
@@ -53,7 +53,7 @@ class PoeBot(BaseBot, PoeBot):
answer = self.handle_message(last_message, history)
yield self.text_event(answer)
def handle_message(self, message, history: Optional[List[str]] = None):
def handle_message(self, message, history: Optional[list[str]] = None):
if message.startswith("/add "):
response = self.add_data(message)
else:
@@ -70,7 +70,7 @@ class PoeBot(BaseBot, PoeBot):
# response = "Some error occurred while adding data."
# return response
def ask_bot(self, message, history: List[str]):
def ask_bot(self, message, history: list[str]):
try:
self.app.llm.set_history(history=history)
response = self.query(message)
+42
View File
@@ -0,0 +1,42 @@
import logging
import os # noqa: F401
from typing import Any
from gptcache import cache # noqa: F401
from gptcache.adapter.adapter import adapt # noqa: F401
from gptcache.config import Config # noqa: F401
from gptcache.manager import get_data_manager
from gptcache.manager.scalar_data.base import Answer
from gptcache.manager.scalar_data.base import DataType as CacheDataType
from gptcache.session import Session
from gptcache.similarity_evaluation.distance import \
SearchDistanceEvaluation # noqa: F401
from gptcache.similarity_evaluation.exact_match import \
ExactMatchEvaluation # noqa: F401
def gptcache_pre_function(data: dict[str, Any], **params: dict[str, Any]):
return data["input_query"]
def gptcache_data_manager(vector_dimension):
return get_data_manager(cache_base="sqlite", vector_base="chromadb", max_size=1000, eviction="LRU")
def gptcache_data_convert(cache_data):
logging.info("[Cache] Cache hit, returning cache data...")
return cache_data
def gptcache_update_cache_callback(llm_data, update_cache_func, *args, **kwargs):
logging.info("[Cache] Cache missed, updating cache...")
update_cache_func(Answer(llm_data, CacheDataType.STR))
return llm_data
def _gptcache_session_hit_func(cur_session_id: str, cache_session_ids: list, cache_questions: list, cache_answer: str):
return cur_session_id in cache_session_ids
def get_gptcache_session(session_id: str):
return Session(name=session_id, check_hit_func=_gptcache_session_hit_func)
+6 -5
View File
@@ -17,7 +17,7 @@ class BaseChunker(JSONSerializable):
"""
Loads data and chunks it.
:param loader: The loader which's `load_data` method is used to create
:param loader: The loader whose `load_data` method is used to create
the raw data.
:param src: The data to be handled by the loader. Can be a URL for
remote sources or local content for local loaders.
@@ -25,7 +25,7 @@ class BaseChunker(JSONSerializable):
"""
documents = []
chunk_ids = []
idMap = {}
id_map = {}
min_chunk_size = config.min_chunk_size if config is not None else 1
logging.info(f"[INFO] Skipping chunks smaller than {min_chunk_size} characters")
data_result = loader.load_data(src)
@@ -49,8 +49,8 @@ class BaseChunker(JSONSerializable):
for chunk in chunks:
chunk_id = hashlib.sha256((chunk + url).encode()).hexdigest()
chunk_id = f"{app_id}--{chunk_id}" if app_id is not None else chunk_id
if idMap.get(chunk_id) is None and len(chunk) >= min_chunk_size:
idMap[chunk_id] = True
if id_map.get(chunk_id) is None and len(chunk) >= min_chunk_size:
id_map[chunk_id] = True
chunk_ids.append(chunk_id)
documents.append(chunk)
metadatas.append(meta_data)
@@ -77,5 +77,6 @@ class BaseChunker(JSONSerializable):
# TODO: This should be done during initialization. This means it has to be done in the child classes.
def get_word_count(self, documents):
@staticmethod
def get_word_count(documents) -> int:
return sum([len(document.split(" ")) for document in documents])
+22
View File
@@ -0,0 +1,22 @@
from typing import Optional
from langchain.text_splitter import RecursiveCharacterTextSplitter
from embedchain.chunkers.base_chunker import BaseChunker
from embedchain.config.add_config import ChunkerConfig
from embedchain.helpers.json_serializable import register_deserializable
@register_deserializable
class GoogleDriveChunker(BaseChunker):
"""Chunker for google drive folder."""
def __init__(self, config: Optional[ChunkerConfig] = None):
if config is None:
config = ChunkerConfig(chunk_size=1000, chunk_overlap=0, length_function=len)
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=config.chunk_size,
chunk_overlap=config.chunk_overlap,
length_function=config.length_function,
)
super().__init__(text_splitter)
+22
View File
@@ -0,0 +1,22 @@
from typing import Optional
from langchain.text_splitter import RecursiveCharacterTextSplitter
from embedchain.chunkers.base_chunker import BaseChunker
from embedchain.config.add_config import ChunkerConfig
from embedchain.helpers.json_serializable import register_deserializable
@register_deserializable
class ImageChunker(BaseChunker):
"""Chunker for Images."""
def __init__(self, config: Optional[ChunkerConfig] = None):
if config is None:
config = ChunkerConfig(chunk_size=2000, chunk_overlap=0, length_function=len)
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=config.chunk_size,
chunk_overlap=config.chunk_overlap,
length_function=config.length_function,
)
super().__init__(text_splitter)
-67
View File
@@ -1,67 +0,0 @@
import hashlib
import logging
from typing import Optional
from langchain.text_splitter import RecursiveCharacterTextSplitter
from embedchain.chunkers.base_chunker import BaseChunker
from embedchain.config.add_config import ChunkerConfig
class ImagesChunker(BaseChunker):
"""Chunker for an Image."""
def __init__(self, config: Optional[ChunkerConfig] = None):
if config is None:
config = ChunkerConfig(chunk_size=300, chunk_overlap=0, length_function=len)
image_splitter = RecursiveCharacterTextSplitter(
chunk_size=config.chunk_size,
chunk_overlap=config.chunk_overlap,
length_function=config.length_function,
)
super().__init__(image_splitter)
def create_chunks(self, loader, src, app_id=None, config: Optional[ChunkerConfig] = None):
"""
Loads the image(s), and creates their corresponding embedding. This creates one chunk for each image
:param loader: The loader whose `load_data` method is used to create
the raw data.
:param src: The data to be handled by the loader. Can be a URL for
remote sources or local content for local loaders.
"""
documents = []
embeddings = []
ids = []
min_chunk_size = config.min_chunk_size if config is not None else 0
logging.info(f"[INFO] Skipping chunks smaller than {min_chunk_size} characters")
data_result = loader.load_data(src)
data_records = data_result["data"]
doc_id = data_result["doc_id"]
doc_id = f"{app_id}--{doc_id}" if app_id is not None else doc_id
metadatas = []
for data in data_records:
meta_data = data["meta_data"]
# add data type to meta data to allow query using data type
meta_data["data_type"] = self.data_type.value
chunk_id = hashlib.sha256(meta_data["url"].encode()).hexdigest()
ids.append(chunk_id)
documents.append(data["content"])
embeddings.append(data["embedding"])
meta_data["doc_id"] = doc_id
metadatas.append(meta_data)
return {
"documents": documents,
"embeddings": embeddings,
"ids": ids,
"metadatas": metadatas,
"doc_id": doc_id,
}
def get_word_count(self, documents):
"""
The number of chunks and the corresponding word count for an image is fixed to 1, as 1 embedding is created for
each image
"""
return 1
+1 -1
View File
@@ -4,7 +4,7 @@ from langchain.text_splitter import RecursiveCharacterTextSplitter
from embedchain.chunkers.base_chunker import BaseChunker
from embedchain.config.add_config import ChunkerConfig
from embedchain.helper.json_serializable import register_deserializable
from embedchain.helpers.json_serializable import register_deserializable
@register_deserializable
+171 -181
View File
@@ -1,16 +1,45 @@
import json
import os
import re
import shutil
import signal
import subprocess
import sys
import tempfile
import time
import zipfile
from pathlib import Path
import click
import pkg_resources
import requests
from rich.console import Console
from embedchain.telemetry.posthog import AnonymousTelemetry
from embedchain.utils.cli import (deploy_fly, deploy_gradio_app,
deploy_hf_spaces, deploy_modal,
deploy_render, deploy_streamlit,
get_pkg_path_from_name, setup_fly_io_app,
setup_gradio_app, setup_hf_app,
setup_modal_com_app, setup_render_com_app,
setup_streamlit_io_app)
console = Console()
api_process = None
ui_process = None
anonymous_telemetry = AnonymousTelemetry()
def signal_handler(sig, frame):
"""Signal handler to catch termination signals and kill server processes."""
global api_process, ui_process
console.print("\n🛑 [bold yellow]Stopping servers...[/bold yellow]")
if api_process:
api_process.terminate()
console.print("🛑 [bold yellow]API server stopped.[/bold yellow]")
if ui_process:
ui_process.terminate()
console.print("🛑 [bold yellow]UI server stopped.[/bold yellow]")
sys.exit(0)
@click.group()
@@ -18,89 +47,130 @@ def cli():
pass
anonymous_telemetry = AnonymousTelemetry()
def get_pkg_path_from_name(template: str):
try:
# Determine the installation location of the embedchain package
package_path = pkg_resources.resource_filename("embedchain", "")
except ImportError:
console.print("❌ [bold red]Failed to locate the 'embedchain' package. Is it installed?[/bold red]")
@cli.command()
@click.argument("app_name")
@click.option("--docker", is_flag=True, help="Use docker to create the app.")
@click.pass_context
def create_app(ctx, app_name, docker):
if Path(app_name).exists():
console.print(
f"❌ [red]Directory '{app_name}' already exists. Try using a new directory name, or remove it.[/red]"
)
return
# Construct the source path from the embedchain package
src_path = os.path.join(package_path, "deployment", template)
os.makedirs(app_name)
os.chdir(app_name)
if not os.path.exists(src_path):
console.print(f"❌ [bold red]Template '{template}' not found.[/bold red]")
# Step 1: Download the zip file
zip_url = "http://github.com/embedchain/ec-admin/archive/main.zip"
console.print(f"Creating a new embedchain app in [green]{Path().resolve()}[/green]\n")
try:
response = requests.get(zip_url)
response.raise_for_status()
with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
tmp_file.write(response.content)
zip_file_path = tmp_file.name
console.print("✅ [bold green]Fetched template successfully.[/bold green]")
except requests.RequestException as e:
console.print(f"❌ [bold red]Failed to download zip file: {e}[/bold red]")
anonymous_telemetry.capture(event_name="ec_create_app", properties={"success": False})
return
return src_path
def setup_fly_io_app(extra_args):
fly_launch_command = ["fly", "launch", "--region", "sjc", "--no-deploy"] + list(extra_args)
# Step 2: Extract the zip file
try:
console.print(f"🚀 [bold cyan]Running: {' '.join(fly_launch_command)}[/bold cyan]")
shutil.move(".env.example", ".env")
subprocess.run(fly_launch_command, check=True)
console.print("✅ [bold green]'fly launch' executed successfully.[/bold green]")
except subprocess.CalledProcessError as e:
console.print(f"❌ [bold red]An error occurred: {e}[/bold red]")
except FileNotFoundError:
console.print(
"❌ [bold red]'fly' command not found. Please ensure Fly CLI is installed and in your PATH.[/bold red]"
)
with zipfile.ZipFile(zip_file_path, "r") as zip_ref:
# Get the name of the root directory inside the zip file
root_dir = Path(zip_ref.namelist()[0])
for member in zip_ref.infolist():
# Build the path to extract the file to, skipping the root directory
target_file = Path(member.filename).relative_to(root_dir)
source_file = zip_ref.open(member, "r")
if member.is_dir():
# Create directory if it doesn't exist
os.makedirs(target_file, exist_ok=True)
else:
with open(target_file, "wb") as file:
# Write the file
shutil.copyfileobj(source_file, file)
console.print("✅ [bold green]Extracted zip file successfully.[/bold green]")
anonymous_telemetry.capture(event_name="ec_create_app", properties={"success": True})
except zipfile.BadZipFile:
console.print("❌ [bold red]Error in extracting zip file. The file might be corrupted.[/bold red]")
anonymous_telemetry.capture(event_name="ec_create_app", properties={"success": False})
return
def setup_modal_com_app(extra_args):
modal_setup_file = os.path.join(os.path.expanduser("~"), ".modal.toml")
if os.path.exists(modal_setup_file):
console.print(
"""✅ [bold green]Modal setup already done. You can now install the dependencies by doing \n
`pip install -r requirements.txt`[/bold green]"""
)
if docker:
subprocess.run(["docker-compose", "build"], check=True)
else:
modal_setup_cmd = ["modal", "setup"] + list(extra_args)
console.print(f"🚀 [bold cyan]Running: {' '.join(modal_setup_cmd)}[/bold cyan]")
subprocess.run(modal_setup_cmd, check=True)
shutil.move(".env.example", ".env")
console.print(
"""Great! Now you can install the dependencies by doing: \n
`pip install -r requirements.txt`\n
\n
To run your app locally:\n
`ec dev`
"""
)
ctx.invoke(install_reqs)
def setup_render_com_app():
render_setup_file = os.path.join(os.path.expanduser("~"), ".render/config.yaml")
if os.path.exists(render_setup_file):
console.print(
"""✅ [bold green]Render setup already done. You can now install the dependencies by doing \n
`pip install -r requirements.txt`[/bold green]"""
)
else:
render_setup_cmd = ["render", "config", "init"]
console.print(f"🚀 [bold cyan]Running: {' '.join(render_setup_cmd)}[/bold cyan]")
subprocess.run(render_setup_cmd, check=True)
shutil.move(".env.example", ".env")
console.print(
"""Great! Now you can install the dependencies by doing: \n
`pip install -r requirements.txt`\n
\n
To run your app locally:\n
`ec dev`
"""
)
@cli.command()
def install_reqs():
try:
console.print("Installing python requirements...\n")
time.sleep(2)
os.chdir("api")
subprocess.run(["pip", "install", "-r", "requirements.txt"], check=True)
os.chdir("..")
console.print("\n ✅ [bold green]Installed API requirements successfully.[/bold green]\n")
except Exception as e:
console.print(f"❌ [bold red]Failed to install API requirements: {e}[/bold red]")
anonymous_telemetry.capture(event_name="ec_install_reqs", properties={"success": False})
return
try:
os.chdir("ui")
subprocess.run(["yarn"], check=True)
console.print("\n✅ [bold green]Successfully installed frontend requirements.[/bold green]")
anonymous_telemetry.capture(event_name="ec_install_reqs", properties={"success": True})
except Exception as e:
console.print(f"❌ [bold red]Failed to install frontend requirements. Error: {e}[/bold red]")
anonymous_telemetry.capture(event_name="ec_install_reqs", properties={"success": False})
def setup_streamlit_io_app():
# nothing needs to be done here
console.print("Great! Now you can install the dependencies by doing `pip install -r requirements.txt`")
@cli.command()
@click.option("--docker", is_flag=True, help="Run inside docker.")
def start(docker):
if docker:
subprocess.run(["docker-compose", "up"], check=True)
return
# Set up signal handling
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
# Step 1: Start the API server
try:
os.chdir("api")
api_process = subprocess.Popen(["python", "-m", "main"], stdout=None, stderr=None)
os.chdir("..")
console.print("✅ [bold green]API server started successfully.[/bold green]")
except Exception as e:
console.print(f"❌ [bold red]Failed to start the API server: {e}[/bold red]")
anonymous_telemetry.capture(event_name="ec_start", properties={"success": False})
return
# Sleep for 2 seconds to give the user time to read the message
time.sleep(2)
# Step 2: Install UI requirements and start the UI server
try:
os.chdir("ui")
subprocess.run(["yarn"], check=True)
ui_process = subprocess.Popen(["yarn", "dev"])
console.print("✅ [bold green]UI server started successfully.[/bold green]")
anonymous_telemetry.capture(event_name="ec_start", properties={"success": True})
except Exception as e:
console.print(f"❌ [bold red]Failed to start the UI server: {e}[/bold red]")
anonymous_telemetry.capture(event_name="ec_start", properties={"success": False})
# Keep the script running until it receives a kill signal
try:
api_process.wait()
ui_process.wait()
except KeyboardInterrupt:
console.print("\n🛑 [bold yellow]Stopping server...[/bold yellow]")
@cli.command()
@@ -108,7 +178,10 @@ def setup_streamlit_io_app():
@click.argument("extra_args", nargs=-1, type=click.UNPROCESSED)
def create(template, extra_args):
anonymous_telemetry.capture(event_name="ec_create", properties={"template_used": template})
src_path = get_pkg_path_from_name(template)
template_dir = template
if "/" in template_dir:
template_dir = template.split("/")[1]
src_path = get_pkg_path_from_name(template_dir)
shutil.copytree(src_path, os.getcwd(), dirs_exist_ok=True)
console.print(f"✅ [bold green]Successfully created app from template '{template}'.[/bold green]")
@@ -120,6 +193,10 @@ def create(template, extra_args):
setup_render_com_app()
elif template == "streamlit.io":
setup_streamlit_io_app()
elif template == "gradio.app":
setup_gradio_app()
elif template == "hf/gradio.app" or template == "hf/streamlit.io":
setup_hf_app()
else:
raise ValueError(f"Unknown template '{template}'.")
@@ -187,6 +264,17 @@ def run_dev_render_com(debug, host, port):
console.print("\n🛑 [bold yellow]FastAPI server stopped[/bold yellow]")
def run_dev_gradio():
gradio_run_cmd = ["gradio", "app.py"]
try:
console.print(f"🚀 [bold cyan]Running Gradio app with command: {' '.join(gradio_run_cmd)}[/bold cyan]")
subprocess.run(gradio_run_cmd, check=True)
except subprocess.CalledProcessError as e:
console.print(f"❌ [bold red]An error occurred: {e}[/bold red]")
except KeyboardInterrupt:
console.print("\n🛑 [bold yellow]Gradio server stopped[/bold yellow]")
@cli.command()
@click.option("--debug", is_flag=True, help="Enable or disable debug mode.")
@click.option("--host", default="127.0.0.1", help="The host address to run the FastAPI app on.")
@@ -204,124 +292,22 @@ def dev(debug, host, port):
run_dev_modal_com()
elif template == "render.com":
run_dev_render_com(debug, host, port)
elif template == "streamlit.io":
elif template == "streamlit.io" or template == "hf/streamlit.app":
run_dev_streamlit_io()
elif template == "gradio.app" or template == "hf/gradio.app":
run_dev_gradio()
else:
raise ValueError(f"Unknown template '{template}'.")
def read_env_file(env_file_path):
"""
Reads an environment file and returns a dictionary of key-value pairs.
Args:
env_file_path (str): The path to the .env file.
Returns:
dict: Dictionary of environment variables.
"""
env_vars = {}
with open(env_file_path, "r") as file:
for line in file:
# Ignore comments and empty lines
if line.strip() and not line.strip().startswith("#"):
# Assume each line is in the format KEY=VALUE
key_value_match = re.match(r"(\w+)=(.*)", line.strip())
if key_value_match:
key, value = key_value_match.groups()
env_vars[key] = value
return env_vars
def deploy_fly():
app_name = ""
with open("fly.toml", "r") as file:
for line in file:
if line.strip().startswith("app ="):
app_name = line.split("=")[1].strip().strip('"')
if not app_name:
console.print("❌ [bold red]App name not found in fly.toml[/bold red]")
return
env_vars = read_env_file(".env")
secrets_command = ["flyctl", "secrets", "set", "-a", app_name] + [f"{k}={v}" for k, v in env_vars.items()]
deploy_command = ["fly", "deploy"]
try:
# Set secrets
console.print(f"🔐 [bold cyan]Setting secrets for {app_name}[/bold cyan]")
subprocess.run(secrets_command, check=True)
# Deploy application
console.print(f"🚀 [bold cyan]Running: {' '.join(deploy_command)}[/bold cyan]")
subprocess.run(deploy_command, check=True)
console.print("✅ [bold green]'fly deploy' executed successfully.[/bold green]")
except subprocess.CalledProcessError as e:
console.print(f"❌ [bold red]An error occurred: {e}[/bold red]")
except FileNotFoundError:
console.print(
"❌ [bold red]'fly' command not found. Please ensure Fly CLI is installed and in your PATH.[/bold red]"
)
def deploy_modal():
modal_deploy_cmd = ["modal", "deploy", "app"]
try:
console.print(f"🚀 [bold cyan]Running: {' '.join(modal_deploy_cmd)}[/bold cyan]")
subprocess.run(modal_deploy_cmd, check=True)
console.print("✅ [bold green]'modal deploy' executed successfully.[/bold green]")
except subprocess.CalledProcessError as e:
console.print(f"❌ [bold red]An error occurred: {e}[/bold red]")
except FileNotFoundError:
console.print(
"❌ [bold red]'modal' command not found. Please ensure Modal CLI is installed and in your PATH.[/bold red]"
)
def deploy_streamlit():
streamlit_deploy_cmd = ["streamlit", "run", "app.py"]
try:
console.print(f"🚀 [bold cyan]Running: {' '.join(streamlit_deploy_cmd)}[/bold cyan]")
console.print(
"""\n\n✅ [bold yellow]To deploy a streamlit app, you can directly it from the UI.\n
Click on the 'Deploy' button on the top right corner of the app.\n
For more information, please refer to https://docs.embedchain.ai/deployment/streamlit_io
[/bold yellow]
\n\n"""
)
subprocess.run(streamlit_deploy_cmd, check=True)
except subprocess.CalledProcessError as e:
console.print(f"❌ [bold red]An error occurred: {e}[/bold red]")
except FileNotFoundError:
console.print(
"""❌ [bold red]'streamlit' command not found.\n
Please ensure Streamlit CLI is installed and in your PATH.[/bold red]"""
)
def deploy_render():
render_deploy_cmd = ["render", "blueprint", "launch"]
try:
console.print(f"🚀 [bold cyan]Running: {' '.join(render_deploy_cmd)}[/bold cyan]")
subprocess.run(render_deploy_cmd, check=True)
console.print("✅ [bold green]'render blueprint launch' executed successfully.[/bold green]")
except subprocess.CalledProcessError as e:
console.print(f"❌ [bold red]An error occurred: {e}[/bold red]")
except FileNotFoundError:
console.print(
"❌ [bold red]'render' command not found. Please ensure Render CLI is installed and in your PATH.[/bold red]"
)
@cli.command()
def deploy():
# Check for platform-specific files
template = ""
ec_app_name = ""
with open("embedchain.json", "r") as file:
embedchain_config = json.load(file)
ec_app_name = embedchain_config["name"] if "name" in embedchain_config else None
template = embedchain_config["provider"]
anonymous_telemetry.capture(event_name="ec_deploy", properties={"template_used": template})
@@ -333,5 +319,9 @@ def deploy():
deploy_render()
elif template == "streamlit.io":
deploy_streamlit()
elif template == "gradio.app":
deploy_gradio_app()
elif template.startswith("hf/"):
deploy_hf_spaces(ec_app_name)
else:
console.print("❌ [bold red]No recognized deployment platform found.[/bold red]")
+2 -4
View File
@@ -31,7 +31,7 @@ class Client:
)
@classmethod
def setup_dir(self):
def setup_dir(cls):
"""
Loads the user id from the config file if it exists, otherwise generates a new
one and saves it to the config file.
@@ -39,9 +39,7 @@ class Client:
:return: user id
:rtype: str
"""
if not os.path.exists(CONFIG_DIR):
os.makedirs(CONFIG_DIR)
os.makedirs(CONFIG_DIR, exist_ok=True)
if os.path.exists(CONFIG_FILE):
with open(CONFIG_FILE, "r") as f:
data = json.load(f)
+2 -2
View File
@@ -1,12 +1,12 @@
# flake8: noqa: F401
from .add_config import AddConfig, ChunkerConfig
from .apps.app_config import AppConfig
from .app_config import AppConfig
from .base_config import BaseConfig
from .cache_config import CacheConfig
from .embedder.base import BaseEmbedderConfig
from .embedder.base import BaseEmbedderConfig as EmbedderConfig
from .llm.base import BaseLlmConfig
from .pipeline_config import PipelineConfig
from .vectordb.chroma import ChromaDbConfig
from .vectordb.elasticsearch import ElasticsearchDBConfig
from .vectordb.opensearch import OpenSearchDBConfig
+5 -3
View File
@@ -1,7 +1,8 @@
import builtins
import logging
from collections.abc import Callable
from importlib import import_module
from typing import Callable, Optional
from typing import Optional
from embedchain.config.base_config import BaseConfig
from embedchain.helpers.json_serializable import register_deserializable
@@ -26,7 +27,7 @@ class ChunkerConfig(BaseConfig):
if self.min_chunk_size >= self.chunk_size:
raise ValueError(f"min_chunk_size {min_chunk_size} should be less than chunk_size {chunk_size}")
if self.min_chunk_size < self.chunk_overlap:
logging.warn(
logging.warning(
f"min_chunk_size {min_chunk_size} should be greater than chunk_overlap {chunk_overlap}, otherwise it is redundant." # noqa:E501
)
@@ -35,7 +36,8 @@ class ChunkerConfig(BaseConfig):
else:
self.length_function = length_function if length_function else len
def load_func(self, dotpath: str):
@staticmethod
def load_func(dotpath: str):
if "." not in dotpath:
return getattr(builtins, dotpath)
else:
@@ -15,8 +15,9 @@ class AppConfig(BaseAppConfig):
self,
log_level: str = "WARNING",
id: Optional[str] = None,
name: Optional[str] = None,
collect_metrics: Optional[bool] = True,
collection_name: Optional[str] = None,
**kwargs,
):
"""
Initializes a configuration class instance for an App. This is the simplest form of an embedchain app.
@@ -28,8 +29,6 @@ class AppConfig(BaseAppConfig):
:type id: Optional[str], optional
:param collect_metrics: Send anonymous telemetry to improve embedchain, defaults to True
:type collect_metrics: Optional[bool], optional
:param collection_name: Default collection name. It's recommended to use app.db.set_collection_name() instead,
defaults to None
:type collection_name: Optional[str], optional
"""
super().__init__(log_level=log_level, id=id, collect_metrics=collect_metrics, collection_name=collection_name)
self.name = name
super().__init__(log_level=log_level, id=id, collect_metrics=collect_metrics, **kwargs)
View File
+3 -3
View File
@@ -1,4 +1,4 @@
from typing import Any, Dict
from typing import Any
from embedchain.helpers.json_serializable import JSONSerializable
@@ -12,10 +12,10 @@ class BaseConfig(JSONSerializable):
"""Initializes a configuration class for a class."""
pass
def as_dict(self) -> Dict[str, Any]:
def as_dict(self) -> dict[str, Any]:
"""Return config object as a dict
:return: config object as dict
:rtype: Dict[str, Any]
:rtype: dict[str, Any]
"""
return vars(self)
+96
View File
@@ -0,0 +1,96 @@
from typing import Any, Optional
from embedchain.config.base_config import BaseConfig
from embedchain.helpers.json_serializable import register_deserializable
@register_deserializable
class CacheSimilarityEvalConfig(BaseConfig):
"""
This is the evaluator to compare two embeddings according to their distance computed in embedding retrieval stage.
In the retrieval stage, `search_result` is the distance used for approximate nearest neighbor search and have been
put into `cache_dict`. `max_distance` is used to bound this distance to make it between [0-`max_distance`].
`positive` is used to indicate this distance is directly proportional to the similarity of two entities.
If `positive` is set `False`, `max_distance` will be used to subtract this distance to get the final score.
:param max_distance: the bound of maximum distance.
:type max_distance: float
:param positive: if the larger distance indicates more similar of two entities, It is True. Otherwise, it is False.
:type positive: bool
"""
def __init__(
self,
strategy: Optional[str] = "distance",
max_distance: Optional[float] = 1.0,
positive: Optional[bool] = False,
):
self.strategy = strategy
self.max_distance = max_distance
self.positive = positive
@staticmethod
def from_config(config: Optional[dict[str, Any]]):
if config is None:
return CacheSimilarityEvalConfig()
else:
return CacheSimilarityEvalConfig(
strategy=config.get("strategy", "distance"),
max_distance=config.get("max_distance", 1.0),
positive=config.get("positive", False),
)
@register_deserializable
class CacheInitConfig(BaseConfig):
"""
This is a cache init config. Used to initialize a cache.
:param similarity_threshold: a threshold ranged from 0 to 1 to filter search results with similarity score higher \
than the threshold. When it is 0, there is no hits. When it is 1, all search results will be returned as hits.
:type similarity_threshold: float
:param auto_flush: it will be automatically flushed every time xx pieces of data are added, default to 20
:type auto_flush: int
"""
def __init__(
self,
similarity_threshold: Optional[float] = 0.8,
auto_flush: Optional[int] = 20,
):
if similarity_threshold < 0 or similarity_threshold > 1:
raise ValueError(f"similarity_threshold {similarity_threshold} should be between 0 and 1")
self.similarity_threshold = similarity_threshold
self.auto_flush = auto_flush
@staticmethod
def from_config(config: Optional[dict[str, Any]]):
if config is None:
return CacheInitConfig()
else:
return CacheInitConfig(
similarity_threshold=config.get("similarity_threshold", 0.8),
auto_flush=config.get("auto_flush", 20),
)
@register_deserializable
class CacheConfig(BaseConfig):
def __init__(
self,
similarity_eval_config: Optional[CacheSimilarityEvalConfig] = CacheSimilarityEvalConfig(),
init_config: Optional[CacheInitConfig] = CacheInitConfig(),
):
self.similarity_eval_config = similarity_eval_config
self.init_config = init_config
@staticmethod
def from_config(config: Optional[dict[str, Any]]):
if config is None:
return CacheConfig()
else:
return CacheConfig(
similarity_eval_config=CacheSimilarityEvalConfig.from_config(config.get("similarity_evaluation", {})),
init_config=CacheInitConfig.from_config(config.get("init_config", {})),
)
+4 -1
View File
@@ -5,7 +5,9 @@ from embedchain.helpers.json_serializable import register_deserializable
@register_deserializable
class BaseEmbedderConfig:
def __init__(self, model: Optional[str] = None, deployment_name: Optional[str] = None):
def __init__(
self, model: Optional[str] = None, deployment_name: Optional[str] = None, api_key: Optional[str] = None
):
"""
Initialize a new instance of an embedder config class.
@@ -16,3 +18,4 @@ class BaseEmbedderConfig:
"""
self.model = model
self.deployment_name = deployment_name
self.api_key = api_key

Some files were not shown because too many files have changed in this diff Show More