diff --git a/Dockerfile b/Dockerfile index f39287d..50d5299 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,25 +1,19 @@ -FROM python:3.9-slim - +FROM python:3.12.7-slim-bullseye WORKDIR /app - COPY requirements.txt . -RUN apt-get update && apt-get install -y libmagic-dev +RUN apt-get update && apt-get install -y \ + build-essential \ + libmagic-dev \ + gcc \ + g++ \ + && rm -rf /var/lib/apt/lists/* RUN pip install --upgrade pip - RUN pip install --no-cache-dir -r requirements.txt - COPY . . - -EXPOSE 8000 - - -ENV PORT=8000 - -# Command to run the application -# CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file +CMD ["uvicorn", "api:app", "--host", "0.0.0.0", "--port", "10000"] \ No newline at end of file diff --git a/README.md b/README.md index 41cdef8..dfa18fe 100644 --- a/README.md +++ b/README.md @@ -192,28 +192,7 @@ percentage, missing keywords, and profile summary. - Choose between vector search or summarization for responses. - Support for multiple Open Source LLMs models. -### 21. Tech News Agent using Crew ai - -- **Route:** `/news_agent` -- **Description:** This endpoint leverages AI agents to conduct research and generate articles on various tech topics. The agents are designed to uncover groundbreaking technologies and narrate compelling tech stories. -- **Features:** - - Accepts a `topic` parameter specifying the tech topic of interest. - - Utilizes caching mechanisms for improved performance by storing and retrieving responses from Redis cache. - - Integrates with MongoDB for storing endpoint usage data. - - Returns articles and research findings related to the specified tech topic. - - Handles exceptions gracefully and returns error messages in JSON format. - -### 22. Query Database - -- **Route:** `/query_db` -- **Description:** This API endpoint facilitates querying SQL databases using a Cohere ReAct Agent, integrated with Langchain's SQLDBToolkit. -- **Feature:** - - Upload a `.db` file containing the database to be queried. - - Provide a natural language prompt or query to retrieve relevant information - from the database. - - Utilizes a Cohere ReAct Agent to process user queries and generate responses. - -### 23. MediGem: Medical Diagnosis AI Assistant +### 21. MediGem: Medical Diagnosis AI Assistant - **Route:** `/MediGem` - **Description:** This API endpoint leverages the New Google Gemini AI Model to analyze medical images and identify potential health conditions. @@ -226,7 +205,7 @@ percentage, missing keywords, and profile summary. - **Image Quality Note:** Indicates if certain aspects are 'Unable to be determined based on the provided image.' - **Disclaimer:** Includes the disclaimer: "Consult with a Doctor before making any decisions." -### 24. NoteGem: Automated Note-Taking Assistant +### 22. NoteGem: Automated Note-Taking Assistant - **Route:** `/NoteGem` - **Description:** This API endpoint leverages the Google Gemini AI Model to generate comprehensive notes from YouTube video transcripts. @@ -236,7 +215,50 @@ percentage, missing keywords, and profile summary. - **Error Handling for Transcripts:** If the transcript is not available, it returns a message indicating that the transcript is not available for transcription. - **AI Summary Generation:** The AI model generates a structured summary of the transcript focusing on main points, critical information, key takeaways, examples or case studies, quotes, and actionable steps. -### 25. Investment Risk Analyst Agent +### 23. Audio Video Transcriber + +- **Route:** `/transcriber` +- **Description:** This API endpoint allows users to upload audio or video files to be transcribed into text using the OpenAI Whisper model. +- **Feature:** + - **File Upload:** Users can upload audio or video files in various formats. + - **Transcription:** The API uses the OpenAI Whisper model to transcribe the uploaded file into text. + +### 24. Agrilens + +- **Route:** `/agrilens` +- **Description:** This API endpoint allows users to upload agricultural images and receive AI-powered insights into crops, pests, diseases, and overall health assessment. +The analysis also includes actionable recommendations for improving agricultural practices and yields. +- **Features:** + - **Image Upload:** Users can upload agricultural images in JPG, JPEG, or PNG formats. + - **Advanced Detection:** Identifies crops, pests, diseases, and farming equipment within the uploaded image. + - **Health Assessment:** Evaluates crop health, identifying stress factors or signs of disease. + - **Smart Recommendations:** Provides actionable insights for enhancing agricultural productivity, such as fertilizer, pesticide, or irrigation advice. + +### AGENTS Endpoint + +### 1. Tech News Agent using Crew ai + +- **Route:** `/news_agent` +- **Description:** This endpoint leverages AI agents to conduct research and generate articles on various tech topics. The agents are designed to uncover groundbreaking technologies and narrate compelling tech stories. +- **Features:** + - Accepts a `topic` parameter specifying the tech topic of interest. + - Utilizes caching mechanisms for improved performance by storing and retrieving responses from Redis cache. + - Integrates with MongoDB for storing endpoint usage data. + - Returns articles and research findings related to the specified tech topic. + - Handles exceptions gracefully and returns error messages in JSON format. + +### 2. Query Database + +- **Route:** `/query_db` +- **Description:** This API endpoint facilitates querying SQL databases using a Cohere ReAct Agent, integrated with Langchain's SQLDBToolkit. +- **Feature:** + - Upload a `.db` file containing the database to be queried. + - Provide a natural language prompt or query to retrieve relevant information + from the database. + - Utilizes a Cohere ReAct Agent to process user queries and generate responses. + + +### 3. Investment Risk Analyst Agent - **Route:** `/investment_risk_agent` - **Description:** This API endpoint coordinates a team of AI agents to perform comprehensive investment risk analysis and strategy development. @@ -247,7 +269,7 @@ percentage, missing keywords, and profile summary. - **Risk Assessment:** The risk management agent evaluates potential risks associated with the trading strategy and suggests mitigation measures. - **Execution Planning:** The execution agent develops a detailed plan for executing the trading strategy, considering the assessed risks. -### 26. Agent Doc +### 4. Agent Doc - **Route:** `/agent_doc` - **Description:** This API endpoint coordinates a team of AI agents to perform comprehensive healthcare diagnosis and treatment recommendations. @@ -256,15 +278,7 @@ percentage, missing keywords, and profile summary. - **Diagnosis:** The diagnostician agent analyzes the input data to provide a preliminary diagnosis with possible conditions. - **Treatment Recommendations:** The treatment advisor agent formulates a suitable treatment plan based on the diagnosis and user-provided information. -### 27. Audio Video Transcriber - -- **Route:** `/transcriber` -- **Description:** This API endpoint allows users to upload audio or video files to be transcribed into text using the OpenAI Whisper model. -- **Feature:** - - **File Upload:** Users can upload audio or video files in various formats. - - **Transcription:** The API uses the OpenAI Whisper model to transcribe the uploaded file into text. - -### 28. Job Posting Agent +### 5. Job Posting Agent - **Route:** `/job_posting_agent` - **Description:** This API endpoint coordinates a team of AI agents to generate a detailed and engaging job posting tailored to the company's culture and values. @@ -275,7 +289,7 @@ percentage, missing keywords, and profile summary. - **Job Posting Drafting:** The job description writer agent uses the insights to create a detailed, engaging, and enticing job posting that aligns with the company's culture and values. - **Review and Editing:** The review and editing specialist agent reviews the job posting for clarity, engagement, grammatical accuracy, and alignment with company values, refining it to ensure perfection. -### 29. ML Assistant Agent +### 6. ML Assistant Agent - **Route:** `/ml_assistant` - **Description:** This endpoint coordinates a team of AI agents to process an uploaded CSV file and a user-defined machine learning problem description. It aims to provide a clear problem definition, assess the data quality, recommend suitable machine learning models, and generate starter Python code for the project. diff --git a/agents/agent_doc/agents.py b/agents/agent_doc/agents.py index 8c9e18f..6d845bf 100644 --- a/agents/agent_doc/agents.py +++ b/agents/agent_doc/agents.py @@ -1,13 +1,11 @@ from crewai import Agent from .tools import scrape_tool, search_tool -from langchain_google_genai import ChatGoogleGenerativeAI import os import settings -llm=ChatGoogleGenerativeAI(model=settings.GEMINI_FLASH, - verbose=True, - temperature=0.7, - google_api_key=os.getenv("GOOGLE_API_KEY")) +os.environ["GEMINI_API_KEY"] = os.environ.get('GEMINI_API_KEY') + +llm = "gemini/gemini-1.5-flash-8b" diagnostician = Agent( diff --git a/agents/agent_doc/crew.py b/agents/agent_doc/crew.py index fa22a6b..476cf78 100644 --- a/agents/agent_doc/crew.py +++ b/agents/agent_doc/crew.py @@ -5,13 +5,12 @@ doc_crew = Crew( agents=[diagnostician, treatment_advisor], - tasks=[diagnose_task, treatment_task], - verbose=2 + tasks=[diagnose_task, treatment_task] ) def run_doc_crew(input_data): result = doc_crew.kickoff(inputs=input_data) - return result + return str(result) if __name__=='__main__': doc_agent_input ={ diff --git a/agents/investment_risk_analyst_agent/agents.py b/agents/investment_risk_analyst_agent/agents.py index 29d4cb8..e3ca7d5 100644 --- a/agents/investment_risk_analyst_agent/agents.py +++ b/agents/investment_risk_analyst_agent/agents.py @@ -2,14 +2,12 @@ from .tools import search_tool,scrape_tool from dotenv import load_dotenv load_dotenv() -from langchain_google_genai import ChatGoogleGenerativeAI import os import settings -llm=ChatGoogleGenerativeAI(model=settings.GEMINI_FLASH, - verbose=True, - temperature=0.5, - google_api_key=os.getenv("GOOGLE_API_KEY")) +os.environ["GEMINI_API_KEY"] = os.environ.get('GEMINI_API_KEY') + +llm = "gemini/gemini-1.5-flash-8b" data_analyst_agent = Agent( role="Data Analyst", diff --git a/agents/investment_risk_analyst_agent/crew.py b/agents/investment_risk_analyst_agent/crew.py index 18968c0..bc06c37 100644 --- a/agents/investment_risk_analyst_agent/crew.py +++ b/agents/investment_risk_analyst_agent/crew.py @@ -7,10 +7,9 @@ from .agents import data_analyst_agent,trading_strategy_agent,execution_agent,risk_management_agent from .tasks import data_analysis_task,strategy_development_task,risk_assessment_task,execution_planning_task -llm=ChatGoogleGenerativeAI(model="gemini-1.5-flash-latest", - verbose=True, - temperature=0.7, - google_api_key=os.getenv("GOOGLE_API_KEY")) +os.environ["GEMINI_API_KEY"] = os.environ.get('GEMINI_API_KEY') + +llm = "gemini/gemini-1.5-flash-8b" financial_trading_crew = Crew( @@ -31,7 +30,7 @@ def run_investment_crew(input_data): result = financial_trading_crew.kickoff(inputs=input_data) - return result + return str(result) if __name__=='__main__': financial_trading_inputs ={ diff --git a/agents/job_posting_agent/agents.py b/agents/job_posting_agent/agents.py index 0666f03..4dab313 100644 --- a/agents/job_posting_agent/agents.py +++ b/agents/job_posting_agent/agents.py @@ -2,12 +2,10 @@ from .tools import web_search_tool, serper_search_tool import os import settings -from langchain_google_genai import ChatGoogleGenerativeAI -llm=ChatGoogleGenerativeAI(model=settings.GEMINI_FLASH, - verbose=True, - temperature=0.7, - google_api_key=os.getenv("GOOGLE_API_KEY")) +os.environ["GEMINI_API_KEY"] = os.environ.get('GEMINI_API_KEY') + +llm = "gemini/gemini-1.5-flash-8b" class JobAgents(): diff --git a/agents/job_posting_agent/crew.py b/agents/job_posting_agent/crew.py index 2915201..2a40eab 100644 --- a/agents/job_posting_agent/crew.py +++ b/agents/job_posting_agent/crew.py @@ -32,7 +32,7 @@ def run_job_crew(input_data): result = job_crew.kickoff(input_data) - return result + return str(result) if __name__=='__main__': job_agent_input = { diff --git a/agents/ml_assistant/agents.py b/agents/ml_assistant/agents.py index 25e3034..4ab7abb 100644 --- a/agents/ml_assistant/agents.py +++ b/agents/ml_assistant/agents.py @@ -6,9 +6,8 @@ class MLAgents(): def __init__(self,model) -> None: - self.llm = ChatGroq( - api_key=os.environ['GROQ_API_KEY'], - model_name=model) + os.environ["GROQ_API_KEY"] = os.environ.get('GROQ_API_KEY') + self.llm = f"groq/{model}" def problem_definition_agent(self): return Agent( diff --git a/agents/ml_assistant/crew.py b/agents/ml_assistant/crew.py index 376e26c..5398356 100644 --- a/agents/ml_assistant/crew.py +++ b/agents/ml_assistant/crew.py @@ -28,7 +28,7 @@ def run_ml_crew(file_path, user_question, model="llama3-70b-8192"): # Format the input data for agents input_data = { "ml_problem": user_question, - "df": df.head(), + "df": df.head().to_json(orient="records"), "file_name": file_path } @@ -40,7 +40,7 @@ def run_ml_crew(file_path, user_question, model="llama3-70b-8192"): ) result = ml_crew.kickoff(input_data) - return result + return str(result) if __name__=="__main__": print(run_ml_crew(file_path="data/iris.csv", diff --git a/agents/tech_news_agent/agents.py b/agents/tech_news_agent/agents.py index 67eb1d9..e1b1112 100644 --- a/agents/tech_news_agent/agents.py +++ b/agents/tech_news_agent/agents.py @@ -2,15 +2,12 @@ from .tools import tool from dotenv import load_dotenv load_dotenv() -from langchain_google_genai import ChatGoogleGenerativeAI import os -## call the gemini models -llm=ChatGoogleGenerativeAI(model="gemini-1.5-flash", - verbose=True, - temperature=0.5, - google_api_key=os.getenv("GOOGLE_API_KEY")) +os.environ["GEMINI_API_KEY"] = os.environ.get('GEMINI_API_KEY') + +llm = "gemini/gemini-1.5-flash-8b" # Creating a senior researcher agent with memory and verbose mode diff --git a/agents/tech_news_agent/crew.py b/agents/tech_news_agent/crew.py index 32edddf..1de701d 100644 --- a/agents/tech_news_agent/crew.py +++ b/agents/tech_news_agent/crew.py @@ -11,7 +11,7 @@ def run_crew(topic): result = crew.kickoff(inputs={'topic': topic}) - return result + return str(result) if __name__=='__main__': print(run_crew(topic="AI in Constructions")) \ No newline at end of file diff --git a/api.py b/api.py index c1d293f..c67b1cb 100644 --- a/api.py +++ b/api.py @@ -15,7 +15,8 @@ from mongo import MongoDB from helper_functions import get_qa_chain,get_gemini_response,get_url_doc_qa,extract_transcript_details,\ get_gemini_response_health,get_gemini_pdf,read_sql_query,remove_substrings,questions_generator,groq_pdf,\ - summarize_audio,chatbot_send_message,extraxt_pdf_text,advance_rag_llama_index,parse_sql_response, extract_video_id + summarize_audio,chatbot_send_message,extraxt_pdf_text,advance_rag_llama_index,parse_sql_response, extract_video_id,\ + encode_image from langchain_groq import ChatGroq from langchain.chains.conversation.base import ConversationChain from langchain.chains.conversation.memory import ConversationBufferWindowMemory @@ -29,29 +30,31 @@ from sendgrid import SendGridAPIClient from sendgrid.helpers.mail import Mail from uuid import uuid4 -from agents.tech_news_agent.crew import run_crew -from agents.investment_risk_analyst_agent.crew import run_investment_crew -from agents.agent_doc.crew import run_doc_crew -from agents.job_posting_agent.crew import run_job_crew -from agents.ml_assistant.crew import run_ml_crew -from langchain.agents import AgentExecutor -from langchain_core.prompts import ChatPromptTemplate -from langchain_cohere.react_multi_hop.agent import create_cohere_react_agent -from langchain_cohere.chat_models import ChatCohere -from langchain_community.utilities.sql_database import SQLDatabase -from langchain_community.agent_toolkits import SQLDatabaseToolkit -import tempfile -import shutil from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound from slowapi import Limiter from slowapi.util import get_remote_address from slowapi.errors import RateLimitExceeded from groq import Groq - -os.environ["LANGCHAIN_TRACING_V2"]="true" -os.environ["LANGCHAIN_API_KEY"]=os.getenv("LANGCHAIN_API_KEY") -os.environ["LANGCHAIN_PROJECT"]="genify" -os.environ["LANGCHAIN_ENDPOINT"]="https://api.smith.langchain.com" +import openai +from dotenv import load_dotenv +# from agents.tech_news_agent.crew import run_crew +# from agents.investment_risk_analyst_agent.crew import run_investment_crew +# from agents.agent_doc.crew import run_doc_crew +# from agents.job_posting_agent.crew import run_job_crew +# from agents.ml_assistant.crew import run_ml_crew +# from langchain.agents import AgentExecutor +# from langchain_cohere.react_multi_hop.agent import create_cohere_react_agent +# from langchain_cohere.chat_models import ChatCohere +# from langchain_community.utilities.sql_database import SQLDatabase +# from langchain_community.agent_toolkits import SQLDatabaseToolkit +# import tempfile +# import shutil +load_dotenv(override=True) + +openai_compatible_client = openai.OpenAI( + base_url="https://api.groq.com/openai/v1", + api_key=os.getenv("GROQ_API_KEY") +) redis = Redis(host=os.getenv("REDIS_HOST"), port=settings.REDIS_PORT, password=os.getenv("REDIS_PASSWORD")) client = Groq() @@ -198,14 +201,14 @@ async def question_answer(prompt: str = Form(...)): else: print("Fetching response from the API") chain = get_qa_chain() - out = chain.invoke(prompt) - redis.set(cache_key, out["result"], ex=60) + out = chain.invoke({"input": prompt}) + redis.set(cache_key, out["answer"], ex=60) db = MongoDB() - payload = {"endpoint": "/qa_from_faqs", "prompt": prompt, "output": out["result"]} + payload = {"endpoint": "/qa_from_faqs", "prompt": prompt, "output": out["answer"]} mongo_data = {"Document": payload} result = db.insert_data(mongo_data) print(result) - return ResponseText(response=out["result"]) + return ResponseText(response=out["answer"]) except Exception as e: return ResponseText(response=f"Error: {str(e)}") @@ -217,12 +220,13 @@ async def qa_url_doc(url: list = Form(None), documents: List[UploadFile] = File( cached_response = redis.get(cache_key) if cached_response: print("Retrieving response from Redis cache") - out = {"result": cached_response.decode("utf-8")} - return ResponseText(response=out["result"]) + out = {"answer": cached_response.decode("utf-8")} + return ResponseText(response=out["answer"]) else: chain = get_url_doc_qa(url, documents) - out = chain.invoke(prompt) - redis.set(cache_key, out["result"], ex=60) + out = chain.invoke({"input": prompt}) + print(out) + redis.set(cache_key, out["answer"], ex=60) else: if documents: contents = [i.file.read().decode("utf-8") for i in documents] @@ -230,7 +234,7 @@ async def qa_url_doc(url: list = Form(None), documents: List[UploadFile] = File( chain = get_url_doc_qa(url, contents) else: raise Exception("Please provide either a URL or upload a document file.") - out = chain.invoke(prompt) + out = chain.invoke({"input": prompt}) db = MongoDB() payload = { @@ -238,12 +242,12 @@ async def qa_url_doc(url: list = Form(None), documents: List[UploadFile] = File( "prompt": prompt, "url": url, "documents": "If URL is null then they might have upload .txt file", - "output": out["result"] + "output": out["answer"] } mongo_data = {"Document": payload} result = db.insert_data(mongo_data) print(result) - return ResponseText(response=out["result"]) + return ResponseText(response=out["answer"]) except Exception as e: return ResponseText(response=f"Error: {str(e)}") @@ -256,7 +260,7 @@ async def youtube_video_transcribe_summarizer_gemini(url: str = Form(...)): print("Retrieving response from Redis cache") return ResponseText(response=cached_response.decode("utf-8")) - model = genai.GenerativeModel(settings.GEMINI_FLASH) + model = genai.GenerativeModel(settings.GEMINI_PRO_2_think) transcript_text = extract_transcript_details(url) response = model.generate_content(settings.youtube_transcribe_prompt + transcript_text) redis.set(cache_key, response.text, ex=60) @@ -314,8 +318,12 @@ async def blogs(topic: str = Form("Generative AI")): print("Retrieving response from Redis cache") return ResponseText(response=cached_response.decode("utf-8")) - model = genai.GenerativeModel(settings.GEMINI_FLASH) - blog_prompt = f""" You are expert in blog writing. Write a blog on the topic {topic}. Use a friendly and informative tone, and include examples and tips to encourage readers to get started with the topic provided. """ + model = genai.GenerativeModel(settings.GEMINI_PRO_2_think) + blog_prompt = f"""You are a professional blog writer with expertise in engaging and educational content creation. + Write a detailed and well-structured blog post on the topic: "{topic}". Use friendly, conversational tone that is both informative and easy to follow. + Break the content into clear sections with helpful subheadings. + Include real-life examples, actionable tips, and practical insights to help readers understand the topic and feel confident getting started. + Aim to inspire and empower your audience to take the next step.""" response = model.generate_content(blog_prompt) redis.set(cache_key, response.text, ex=60) db = MongoDB() @@ -336,17 +344,17 @@ async def talk_pdf(pdf: UploadFile = File(...),prompt: str = Form(...)): try: # contents = [i.file.read().decode("utf-8") for i in pdf ] chain = get_gemini_pdf(pdf.file) - out = chain.invoke(prompt) + out = chain.invoke({"input": prompt}) db = MongoDB() payload = { "endpoint" : "/talk2PDF", "prompt" : prompt, - "output" : out["result"] + "output" : out["answer"] } mongo_data = {"Document": payload} result = db.insert_data(mongo_data) print(result) - return ResponseText(response=out["result"]) + return ResponseText(response=out["answer"]) except Exception as e: return ResponseText(response=f"Error: {str(e)}") @@ -361,7 +369,7 @@ async def sql_query(prompt: str = Form("Tell me the employees living in city Noi cached_data = json.loads(cached_response) return cached_data - model = genai.GenerativeModel(settings.GEMINI_PRO_1_5) + model = genai.GenerativeModel(settings.GEMINI_PRO_2_think) response = model.generate_content([settings.text2sql_prompt, prompt]) output_query = remove_substrings(response.text) print(output_query) @@ -407,10 +415,11 @@ async def pdf_questions_generator(pdf: UploadFile = File(...)): return ResponseText(response=f"Error: {str(e)}") @app.post("/chat_groq", description= """This route uses groq for faster response using Language Processing Unit(LPU). - \n In model input default is llama-3.1-70b-versatile but you can choose gemma2-9b-it, gemma-7b-it, mixtral-8x7b-32768, llama-3.1-8b-instant, llama3-70b-8192 and llama3-8b-8192. + \n In model input default is meta-llama/llama-4-maverick-17b-128e-instruct but you can choose gemma2-9b-it, llama-3.3-70b-versatile, + mistral-saba-24b, llama-3.1-8b-instant, llama3-70b-8192 and deepseek-r1-distill-qwen-32b. \n conversational_memory_length ranges from 1 to 10. It keeps a list of the interactions of the conversation over time. It only uses the last K interactions """) -async def groq_chatbot(question: str = Form(...), model: Optional[str] = Form('llama-3.1-70b-versatile'), +async def groq_chatbot(question: str = Form(...), model: Optional[str] = Form('meta-llama/llama-4-maverick-17b-128e-instruct'), conversational_memory_length: Optional[int] = Form(5)): try: memory=ConversationBufferWindowMemory(k=conversational_memory_length) @@ -434,11 +443,11 @@ async def groq_chatbot(question: str = Form(...), model: Optional[str] = Form('l @app.post("/text_summarizer_groq", description= """This route uses groq for faster response using Language Processing Unit(LPU). - \n This route will provide the concise summary from the text provided & and model used is mixtral-8x7b-32768 + \n This route will provide the concise summary from the text provided & and model used is mistral-saba-24b """) async def groq_text_summary(input_text: str = Form(...)): try: - chat = ChatGroq(temperature=0, model_name="mixtral-8x7b-32768",api_key=os.environ['GROQ_API_KEY']) + chat = ChatGroq(temperature=0, model_name="mistral-saba-24b",api_key=os.environ['GROQ_API_KEY']) system = """You are a helpful AI assistant skilled at summarizing text. Your task is to summarize the following text in a clear and concise manner, capturing the main ideas and key points. Show result in the points. @@ -462,9 +471,9 @@ async def groq_text_summary(input_text: str = Form(...)): return ResponseText(response=f"Error: {str(e)}") @app.post("/RAG_PDF_Groq",description="The endpoint uses the pdf and give the answer based on the prompt provided using groq\ - In model input default is llama-3.1-70b-versatile but you can choose mixtral-8x7b-32768, gemma-7b-it, gemma2-9b-it, llama-3.1-8b-instant, llama3-70b-8192 and llama3-8b-8192.") + In model input default is meta-llama/llama-4-maverick-17b-128e-instruct but you can choose gemma2-9b-it, llama-3.3-70b-versatile, mistral-saba-24b, llama-3.1-8b-instant, llama3-70b-8192 and deepseek-r1-distill-qwen-32b.") async def talk_pdf_groq(pdf: UploadFile = File(...),prompt: str = Form(...), - model: Optional[str] = Form('llama-3.1-70b-versatile')): + model: Optional[str] = Form('meta-llama/llama-4-maverick-17b-128e-instruct')): try: rag_chain = groq_pdf(pdf.file,model) out = rag_chain.invoke(prompt) @@ -482,7 +491,7 @@ async def talk_pdf_groq(pdf: UploadFile = File(...),prompt: str = Form(...), except Exception as e: return ResponseText(response=f"Error: {str(e)}") -@app.post("/summarize_audio", description="""Endpoint to summarize an uploaded audio file using gemini-1.5-pro-latest.""") +@app.post("/summarize_audio", description="""Endpoint to summarize an uploaded audio file using gemini-2.0-flash-thinking-exp-01-21.""") async def summarize_audio_endpoint(audio_file: UploadFile = File(...)): try: cache_key = f"summarize_audio:{audio_file.filename}" @@ -506,12 +515,12 @@ async def summarize_audio_endpoint(audio_file: UploadFile = File(...)): return {"error": str(e)} @app.post("/stream_chat",description="This endpoint streams responses from the language model based on the user's input message.") -async def stream_chat(message: str = Form("What is RLHF in LLM?"),llm: str = Form("llama3-70b-8192")): +async def stream_chat(message: str = Form("What is RLHF in LLM?"),llm: str = Form("meta-llama/llama-4-maverick-17b-128e-instruct")): generator = chatbot_send_message(message,model=llm) return StreamingResponse(generator, media_type="text/event-stream") @app.post("/smart_ats", description="""This endpoint is developed using the powerful - Gemini Pro 1.5 model to streamline the hiring process by analyzing job descriptions and resumes. + Gemini Pro 2.0 thinking model to streamline the hiring process by analyzing job descriptions and resumes. It provides valuable insights such as job description match, missing keywords, and profile summary""") async def ats(resume_pdf: UploadFile = File(...), job_description: str = Form(...)): @@ -523,23 +532,23 @@ async def ats(resume_pdf: UploadFile = File(...), job_description: str = Form(.. return ResponseText(response=cached_response.decode("utf-8")) text = extraxt_pdf_text(resume_pdf.file) - model = genai.GenerativeModel(settings.GEMINI_PRO_1_5) + model = genai.GenerativeModel(settings.GEMINI_PRO_2_think) ats_prompt = f""" - Hey Act Like a skilled or very experienced ATS (Application Tracking System) - with a deep understanding of the tech field, software engineering, data science, data analysis, - and big data engineering. Your task is to evaluate the resume based on the given job description. - You must consider the job market is very competitive and you should provide - the best assistance for improving the resumes. Assign the percentage Matching based - on job description and - the missing keywords with high accuracy - resume:{text} - job description:{job_description} - - I want the response as per below structure - Job Description Match": "%","MissingKeywords": [],"Profile Summary": "". - Also, tell what more should be added or to be removed in the resume. - Also, provide the list of some technical questions along with their answers that can be asked in the interview based on the job description. - """ + You are an advanced and highly skilled Applicant Tracking System (ATS) with deep expertise in evaluating resumes for roles in the tech industry — including software engineering, data science, data analysis, and big data engineering. + + Your task is to critically evaluate the provided resume against the given job description. Keep in mind that the job market is highly competitive, and your goal is to offer precise, actionable feedback to help the candidate optimize their resume. + + Please provide the following in your response: + 1. "Job Description Match": Percentage (%) match between the resume and job description. + 2. "MissingKeywords": List of important keywords or skills present in the job description but missing from the resume. + 3. "Profile Summary": A concise summary highlighting the candidate’s strengths and areas of improvement. + 4. Resume Recommendations: Specific suggestions on what content should be **added, improved, or removed** to better align with the job description. + 5. Interview Preparation: A list of **technical interview questions** (along with ideal answers) relevant to the job description, to help the candidate prepare. + + Here is the input data: + Resume: {text} + Job Description: {job_description} + """ response = model.generate_content(ats_prompt) redis.set(cache_key, response.text, ex=20) @@ -558,9 +567,9 @@ async def ats(resume_pdf: UploadFile = File(...), job_description: str = Form(.. return ResponseText(response=f"Error: {str(e)}") @app.post("/advance_rag_llama_index",description="The endpoint build a Router that can choose whether to do vector search or summarization\ - In model input default is gemma2-9b-it but you can choose mixtral-8x7b-32768, gemma-7b-it, llama-3.1-70b-versatile, llama-3.1-8b-instant, llama3-70b-8192 and llama3-8b-8192.") + In model input default is mistral-saba-24b but you can choose gemma2-9b-it, llama-3.3-70b-versatile, , llama-3.1-8b-instant and llama3-70b-8192.") async def llama_index_rag(pdf: UploadFile = File(...),question: str = Form(...), - model: Optional[str] = Form('gemma2-9b-it')): + model: Optional[str] = Form('mistral-saba-24b')): try: rag_output = advance_rag_llama_index(pdf,model,question) db = MongoDB() @@ -654,88 +663,6 @@ async def get_data(endpoint_name: str, token: str = Depends(oauth2_scheme)): return data -@app.post("/news_agent",description=""" - This endpoint leverages AI agents to conduct research and generate articles on various tech topics. - The agents are designed to uncover groundbreaking technologies and narrate compelling tech stories - """) -async def run_news_agent(topic: str = Form("AI in healthcare")): - try: - cache_key = f"news_agent:{topic}" - cached_response = redis.get(cache_key) - if cached_response: - print("Retrieving response from Redis cache") - return ResponseText(response=cached_response.decode("utf-8")) - - output = run_crew(topic=topic) - redis.set(cache_key, output, ex=10) - db = MongoDB() - payload = { - "endpoint": "/news_agent", - "topic" : topic, - "output": output - } - mongo_data = {"Document": payload} - result = db.insert_data(mongo_data) - print(result) - return ResponseText(response=output) - except Exception as e: - return {"error": str(e)} - -@app.post("/query_db",description=""" - The Query Database endpoint provides a service for interacting with SQL databases using a Cohere ReAct Agent. - It leverages Langchain's existing SQLDBToolkit to answer questions and perform queries over SQL database. - """) -async def query_db(database: UploadFile = File(...), prompt: str = Form(...)): - try: - with tempfile.NamedTemporaryFile(delete=False, suffix='.' + database.filename.split('.')[-1]) as temp_file: - shutil.copyfileobj(database.file, temp_file) - db_path = temp_file.name - - llm = ChatCohere(model="command-r-plus", temperature=0.1, verbose=True,cohere_api_key=os.getenv("COHERE_API_KEY")) - db = SQLDatabase.from_uri(f"sqlite:///{db_path}") - toolkit = SQLDatabaseToolkit(db=db, llm=llm) - context = toolkit.get_context() - tools = toolkit.get_tools() - chat_prompt = ChatPromptTemplate.from_template("{input}") - - agent = create_cohere_react_agent( - llm=llm, - tools=tools, - prompt=chat_prompt - ) - agent_executor = AgentExecutor( - agent=agent, - tools=tools, - verbose=True, - return_intermediate_steps=False, - ) - - preamble = settings.QUERY_DB_PROMPT.format(schema_info=context) - - out = agent_executor.invoke({ - "input": prompt, - "preamble": preamble - }) - - output = parse_sql_response(out["output"]) - db = MongoDB() - payload = { - "endpoint": "/query_db", - "input": prompt, - "output": output - } - mongo_data = {"Document": payload} - result = db.insert_data(mongo_data) - print(result) - - return ResponseText(response=output) - - except Exception as e: - raise Exception(f"Error handling uploaded file: {e}") - - finally: - database.file.close() - @app.post("/MediGem",description="Medical Diagnosis AI Assistant") async def medigem(image_file: UploadFile = File(...)): @@ -744,7 +671,7 @@ async def medigem(image_file: UploadFile = File(...)): "mime_type": "image/jpeg", "data": image }] - model = genai.GenerativeModel(settings.GEMINI_PRO_1_5) + model = genai.GenerativeModel(settings.GEMINI_PRO_2_think) response = model.generate_content([image_parts[0], settings.MEDI_GEM_PROMPT]) db = MongoDB() payload = { @@ -779,7 +706,7 @@ async def process_video(request: Request, video_url: str = Form(...)): print("Retrieving response from Redis cache") return ResponseText(response=cached_response.decode("utf-8")) - model = genai.GenerativeModel(settings.GEMINI_PRO_1_5) + model = genai.GenerativeModel(settings.GEMINI_PRO_2_think) response = model.generate_content(settings.NOTE_GEN_PROMPT + transcript) summary = response.text redis.set(cache_key, summary, ex=60) @@ -796,111 +723,6 @@ async def process_video(request: Request, video_url: str = Form(...)): except Exception as e: raise HTTPException(status_code=500, detail=str(e)) -@app.post("/investment_risk_agent",description=""" - This route implements an investment risk analyst agent system using a crew of AI agents. - Each agent is responsible for different aspects of financial trading and risk management, - working together to analyze data, develop trading strategies, assess risks, and plan executions. - - NOTE : Output will take more than 5 minutes as multiple agents are working together. - """) -@limiter.limit("2/30minute") -async def run_risk_investment_agent(request:Request,stock_selection: str = Form("AAPL"), - risk_tolerance : str = Form("Medium"), - trading_strategy_preference: str = Form("Day Trading"), - token: str = Depends(oauth2_scheme)): - try: - payload = jwt.decode(token, os.getenv("TOKEN_SECRET_KEY"), algorithms=[settings.ALGORITHM]) - email = payload.get("sub") - if email is None: - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") - user = users_collection.find_one({"email": email}) - if user is None: - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found") - except JWTError: - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") - - try: - input_data = {"stock_selection": stock_selection, - "risk_tolerance": risk_tolerance, - "trading_strategy_preference": trading_strategy_preference, - "news_impact_consideration": True - } - print(input_data) - cache_key = f"investment_risk_agent:{input_data}" - cached_response = redis.get(cache_key) - if cached_response: - print("Retrieving response from Redis cache") - return ResponseText(response=cached_response.decode("utf-8")) - - report = run_investment_crew(input_data) - redis.set(cache_key, report, ex=10) - db = MongoDB() - payload = { - "endpoint": "/investment_risk_agent", - "input_data" : input_data, - "Investment_report": report - } - mongo_data = {"Document": payload} - result = db.insert_data(mongo_data) - print(result) - return ResponseText(response=report) - except Exception as e: - return {"error": str(e)} - -@app.post("/agent_doc",description=""" - This route leverages AI agents to assist doctors in diagnosing medical conditions and - recommending treatment plans based on patient-reported symptoms and medical history. - - NOTE : Output will take some time as multiple agents are working together. - """) -@limiter.limit("2/30minute") -async def run_doc_agent(request:Request,gender: str = Form("Male"), - age : int = Form("28"), - symptoms: str = Form("fever, cough, headache"), - medical_history : str = Form("diabetes, hypertension"), - token: str = Depends(oauth2_scheme)): - try: - payload = jwt.decode(token, os.getenv("TOKEN_SECRET_KEY"), algorithms=[settings.ALGORITHM]) - email = payload.get("sub") - if email is None: - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") - user = users_collection.find_one({"email": email}) - if user is None: - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found") - except JWTError: - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") - - try: - input_data = {"gender": gender, - "age": age, - "symptoms": symptoms, - "medical_history": medical_history - } - print(input_data) - cache_key = f"agent_doc:{input_data}" - cached_response = redis.get(cache_key) - if cached_response: - print("Retrieving response from Redis cache") - return ResponseText(response=cached_response.decode("utf-8")) - - report = run_doc_crew(input_data) - redis.set(cache_key, report, ex=10) - db = MongoDB() - payload = { - "endpoint": "/agent_doc", - "Gender" : gender, - "Age" : age, - "Symptoms" : symptoms, - "Medical History" : medical_history, - "Medical Report": report - } - mongo_data = {"Document": payload} - result = db.insert_data(mongo_data) - print(result) - return ResponseText(response=report) - except Exception as e: - return {"error": str(e)} - @app.post("/transcriber", description= """ This route can transcribe audio and video files of any format into text. @@ -937,21 +759,8 @@ async def transcribe_audio_video(request: Request, file: UploadFile = File(...)) except Exception as e: return JSONResponse(content={"error": str(e)}, status_code=500) -@app.post("/job_posting_agent",description=""" - This endpoint generates a job posting by analyzing the company's website and description. - Multiple agents work together to produce a detailed, engaging, and well-aligned job posting. - - NOTE : Output will take some time as multiple agents are working together. - """) -@limiter.limit("2/30minute") -async def run_job_agent(request:Request, - company_description: str = Form("""Microsoft is a global technology company that develops, manufactures, licenses, supports, - and sells a wide range of software products, services, and devices, including the Windows operating system, - Office suite, Azure cloud services, and Surface devices."""), - company_domain : str = Form("https://www.microsoft.com/"), - hiring_needs: str = Form("Data Scientist"), - specific_benefits : str = Form("work from home, medical insurance, generous parental leave, on-site fitness centers, and stock purchase plan"), - token: str = Depends(oauth2_scheme)): +@app.post("/agrilens") +async def analyze_image(file: UploadFile,custom_prompt: str = Form(""),token: str = Depends(oauth2_scheme)): try: payload = jwt.decode(token, os.getenv("TOKEN_SECRET_KEY"), algorithms=[settings.ALGORITHM]) email = payload.get("sub") @@ -962,87 +771,345 @@ async def run_job_agent(request:Request, raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found") except JWTError: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") - - try: - input_data = {"company_description": company_description, - "company_domain": company_domain, - "hiring_needs": hiring_needs, - "specific_benefits": specific_benefits - } - print(input_data) - cache_key = f"job_posting_agent:{input_data}" - cached_response = redis.get(cache_key) - if cached_response: - print("Retrieving response from Redis cache") - return ResponseText(response=cached_response.decode("utf-8")) - - jd = run_job_crew(input_data) - redis.set(cache_key, jd, ex=10) - db = MongoDB() - payload = { - "endpoint": "/job_posting_agent", - "Company Description" : company_description, - "Company Domain" : company_domain, - "Hiring Needs" : hiring_needs, - "Specific Benefits" : specific_benefits, - "Job Description": jd - } - mongo_data = {"Document": payload} - result = db.insert_data(mongo_data) - print(result) - return ResponseText(response=jd) - except Exception as e: - return {"error": str(e)} -@app.post("/ml_assistant",description=""" - Upload a CSV file and describe your machine learning problem. - The API will process the file and input to provide problem definition, data assessment, model recommendation, and starter code. - NOTE: In model input default is llama-3.1-70b-versatile but you can choose mixtral-8x7b-32768, gemma2-9b-it, gemma-7b-it, llama-3.1-8b-instant, llama3-70b-8192 and llama3-8b-8192." - """) -async def ml_crew(file: UploadFile = File(...),user_question: str = Form(...),model: str = Form("llama-3.1-70b-versatile"),token: str = Depends(oauth2_scheme)): - try: - payload = jwt.decode(token, os.getenv("TOKEN_SECRET_KEY"), algorithms=[settings.ALGORITHM]) - email = payload.get("sub") - if email is None: - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") - user = users_collection.find_one({"email": email}) - if user is None: - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found") - except JWTError: - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") + if not file.filename.lower().endswith(('.jpg', '.jpeg', '.png')): + raise HTTPException(status_code=400, detail="Invalid file type. Only JPG, JPEG, and PNG are supported.") - try: - with tempfile.NamedTemporaryFile(delete=False, suffix='.' + file.filename.split('.')[-1]) as tmp: - shutil.copyfileobj(file.file, tmp) - file_location = tmp.name - except Exception as e: - return JSONResponse(content={"error": f"Error handling uploaded file: {e}"}, status_code=400) - finally: - file.file.close() + image_data = await file.read() + base64_image = encode_image(image_data) + + final_prompt = custom_prompt if custom_prompt and custom_prompt.strip() else settings.AGRILENS_DEFAULT_PROMPT - try: - output = run_ml_crew(file_location, user_question,model=model) - os.remove(file_location) + chat_completion = openai_compatible_client.chat.completions.create( + messages=[ + { + "role": "user", + "content": [ + { + "type": "image_url", + "image_url": { + "url": f"data:image/jpeg;base64,{base64_image}" + }, + }, + {"type": "text", "text": final_prompt}, + ], + } + ], + model="llama-3.2-90b-vision-preview" + ) - if "error" in output: - return JSONResponse(content=output, status_code=400) - + response_content = chat_completion.choices[0].message.content db = MongoDB() payload = { - "endpoint": "/ml_assistant", - "propmt" : user_question, - "Model" : model, - "Output" : output + "endpoint": "/agrilens", + "custom_prompt" : final_prompt, + "Output" : response_content } mongo_data = {"Document": payload} result = db.insert_data(mongo_data) print(result) - return ResponseText(response=output) + return ResponseText(response=response_content) except Exception as e: - return {"error": str(e)} + raise HTTPException(status_code=500, detail=f"Error during analysis: {e}") + +# @app.post("/news_agent",description=""" +# This endpoint leverages AI agents to conduct research and generate articles on various tech topics. +# The agents are designed to uncover groundbreaking technologies and narrate compelling tech stories +# """) +# async def run_news_agent(topic: str = Form("AI in healthcare")): +# try: +# cache_key = f"news_agent:{topic}" +# cached_response = redis.get(cache_key) +# if cached_response: +# print("Retrieving response from Redis cache") +# return ResponseText(response=cached_response.decode("utf-8")) + +# output = run_crew(topic=topic) +# redis.set(cache_key, output, ex=10) +# db = MongoDB() +# payload = { +# "endpoint": "/news_agent", +# "topic" : topic, +# "output": output +# } +# mongo_data = {"Document": payload} +# result = db.insert_data(mongo_data) +# print(result) +# return ResponseText(response=output) +# except Exception as e: +# return {"error": str(e)} + +# @app.post("/query_db",description=""" +# The Query Database endpoint provides a service for interacting with SQL databases using a Cohere ReAct Agent. +# It leverages Langchain's existing SQLDBToolkit to answer questions and perform queries over SQL database. +# """) +# async def query_db(database: UploadFile = File(...), prompt: str = Form(...)): +# try: +# with tempfile.NamedTemporaryFile(delete=False, suffix='.' + database.filename.split('.')[-1]) as temp_file: +# shutil.copyfileobj(database.file, temp_file) +# db_path = temp_file.name + +# llm = ChatCohere(model="command-r-plus", temperature=0.1, verbose=True,cohere_api_key=os.getenv("COHERE_API_KEY")) +# db = SQLDatabase.from_uri(f"sqlite:///{db_path}") +# toolkit = SQLDatabaseToolkit(db=db, llm=llm) +# context = toolkit.get_context() +# tools = toolkit.get_tools() +# chat_prompt = ChatPromptTemplate.from_template("{input}") + +# agent = create_cohere_react_agent( +# llm=llm, +# tools=tools, +# prompt=chat_prompt +# ) +# agent_executor = AgentExecutor( +# agent=agent, +# tools=tools, +# verbose=True, +# return_intermediate_steps=False, +# ) + +# preamble = settings.QUERY_DB_PROMPT.format(schema_info=context) + +# out = agent_executor.invoke({ +# "input": prompt, +# "preamble": preamble +# }) + +# output = parse_sql_response(out["output"]) +# db = MongoDB() +# payload = { +# "endpoint": "/query_db", +# "input": prompt, +# "output": output +# } +# mongo_data = {"Document": payload} +# result = db.insert_data(mongo_data) +# print(result) + +# return ResponseText(response=output) + +# except Exception as e: +# raise Exception(f"Error handling uploaded file: {e}") + +# finally: +# database.file.close() + + + +# @app.post("/investment_risk_agent",description=""" +# This route implements an investment risk analyst agent system using a crew of AI agents. +# Each agent is responsible for different aspects of financial trading and risk management, +# working together to analyze data, develop trading strategies, assess risks, and plan executions. + +# NOTE : Output will take more than 5 minutes as multiple agents are working together. +# """) +# @limiter.limit("2/30minute") +# async def run_risk_investment_agent(request:Request,stock_selection: str = Form("AAPL"), +# risk_tolerance : str = Form("Medium"), +# trading_strategy_preference: str = Form("Day Trading"), +# token: str = Depends(oauth2_scheme)): +# try: +# payload = jwt.decode(token, os.getenv("TOKEN_SECRET_KEY"), algorithms=[settings.ALGORITHM]) +# email = payload.get("sub") +# if email is None: +# raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") +# user = users_collection.find_one({"email": email}) +# if user is None: +# raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found") +# except JWTError: +# raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") + +# try: +# input_data = {"stock_selection": stock_selection, +# "risk_tolerance": risk_tolerance, +# "trading_strategy_preference": trading_strategy_preference, +# "news_impact_consideration": True +# } +# print(input_data) +# cache_key = f"investment_risk_agent:{input_data}" +# cached_response = redis.get(cache_key) +# if cached_response: +# print("Retrieving response from Redis cache") +# return ResponseText(response=cached_response.decode("utf-8")) + +# report = run_investment_crew(input_data) +# redis.set(cache_key, report, ex=10) +# db = MongoDB() +# payload = { +# "endpoint": "/investment_risk_agent", +# "input_data" : input_data, +# "Investment_report": report +# } +# mongo_data = {"Document": payload} +# result = db.insert_data(mongo_data) +# print(result) +# return ResponseText(response=report) +# except Exception as e: +# return {"error": str(e)} +# +# @app.post("/agent_doc",description=""" +# This route leverages AI agents to assist doctors in diagnosing medical conditions and +# recommending treatment plans based on patient-reported symptoms and medical history. + +# NOTE : Output will take some time as multiple agents are working together. +# """) +# @limiter.limit("2/30minute") +# async def run_doc_agent(request:Request,gender: str = Form("Male"), +# age : int = Form("28"), +# symptoms: str = Form("fever, cough, headache"), +# medical_history : str = Form("diabetes, hypertension"), +# token: str = Depends(oauth2_scheme)): +# try: +# payload = jwt.decode(token, os.getenv("TOKEN_SECRET_KEY"), algorithms=[settings.ALGORITHM]) +# email = payload.get("sub") +# if email is None: +# raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") +# user = users_collection.find_one({"email": email}) +# if user is None: +# raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found") +# except JWTError: +# raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") + +# try: +# input_data = {"gender": gender, +# "age": age, +# "symptoms": symptoms, +# "medical_history": medical_history +# } +# print(input_data) +# cache_key = f"agent_doc:{input_data}" +# cached_response = redis.get(cache_key) +# if cached_response: +# print("Retrieving response from Redis cache") +# return ResponseText(response=cached_response.decode("utf-8")) + +# report = run_doc_crew(input_data) +# redis.set(cache_key, report, ex=10) +# db = MongoDB() +# payload = { +# "endpoint": "/agent_doc", +# "Gender" : gender, +# "Age" : age, +# "Symptoms" : symptoms, +# "Medical History" : medical_history, +# "Medical Report": report +# } +# mongo_data = {"Document": payload} +# result = db.insert_data(mongo_data) +# print(result) +# return ResponseText(response=report) +# except Exception as e: +# return {"error": str(e)} + +# @app.post("/job_posting_agent",description=""" +# This endpoint generates a job posting by analyzing the company's website and description. +# Multiple agents work together to produce a detailed, engaging, and well-aligned job posting. + +# NOTE : Output will take some time as multiple agents are working together. +# """) +# @limiter.limit("2/30minute") +# async def run_job_agent(request:Request, +# company_description: str = Form("""Microsoft is a global technology company that develops, manufactures, licenses, supports, +# and sells a wide range of software products, services, and devices, including the Windows operating system, +# Office suite, Azure cloud services, and Surface devices."""), +# company_domain : str = Form("https://www.microsoft.com/"), +# hiring_needs: str = Form("Data Scientist"), +# specific_benefits : str = Form("work from home, medical insurance, generous parental leave, on-site fitness centers, and stock purchase plan"), +# token: str = Depends(oauth2_scheme)): +# try: +# payload = jwt.decode(token, os.getenv("TOKEN_SECRET_KEY"), algorithms=[settings.ALGORITHM]) +# email = payload.get("sub") +# if email is None: +# raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") +# user = users_collection.find_one({"email": email}) +# if user is None: +# raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found") +# except JWTError: +# raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") + +# try: +# input_data = {"company_description": company_description, +# "company_domain": company_domain, +# "hiring_needs": hiring_needs, +# "specific_benefits": specific_benefits +# } +# print(input_data) +# cache_key = f"job_posting_agent:{input_data}" +# cached_response = redis.get(cache_key) +# if cached_response: +# print("Retrieving response from Redis cache") +# return ResponseText(response=cached_response.decode("utf-8")) + +# jd = run_job_crew(input_data) +# redis.set(cache_key, jd, ex=10) +# db = MongoDB() +# payload = { +# "endpoint": "/job_posting_agent", +# "Company Description" : company_description, +# "Company Domain" : company_domain, +# "Hiring Needs" : hiring_needs, +# "Specific Benefits" : specific_benefits, +# "Job Description": jd +# } +# mongo_data = {"Document": payload} +# result = db.insert_data(mongo_data) +# print(result) +# return ResponseText(response=jd) +# except Exception as e: +# return {"error": str(e)} +# +# @app.post("/ml_assistant",description=""" +# Upload a CSV file and describe your machine learning problem. +# The API will process the file and input to provide problem definition, data assessment, model recommendation, and starter code. + +# NOTE: In model input default is llama-3.1-70b-versatile but you can choose mixtral-8x7b-32768, gemma2-9b-it, gemma-7b-it, llama-3.1-8b-instant, llama3-70b-8192 and llama3-8b-8192." +# """) +# async def ml_crew(file: UploadFile = File(...),user_question: str = Form(...),model: str = Form("llama-3.1-70b-versatile"),token: str = Depends(oauth2_scheme)): +# try: +# payload = jwt.decode(token, os.getenv("TOKEN_SECRET_KEY"), algorithms=[settings.ALGORITHM]) +# email = payload.get("sub") +# if email is None: +# raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") +# user = users_collection.find_one({"email": email}) +# if user is None: +# raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found") +# except JWTError: +# raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token") + +# try: +# with tempfile.NamedTemporaryFile(delete=False, suffix='.' + file.filename.split('.')[-1]) as tmp: +# shutil.copyfileobj(file.file, tmp) +# file_location = tmp.name +# except Exception as e: +# return JSONResponse(content={"error": f"Error handling uploaded file: {e}"}, status_code=400) +# finally: +# file.file.close() + + +# try: +# output = run_ml_crew(file_location, user_question,model=model) +# os.remove(file_location) + +# if "error" in output: +# return JSONResponse(content=output, status_code=400) + +# db = MongoDB() +# payload = { +# "endpoint": "/ml_assistant", +# "prompt" : user_question, +# "Model" : model, +# "Output" : output +# } +# mongo_data = {"Document": payload} +# result = db.insert_data(mongo_data) +# print(result) +# return ResponseText(response=output) + +# except Exception as e: +# return {"error": str(e)} if __name__ == '__main__': import uvicorn diff --git a/create_fake_db.py b/create_fake_db.py index 2c72ca1..8668387 100644 --- a/create_fake_db.py +++ b/create_fake_db.py @@ -41,10 +41,11 @@ def generate_employee(self, used_employee_ids): last_names = ['Smith', 'Johnson', 'Brown', 'Taylor', 'Williams', 'Jones'] departments = ['HR', 'Finance', 'IT', 'Marketing', 'Operations'] job_titles = { - 'HR': ['HR Manager', 'HR Coordinator', 'HR Assistant'], - 'Finance': ['Financial Analyst', 'Finance Manager', 'Accountant'], - 'IT': ['Software Engineer', 'IT Specialist', 'System Administrator'], - 'Marketing': ['Marketing Manager', 'Marketing Coordinator', 'Digital Marketer'], + 'HR': ['HR Manager', 'HR Coordinator', 'HR Assistant', 'Recruiter'], + 'Finance': ['Financial Analyst', 'Finance Manager', 'Accountant', 'Auditor'], + 'IT': ['Software Engineer', 'IT Specialist', 'System Administrator','Data Scientist','Frontend Developer'], + 'Marketing': ['Marketing Manager', 'Marketing Coordinator', 'Digital Marketer', 'SEO Specialist'], + 'Sales': ['Sales Manager', 'Sales Associate', 'Sales Executive', 'Account Manager'], 'Operations': ['Operations Manager', 'Operations Coordinator', 'Operations Analyst'] } @@ -56,7 +57,7 @@ def generate_employee(self, used_employee_ids): department = random.choice(departments) title = random.choice(job_titles[department]) email = self.random_email() - city = random.choice(['New York', 'Los Angeles', 'Chicago', 'Houston', 'Phoenix']) + city = random.choice(['New York', 'Los Angeles', 'Chicago', 'Houston', 'Phoenix','Noida']) salary = random.randint(30000, 150000) # Random salary between $30,000 and $150,000 work_experience = random.randint(0, 20) # Random work experience between 0 and 20 years return (employee_id, name, department, title, email, city, salary, work_experience) diff --git a/data/employees.db b/data/employees.db index aafc91d..45364dc 100644 Binary files a/data/employees.db and b/data/employees.db differ diff --git a/helper_functions.py b/helper_functions.py index 125a762..7227fe3 100644 --- a/helper_functions.py +++ b/helper_functions.py @@ -7,7 +7,8 @@ from langchain.text_splitter import RecursiveCharacterTextSplitter,TokenTextSplitter from langchain_community.vectorstores import FAISS from langchain.prompts import PromptTemplate -from langchain.chains import RetrievalQA +from langchain.chains import create_retrieval_chain +from langchain.chains.combine_documents import create_stuff_documents_chain from langchain.chains.summarize import load_summarize_chain from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough @@ -31,6 +32,7 @@ from llama_index.core.tools import QueryEngineTool, ToolMetadata from llama_index.core.query_engine import RouterQueryEngine import shutil +import base64 load_dotenv() genai.configure(api_key=os.getenv("GOOGLE_API_KEY")) @@ -53,7 +55,7 @@ def get_gemini_response(input, image_file, prompt): try: print(prompt,input) - model = genai.GenerativeModel(settings.GEMINI_PRO_1_5) + model = genai.GenerativeModel(settings.GEMINI_PRO_2_think) response = model.generate_content([input, image_file[0], prompt]) return response.text @@ -62,7 +64,7 @@ def get_gemini_response(input, image_file, prompt): def get_gemini_response_health(image_file, prompt): try: - model = genai.GenerativeModel(settings.GEMINI_PRO_1_5) + model = genai.GenerativeModel(settings.GEMINI_PRO_2_think) response = model.generate_content([image_file[0], prompt]) return response.text @@ -76,24 +78,21 @@ def create_vector_db(): vectordb.save_local(settings.VECTORDB_PATH) def get_qa_chain(): - llm = GoogleGenerativeAI(model= settings.GEMINI_FLASH, google_api_key=os.getenv("GOOGLE_API_KEY"),temperature=0.2) + llm = GoogleGenerativeAI(model= settings.GEMINI_PRO_2_think, google_api_key=os.getenv("GOOGLE_API_KEY"),temperature=0.2) vectordb = FAISS.load_local(settings.VECTORDB_PATH,google_embedding,allow_dangerous_deserialization=True) retriever = vectordb.as_retriever(score_threshold=0.7) - PROMPT = PromptTemplate( - template=settings.qa_prompt, input_variables=["context", "question"] + prompt = PromptTemplate( + template=settings.qa_prompt, input_variables=["context", "input"] ) - chain = RetrievalQA.from_chain_type(llm=llm, - chain_type="stuff", - retriever=retriever, - input_key="query", - return_source_documents=True, - chain_type_kwargs={"prompt": PROMPT}) + document_chain = create_stuff_documents_chain(llm, prompt) - return chain + retrieval_chain = create_retrieval_chain(retriever, document_chain) + + return retrieval_chain def get_url_doc_qa(url,doc): - llm = GoogleGenerativeAI(model= settings.GEMINI_FLASH, google_api_key=os.getenv("GOOGLE_API_KEY"),temperature=0.3) + llm = GoogleGenerativeAI(model= settings.GEMINI_PRO_2_think, google_api_key=os.getenv("GOOGLE_API_KEY"),temperature=0.3) if url: loader = WebBaseLoader(url) data = loader.load() @@ -108,12 +107,19 @@ def get_url_doc_qa(url,doc): docs = text_splitter.create_documents(doc) vectorstore = FAISS.from_documents(documents = docs,embedding=google_embedding) - chain = RetrievalQA.from_chain_type(llm=llm, - chain_type="stuff", - retriever=vectorstore.as_retriever(), - input_key="query", - return_source_documents=True) - return chain + system_prompt = ( + "Use the given context to answer the question. " + "If you don't know the answer, say you don't know. " + "{context}" + ) + prompt = ChatPromptTemplate.from_messages([ + ("system", system_prompt), + ("human", "{input}") + ]) + document_chain = create_stuff_documents_chain(llm, prompt) + retrieval_chain = create_retrieval_chain(vectorstore.as_retriever(), document_chain) + + return retrieval_chain def extract_transcript_details(youtube_video_url): try: @@ -135,20 +141,17 @@ def get_gemini_pdf(pdf): text_splitter = RecursiveCharacterTextSplitter(chunk_size=10000, chunk_overlap=1000) chunks = text_splitter.split_text(text) vector_store = FAISS.from_texts(chunks, embedding=google_embedding) - llm = GoogleGenerativeAI(model= settings.GEMINI_FLASH, google_api_key=os.getenv("GOOGLE_API_KEY"),temperature=0.7) + llm = GoogleGenerativeAI(model= settings.GEMINI_PRO_2_think, google_api_key=os.getenv("GOOGLE_API_KEY"),temperature=0.7) retriever = vector_store.as_retriever(score_threshold=0.7) - PROMPT = PromptTemplate( - template=settings.prompt_pdf, input_variables=["context", "question"] + prompt = PromptTemplate( + template=settings.prompt_pdf, input_variables=["context", "input"] ) - chain = RetrievalQA.from_chain_type(llm=llm, - chain_type="stuff", - retriever=retriever, - input_key="query", - return_source_documents=True, - chain_type_kwargs={"prompt": PROMPT}) + document_chain = create_stuff_documents_chain(llm, prompt) - return chain + retrieval_chain = create_retrieval_chain(retriever, document_chain) + + return retrieval_chain def read_sql_query(query,db): conn=sqlite3.connect(db) @@ -188,7 +191,7 @@ def questions_generator(doc): # splitter_ans_gen = TokenTextSplitter(chunk_size = 1000,chunk_overlap = 100) # document_answer_gen = splitter_ans_gen.split_documents(document_ques_gen) - llm_ques_gen_pipeline = ChatGoogleGenerativeAI(model= settings.GEMINI_FLASH,google_api_key=os.getenv("GOOGLE_API_KEY"),temperature=0.3) + llm_ques_gen_pipeline = ChatGoogleGenerativeAI(model= settings.GEMINI_PRO_2_think,google_api_key=os.getenv("GOOGLE_API_KEY"),temperature=0.3) PROMPT_QUESTIONS = PromptTemplate(template=settings.question_prompt_template, input_variables=["text"]) REFINE_PROMPT_QUESTIONS = PromptTemplate(input_variables=["existing_answer", "text"],template=settings.question_refine_template) ques_gen_chain = load_summarize_chain(llm = llm_ques_gen_pipeline, @@ -291,7 +294,7 @@ def advance_rag_llama_index(pdf,model,question): pdf.file.close() llm = Groq(model=model,api_key=os.getenv("GROQ_API_KEY")) embed_model = HuggingFaceInferenceAPIEmbeddings( - api_key=os.getenv("HUGGINGFACE_API_KEY"), model_name=settings.INSTRUCTOR_EMBEDDING,query_instruction="Represent the query for retrieval: ") + api_key=os.getenv("HUGGINGFACE_API_KEY"), model_name=settings.INSTRUCTOR_EMBEDDING) core.Settings.llm = llm core.Settings.embed_model = embed_model @@ -353,6 +356,9 @@ def extract_video_id(url): break return video_id +def encode_image(image_data: bytes) -> str: + return base64.b64encode(image_data).decode("utf-8") + if __name__ == "__main__": create_vector_db() chain = get_qa_chain() diff --git a/requirements.txt b/requirements.txt index b1b6fb3..bb300dd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ langchain_community google-generativeai langchain-google-genai faiss-cpu -fastapi +fastapi[standard] uvicorn pydantic python-dotenv @@ -24,9 +24,9 @@ python-jose sendgrid llama-index-llms-groq llama-index-embeddings-langchain -grpcio -crewai -crewai-tools -proto-plus -langchain-cohere -slowapi \ No newline at end of file +slowapi +# grpcio +# crewai +# crewai-tools +# proto-plus +# langchain-cohere diff --git a/settings.py b/settings.py index 362c01e..9e17376 100644 --- a/settings.py +++ b/settings.py @@ -1,22 +1,23 @@ -GEMINI_PRO_1_5 = "gemini-1.5-pro-latest" -GEMINI_FLASH = "gemini-1.5-flash-latest" +GEMINI_PRO_2_think = "gemini-2.0-flash-thinking-exp-01-21" +# GEMINI_FLASH = "gemini-1.5-flash-latest" +# GEMINI_FLASH_8B = "gemini-1.5-flash-8b" GOOGLE_EMBEDDING = "models/embedding-001" FAQ_FILE = 'data/faqs.csv' EMPLOYEE_DB = "data/employees.db" INSTRUCTOR_EMBEDDING = "sentence-transformers/all-MiniLM-l6-v2" VECTORDB_PATH = "faiss_index" -REDIS_PORT = 19061 +REDIS_PORT = 16789 ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 30 qa_prompt = """ - Given the following context and a question, generate an answer based on this context only. - In the answer try to provide as much text as possible from "response" section in the source document context without making much changes. - If the answer is not found in the context, kindly state "I don't know." Don't try to make up an answer. +Given the following context and a question, generate an answer solely based on the provided context. +In your answer, try to incorporate as much content as possible from the "response" section of the context, making only minimal modifications. +Do not fabricate any information. - CONTEXT: {context} +CONTEXT: {context} - QUESTION: {question} - """ +QUESTION: {input} +""" invoice_prompt = """ You are an expert in understanding invoices. You will receive input images as invoices & @@ -30,7 +31,7 @@ Answer the question as detailed as possible from the provided context, make sure to provide all the details, if the answer is not in provided context just say, "Answer is not available in the context !!!!!!!", don't provide the wrong answer\n\n Context:\n {context}?\n - Question: \n{question}\n + Question: \n{input}\n Answer: """ @@ -153,4 +154,15 @@ 6. Actionable steps or recommendations Make sure the notes are well-structured and formatted as bullet points. The total length should not exceed 1000 words. Please summarize the following text: +""" + +AGRILENS_DEFAULT_PROMPT = """ +Analyze the uploaded image, which is related to agriculture. +Identify the key elements present in the image, such as crops, soil, pests, diseases, farming equipment, or other agricultural features. +Provide the following details: +1. Description: A brief overview of what is visible in the image. +2. Detailed Identification: Name the type of crop, pest, disease, or farming equipment, if applicable. +3. Condition Assessment: If the image contains crops, assess their health (e.g., healthy, stressed, diseased). If there are visible pests or diseases, specify their type and possible impact. +4. Recommendations: Suggest actionable insights to improve the situation, such as applying fertilizers, pesticides, irrigation, or other agricultural practices. +5. Additional Observations: Any other insights or anomalies you notice in the image relevant to agriculture. """ \ No newline at end of file diff --git a/templates/ats.html b/templates/ats.html index a7489a7..60ee66c 100644 --- a/templates/ats.html +++ b/templates/ats.html @@ -11,12 +11,20 @@ :root { --color-bg: #121212; --color-fg: #ffffff; + --color-primary: #3d8ec9; + --color-secondary: #6c757d; + --color-light: #f8f9fa; + --color-dark: #2b2b2b; } /* Light mode styles */ [data-theme="light"] { --color-bg: #ffffff; --color-fg: #000000; + --color-primary: #007bff; + --color-secondary: #6c757d; + --color-light: #f8f9fa; + --color-dark: #343a40; } /* Common styles */ @@ -35,9 +43,9 @@ max-width: 800px; margin: 50px auto; padding: 40px; - background-color: #fff; /* Light mode background */ + background-color: var(--color-light); box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); - border-radius: 10px; + border-radius: 15px; display: flex; flex-direction: column; align-items: center; @@ -45,15 +53,14 @@ } [data-theme="dark"] .container { - background-color: #2b2b2b; /* Dark mode background */ - /* Add any other desired styles for dark mode */ + background-color: var(--color-dark); } h1 { text-align: center; margin-bottom: 30px; font-weight: 700; - color: #3d8ec9; + color: var(--color-primary); position: relative; animation: slideInDown 1s ease; } @@ -66,7 +73,7 @@ transform: translateX(-50%); width: 50px; height: 3px; - background-color: #3d8ec9; + background-color: var(--color-primary); } form { @@ -80,34 +87,36 @@ label { font-size: 1.2rem; margin-bottom: 10px; - color: #3d8ec9; + color: var(--color-primary); } input[type="file"], textarea { - width: 300px; - padding: 10px; - border: 1px solid #ccc; - border-radius: 5px; + width: 100%; + max-width: 400px; + padding: 15px; + border: 1px solid var(--color-secondary); + border-radius: 8px; margin-bottom: 10px; transition: border-color 0.3s ease; animation: fadeIn 1s ease; - background-color: rgba(255, 255, 255, 0.9); + background-color: var(--color-bg); + color: var(--color-fg); } input[type="file"]:focus, textarea:focus { - border-color: #3d8ec9; + border-color: var(--color-primary); outline: none; - background-color: rgba(255, 255, 255, 1); + background-color: var(--color-light); } button { padding: 10px 20px; - background-color: #3d8ec9; + background-color: var(--color-primary); color: #fff; border: none; - border-radius: 5px; + border-radius: 8px; cursor: pointer; transition: background-color 0.3s ease; display: flex; @@ -125,13 +134,15 @@ } #output { - border: 1px solid var(--color-fg); + border: 1px solid var(--color-secondary); padding: 20px; - border-radius: 5px; + border-radius: 8px; background-color: var(--color-bg); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); transition: transform 0.3s ease; animation: fadeIn 1s ease; + width: 100%; + max-width: 600px; } #output:hover { @@ -169,7 +180,7 @@ .spinner { border: 4px solid rgba(61, 142, 201, 0.2); - border-left-color: #3d8ec9; + border-left-color: var(--color-primary); border-radius: 50%; width: 30px; height: 30px; @@ -194,7 +205,7 @@ } .copy-btn { - background-color: #6c757d; + background-color: var(--color-secondary); transition: background-color 0.3s ease; } @@ -230,7 +241,7 @@ input[type="text"], input[type="file"], textarea { - width: 250px; + width: 100%; } } @@ -241,7 +252,7 @@ input[type="text"], input[type="file"], textarea { - width: 200px; + width: 100%; } } @@ -252,7 +263,7 @@ input[type="text"], input[type="file"], textarea { - width: 160px; + width: 100%; } } @@ -292,8 +303,6 @@ } } - /* Rest of your CSS styles... */ - #theme-toggle { position: absolute; top: 10px; @@ -306,7 +315,45 @@ #theme-toggle i { font-size: 20px; - color: #3d8ec9; + color: var(--color-primary); + } + + .follow-container { + margin-top: 20px; + text-align: center; + } + + .follow-container p { + margin: 0; + font-size: 1rem; + } + + .follow-container a { + color: var(--color-primary); + text-decoration: none; + } + + .follow-container a:hover { + text-decoration: underline; + } + + footer { + margin-top: 20px; + text-align: center; + font-size: 0.9rem; + } + + footer p { + margin: 0; + } + + footer a { + color: var(--color-primary); + text-decoration: none; + } + + footer a:hover { + text-decoration: underline; } @@ -318,20 +365,21 @@

Smart ATS

- + - +
-

Follow me on - -

+

Follow me on + + +