Spaces:
Sleeping
Sleeping
initial no content
Browse files- .gitignore +16 -0
- app.py +110 -0
- file_convert.py +52 -0
- pythia.py +23 -0
- websites.txt +0 -0
.gitignore
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.env
|
| 2 |
+
*.key
|
| 3 |
+
*.pem
|
| 4 |
+
__pycache__/
|
| 5 |
+
*.pyc
|
| 6 |
+
*.pyo
|
| 7 |
+
*.pyd
|
| 8 |
+
.Python
|
| 9 |
+
.vscode/
|
| 10 |
+
*.code-workspace
|
| 11 |
+
.DS_Store
|
| 12 |
+
Thumbs.db
|
| 13 |
+
*.log
|
| 14 |
+
*.tmp
|
| 15 |
+
faiss_index/
|
| 16 |
+
*.faiss
|
app.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from dotenv import load_dotenv
|
| 3 |
+
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
|
| 4 |
+
from langchain_community.vectorstores import FAISS
|
| 5 |
+
from langchain_community.document_loaders import PyPDFDirectoryLoader, WebBaseLoader
|
| 6 |
+
from langchain_text_splitters import RecursiveCharacterTextSplitter
|
| 7 |
+
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
| 8 |
+
from langchain_community.tools.tavily_search import TavilySearchResults
|
| 9 |
+
from langchain.tools.retriever import create_retriever_tool
|
| 10 |
+
from langchain.agents import create_tool_calling_agent, AgentExecutor
|
| 11 |
+
from langchain_core.tools import tool
|
| 12 |
+
import gradio as gr
|
| 13 |
+
import numpy as np
|
| 14 |
+
|
| 15 |
+
load_dotenv()
|
| 16 |
+
os.environ['USER_AGENT'] = os.getenv('USER_AGENT', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)')
|
| 17 |
+
|
| 18 |
+
def load_web_resources(file='websites.txt'):
|
| 19 |
+
urls = ['https://steveblank.com/']
|
| 20 |
+
if os.path.exists(file):
|
| 21 |
+
with open(file, 'r') as f:
|
| 22 |
+
urls.extend(line.strip() for line in f if line.strip())
|
| 23 |
+
web_docs = []
|
| 24 |
+
for url in urls:
|
| 25 |
+
try:
|
| 26 |
+
loader = WebBaseLoader(url)
|
| 27 |
+
web_docs.extend(loader.load())
|
| 28 |
+
except Exception as e:
|
| 29 |
+
print(f"Failed to load {url}: {e}")
|
| 30 |
+
return web_docs
|
| 31 |
+
|
| 32 |
+
def build_vectorstore(pdf_dir="ConvertedFiles"):
|
| 33 |
+
loader = PyPDFDirectoryLoader(pdf_dir)
|
| 34 |
+
docs = loader.load()
|
| 35 |
+
web_docs = load_web_resources()
|
| 36 |
+
all_docs = docs + web_docs
|
| 37 |
+
splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
|
| 38 |
+
splits = splitter.split_documents(all_docs)
|
| 39 |
+
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
|
| 40 |
+
vectorstore = FAISS.from_documents(splits, embeddings)
|
| 41 |
+
vectorstore.save_local("faiss_index")
|
| 42 |
+
return vectorstore
|
| 43 |
+
|
| 44 |
+
@tool
|
| 45 |
+
def scenario_simulator(params: dict) -> str:
|
| 46 |
+
"""Simulates product adoption using Monte Carlo. Params: initial_users, growth_rate, time_months, uncertainty."""
|
| 47 |
+
try:
|
| 48 |
+
initial_users = params.get("initial_users", 1000)
|
| 49 |
+
growth_rate = params.get("growth_rate", 0.05) # 5%/month
|
| 50 |
+
time_months = params.get("time_months", 12)
|
| 51 |
+
uncertainty = params.get("uncertainty", 0.1) # 10% variance
|
| 52 |
+
runs = 1000
|
| 53 |
+
final_users = []
|
| 54 |
+
for _ in range(runs):
|
| 55 |
+
users = initial_users
|
| 56 |
+
for _ in range(time_months):
|
| 57 |
+
users *= (1 + np.random.normal(growth_rate, uncertainty))
|
| 58 |
+
final_users.append(users)
|
| 59 |
+
mean = np.mean(final_users)
|
| 60 |
+
std = np.std(final_users)
|
| 61 |
+
return f"Predicted users after {time_months} months: {mean:.0f} ± {std:.0f} (mean ± std, {runs} runs)."
|
| 62 |
+
except Exception as e:
|
| 63 |
+
return f"Sim error: {e}. Check params: {params}"
|
| 64 |
+
|
| 65 |
+
def setup_agent(vectorstore):
|
| 66 |
+
retriever_tool = create_retriever_tool(
|
| 67 |
+
vectorstore.as_retriever(search_kwargs={"k": 5}),
|
| 68 |
+
"course_materials_retriever",
|
| 69 |
+
"Searches PDFs and crawled web resources on optimization/sim/decision tech/project mgmt/lean startup."
|
| 70 |
+
)
|
| 71 |
+
web_tool = TavilySearchResults(max_results=3)
|
| 72 |
+
tools = [retriever_tool, web_tool, scenario_simulator]
|
| 73 |
+
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.3)
|
| 74 |
+
prompt = ChatPromptTemplate.from_messages([
|
| 75 |
+
("system", "You are Dr. Sue Cohen's Teaching Assistant, a passionate tutor for Applied Optimization/Simulation/Decision Tech/Project Mgmt. Guide users with sharp insights, probing questions, and hints from course materials/web. Be witty (e.g., 'Solid, but don’t optimize for chaos—how’s this tie to diffusion?'), professional, encouraging. Run scenario sims for adoption/scalability queries with clear params. Prioritize course/web data, use web for updates. Be concise, cite sources, never solve outright, redirect if off-topic, prompt next steps."),
|
| 76 |
+
("human", "{input}"),
|
| 77 |
+
MessagesPlaceholder("agent_scratchpad")
|
| 78 |
+
])
|
| 79 |
+
agent = create_tool_calling_agent(llm, tools, prompt)
|
| 80 |
+
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
|
| 81 |
+
return executor
|
| 82 |
+
|
| 83 |
+
def chat(message, history):
|
| 84 |
+
# Parse query for scenario_simulator if needed
|
| 85 |
+
if "initial_users" in message:
|
| 86 |
+
params = {}
|
| 87 |
+
for pair in message.split(","):
|
| 88 |
+
key, value = pair.split(":")
|
| 89 |
+
key = key.strip()
|
| 90 |
+
value = float(value.strip().replace("%", "")) / 100 if "%" in value else int(value.strip())
|
| 91 |
+
params[key] = value
|
| 92 |
+
return scenario_simulator(params)
|
| 93 |
+
return agent.invoke({"input": message})["output"]
|
| 94 |
+
|
| 95 |
+
if not os.path.exists("faiss_index"):
|
| 96 |
+
vectorstore = build_vectorstore()
|
| 97 |
+
else:
|
| 98 |
+
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
|
| 99 |
+
vectorstore = FAISS.load_local("faiss_index", embeddings, allow_dangerous_deserialization=True)
|
| 100 |
+
|
| 101 |
+
agent = setup_agent(vectorstore)
|
| 102 |
+
|
| 103 |
+
demo = gr.ChatInterface(
|
| 104 |
+
fn=chat,
|
| 105 |
+
title="Opt/Sim Project RAG Bot",
|
| 106 |
+
description="Query materials + web aug, e.g., 'Latest on genetic algos in scheduling?'"
|
| 107 |
+
)
|
| 108 |
+
|
| 109 |
+
if __name__ == "__main__":
|
| 110 |
+
demo.launch(server_name="0.0.0.0", server_port=7860)
|
file_convert.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import shutil
|
| 3 |
+
import sys
|
| 4 |
+
|
| 5 |
+
# For .docx conversion
|
| 6 |
+
try:
|
| 7 |
+
from docx2pdf import convert as docx_convert
|
| 8 |
+
except ImportError:
|
| 9 |
+
print("Error: docx2pdf not installed. Run 'pip install docx2pdf' and try again.")
|
| 10 |
+
sys.exit(1)
|
| 11 |
+
|
| 12 |
+
# For .pptx conversion (requires PowerPoint installed)
|
| 13 |
+
try:
|
| 14 |
+
import win32com.client
|
| 15 |
+
except ImportError:
|
| 16 |
+
print("Error: pywin32 not installed. Run 'pip install pywin32' and try again.")
|
| 17 |
+
sys.exit(1)
|
| 18 |
+
|
| 19 |
+
def main(input_dir, output_dir):
|
| 20 |
+
if not os.path.isdir(input_dir):
|
| 21 |
+
print(f"Error: {input_dir} is not a directory.")
|
| 22 |
+
sys.exit(1)
|
| 23 |
+
|
| 24 |
+
os.makedirs(output_dir, exist_ok=True)
|
| 25 |
+
|
| 26 |
+
for root, dirs, files in os.walk(input_dir):
|
| 27 |
+
rel_dir = os.path.relpath(root, input_dir)
|
| 28 |
+
target_subdir = os.path.join(output_dir, rel_dir)
|
| 29 |
+
os.makedirs(target_subdir, exist_ok=True)
|
| 30 |
+
|
| 31 |
+
for file in files:
|
| 32 |
+
filepath = os.path.join(root, file)
|
| 33 |
+
base, ext = os.path.splitext(file)
|
| 34 |
+
output_pdf = os.path.join(target_subdir, base + '.pdf')
|
| 35 |
+
|
| 36 |
+
if ext.lower() == '.docx':
|
| 37 |
+
docx_convert(filepath, output_pdf)
|
| 38 |
+
elif ext.lower() == '.pptx':
|
| 39 |
+
try:
|
| 40 |
+
ppt_app = win32com.client.Dispatch("PowerPoint.Application")
|
| 41 |
+
pres = ppt_app.Presentations.Open(os.path.abspath(filepath), WithWindow=False)
|
| 42 |
+
pres.SaveAs(output_pdf, 32) # 32 = ppSaveAsPDF
|
| 43 |
+
pres.Close()
|
| 44 |
+
ppt_app.Quit()
|
| 45 |
+
except Exception as e:
|
| 46 |
+
print(f"Failed to convert {filepath}: {e}. PowerPoint installed?")
|
| 47 |
+
elif ext.lower() == '.pdf':
|
| 48 |
+
shutil.copy(filepath, output_pdf)
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
main("OrigFolder","ConvertedFiles")
|
pythia.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
from langchain_core.tools import tool
|
| 3 |
+
|
| 4 |
+
@tool
|
| 5 |
+
def scenario_simulator(query: str, params: dict) -> str:
|
| 6 |
+
"""Simulates product adoption scenarios using Monte Carlo. Params: initial_users, growth_rate, time_months, uncertainty."""
|
| 7 |
+
try:
|
| 8 |
+
initial_users = params.get("initial_users", 1000)
|
| 9 |
+
growth_rate = params.get("growth_rate", 0.05) # 5%/month default
|
| 10 |
+
time_months = params.get("time_months", 12)
|
| 11 |
+
uncertainty = params.get("uncertainty", 0.1) # 10% variance
|
| 12 |
+
runs = 1000
|
| 13 |
+
final_users = []
|
| 14 |
+
for _ in range(runs):
|
| 15 |
+
users = initial_users
|
| 16 |
+
for _ in range(time_months):
|
| 17 |
+
users *= (1 + np.random.normal(growth_rate, uncertainty))
|
| 18 |
+
final_users.append(users)
|
| 19 |
+
mean = np.mean(final_users)
|
| 20 |
+
std = np.std(final_users)
|
| 21 |
+
return f"Predicted users after {time_months} months: {mean:.0f} ± {std:.0f} (mean ± std, {runs} runs)."
|
| 22 |
+
except Exception as e:
|
| 23 |
+
return f"Sim error: {e}. Check params: {params}"
|
websites.txt
ADDED
|
File without changes
|