pkraman06's picture
Rename src/model.py to model.py
63e1c74 verified
Raw
History Blame Contribute Delete
7.26 kB
# model.py
import os
import json
from langchain_huggingface import HuggingFaceEndpoint, ChatHuggingFace
from langchain_openai import ChatOpenAI
from langchain_community.document_loaders import PyPDFLoader
from crewai import Agent, Task, Crew, Process
# --- 1. LLM Factory Engine ---
def initialize_llm(provider, selected_model, user_token=None):
"""
Initializes and returns the appropriate LangChain chat wrapper
depending on the chosen provider (Hugging Face or OpenAI).
"""
if provider == "Hugging Face Serverless (Default)":
# Resolve token priority: Explicit user token -> Env variable secrets
token = user_token if user_token else (os.getenv("HUGGINGFACEHUB_API_TOKEN") or os.getenv("HF_TOKEN"))
if not token:
raise ValueError("Hugging Face API Token missing! Please provide it in the sidebar or Space Secrets.")
base_endpoint = HuggingFaceEndpoint(
repo_id=selected_model,
task="text-generation",
huggingfacehub_api_token=token,
max_new_tokens=1500,
temperature=0.2
)
return ChatHuggingFace(llm=base_endpoint)
elif provider == "OpenAI (Optional Override)":
token = user_token if user_token else os.getenv("OPENAI_API_KEY")
if not token:
raise ValueError("OpenAI API Key missing! Please provide it in the sidebar input field.")
return ChatOpenAI(model=selected_model, api_key=token, temperature=0.1)
else:
raise ValueError(f"Unknown provider type: {provider}")
# --- 2. Advanced Document Context Parser ---
def parse_uploaded_file_content(file_name, file_bytes):
"""
Extracts raw text strings from multiple formats: .pdf, .ipynb, .py, .txt
"""
# Write to a temporary file locally so loaders can reference it
with open(file_name, "wb") as temp_file:
temp_file.write(file_bytes)
try:
if file_name.endswith(".pdf"):
loader = PyPDFLoader(file_name)
pages = loader.load_and_split()
extracted_text = "\n".join([page.page_content for page in pages])
elif file_name.endswith(".ipynb"):
notebook_data = json.loads(file_bytes.decode("utf-8"))
code_lines = []
for cell in notebook_data.get("cells", []):
if cell.get("cell_type") == "code":
code_lines.append("".join(cell.get("source", [])))
extracted_text = "\n# --- Notebook Cell Output ---\n".join(code_lines)
else:
# Fallback text decoder for standard code scripts (.py, .txt, .md)
extracted_text = file_bytes.decode("utf-8")
# Context cleaning/wrapping
return f"\n\n--- REFERENCE DOCUMENT ATTACHED ({file_name}) ---\n{extracted_text}\n"
except Exception as parse_error:
return f"\n\n[Error parsing document data from {file_name}: {str(parse_error)}]\n"
finally:
# Guarantee local filesystem cleanup
if os.path.exists(file_name):
os.remove(file_name)
# --- 3. Specialist Agent Configurations Catalog ---
AGENT_PERSONAS = {
"Personal Motivator": {
"role": "High-Performance Life Coach",
"backstory": "An inspiring professional who helps users crush creative blockages, break down bad habits, and build an unstoppable focus mindset.",
"goal": "Inject intense enthusiasm, structured routines, and motivational insight into the user prompt."
},
"Code Reviewer": {
"role": "Principal Software Engineer & Architect",
"backstory": "An expert with decades of experience tracking down edge-cases, semantic errors, bad performance bottlenecks, and structural refactoring improvements.",
"goal": "Thoroughly review structural files or algorithms to provide high-quality code changes."
},
"Technical Researcher": {
"role": "Lead Data Analytics Scholar",
"backstory": "A detail-oriented analyst who excels at parsing complex raw documents, compiling literature overviews, and summarizing trends accurately.",
"goal": "Identify hidden insights from context and write clear technical documentation summaries."
},
"Physics Formula Explainer": {
"role": "Theoretical Physics Professor",
"backstory": "An educator who makes complex physical theories, mathematical proofs, and equations easy to understand by using intuitive analogies and practical real-world applications.",
"goal": "Deconstruct complex physics models and equations step-by-step into clear, understandable explanations."
},
"General Purpose Assistant": {
"role": "Contextual Problem Solver",
"backstory": "A versatile technical assistant skilled at answering cross-functional development questions clearly.",
"goal": "Fulfill the user request precisely while adjusting to the provided documentation constraints."
}
}
# --- 4. Main Multi-Agent Execution Orchestrator ---
def run_agent_pipeline(provider, model_name, token, persona_key, user_prompt, context_text):
"""
Coordinates the selected Agent Persona alongside a secondary Quality Assurance
Auditor to review and polish the output before displaying it.
"""
# 1. Instantiate the chosen LLM runtime
llm = initialize_llm(provider, model_name, user_token=token)
# 2. Extract Persona Definitions
persona = AGENT_PERSONAS[persona_key]
# 3. Assemble Specialist Agent
specialist_agent = Agent(
role=persona["role"],
backstory=persona["backstory"],
goal=persona["goal"],
llm=llm,
verbose=True,
allow_delegation=False
)
# 4. Assemble Independent QA Critic Agent
auditor_agent = Agent(
role="Senior QA & Compliance Auditor",
backstory="An unyielding editor focused on correcting hallucinations, logic formatting errors, typos, and completeness issues.",
goal="Critique the primary specialist's generated draft response and output a polished, final version.",
llm=llm,
verbose=True
)
# 5. Define Task Blueprints
complete_task_description = f"{user_prompt}\n\n{context_text}"
generation_task = Task(
description=f"Address the user requirements thoroughly using your specific persona parameters.\nRequirements:\n{complete_task_description}",
agent=specialist_agent,
expected_output="A rich, highly comprehensive response matching your assigned persona specialty."
)
review_task = Task(
description="Review the generated response for accuracy, clarity, and formatting. Correct any typos or logical errors, and format it cleanly in Markdown.",
agent=auditor_agent,
context=[generation_task],
expected_output="The final, polished markdown response, safe for production delivery."
)
# 6. Execute via Sequential Flow Pipeline
crew_system = Crew(
agents=[specialist_agent, auditor_agent],
tasks=[generation_task, review_task],
process=Process.sequential,
verbose=True
)
return crew_system.kickoff()