mgbam commited on
Commit
b31058d
·
verified ·
1 Parent(s): 92b5f8b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +184 -172
app.py CHANGED
@@ -3,30 +3,29 @@
3
  # ------------------------------
4
  from langchain_openai import OpenAIEmbeddings
5
  from langchain_community.vectorstores import Chroma
6
- from langchain_core.messages import HumanMessage, AIMessage, ToolMessage
7
  from langchain.text_splitter import RecursiveCharacterTextSplitter
 
8
  from langgraph.graph import END, StateGraph
9
- from langgraph.prebuilt import ToolNode
10
- from langgraph.graph.message import add_messages
11
  from typing_extensions import TypedDict, Annotated
12
  from typing import Sequence, Dict, List, Optional, Any
13
  import chromadb
14
- import re
15
  import os
16
  import streamlit as st
17
  import requests
18
  import hashlib
19
- import json
20
  import time
21
- from langchain.tools.retriever import create_retriever_tool
22
  from concurrent.futures import ThreadPoolExecutor, as_completed
23
  from datetime import datetime
 
24
 
25
  # ------------------------------
26
  # State Schema Definition
27
  # ------------------------------
28
  class AgentState(TypedDict):
29
- messages: Annotated[Sequence[AIMessage | HumanMessage | ToolMessage], add_messages]
30
  context: Dict[str, Any]
31
  metadata: Dict[str, Any]
32
 
@@ -40,37 +39,56 @@ class ResearchConfig:
40
  CHUNK_OVERLAP = 64
41
  MAX_CONCURRENT_REQUESTS = 5
42
  EMBEDDING_DIMENSIONS = 1536
 
 
43
  DOCUMENT_MAP = {
44
- "Research Report: Results of a New AI Model Improving Image Recognition Accuracy to 98%":
45
- "CV-Transformer Hybrid Architecture",
46
- "Academic Paper Summary: Why Transformers Became the Mainstream Architecture in Natural Language Processing":
47
- "Transformer Architecture Analysis",
48
- "Latest Trends in Machine Learning Methods Using Quantum Computing":
49
- "Quantum ML Frontiers"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  }
51
- ANALYSIS_TEMPLATE = """Analyze these technical documents with scientific rigor:
 
52
  {context}
53
 
54
- Respond with:
55
- 1. Key Technical Contributions (bullet points)
56
- 2. Novel Methodologies
57
- 3. Empirical Results (with metrics)
58
- 4. Potential Applications
59
- 5. Limitations & Future Directions
60
 
61
- Format: Markdown with LaTeX mathematical notation where applicable
62
- """
63
 
64
- # Validation
65
  if not ResearchConfig.DEEPSEEK_API_KEY:
66
- st.error("""**Research Portal Configuration Required**
67
- 1. Obtain DeepSeek API key: [platform.deepseek.com](https://platform.deepseek.com/)
68
- 2. Configure secret: `DEEPSEEK_API_KEY` in Space settings
69
  3. Rebuild deployment""")
70
  st.stop()
71
 
72
  # ------------------------------
73
- # Quantum Document Processing
74
  # ------------------------------
75
  class QuantumDocumentManager:
76
  def __init__(self):
@@ -80,17 +98,29 @@ class QuantumDocumentManager:
80
  dimensions=ResearchConfig.EMBEDDING_DIMENSIONS
81
  )
82
 
83
- def create_collection(self, documents: List[str], collection_name: str) -> Chroma:
84
  splitter = RecursiveCharacterTextSplitter(
85
  chunk_size=ResearchConfig.CHUNK_SIZE,
86
  chunk_overlap=ResearchConfig.CHUNK_OVERLAP,
87
  separators=["\n\n", "\n", "|||"]
88
  )
89
- docs = splitter.create_documents(documents)
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  return Chroma.from_documents(
91
  documents=docs,
92
  embedding=self.embeddings,
93
- client=self.client,
94
  collection_name=collection_name,
95
  ids=[self._document_id(doc.page_content) for doc in docs]
96
  )
@@ -98,78 +128,49 @@ class QuantumDocumentManager:
98
  def _document_id(self, content: str) -> str:
99
  return f"{hashlib.sha256(content.encode()).hexdigest()[:16]}-{int(time.time())}"
100
 
101
- # Initialize document collections
102
  qdm = QuantumDocumentManager()
103
- research_docs = qdm.create_collection([
104
- "Research Report: Results of a New AI Model Improving Image Recognition Accuracy to 98%",
105
- "Academic Paper Summary: Why Transformers Became the Mainstream Architecture in Natural Language Processing",
106
- "Latest Trends in Machine Learning Methods Using Quantum Computing"
107
- ], "research")
108
-
109
- development_docs = qdm.create_collection([
110
- "Project A: UI Design Completed, API Integration in Progress",
111
- "Project B: Testing New Feature X, Bug Fixes Needed",
112
- "Product Y: In the Performance Optimization Stage Before Release"
113
- ], "development")
114
 
115
  # ------------------------------
116
- # Advanced Retrieval System
117
  # ------------------------------
118
  class ResearchRetriever:
119
  def __init__(self):
120
- self.retrievers = {
121
- "research": research_docs.as_retriever(
122
- search_type="mmr",
123
- search_kwargs={
124
- 'k': 4,
125
- 'fetch_k': 20,
126
- 'lambda_mult': 0.85
127
- }
128
- ),
129
- "development": development_docs.as_retriever(
130
- search_type="similarity",
131
- search_kwargs={'k': 3}
132
- )
133
- }
134
 
135
- def retrieve(self, query: str, domain: str) -> List[Any]:
136
  try:
137
- return self.retrievers[domain].invoke(query)
138
- except KeyError:
 
 
 
 
139
  return []
140
 
141
- retriever = ResearchRetriever()
142
-
143
  # ------------------------------
144
- # Cognitive Processing Unit
145
  # ------------------------------
146
  class CognitiveProcessor:
147
  def __init__(self):
148
  self.executor = ThreadPoolExecutor(max_workers=ResearchConfig.MAX_CONCURRENT_REQUESTS)
149
- self.session_id = hashlib.sha256(datetime.now().isoformat().encode()).hexdigest()[:12]
150
 
151
  def process_query(self, prompt: str) -> Dict:
152
- futures = []
153
- for _ in range(3): # Triple redundancy
154
- futures.append(self.executor.submit(
155
- self._execute_api_request,
156
- prompt
157
- ))
158
-
159
- results = []
160
- for future in as_completed(futures):
161
- try:
162
- results.append(future.result())
163
- except Exception as e:
164
- st.error(f"Processing Error: {str(e)}")
165
-
166
- return self._consensus_check(results)
167
-
168
- def _execute_api_request(self, prompt: str) -> Dict:
169
  headers = {
170
  "Authorization": f"Bearer {ResearchConfig.DEEPSEEK_API_KEY}",
171
- "Content-Type": "application/json",
172
- "X-Research-Session": self.session_id
173
  }
174
 
175
  try:
@@ -190,20 +191,25 @@ class CognitiveProcessor:
190
  )
191
  response.raise_for_status()
192
  return response.json()
193
- except requests.exceptions.RequestException as e:
194
  return {"error": str(e)}
195
 
196
- def _consensus_check(self, results: List[Dict]) -> Dict:
197
  valid = [r for r in results if "error" not in r]
198
  if not valid:
199
  return {"error": "All API requests failed"}
200
- return max(valid, key=lambda x: len(x.get('choices', [{}])[0].get('message', {}).get('content', '')))
 
 
 
 
201
 
202
  # ------------------------------
203
- # Research Workflow Engine
204
  # ------------------------------
205
  class ResearchWorkflow:
206
  def __init__(self):
 
207
  self.processor = CognitiveProcessor()
208
  self.workflow = StateGraph(AgentState)
209
  self._build_workflow()
@@ -241,70 +247,87 @@ class ResearchWorkflow:
241
 
242
  def retrieve_documents(self, state: AgentState) -> Dict:
243
  try:
244
- query = state["context"]["raw_query"]
245
- docs = retriever.retrieve(query, "research")
 
246
  return {
247
  "messages": [AIMessage(content=f"Retrieved {len(docs)} documents")],
248
- "context": {
249
- "documents": docs,
250
- "retrieval_time": time.time()
251
- }
252
  }
253
  except Exception as e:
254
  return self._error_state(f"Retrieval Error: {str(e)}")
255
 
256
  def analyze_content(self, state: AgentState) -> Dict:
257
  try:
258
- docs = "\n\n".join([d.page_content for d in state["context"]["documents"]])
259
- prompt = ResearchConfig.ANALYSIS_TEMPLATE.format(context=docs)
 
260
  response = self.processor.process_query(prompt)
261
 
262
  if "error" in response:
263
- return self._error_state(response["error"])
 
 
 
264
 
265
  return {
266
- "messages": [AIMessage(content=response['choices'][0]['message']['content'])],
267
- "context": {"analysis": response}
268
  }
269
  except Exception as e:
270
  return self._error_state(f"Analysis Error: {str(e)}")
271
 
272
  def validate_output(self, state: AgentState) -> Dict:
273
- analysis = state["messages"][-1].content
274
- validation_prompt = f"""Validate research analysis:
275
- {analysis}
276
-
277
- Check for:
278
- 1. Technical accuracy
279
- 2. Citation support
280
- 3. Logical consistency
281
- 4. Methodological soundness
282
-
283
- Respond with 'VALID' or 'INVALID'"""
284
 
285
  response = self.processor.process_query(validation_prompt)
 
286
  return {
287
- "messages": [AIMessage(content=analysis + f"\n\nValidation: {response.get('choices', [{}])[0].get('message', {}).get('content', '')}")]
 
288
  }
289
 
290
  def refine_results(self, state: AgentState) -> Dict:
291
- refinement_prompt = f"""Refine this analysis:
292
- {state["messages"][-1].content}
293
-
294
- Improve:
295
- 1. Technical precision
296
- 2. Empirical grounding
297
- 3. Theoretical coherence"""
298
 
299
  response = self.processor.process_query(refinement_prompt)
300
  return {
301
- "messages": [AIMessage(content=response.get('choices', [{}])[0].get('message', {}).get('content', ''))],
302
  "context": state["context"]
303
  }
304
 
305
  def _quality_check(self, state: AgentState) -> str:
306
- content = state["messages"][-1].content
307
- return "valid" if "VALID" in content else "invalid"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
 
309
  def _error_state(self, message: str) -> Dict:
310
  return {
@@ -374,20 +397,24 @@ class ResearchInterface:
374
  border-radius: 8px;
375
  margin: 1rem 0;
376
  }
 
 
 
 
 
 
 
377
  </style>
378
  """, unsafe_allow_html=True)
379
 
380
  def _build_sidebar(self):
381
  with st.sidebar:
382
  st.title("🔍 Research Database")
383
- st.subheader("Technical Papers")
384
- for title, short in ResearchConfig.DOCUMENT_MAP.items():
385
- with st.expander(short):
386
- st.markdown(f"```\n{title}\n```")
387
-
388
- st.subheader("Analysis Metrics")
389
- st.metric("Vector Collections", 2)
390
  st.metric("Embedding Dimensions", ResearchConfig.EMBEDDING_DIMENSIONS)
 
391
 
392
  def _build_main_interface(self):
393
  st.title("🧠 NeuroResearch AI")
@@ -399,54 +426,39 @@ class ResearchInterface:
399
 
400
  def _execute_analysis(self, query: str):
401
  try:
402
- with st.spinner("Initializing Quantum Analysis..."):
403
- results = self.workflow.app.stream(
404
- {"messages": [HumanMessage(content=query)], "context": {}, "metadata": {}}
405
  )
406
 
407
- for event in results:
408
- self._render_event(event)
409
-
410
- st.success("✅ Analysis Completed Successfully")
411
- except Exception as e:
412
- st.error(f"""**Analysis Failed**
413
- {str(e)}
414
- Potential issues:
415
- - Complex query structure
416
- - Document correlation failure
417
- - Temporal processing constraints""")
418
-
419
- def _render_event(self, event: Dict):
420
- if 'ingest' in event:
421
- with st.container():
422
- st.success("✅ Query Ingested")
423
-
424
- elif 'retrieve' in event:
425
- with st.container():
426
- docs = event['retrieve']['context']['documents']
427
- st.info(f"📚 Retrieved {len(docs)} documents")
428
- with st.expander("View Retrieved Documents", expanded=False):
429
- for i, doc in enumerate(docs, 1):
430
- st.markdown(f"**Document {i}**")
431
- st.code(doc.page_content, language='text')
432
-
433
- elif 'analyze' in event:
434
- with st.container():
435
- content = event['analyze']['messages'][0].content
436
- with st.expander("Technical Analysis Report", expanded=True):
437
- st.markdown(content)
438
-
439
- elif 'validate' in event:
440
- with st.container():
441
- content = event['validate']['messages'][0].content
442
- if "VALID" in content:
443
- st.success("✅ Validation Passed")
444
- with st.expander("View Validated Analysis", expanded=True):
445
- st.markdown(content.split("Validation:")[0])
446
  else:
447
- st.warning("⚠️ Validation Issues Detected")
448
- with st.expander("View Validation Details", expanded=True):
449
- st.markdown(content)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
450
 
451
  if __name__ == "__main__":
452
  ResearchInterface()
 
3
  # ------------------------------
4
  from langchain_openai import OpenAIEmbeddings
5
  from langchain_community.vectorstores import Chroma
6
+ from langchain_core.messages import HumanMessage, AIMessage
7
  from langchain.text_splitter import RecursiveCharacterTextSplitter
8
+ from langchain_core.documents import Document
9
  from langgraph.graph import END, StateGraph
 
 
10
  from typing_extensions import TypedDict, Annotated
11
  from typing import Sequence, Dict, List, Optional, Any
12
  import chromadb
13
+ import numpy as np
14
  import os
15
  import streamlit as st
16
  import requests
17
  import hashlib
18
+ import re
19
  import time
 
20
  from concurrent.futures import ThreadPoolExecutor, as_completed
21
  from datetime import datetime
22
+ from sklearn.metrics.pairwise import cosine_similarity
23
 
24
  # ------------------------------
25
  # State Schema Definition
26
  # ------------------------------
27
  class AgentState(TypedDict):
28
+ messages: Annotated[Sequence[AIMessage | HumanMessage], add_messages]
29
  context: Dict[str, Any]
30
  metadata: Dict[str, Any]
31
 
 
39
  CHUNK_OVERLAP = 64
40
  MAX_CONCURRENT_REQUESTS = 5
41
  EMBEDDING_DIMENSIONS = 1536
42
+ RESEARCH_EMBEDDING = np.random.randn(1536)
43
+
44
  DOCUMENT_MAP = {
45
+ "CV-Transformer Hybrid Architecture": {
46
+ "title": "Research Report: CV-Transformer Model (98% Accuracy)",
47
+ "content": """
48
+ Hybrid architecture combining CNNs and Transformers achieves 98% image recognition accuracy.
49
+ Key equation: $f(x) = \text{Attention}(\text{CNN}(x))$
50
+ Validation on ImageNet-1k: Top-1 Accuracy 98.2%, Inference Speed 42ms/img
51
+ """
52
+ },
53
+ "Transformer Architecture Analysis": {
54
+ "title": "Academic Paper: Transformers in NLP",
55
+ "content": """
56
+ Self-attention mechanism remains core innovation:
57
+ $\text{Attention}(Q, K, V) = \text{softmax}(\frac{QK^T}{\sqrt{d_k}})V$
58
+ GLUE Benchmark Score: 92.4%, Training Efficiency: 1.8x vs RNNs
59
+ """
60
+ },
61
+ "Quantum ML Frontiers": {
62
+ "title": "Quantum Machine Learning Review",
63
+ "content": """
64
+ Quantum gradient descent enables faster optimization:
65
+ $\theta_{t+1} = \theta_t - \eta \nabla_\theta \mathcal{L}(\theta_t)$
66
+ 100x speedup on optimization tasks, 58% energy reduction
67
+ """
68
+ }
69
  }
70
+
71
+ ANALYSIS_TEMPLATE = """Analyze these technical documents:
72
  {context}
73
 
74
+ Respond in MARKDOWN with:
75
+ 1. **Key Technical Contributions** (bullet points with equations)
76
+ 2. **Novel Methodologies** (algorithms with math notation)
77
+ 3. **Empirical Results** (comparative metrics)
78
+ 4. **Applications** (domain-specific implementations)
79
+ 5. **Limitations** (theoretical/practical boundaries)
80
 
81
+ Include LaTeX equations where applicable."""
 
82
 
 
83
  if not ResearchConfig.DEEPSEEK_API_KEY:
84
+ st.error("""**Configuration Required**
85
+ 1. Get DeepSeek API key: [platform.deepseek.com](https://platform.deepseek.com/)
86
+ 2. Set secret: `DEEPSEEK_API_KEY`
87
  3. Rebuild deployment""")
88
  st.stop()
89
 
90
  # ------------------------------
91
+ # Document Processing System
92
  # ------------------------------
93
  class QuantumDocumentManager:
94
  def __init__(self):
 
98
  dimensions=ResearchConfig.EMBEDDING_DIMENSIONS
99
  )
100
 
101
+ def create_collection(self, document_map: Dict[str, Dict[str, str]], collection_name: str) -> Chroma:
102
  splitter = RecursiveCharacterTextSplitter(
103
  chunk_size=ResearchConfig.CHUNK_SIZE,
104
  chunk_overlap=ResearchConfig.CHUNK_OVERLAP,
105
  separators=["\n\n", "\n", "|||"]
106
  )
107
+
108
+ docs = []
109
+ for key, data in document_map.items():
110
+ chunks = splitter.split_text(data["content"])
111
+ for chunk in chunks:
112
+ docs.append(Document(
113
+ page_content=chunk,
114
+ metadata={
115
+ "title": data["title"],
116
+ "source": collection_name,
117
+ "hash": hashlib.sha256(chunk.encode()).hexdigest()[:16]
118
+ }
119
+ ))
120
+
121
  return Chroma.from_documents(
122
  documents=docs,
123
  embedding=self.embeddings,
 
124
  collection_name=collection_name,
125
  ids=[self._document_id(doc.page_content) for doc in docs]
126
  )
 
128
  def _document_id(self, content: str) -> str:
129
  return f"{hashlib.sha256(content.encode()).hexdigest()[:16]}-{int(time.time())}"
130
 
131
+ # Initialize document system
132
  qdm = QuantumDocumentManager()
133
+ research_docs = qdm.create_collection(ResearchConfig.DOCUMENT_MAP, "research")
 
 
 
 
 
 
 
 
 
 
134
 
135
  # ------------------------------
136
+ # Intelligent Retrieval System
137
  # ------------------------------
138
  class ResearchRetriever:
139
  def __init__(self):
140
+ self.retriever = research_docs.as_retriever(
141
+ search_type="mmr",
142
+ search_kwargs={
143
+ 'k': 4,
144
+ 'fetch_k': 20,
145
+ 'lambda_mult': 0.85
146
+ }
147
+ )
 
 
 
 
 
 
148
 
149
+ def retrieve(self, query: str) -> List[Document]:
150
  try:
151
+ docs = self.retriever.invoke(query)
152
+ if not docs:
153
+ raise ValueError("No relevant documents found")
154
+ return docs
155
+ except Exception as e:
156
+ st.error(f"Retrieval Error: {str(e)}")
157
  return []
158
 
 
 
159
  # ------------------------------
160
+ # Robust Processing Core
161
  # ------------------------------
162
  class CognitiveProcessor:
163
  def __init__(self):
164
  self.executor = ThreadPoolExecutor(max_workers=ResearchConfig.MAX_CONCURRENT_REQUESTS)
 
165
 
166
  def process_query(self, prompt: str) -> Dict:
167
+ futures = [self.executor.submit(self._api_request, prompt) for _ in range(3)]
168
+ return self._best_result([f.result() for f in as_completed(futures)])
169
+
170
+ def _api_request(self, prompt: str) -> Dict:
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  headers = {
172
  "Authorization": f"Bearer {ResearchConfig.DEEPSEEK_API_KEY}",
173
+ "Content-Type": "application/json"
 
174
  }
175
 
176
  try:
 
191
  )
192
  response.raise_for_status()
193
  return response.json()
194
+ except Exception as e:
195
  return {"error": str(e)}
196
 
197
+ def _best_result(self, results: List[Dict]) -> Dict:
198
  valid = [r for r in results if "error" not in r]
199
  if not valid:
200
  return {"error": "All API requests failed"}
201
+
202
+ # Select response with most technical content
203
+ contents = [r.get('choices', [{}])[0].get('message', {}).get('content', '') for r in valid]
204
+ tech_scores = [len(re.findall(r"\$.*?\$", c)) for c in contents]
205
+ return valid[np.argmax(tech_scores)]
206
 
207
  # ------------------------------
208
+ # Validation Workflow Engine
209
  # ------------------------------
210
  class ResearchWorkflow:
211
  def __init__(self):
212
+ self.retriever = ResearchRetriever()
213
  self.processor = CognitiveProcessor()
214
  self.workflow = StateGraph(AgentState)
215
  self._build_workflow()
 
247
 
248
  def retrieve_documents(self, state: AgentState) -> Dict:
249
  try:
250
+ docs = self.retriever.retrieve(state["context"]["raw_query"])
251
+ if not docs:
252
+ return self._error_state("Document correlation failure - no relevant papers found")
253
  return {
254
  "messages": [AIMessage(content=f"Retrieved {len(docs)} documents")],
255
+ "context": {"documents": docs}
 
 
 
256
  }
257
  except Exception as e:
258
  return self._error_state(f"Retrieval Error: {str(e)}")
259
 
260
  def analyze_content(self, state: AgentState) -> Dict:
261
  try:
262
+ docs = state["context"]["documents"]
263
+ context = "\n\n".join([f"### {doc.metadata['title']}\n{doc.page_content}" for doc in docs])
264
+ prompt = ResearchConfig.ANALYSIS_TEMPLATE.format(context=context)
265
  response = self.processor.process_query(prompt)
266
 
267
  if "error" in response:
268
+ raise RuntimeError(response["error"])
269
+
270
+ analysis = response['choices'][0]['message']['content']
271
+ self._validate_analysis_structure(analysis)
272
 
273
  return {
274
+ "messages": [AIMessage(content=analysis)],
275
+ "context": {"analysis": analysis}
276
  }
277
  except Exception as e:
278
  return self._error_state(f"Analysis Error: {str(e)}")
279
 
280
  def validate_output(self, state: AgentState) -> Dict:
281
+ validation_prompt = f"""Validate this technical analysis:
282
+ {state["messages"][-1].content}
283
+
284
+ Check for:
285
+ 1. Mathematical accuracy
286
+ 2. Empirical evidence
287
+ 3. Technical depth
288
+ 4. Logical consistency
289
+
290
+ Respond with 'VALID' or 'INVALID'"""
 
291
 
292
  response = self.processor.process_query(validation_prompt)
293
+ content = response.get('choices', [{}])[0].get('message', {}).get('content', '')
294
  return {
295
+ "messages": [AIMessage(content=f"{state['messages'][-1].content}\n\n## Validation\n{content}")],
296
+ "context": {"valid": "VALID" in content}
297
  }
298
 
299
  def refine_results(self, state: AgentState) -> Dict:
300
+ refinement_prompt = f"""Improve this analysis:
301
+ {state["messages"][-1].content}
302
+
303
+ Focus on:
304
+ 1. Enhancing mathematical rigor
305
+ 2. Adding empirical references
306
+ 3. Strengthening technical arguments"""
307
 
308
  response = self.processor.process_query(refinement_prompt)
309
  return {
310
+ "messages": [AIMessage(content=response['choices'][0]['message']['content'])],
311
  "context": state["context"]
312
  }
313
 
314
  def _quality_check(self, state: AgentState) -> str:
315
+ return "valid" if state.get("context", {}).get("valid", False) else "invalid"
316
+
317
+ def _validate_analysis_structure(self, content: str):
318
+ required_sections = [
319
+ "Key Technical Contributions",
320
+ "Novel Methodologies",
321
+ "Empirical Results",
322
+ "Applications",
323
+ "Limitations"
324
+ ]
325
+ missing = [s for s in required_sections if f"## {s}" not in content]
326
+ if missing:
327
+ raise ValueError(f"Missing critical sections: {', '.join(missing)}")
328
+
329
+ if not re.search(r"\$.*?\$", content):
330
+ raise ValueError("Analysis lacks required mathematical notation")
331
 
332
  def _error_state(self, message: str) -> Dict:
333
  return {
 
397
  border-radius: 8px;
398
  margin: 1rem 0;
399
  }
400
+
401
+ code {
402
+ color: #2ecc71;
403
+ background: #002200;
404
+ padding: 2px 4px;
405
+ border-radius: 4px;
406
+ }
407
  </style>
408
  """, unsafe_allow_html=True)
409
 
410
  def _build_sidebar(self):
411
  with st.sidebar:
412
  st.title("🔍 Research Database")
413
+ for key, data in ResearchConfig.DOCUMENT_MAP.items():
414
+ with st.expander(data["title"]):
415
+ st.markdown(f"```\n{data['content']}\n```")
 
 
 
 
416
  st.metric("Embedding Dimensions", ResearchConfig.EMBEDDING_DIMENSIONS)
417
+ st.metric("Document Chunks", len(research_docs.get()['ids']))
418
 
419
  def _build_main_interface(self):
420
  st.title("🧠 NeuroResearch AI")
 
426
 
427
  def _execute_analysis(self, query: str):
428
  try:
429
+ with st.spinner("Performing deep technical analysis..."):
430
+ result = self.workflow.app.invoke(
431
+ {"messages": [HumanMessage(content=query)]}
432
  )
433
 
434
+ if result.get("context", {}).get("error"):
435
+ self._show_error(result["context"].get("error", "Unknown error"))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
  else:
437
+ self._display_results(result)
438
+ except Exception as e:
439
+ self._show_error(str(e))
440
+
441
+ def _display_results(self, result):
442
+ content = result["messages"][-1].content
443
+ with st.expander("Technical Analysis Report", expanded=True):
444
+ st.markdown(content)
445
+
446
+ with st.expander("Source Documents", expanded=False):
447
+ for doc in result["context"].get("documents", []):
448
+ st.markdown(f"**{doc.metadata['title']}**")
449
+ st.code(doc.page_content, language='latex')
450
+
451
+ def _show_error(self, message):
452
+ st.error(f"""
453
+ ⚠️ Analysis Failed: {message}
454
+
455
+ Troubleshooting Steps:
456
+ 1. Check query specificity
457
+ 2. Verify document connections
458
+ 3. Ensure mathematical notation in sources
459
+ 4. Review API key validity
460
+ 5. Simplify complex query structures
461
+ """)
462
 
463
  if __name__ == "__main__":
464
  ResearchInterface()