AyoubChLin commited on
Commit
488f910
·
1 Parent(s): 6286af8
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ vector_store/db/chroma.sqlite3
2
+ vector_store/db/a83981c6-dd1a-4d14-9eba-0296b4da1fd2/data_level0.bin
app.py ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # # Cell 2 - Login Setup
3
+ # from huggingface_hub import login
4
+ # from dotenv import load_dotenv
5
+ # import os
6
+ # load_dotenv()
7
+
8
+ # login(token=os.getenv("HUGGINGFACEHUB_API_TOKEN"), add_to_git_credential=True)
9
+
10
+
11
+ # from embedding import embeddings
12
+ # from db.chroma import load_and_setup_db,search_cases
13
+ # from chat.chat.hermes_llm import ChatManager
14
+
15
+ # VECTOR_DB_PATH = os.getenv("VECTOR_DB_PATH")
16
+
17
+ # vector_store = load_and_setup_db(VECTOR_DB_PATH,embeddings)
18
+
19
+
20
+ # query = "somthing"
21
+
22
+ # result = search_cases(vectorstore=vector_store,query=query,k=1)
23
+ # legal_chat = ChatManager(temperature=0.1)
24
+
25
+ # respose = legal_chat.get_response(legal_chat[0]['content'],query=query)
26
+
27
+ import gradio as gr
28
+ import os
29
+ from huggingface_hub import login
30
+ from dotenv import load_dotenv
31
+ from embedding import embeddings
32
+ from db.chroma import load_and_setup_db, search_cases
33
+ from chat.hermes_llm import ChatManager
34
+
35
+ # Load environment variables
36
+ load_dotenv()
37
+
38
+ # Login to Hugging Face
39
+ login(token=os.getenv("HUGGINGFACEHUB_API_TOKEN"), add_to_git_credential=True)
40
+
41
+ # Initialize components
42
+ VECTOR_DB_PATH = os.getenv("VECTOR_DB_PATH")
43
+ vector_store = load_and_setup_db(VECTOR_DB_PATH, embeddings)
44
+ legal_chat = ChatManager(temperature=0.1)
45
+
46
+ def process_query(query, chat_history):
47
+ try:
48
+ # Search relevant cases
49
+ results = search_cases(vectorstore=vector_store, query=query, k=1)
50
+ response=None
51
+ if len(results)>0:
52
+ # Get response from chat manager
53
+ response = legal_chat.get_response(results[0]['content'], query=query)
54
+ else :
55
+ response = "No Document match"
56
+ # Update chat history
57
+ chat_history.append((query, response))
58
+ return "", chat_history
59
+ except Exception as e:
60
+ return "", chat_history + [(query, f"Error: {str(e)}")]
61
+
62
+ # Create Gradio interface
63
+ with gr.Blocks(title="Legal Chat Assistant") as demo:
64
+ gr.Markdown("# Legal Chat Assistant")
65
+ gr.Markdown("Ask questions about legal cases and get AI-powered responses.")
66
+
67
+ chatbot = gr.Chatbot(
68
+ [],
69
+ elem_id="chatbot",
70
+ bubble_full_width=False,
71
+ height=400
72
+ )
73
+
74
+ with gr.Row():
75
+ query_input = gr.Textbox(
76
+ placeholder="Enter your query here...",
77
+ show_label=False,
78
+ scale=4
79
+ )
80
+ submit_btn = gr.Button("Send", scale=1)
81
+
82
+
83
+ # Set up event handlers
84
+ submit_btn.click(
85
+ process_query,
86
+ inputs=[query_input, chatbot],
87
+ outputs=[query_input, chatbot]
88
+ )
89
+ query_input.submit(
90
+ process_query,
91
+ inputs=[query_input, chatbot],
92
+ outputs=[query_input, chatbot]
93
+ )
94
+
95
+ if __name__ == "__main__":
96
+ demo.launch(share=True)
chat/__init__.py ADDED
File without changes
chat/hermes_llm.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from langchain_community.chat_models import ChatOpenAI
3
+ from langchain_core.prompts import ChatPromptTemplate
4
+ from typing import List, Dict
5
+ import os
6
+ OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
7
+ OPENROUTER_API_BASE = "https://openrouter.ai/api/v1"
8
+ DEFAULT_MODEL = "nousresearch/hermes-3-llama-3.1-405b:free"
9
+
10
+ class ChatManager:
11
+ def __init__(self, temperature: float = 0.7):
12
+ self.chat = ChatOpenAI(
13
+ openai_api_base=OPENROUTER_API_BASE,
14
+ openai_api_key=OPENROUTER_API_KEY,
15
+ model_name=DEFAULT_MODEL,
16
+ temperature=temperature,
17
+ )
18
+
19
+ self.system_message = """You are an advanced assistant designed to help users by retrieving the most relevant information from a predefined set of documents or cases and then providing an accurate response based on that data.
20
+
21
+ Your job is as follows:
22
+
23
+ 1. When the user submits a query, match the query with the most relevant case from the database.
24
+ 2. Extract only the denoised and contextually relevant text from that case.
25
+ 3. Use that extracted text to answer the user's query with precision and clarity.
26
+ 4. If the relevant text isn't found, let the user know that the information is not available or ask for more clarification.
27
+ 5. Avoid providing information outside the scope of the retrieved text.
28
+
29
+ Always focus on relevance and clarity in your response, maintaining coherence with the user's original query."""
30
+
31
+ self.user_message = """
32
+ Context: {context}
33
+
34
+ Query: {query}
35
+ """
36
+
37
+ self.prompt = ChatPromptTemplate.from_messages([
38
+ ("system", self.system_message),
39
+ ("human", self.user_message),
40
+ ])
41
+
42
+ def get_response(self, context: str, query: str) -> str:
43
+ prompt_value = self.prompt.invoke({
44
+ "context": context,
45
+ "query": query
46
+ })
47
+ messages = prompt_value.to_messages()
48
+ response = self.chat(messages)
49
+ return response.content
db/__init__.py ADDED
File without changes
db/chroma.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain.vectorstores import Chroma
2
+ from langchain.embeddings import HuggingFaceEmbeddings
3
+ from typing import List, Dict, Optional
4
+ from tqdm import tqdm
5
+
6
+ def load_and_setup_db(
7
+ persist_directory: str,
8
+ embeddings
9
+ ) -> Chroma:
10
+ """
11
+ Load the previously created ChromaDB with the same embedding model.
12
+
13
+ Args:
14
+ persist_directory: Directory where the database is stored
15
+ embedding_model_name: Name of the embedding model to use
16
+
17
+ Returns:
18
+ Chroma: Loaded vector store
19
+ """
20
+
21
+ # Load the existing database
22
+ vectorstore = Chroma(
23
+ embedding_function=embeddings,
24
+ persist_directory=persist_directory
25
+ )
26
+
27
+ return vectorstore
28
+
29
+ def search_cases(
30
+ vectorstore: Chroma,
31
+ query: str,
32
+ k: int = 5,
33
+ metadata_filter: Optional[Dict] = None,
34
+ score_threshold: Optional[float] = 0.0
35
+ ) -> List[Dict]:
36
+ """
37
+ Search the database for relevant cases.
38
+
39
+ Args:
40
+ vectorstore: Loaded Chroma vector store
41
+ query: Search query text
42
+ k: Number of results to return
43
+ metadata_filter: Optional filter for metadata fields
44
+ score_threshold: Minimum similarity score threshold
45
+
46
+ Returns:
47
+ List of relevant documents with scores and metadata
48
+ """
49
+ # Perform similarity search with metadata filtering
50
+ docs_and_scores = vectorstore.similarity_search_with_score(
51
+ query,
52
+ k=k,
53
+ filter=metadata_filter
54
+ )
55
+
56
+ # Process and filter results
57
+ results = []
58
+ for doc, score in docs_and_scores:
59
+ # Convert score to similarity (assuming distance score)
60
+ similarity = 1 - score
61
+
62
+ # Apply score threshold
63
+ if score_threshold and similarity < score_threshold:
64
+ continue
65
+
66
+ result = {
67
+ 'content': doc.page_content,
68
+ 'metadata': doc.metadata,
69
+ 'similarity_score': round(similarity, 4)
70
+ }
71
+ results.append(result)
72
+ if len(results)==0 and len(docs_and_scores)>0:
73
+ results.append(docs_and_scores[0])
74
+ return results
75
+
76
+ # Example usage function
77
+ def search_and_display_results(
78
+ vectorstore: Chroma,
79
+ query: str,
80
+ k: int = 5,
81
+ metadata_filter: Optional[Dict] = None,
82
+ score_threshold: float = 0.7
83
+ ) -> None:
84
+ """
85
+ Search and display results in a formatted way.
86
+ """
87
+ print(f"\nSearching for: {query}")
88
+ print("-" * 50)
89
+
90
+ results = search_cases(
91
+ vectorstore=vectorstore,
92
+ query=query,
93
+ k=k,
94
+ metadata_filter=metadata_filter,
95
+ score_threshold=score_threshold
96
+ )
97
+
98
+ if not results:
99
+ print("No matching results found.")
100
+ return
101
+
102
+ print(f"Found {len(results)} relevant matches:\n")
103
+
104
+ for i, result in enumerate(results, 1):
105
+ print(f"Match {i}:")
106
+ print(f"Similarity Score: {result['similarity_score']}")
107
+ print(f"Metadata: {result['metadata']}")
108
+ print(f"Content: {result['content'][:200]}...") # Show first 200 chars
109
+ print("-" * 50)
embedding.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ from langchain.embeddings import HuggingFaceInferenceAPIEmbeddings
2
+ from dotenv import load_dotenv
3
+ import os
4
+ load_dotenv()
5
+
6
+ embeddings = HuggingFaceInferenceAPIEmbeddings(
7
+ api_key=os.getenv("HUGGINGFACEHUB_API_TOKEN"), model_name="sentence-transformers/all-MiniLM-L6-v2"
8
+ )
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ langchain
2
+ langchain_community
3
+ chromadb
4
+ python-dotenv
vector_store/db/a83981c6-dd1a-4d14-9eba-0296b4da1fd2/header.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:83384ec1ec80f415f9b29c84d9ef966930faf31d936cfa2c22eb0b0c9bf59924
3
+ size 100
vector_store/db/a83981c6-dd1a-4d14-9eba-0296b4da1fd2/index_metadata.pickle ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e29cdd64643b3a13902e63a70336a1287517f59e4873145c60c0f1179e68b795
3
+ size 752123
vector_store/db/a83981c6-dd1a-4d14-9eba-0296b4da1fd2/length.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:24281a3e8212857faa150d8b5f534cf0847f3971bd40a1144149b57c10410bbf
3
+ size 52000
vector_store/db/a83981c6-dd1a-4d14-9eba-0296b4da1fd2/link_lists.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:667a7d6a2ad2c3ab267035a264717476a2da859dd8cde2d1565c2bfb65610908
3
+ size 110344