import os import gradio as gr from dotenv import load_dotenv from langchain_chroma import Chroma from langchain_community.tools import DuckDuckGoSearchRun from langchain_core.messages import HumanMessage, SystemMessage from langchain_huggingface import HuggingFaceEmbeddings from langchain_openai import ChatOpenAI from news_price_correlation import build_correlation_analysis from nvidia_agent_core import forecast_markdown, predict_nvidia_stock_payload, route_query load_dotenv() if not os.getenv("OPENAI_API_KEY"): raise ValueError("OPENAI_API_KEY was not found. Add it to .env or your environment.") llm = ChatOpenAI(model="gpt-5.4", temperature=0.3, max_tokens=1024) ddg_search = DuckDuckGoSearchRun() vectorstore = None try: import chromadb from chromadb.config import Settings embeddings = HuggingFaceEmbeddings(model_name="all-mpnet-base-v2", model_kwargs={"device": "cpu"}) client = chromadb.PersistentClient(path="./chroma_db_v2", settings=Settings(allow_reset=True)) vectorstore = Chroma( client=client, collection_name="nvidia_annual_reports_2014_2025", embedding_function=embeddings, ) except Exception as exc: print(f"RAG unavailable; Gradio app will continue without annual-report retrieval: {exc}") def forecast_answer() -> str: payload = predict_nvidia_stock_payload(periods=7) return forecast_markdown(payload) def correlation_answer(query: str) -> str: return build_correlation_analysis( query=query, search=ddg_search.run, llm=llm, csv_path="nvda_2014_to_2026.csv", ) def researcher_answer(query: str) -> str: context = "" if vectorstore: docs = vectorstore.similarity_search(query, k=5) context = "\n\n".join(doc.page_content[:700] for doc in docs) news = ddg_search.run(f"NVIDIA {query} latest news OR earnings OR Blackwell OR Huawei")[:1000] response = llm.invoke( [ SystemMessage(content="You are NVIDIA's expert financial and strategy analyst."), HumanMessage(content=f"Question: {query}\n\nAnnual-report context:\n{context}\n\nNews:\n{news}"), ] ) return response.content def get_response(query: str) -> str: route = route_query(query) if route == "ML_agent": return forecast_answer() if route == "correlation_agent": return correlation_answer(query) if route in {"results_strategy_agent", "outlook_agent"}: return researcher_answer(query) response = llm.invoke( [ SystemMessage(content="You are a helpful NVIDIA assistant."), HumanMessage(content=query), ] ) return response.content def chat(message, history): try: return get_response(message) except Exception as exc: return f"Error: {exc}" demo = gr.ChatInterface( fn=chat, title="NVIDIA AI Assistant", description="Notebook-aligned multi-agent assistant with RAG, news correlation, and Prophet v3 residual ML forecasting.", examples=[ "Predict Nvidia stock price for the next 7 business days", "What did Nvidia report about gross profit in the 2025 annual report?", "Why did NVDA sell off on China/Huawei export-control news?", "If CCP China invades Taiwan, predict the scale of NVDA selloff and share price drop", ], ) if __name__ == "__main__": demo.launch(server_name="0.0.0.0", server_port=7860, share=False)