Merge branch 'main' into byt3h3ad-patch-1

pull/447/head
Alex 9 months ago committed by GitHub
commit cafc068c39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -2,7 +2,7 @@
## Our Pledge ## Our Pledge
We as members, contributors, and leaders pledge to make participation in our We as members, contributors, and leaders, pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status, identity and expression, level of experience, education, socio-economic status,
@ -10,20 +10,20 @@ nationality, personal appearance, race, religion, or sexual identity
and orientation. and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming, We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community. diverse, inclusive, and a healthy community.
## Our Standards ## Our Standards
Examples of behavior that contributes to a positive environment for our Examples of behavior that contribute to a positive environment for our
community include: community include:
* Demonstrating empathy and kindness toward other people * Demonstrating empathy and kindness towards other people
* Being respectful of differing opinions, viewpoints, and experiences * Being respectful and open to differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback * Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes, * Taking accountability and offering apologies to those who have been impacted by our errors,
and learning from the experience while also gaining insights from the situation
* Focusing on what is best not just for us as individuals, but for the * Focusing on what is best not just for us as individuals, but for the
overall community community as a whole
Examples of unacceptable behavior include: Examples of unacceptable behavior include:
@ -31,7 +31,7 @@ Examples of unacceptable behavior include:
advances of any kind advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks * Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment * Public or private harassment
* Publishing others' private information, such as a physical or email * Publishing other's private information, such as a physical or email
address, without their explicit permission address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a * Other conduct which could reasonably be considered inappropriate in a
professional setting professional setting
@ -74,7 +74,7 @@ the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction ### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed **Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community. unprofessional or unwelcome in the community space.
**Consequence**: A private, written warning from community leaders, providing **Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the clarity around the nature of the violation and an explanation of why the
@ -107,7 +107,7 @@ Violating these terms may lead to a permanent ban.
**Community Impact**: Demonstrating a pattern of violation of community **Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals. individual, or aggression towards or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within **Consequence**: A permanent ban from any sort of public interaction within
the community. the community.

@ -1,68 +1,41 @@
import platform import platform
import dotenv import dotenv
from application.celery import celery from application.celery import celery
from flask import Flask, request, redirect from flask import Flask, request, redirect
from application.core.settings import settings from application.core.settings import settings
from application.api.user.routes import user from application.api.user.routes import user
from application.api.answer.routes import answer from application.api.answer.routes import answer
from application.api.internal.routes import internal from application.api.internal.routes import internal
# Redirect PosixPath to WindowsPath on Windows
if platform.system() == "Windows": if platform.system() == "Windows":
import pathlib import pathlib
temp = pathlib.PosixPath
pathlib.PosixPath = pathlib.WindowsPath pathlib.PosixPath = pathlib.WindowsPath
# loading the .env file
dotenv.load_dotenv() dotenv.load_dotenv()
app = Flask(__name__) app = Flask(__name__)
app.register_blueprint(user) app.register_blueprint(user)
app.register_blueprint(answer) app.register_blueprint(answer)
app.register_blueprint(internal) app.register_blueprint(internal)
app.config["UPLOAD_FOLDER"] = UPLOAD_FOLDER = "inputs" app.config.update(
app.config["CELERY_BROKER_URL"] = settings.CELERY_BROKER_URL UPLOAD_FOLDER="inputs",
app.config["CELERY_RESULT_BACKEND"] = settings.CELERY_RESULT_BACKEND CELERY_BROKER_URL=settings.CELERY_BROKER_URL,
app.config["MONGO_URI"] = settings.MONGO_URI CELERY_RESULT_BACKEND=settings.CELERY_RESULT_BACKEND,
MONGO_URI=settings.MONGO_URI
)
celery.config_from_object("application.celeryconfig") celery.config_from_object("application.celeryconfig")
@app.route("/") @app.route("/")
def home(): def home():
""" return redirect('http://localhost:5173') if request.remote_addr in ('0.0.0.0', '127.0.0.1', 'localhost', '172.18.0.1') else 'Welcome to DocsGPT Backend!'
The frontend source code lives in the /frontend directory of the repository.
"""
if request.remote_addr in ('0.0.0.0', '127.0.0.1', 'localhost', '172.18.0.1'):
# If users locally try to access DocsGPT running in Docker,
# they will be redirected to the Frontend application.
return redirect('http://localhost:5173')
else:
# Handle other cases or render the default page
return 'Welcome to DocsGPT Backend!'
# handling CORS
@app.after_request @app.after_request
def after_request(response): def after_request(response):
response.headers.add("Access-Control-Allow-Origin", "*") response.headers.add("Access-Control-Allow-Origin", "*")
response.headers.add("Access-Control-Allow-Headers", "Content-Type,Authorization") response.headers.add("Access-Control-Allow-Headers", "Content-Type,Authorization")
response.headers.add("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS") response.headers.add("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS")
# response.headers.add("Access-Control-Allow-Credentials", "true")
return response return response
if __name__ == "__main__": if __name__ == "__main__":
app.run(debug=True, port=7091) app.run(debug=True, port=7091)

@ -19,7 +19,6 @@ services:
- CELERY_BROKER_URL=redis://redis:6379/0 - CELERY_BROKER_URL=redis://redis:6379/0
- CELERY_RESULT_BACKEND=redis://redis:6379/1 - CELERY_RESULT_BACKEND=redis://redis:6379/1
- MONGO_URI=mongodb://mongo:27017/docsgpt - MONGO_URI=mongodb://mongo:27017/docsgpt
- SELF_HOSTED_MODEL=$SELF_HOSTED_MODEL
ports: ports:
- "7091:7091" - "7091:7091"
volumes: volumes:

@ -4,7 +4,7 @@ Here's a step-by-step guide on how to setup an Amazon Lightsail instance to host
## Configuring your instance ## Configuring your instance
(If you know how to create a Lightsail instance, you can skip to the recommended configuration part by clicking here) (If you know how to create a Lightsail instance, you can skip to the recommended configuration part by clicking here).
### 1. Create an account or login to https://lightsail.aws.amazon.com ### 1. Create an account or login to https://lightsail.aws.amazon.com
@ -36,7 +36,7 @@ Your instance will be ready for use a few minutes after being created. To access
#### Clone the repository #### Clone the repository
A terminal window will pop up, and the first step will be to clone the DocsGPT git repository. A terminal window will pop up, and the first step will be to clone the DocsGPT git repository:
`git clone https://github.com/arc53/DocsGPT.git` `git clone https://github.com/arc53/DocsGPT.git`
@ -64,11 +64,11 @@ Enter the following command to access the folder in which DocsGPT docker-compose
#### Prepare the environment #### Prepare the environment
Inside the DocsGPT folder create a .env file and copy the contents of .env_sample into it. Inside the DocsGPT folder create a `.env` file and copy the contents of `.env_sample` into it.
`nano .env` `nano .env`
Make sure your .env file looks like this: Make sure your `.env` file looks like this:
``` ```
OPENAI_API_KEY=(Your OpenAI API key) OPENAI_API_KEY=(Your OpenAI API key)
@ -103,10 +103,10 @@ Before you are able to access your live instance, you must first enable the port
Open your Lightsail instance and head to "Networking". Open your Lightsail instance and head to "Networking".
Then click on "Add rule" under "IPv4 Firewall", enter 5173 as your port, and hit "Create". Then click on "Add rule" under "IPv4 Firewall", enter `5173` as your port, and hit "Create".
Repeat the process for port 7091. Repeat the process for port `7091`.
#### Access your instance #### Access your instance
Your instance will now be available under your Public IP Address and port 5173. Enjoy! Your instance will now be available under your Public IP Address and port `5173`. Enjoy!

@ -9,23 +9,23 @@ It will install all the dependencies and give you an option to download the loca
Otherwise, refer to this Guide: Otherwise, refer to this Guide:
1. Open and download this repository with `git clone https://github.com/arc53/DocsGPT.git` 1. Open and download this repository with `git clone https://github.com/arc53/DocsGPT.git`.
2. Create a .env file in your root directory and set your `API_KEY` with your openai api key 2. Create a `.env` file in your root directory and set your `API_KEY` with your [OpenAI api key](https://platform.openai.com/account/api-keys).
3. Run `docker-compose build && docker-compose up` 3. Run `docker-compose build && docker-compose up`.
4. Navigate to `http://localhost:5173/` 4. Navigate to `http://localhost:5173/`.
To stop just run Ctrl + C To stop just run `Ctrl + C`.
### Chrome Extension ### Chrome Extension
To install the Chrome extension: To install the Chrome extension:
1. In the DocsGPT GitHub repository, click on the "Code" button and select Download ZIP 1. In the DocsGPT GitHub repository, click on the "Code" button and select "Download ZIP".
2. Unzip the downloaded file to a location you can easily access 2. Unzip the downloaded file to a location you can easily access.
3. Open the Google Chrome browser and click on the three dots menu (upper right corner) 3. Open the Google Chrome browser and click on the three dots menu (upper right corner).
4. Select "More Tools" and then "Extensions" 4. Select "More Tools" and then "Extensions".
5. Turn on the "Developer mode" switch in the top right corner of the Extensions page 5. Turn on the "Developer mode" switch in the top right corner of the Extensions page.
6. Click on the "Load unpacked" button 6. Click on the "Load unpacked" button.
7. Select the "Chrome" folder where the DocsGPT files have been unzipped (docsgpt-main > extensions > chrome) 7. Select the "Chrome" folder where the DocsGPT files have been unzipped (docsgpt-main > extensions > chrome).
8. The extension should now be added to Google Chrome and can be managed on the Extensions page 8. The extension should now be added to Google Chrome and can be managed on the Extensions page.
9. To disable or remove the extension, simply turn off the toggle switch on the extension card or click the "Remove" button. 9. To disable or remove the extension, simply turn off the toggle switch on the extension card or click the "Remove" button.

@ -1,8 +1,8 @@
App currently has two main api endpoints: Currently, the application provides the following main API endpoints:
### /api/answer ### /api/answer
Its a POST request that sends a JSON in body with 4 values. Here is a JavaScript fetch example It's a POST request that sends a JSON in body with 4 values. It will receive an answer for a user provided question.
It will receive an answer for a user provided question Here is a JavaScript fetch example:
```js ```js
// answer (POST http://127.0.0.1:5000/api/answer) // answer (POST http://127.0.0.1:5000/api/answer)
@ -29,8 +29,8 @@ In response you will get a json document like this one:
``` ```
### /api/docs_check ### /api/docs_check
It will make sure documentation is loaded on a server (just run it every time user is switching between libraries (documentations) It will make sure documentation is loaded on a server (just run it every time user is switching between libraries (documentations)).
Its a POST request that sends a JSON in body with 1 value. Here is a JavaScript fetch example It's a POST request that sends a JSON in body with 1 value. Here is a JavaScript fetch example:
```js ```js
// answer (POST http://127.0.0.1:5000/api/docs_check) // answer (POST http://127.0.0.1:5000/api/docs_check)
@ -54,10 +54,10 @@ In response you will get a json document like this one:
### /api/combine ### /api/combine
Provides json that tells UI which vectors are available and where they are located with a simple get request Provides json that tells UI which vectors are available and where they are located with a simple get request.
Respsonse will include: Response will include:
date, description, docLink, fullName, language, location (local or docshub), model, name, version `date`, `description`, `docLink`, `fullName`, `language`, `location` (local or docshub), `model`, `name`, `version`.
Example of json in Docshub and local: Example of json in Docshub and local:
<img width="295" alt="image" src="https://user-images.githubusercontent.com/15183589/224714085-f09f51a4-7a9a-4efb-bd39-798029bb4273.png"> <img width="295" alt="image" src="https://user-images.githubusercontent.com/15183589/224714085-f09f51a4-7a9a-4efb-bd39-798029bb4273.png">
@ -73,11 +73,10 @@ HTML example:
<input type="text" name="user" value="local" hidden> <input type="text" name="user" value="local" hidden>
<input type="text" name="name" placeholder="Name:"> <input type="text" name="name" placeholder="Name:">
<button type="submit" class="py-2 px-4 text-white bg-blue-500 rounded-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> <button type="submit" class="py-2 px-4 text-white bg-blue-500 rounded-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
Upload Upload
</button> </button>
</form> </form>
``` ```
Response: Response:
@ -90,7 +89,7 @@ Response:
``` ```
### /api/task_status ### /api/task_status
Gets task status (task_id) from /api/upload Gets task status (`task_id`) from `/api/upload`:
```js ```js
// Task status (Get http://127.0.0.1:5000/api/task_status) // Task status (Get http://127.0.0.1:5000/api/task_status)
fetch("http://localhost:5001/api/task_status?task_id=b2d2a0f4-387c-44fd-a443-e4fe2e7454d1", { fetch("http://localhost:5001/api/task_status?task_id=b2d2a0f4-387c-44fd-a443-e4fe2e7454d1", {
@ -105,7 +104,7 @@ fetch("http://localhost:5001/api/task_status?task_id=b2d2a0f4-387c-44fd-a443-e4f
Responses: Responses:
There are two types of responses: There are two types of responses:
1. while task it still running, where "current" will show progress from 0 - 100 1. while task it still running, where "current" will show progress from 0 to 100
```json ```json
{ {
"result": { "result": {
@ -134,7 +133,7 @@ There are two types of responses:
``` ```
### /api/delete_old ### /api/delete_old
deletes old vecotstores Deletes old vectorstores:
```js ```js
// Task status (GET http://127.0.0.1:5000/api/docs_check) // Task status (GET http://127.0.0.1:5000/api/docs_check)
fetch("http://localhost:5001/api/task_status?task_id=b2d2a0f4-387c-44fd-a443-e4fe2e7454d1", { fetch("http://localhost:5001/api/task_status?task_id=b2d2a0f4-387c-44fd-a443-e4fe2e7454d1", {
@ -146,7 +145,8 @@ fetch("http://localhost:5001/api/task_status?task_id=b2d2a0f4-387c-44fd-a443-e4f
.then((res) => res.text()) .then((res) => res.text())
.then(console.log.bind(console)) .then(console.log.bind(console))
``` ```
response:
Response:
```json ```json
{ "status": "ok" } { "status": "ok" }

@ -1,9 +1,8 @@
### To start chatwoot extension: ### To start chatwoot extension:
1. Prepare and start the DocsGPT itself (load your documentation too) 1. Prepare and start the DocsGPT itself (load your documentation too). Follow our [wiki](https://github.com/arc53/DocsGPT/wiki) to start it and to [ingest](https://github.com/arc53/DocsGPT/wiki/How-to-train-on-other-documentation) data.
Follow our [wiki](https://github.com/arc53/DocsGPT/wiki) to start it and to [ingest](https://github.com/arc53/DocsGPT/wiki/How-to-train-on-other-documentation) data 2. Go to chatwoot, **Navigate** to your profile (bottom left), click on profile settings, scroll to the bottom and copy **Access Token**.
2. Go to chatwoot, Navigate to your profile (bottom left), click on profile settings, scroll to the bottom and copy Access Token 3. Navigate to `/extensions/chatwoot`. Copy `.env_sample` and create `.env` file.
2. Navigate to `/extensions/chatwoot`. Copy .env_sample and create .env file 4. Fill in the values.
3. Fill in the values
``` ```
docsgpt_url=<docsgpt_api_url> docsgpt_url=<docsgpt_api_url>
@ -12,18 +11,19 @@ docsgpt_key=<openai_api_key or other llm key>
chatwoot_token=<from part 2> chatwoot_token=<from part 2>
``` ```
4. start with `flask run` command 5. Start with `flask run` command.
If you want for bot to stop responding to questions for a specific user or session just add label `human-requested` in your conversation If you want for bot to stop responding to questions for a specific user or session just add label `human-requested` in your conversation.
### Optional (extra validation) ### Optional (extra validation)
In app.py uncomment lines 12-13 and 71-75 In `app.py` uncomment lines 12-13 and 71-75
in your .env file add: in your `.env` file add:
`account_id=(optional) 1 ` ```
account_id=(optional) 1
`assignee_id=(optional) 1` assignee_id=(optional) 1
```
Those are chatwoot values and will allow you to check if you are responding to correct widget and responding to questions assigned to specific user Those are chatwoot values and will allow you to check if you are responding to correct widget and responding to questions assigned to specific user.

@ -1,7 +1,7 @@
### How to set up react docsGPT widget on your website: ### How to set up react docsGPT widget on your website:
### Installation ### Installation
Got to your project and install a new dependency: `npm install docsgpt` Got to your project and install a new dependency: `npm install docsgpt`.
### Usage ### Usage
Go to your project and in the file where you want to use the widget import it: Go to your project and in the file where you want to use the widget import it:
@ -14,9 +14,9 @@ import "docsgpt/dist/style.css";
Then you can use it like this: `<DocsGPTWidget />` Then you can use it like this: `<DocsGPTWidget />`
DocsGPTWidget takes 3 props: DocsGPTWidget takes 3 props:
- `apiHost` - url of your DocsGPT API - `apiHost` — url of your DocsGPT API.
- `selectDocs` - documentation that you want to use for your widget (eg. `default` or `local/docs1.zip`) - `selectDocs` documentation that you want to use for your widget (eg. `default` or `local/docs1.zip`).
- `apiKey` - usually its empty - `apiKey` — usually its empty.
### How to use DocsGPTWidget with [Nextra](https://nextra.site/) (Next.js + MDX) ### How to use DocsGPTWidget with [Nextra](https://nextra.site/) (Next.js + MDX)
Install you widget as described above and then go to your `pages/` folder and create a new file `_app.js` with the following content: Install you widget as described above and then go to your `pages/` folder and create a new file `_app.js` with the following content:

@ -1,4 +1,4 @@
## To customise a main prompt navigate to `/application/prompt/combine_prompt.txt` ## To customize a main prompt navigate to `/application/prompt/combine_prompt.txt`
You can try editing it to see how the model responds. You can try editing it to see how the model responses.

@ -3,14 +3,13 @@ This AI can use any documentation, but first it needs to be prepared for similar
![video-example-of-how-to-do-it](https://d3dg1063dc54p9.cloudfront.net/videos/how-to-vectorise.gif) ![video-example-of-how-to-do-it](https://d3dg1063dc54p9.cloudfront.net/videos/how-to-vectorise.gif)
Start by going to Start by going to `/scripts/` folder.
`/scripts/` folder
If you open this file you will see that it uses RST files from the folder to create a `index.faiss` and `index.pkl`. If you open this file you will see that it uses RST files from the folder to create a `index.faiss` and `index.pkl`.
It currently uses OPEN_AI to create vector store, so make sure your documentation is not too big. Pandas cost me around 3-4$ It currently uses OPEN_AI to create vector store, so make sure your documentation is not too big. Pandas cost me around 3-4$.
You can usually find documentation on github in docs/ folder for most open-source projects. You can usually find documentation on github in `docs/` folder for most open-source projects.
### 1. Find documentation in .rst/.md and create a folder with it in your scripts directory ### 1. Find documentation in .rst/.md and create a folder with it in your scripts directory
Name it `inputs/` Name it `inputs/`
@ -36,7 +35,7 @@ It will tell you how much it will cost
Once you run it will use new context that is relevant to your documentation Once you run it will use new context that is relevant to your documentation
Make sure you select default in the dropdown in the UI Make sure you select default in the dropdown in the UI
## Customisation ## Customization
You can learn more about options while running ingest.py by running: You can learn more about options while running ingest.py by running:
`python ingest.py --help` `python ingest.py --help`

@ -1,10 +1,10 @@
Fortunately there are many providers for LLM's and some of them can even be ran locally Fortunately there are many providers for LLM's and some of them can even be ran locally
There are two models used in the app: There are two models used in the app:
1. Embeddings 1. Embeddings.
2. Text generation 2. Text generation.
By default we use OpenAI's models but if you want to change it or even run it locally, its very simple! By default, we use OpenAI's models but if you want to change it or even run it locally, it's very simple!
### Go to .env file or set environment variables: ### Go to .env file or set environment variables:
@ -18,7 +18,7 @@ By default we use OpenAI's models but if you want to change it or even run it lo
`VITE_API_STREAMING=<true or false (true if using openai, false for all others)>` `VITE_API_STREAMING=<true or false (true if using openai, false for all others)>`
You dont need to provide keys if you are happy with users providing theirs, so make sure you set LLM_NAME and EMBEDDINGS_NAME You don't need to provide keys if you are happy with users providing theirs, so make sure you set `LLM_NAME` and `EMBEDDINGS_NAME`.
Options: Options:
LLM_NAME (openai, manifest, cohere, Arc53/docsgpt-14b, Arc53/docsgpt-7b-falcon) LLM_NAME (openai, manifest, cohere, Arc53/docsgpt-14b, Arc53/docsgpt-7b-falcon)
@ -27,6 +27,6 @@ EMBEDDINGS_NAME (openai_text-embedding-ada-002, huggingface_sentence-transformer
That's it! That's it!
### Hosting everything locally and privately (for using our optimised open-source models) ### Hosting everything locally and privately (for using our optimised open-source models)
If you are working with important data and dont want anything to leave your premises. If you are working with important data and don't want anything to leave your premises.
Make sure you set SELF_HOSTED_MODEL as true in you .env variable and for your LLM_NAME you can use anything that's on Hugging Face Make sure you set `SELF_HOSTED_MODEL` as true in you `.env` variable and for your `LLM_NAME` you can use anything that's on Hugging Face.

@ -0,0 +1,7 @@
<svg width="33" height="33" viewBox="0 0 33 33" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.25 13.75V11C8.25 6.44875 9.625 2.75 16.5 2.75C23.375 2.75 24.75 6.44875 24.75 11V13.75" stroke="#3A363E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M23.375 30.25H9.625C4.125 30.25 2.75 28.875 2.75 23.375V20.625C2.75 15.125 4.125 13.75 9.625 13.75H23.375C28.875 13.75 30.25 15.125 30.25 20.625V23.375C30.25 28.875 28.875 30.25 23.375 30.25Z" stroke="#3A363E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M21.9951 22H22.0075" stroke="#3A363E" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16.4938 22H16.5061" stroke="#3A363E" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10.9924 22H11.0048" stroke="#3A363E" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 910 B

@ -0,0 +1,6 @@
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.75 28.455H12C6 28.455 3 26.955 3 19.455V11.955C3 5.95496 6 2.95496 12 2.95496H24C30 2.95496 33 5.95496 33 11.955V19.455C33 25.455 30 28.455 24 28.455H23.25C22.785 28.455 22.335 28.68 22.05 29.055L19.8 32.055C18.81 33.375 17.19 33.375 16.2 32.055L13.95 29.055C13.71 28.725 13.17 28.455 12.75 28.455Z" stroke="#3E3434" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 13.05L9 16.05L12 19.05" stroke="#3E3434" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M24 13.05L27 16.05L24 19.05" stroke="#3E3434" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M19.5 12.5549L16.5 19.545" stroke="#3E3434" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 951 B

@ -0,0 +1,5 @@
<svg width="29" height="29" viewBox="0 0 29 29" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.2708 22.9583H9.66663C4.83329 22.9583 2.41663 21.75 2.41663 15.7083V9.66663C2.41663 4.83329 4.83329 2.41663 9.66663 2.41663H19.3333C24.1666 2.41663 26.5833 4.83329 26.5833 9.66663V15.7083C26.5833 20.5416 24.1666 22.9583 19.3333 22.9583H18.7291C18.3545 22.9583 17.992 23.1395 17.7625 23.4416L15.95 25.8583C15.1525 26.9216 13.8475 26.9216 13.05 25.8583L11.2375 23.4416C11.0441 23.1758 10.597 22.9583 10.2708 22.9583Z" stroke="#363A3F" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8.45837 9.66663H20.5417" stroke="#363A3F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8.45837 15.7084H15.7084" stroke="#363A3F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 873 B

@ -1,7 +1,7 @@
export default function Hero({ className = '' }: { className?: string }) { export default function Hero({ className = '' }: { className?: string }) {
return ( return (
<div className={`flex flex-col ${className}`}> <div className={`mt-14 mb-12 flex flex-col `}>
<div className="mb-10 flex items-center justify-center"> <div className="mb-10 flex items-center justify-center ">
<p className="mr-2 text-4xl font-semibold">DocsGPT</p> <p className="mr-2 text-4xl font-semibold">DocsGPT</p>
<p className="text-[27px]">🦖</p> <p className="text-[27px]">🦖</p>
</div> </div>
@ -17,6 +17,53 @@ export default function Hero({ className = '' }: { className?: string }) {
Start by entering your query in the input field below and we will do the Start by entering your query in the input field below and we will do the
rest! rest!
</p> </p>
<div className="sections mt-1 flex flex-wrap items-center justify-center gap-1 sm:gap-1 md:gap-0 ">
<div className=" rounded-[50px] bg-gradient-to-l from-[#6EE7B7]/70 via-[#3B82F6] to-[#9333EA]/50 p-1 md:rounded-tr-none md:rounded-br-none">
<div className="h-full rounded-[45px] bg-white p-6 md:rounded-tr-none md:rounded-br-none">
<img
src="/message-text.svg"
alt="lock"
className="h-[24px] w-[24px]"
/>
<h2 className="mt-2 mb-3 text-lg font-bold">Chat with Your Data</h2>
<p className="w-[250px] text-xs text-gray-500">
DocsGPT will use your data to answer questions. Whether its
documentation, source code, or Microsoft files, DocsGPT allows you
to have interactive conversations and find answers based on the
provided data.
</p>
</div>
</div>
<div className=" rounded-[50px] bg-gradient-to-r from-[#6EE7B7]/70 via-[#3B82F6] to-[#9333EA]/50 p-1 md:rounded-none md:py-1 md:px-0">
<div className="rounded-[45px] bg-white px-6 py-4 md:rounded-none">
<img src="/lock.svg" alt="lock" className="h-[24px] w-[24px]" />
<h2 className="mt-2 mb-3 text-lg font-bold">Secure Data Storage</h2>
<p className=" w-[250px] text-xs text-gray-500">
The security of your data is our top priority. DocsGPT ensures the
utmost protection for your sensitive information. With secure data
storage and privacy measures in place, you can trust that your
data is kept safe and confidential.
</p>
</div>
</div>
<div className=" rounded-[50px] bg-gradient-to-l from-[#6EE7B7]/80 via-[#3B82F6] to-[#9333EA]/50 p-1 md:rounded-tl-none md:rounded-bl-none">
<div className="rounded-[45px] bg-white px-6 p-6 lg:rounded-tl-none lg:rounded-bl-none">
<img
src="/message-programming.svg"
alt="lock"
className="h-[24px] w-[24px]"
/>
<h2 className="mt-2 mb-3 text-lg font-bold">Open Source Code</h2>
<p className=" w-[250px] text-xs text-gray-500">
DocsGPT is built on open source principles, promoting transparency
and collaboration. The source code is freely available, enabling
developers to contribute, enhance, and customize the app to meet
their specific needs.
</p>
</div>
</div>
</div>
</div> </div>
); );
} }

@ -113,7 +113,7 @@ export default function Conversation() {
}; };
return ( return (
<div className="flex justify-center p-4"> <div className="flex flex-col justify-center p-4 md:flex-row">
{queries.length > 0 && !hasScrolledToLast ? ( {queries.length > 0 && !hasScrolledToLast ? (
<button <button
onClick={scrollIntoView} onClick={scrollIntoView}
@ -146,9 +146,11 @@ export default function Conversation() {
})} })}
</div> </div>
)} )}
{queries.length === 0 && <Hero className="mt-24 md:mt-52"></Hero>} {queries.length === 0 && (
<div className="fixed bottom-0 flex w-10/12 flex-col items-end self-center md:w-[50%]"> <Hero className="mt-24 h-[100vh] md:mt-52"></Hero>
<div className="flex w-full"> )}
<div className="relative bottom-0 flex w-10/12 flex-col items-end self-center md:fixed md:w-[50%]">
<div className="flex h-full w-full">
<div <div
ref={inputRef} ref={inputRef}
placeholder="Type your message here..." placeholder="Type your message here..."

Loading…
Cancel
Save