Spaces:
Runtime error
Runtime error
Commit
·
12611d9
1
Parent(s):
8411de3
Fix LFS tracking
Browse files- .gitattributes +1 -0
- .gitignore +83 -0
- Dockerfile +16 -0
- README.md +5 -4
- app.py +129 -0
- chroma_langchain_db1/chroma.sqlite3 +3 -0
- email_ai.py +75 -0
- requirements.txt +13 -0
.gitattributes
CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
chroma_langchain_db1/chroma.sqlite3 filter=lfs diff=lfs merge=lfs -text
|
.gitignore
ADDED
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#custom
|
2 |
+
report endpoint for flagging bit response
|
3 |
+
.env
|
4 |
+
*.pdf
|
5 |
+
app copy.py
|
6 |
+
myenv/
|
7 |
+
|
8 |
+
# Byte-compiled / optimized / DLL files
|
9 |
+
__pycache__/
|
10 |
+
*.py[cod]
|
11 |
+
*$py.class
|
12 |
+
|
13 |
+
# C extensions
|
14 |
+
*.so
|
15 |
+
|
16 |
+
# Environment variables
|
17 |
+
.env
|
18 |
+
|
19 |
+
# Logs
|
20 |
+
*.log
|
21 |
+
logs/
|
22 |
+
|
23 |
+
# Virtual environment
|
24 |
+
venv/
|
25 |
+
env/
|
26 |
+
*.venv
|
27 |
+
*.env/
|
28 |
+
|
29 |
+
# Dependency directories
|
30 |
+
pip-wheel-metadata/
|
31 |
+
*.egg-info/
|
32 |
+
.dist-info/
|
33 |
+
.Python
|
34 |
+
node_modules/
|
35 |
+
|
36 |
+
# Operating system files
|
37 |
+
.DS_Store
|
38 |
+
Thumbs.db
|
39 |
+
|
40 |
+
# Database files
|
41 |
+
# *.sqlite3
|
42 |
+
*.db
|
43 |
+
|
44 |
+
# ChromaDB files
|
45 |
+
chroma/
|
46 |
+
*.chroma
|
47 |
+
# chroma.sqlite3
|
48 |
+
|
49 |
+
# Hugging Face Spaces large files
|
50 |
+
.git-lfs*
|
51 |
+
|
52 |
+
# Temporary files
|
53 |
+
*.bak
|
54 |
+
*.swp
|
55 |
+
*.tmp
|
56 |
+
|
57 |
+
# IDE and editor settings
|
58 |
+
.idea/
|
59 |
+
.vscode/
|
60 |
+
*.code-workspace
|
61 |
+
|
62 |
+
# Jupyter Notebook checkpoints
|
63 |
+
.ipynb_checkpoints/
|
64 |
+
|
65 |
+
# Build artifacts
|
66 |
+
build/
|
67 |
+
dist/
|
68 |
+
*.egg
|
69 |
+
*.whl
|
70 |
+
|
71 |
+
# Coverage reports
|
72 |
+
htmlcov/
|
73 |
+
.coverage
|
74 |
+
.tox/
|
75 |
+
.cache/
|
76 |
+
|
77 |
+
# Deployment files
|
78 |
+
*.pid
|
79 |
+
*.lock
|
80 |
+
*.sock
|
81 |
+
|
82 |
+
# Ignore any large files not tracked by Git LFS
|
83 |
+
!*.lfs
|
Dockerfile
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
|
2 |
+
# you will also find guides on how best to write your Dockerfile
|
3 |
+
|
4 |
+
FROM python:3.9-slim
|
5 |
+
|
6 |
+
RUN useradd -m -u 1000 user
|
7 |
+
USER user
|
8 |
+
ENV PATH="/home/user/.local/bin:$PATH"
|
9 |
+
|
10 |
+
WORKDIR /app
|
11 |
+
|
12 |
+
COPY --chown=user ./requirements.txt requirements.txt
|
13 |
+
RUN pip install --no-cache-dir --upgrade -r requirements.txt
|
14 |
+
|
15 |
+
COPY --chown=user . /app
|
16 |
+
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
|
README.md
CHANGED
@@ -1,10 +1,11 @@
|
|
1 |
---
|
2 |
-
title: Email
|
3 |
-
emoji:
|
4 |
-
colorFrom:
|
5 |
-
colorTo:
|
6 |
sdk: docker
|
7 |
pinned: false
|
|
|
8 |
---
|
9 |
|
10 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
---
|
2 |
+
title: Email AI
|
3 |
+
emoji: 🌍
|
4 |
+
colorFrom: red
|
5 |
+
colorTo: pink
|
6 |
sdk: docker
|
7 |
pinned: false
|
8 |
+
short_description: testing fastapi server
|
9 |
---
|
10 |
|
11 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
app.py
ADDED
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI, Depends, HTTPException, Header, File, UploadFile
|
2 |
+
from pydantic import BaseModel
|
3 |
+
from typing import List, Dict, Optional
|
4 |
+
from email_ai import initialize_conversation, intro_message, get_chat_model_completions
|
5 |
+
|
6 |
+
import google.generativeai as genai
|
7 |
+
import os
|
8 |
+
from dotenv import load_dotenv
|
9 |
+
|
10 |
+
import speech_recognition as sr
|
11 |
+
from io import BytesIO
|
12 |
+
import wave
|
13 |
+
|
14 |
+
# Load environment variables
|
15 |
+
load_dotenv()
|
16 |
+
# gemini_api_key = os.getenv("GEMINI_API_KEY")
|
17 |
+
# genai.configure(api_key=gemini_api_key)
|
18 |
+
|
19 |
+
# Define a secret API key (use environment variables in production)
|
20 |
+
API_KEY = os.getenv("API_KEY")
|
21 |
+
|
22 |
+
app = FastAPI()
|
23 |
+
|
24 |
+
# Initialize speech recognizer
|
25 |
+
recognizer = sr.Recognizer()
|
26 |
+
|
27 |
+
# Pydantic models for request/response validation
|
28 |
+
class Message(BaseModel):
|
29 |
+
role: str
|
30 |
+
content: str
|
31 |
+
|
32 |
+
class ChatRequest(BaseModel):
|
33 |
+
message: str
|
34 |
+
|
35 |
+
class ChatResponse(BaseModel):
|
36 |
+
response: str
|
37 |
+
conversation: List[Message]
|
38 |
+
|
39 |
+
class Report(BaseModel):
|
40 |
+
response: str
|
41 |
+
message: str
|
42 |
+
timestamp: str
|
43 |
+
|
44 |
+
# Dependency to check the API key
|
45 |
+
async def verify_api_key(x_api_key: str = Header(...)):
|
46 |
+
if x_api_key != API_KEY:
|
47 |
+
raise HTTPException(status_code=403, detail="Unauthorized")
|
48 |
+
|
49 |
+
@app.get("/init", response_model=ChatResponse, dependencies=[Depends(verify_api_key)])
|
50 |
+
async def get_conversation():
|
51 |
+
global llm, chroma_retriever, conversation_bot
|
52 |
+
|
53 |
+
conversation_bot = [Message(role="bot", content=intro_message)]
|
54 |
+
llm, chroma_retriever = initialize_conversation()
|
55 |
+
|
56 |
+
return ChatResponse(
|
57 |
+
response=intro_message,
|
58 |
+
conversation=conversation_bot
|
59 |
+
)
|
60 |
+
|
61 |
+
@app.post("/chat", response_model=ChatResponse, dependencies=[Depends(verify_api_key)])
|
62 |
+
async def send_message(request: ChatRequest):
|
63 |
+
global conversation_bot
|
64 |
+
|
65 |
+
conversation_bot.append(Message(role="user", content=request.message))
|
66 |
+
response_assistant = get_chat_model_completions(llm, chroma_retriever, request.message)
|
67 |
+
conversation_bot.append(Message(role="bot", content=response_assistant.content))
|
68 |
+
|
69 |
+
return ChatResponse(
|
70 |
+
response=response_assistant.content,
|
71 |
+
conversation=conversation_bot
|
72 |
+
)
|
73 |
+
|
74 |
+
# Voice processing endpoint
|
75 |
+
@app.post("/process-voice")
|
76 |
+
async def process_voice(audio_file: UploadFile = File(...), dependencies=[Depends(verify_api_key)]):
|
77 |
+
# async def process_voice(name: str):
|
78 |
+
|
79 |
+
global conversation_bot
|
80 |
+
|
81 |
+
try:
|
82 |
+
# Read the audio file
|
83 |
+
contents = await audio_file.read()
|
84 |
+
audio_data = BytesIO(contents)
|
85 |
+
|
86 |
+
# Convert audio to wav format for speech recognition
|
87 |
+
with sr.AudioFile(audio_data) as source:
|
88 |
+
audio = recognizer.record(source)
|
89 |
+
|
90 |
+
# Perform speech recognition
|
91 |
+
text = recognizer.recognize_google(audio)
|
92 |
+
print(text)
|
93 |
+
|
94 |
+
conversation_bot.append(Message(role="user", content=text))
|
95 |
+
response_assistant = get_chat_model_completions(llm, chroma_retriever, text)
|
96 |
+
conversation_bot.append(Message(role="bot", content=response_assistant.content))
|
97 |
+
# print('response_assistant.content')
|
98 |
+
return {
|
99 |
+
"transcribed_text": text,
|
100 |
+
"response": response_assistant.content
|
101 |
+
}
|
102 |
+
|
103 |
+
except Exception as e:
|
104 |
+
return {"error": f"Error processing voice input: {str(e)}"}
|
105 |
+
|
106 |
+
@app.post("/report")
|
107 |
+
async def handle_feedback(
|
108 |
+
request: Report,
|
109 |
+
dependencies=[Depends(verify_api_key)]
|
110 |
+
):
|
111 |
+
# if x_api_key != VALID_API_KEY:
|
112 |
+
# raise HTTPException(status_code=403, detail="Invalid API key")
|
113 |
+
|
114 |
+
# Here you can store the feedback in your database
|
115 |
+
# For example:
|
116 |
+
# await db.store_feedback(message, is_positive)
|
117 |
+
|
118 |
+
return {"status": "success"}
|
119 |
+
|
120 |
+
@app.post("/reset")
|
121 |
+
async def reset_conversation():
|
122 |
+
global conversation_bot, llm, chroma_retriever
|
123 |
+
conversation_bot = [{'bot': intro_message}]
|
124 |
+
llm, chroma_retriever = initialize_conversation()
|
125 |
+
return {"status": "conversation reset"}
|
126 |
+
|
127 |
+
if __name__ == "__main__":
|
128 |
+
import uvicorn
|
129 |
+
uvicorn.run(app, host="0.0.0.0", port=8000)
|
chroma_langchain_db1/chroma.sqlite3
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:b1523f0becd11cbf3a849961b447e745e0c7bde5c7cd9b6faa8e30271974655a
|
3 |
+
size 1716224
|
email_ai.py
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
+
# Import all the required Libraries
|
3 |
+
|
4 |
+
import os
|
5 |
+
from pathlib import Path
|
6 |
+
import pandas as pd
|
7 |
+
from langchain_google_genai.chat_models import ChatGoogleGenerativeAI
|
8 |
+
from langchain_core.messages import HumanMessage, SystemMessage
|
9 |
+
from langchain_text_splitters import RecursiveCharacterTextSplitter
|
10 |
+
from langchain_huggingface import HuggingFaceEmbeddings
|
11 |
+
|
12 |
+
from langchain.vectorstores import Chroma
|
13 |
+
from langchain.schema.runnable import RunnablePassthrough
|
14 |
+
|
15 |
+
# from langchain_openai import ChatOpenAI
|
16 |
+
from langchain.prompts import ChatPromptTemplate
|
17 |
+
|
18 |
+
import google.generativeai as genai
|
19 |
+
import os
|
20 |
+
from dotenv import load_dotenv
|
21 |
+
|
22 |
+
# Load environment variables
|
23 |
+
load_dotenv()
|
24 |
+
gemini_api_key = os.getenv("GEMINI_API_KEY")
|
25 |
+
|
26 |
+
## load the GROQ And OpenAI API KEY
|
27 |
+
# gemini_api_key = open("gemini_api_key.txt", "r").read().strip()
|
28 |
+
|
29 |
+
def initialize_conversation():
|
30 |
+
|
31 |
+
llm = ChatGoogleGenerativeAI(model="gemini-1.5-flash-latest", api_key=gemini_api_key)
|
32 |
+
embeddings_model = HuggingFaceEmbeddings()
|
33 |
+
db = Chroma(persist_directory="/Users/daddy/aimlprojects/email_ai/chroma_langchain_db1", embedding_function=embeddings_model)
|
34 |
+
chroma_retriever = db.as_retriever(search_kwargs={"k":50})
|
35 |
+
|
36 |
+
return llm, chroma_retriever
|
37 |
+
# initialize_conversation()
|
38 |
+
|
39 |
+
# def get_template_prompt(query):
|
40 |
+
# return docs, prompt
|
41 |
+
|
42 |
+
intro_message = 'Hello! 😊 How can I assist you today?'
|
43 |
+
|
44 |
+
#"""You are a email assistant answering queries on a knowledgebase fo email threads provided in the context:
|
45 |
+
template = """Answer the question based only on the following context:
|
46 |
+
{context}
|
47 |
+
provide citations consisting of date of email and from whom the email was sent.
|
48 |
+
If you don't know the answer, just say that you don't know, don't try to make up an answer.
|
49 |
+
|
50 |
+
Question: {question}
|
51 |
+
"""
|
52 |
+
|
53 |
+
def get_chat_model_completions(llm, chroma_retriever, query):
|
54 |
+
|
55 |
+
# docs = chroma_retriever.get_relevant_documents(query) #, search_kwargs={"k": 3}) 'k' does not work here
|
56 |
+
prompt = ChatPromptTemplate.from_template(template)
|
57 |
+
|
58 |
+
chain = (
|
59 |
+
{"context": chroma_retriever, "question": RunnablePassthrough()}
|
60 |
+
| prompt
|
61 |
+
| llm
|
62 |
+
#| StrOutputParser()
|
63 |
+
)
|
64 |
+
|
65 |
+
# response = chain.invoke("Generate report on ideas for maintaining Enron's edge?")
|
66 |
+
# response = chain.invoke("what is disccussed in the emails?")
|
67 |
+
response = chain.invoke(query)
|
68 |
+
# response = chain.invoke("What are issues with the email system?")
|
69 |
+
# response = chain.invoke("What were the solutions proposed for email system issues?")
|
70 |
+
# response = chain.invoke("Was the issue with the emal system resolved and when?")
|
71 |
+
|
72 |
+
# print(response.content)
|
73 |
+
return response
|
74 |
+
# response=get_chat_model_completions(initialize_conversation(), query)
|
75 |
+
# print(response.response)
|
requirements.txt
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
pandas
|
2 |
+
langchain
|
3 |
+
langchain-community
|
4 |
+
# langchain-openai
|
5 |
+
langchain-core
|
6 |
+
langchain-google-genai
|
7 |
+
langchain-huggingface
|
8 |
+
chromadb
|
9 |
+
SpeechRecognition
|
10 |
+
python-dotenv
|
11 |
+
fastapi
|
12 |
+
uvicorn[standard]
|
13 |
+
python-multipart
|