krishnadhulipalla commited on
Commit
aedbc59
Β·
1 Parent(s): 7a5116e
Files changed (1) hide show
  1. app.py +39 -29
app.py CHANGED
@@ -3,6 +3,7 @@ import json
3
  import re
4
  import hashlib
5
  import gradio as gr
 
6
  from functools import partial
7
  import concurrent.futures
8
  from collections import defaultdict
@@ -95,7 +96,6 @@ class KnowledgeBase(BaseModel):
95
  # Initialize the knowledge base
96
  knowledge_base = KnowledgeBase()
97
 
98
-
99
  # LLMs
100
  # repharser_llm = ChatNVIDIA(model="mistralai/mistral-7b-instruct-v0.3") | StrOutputParser()
101
  repharser_llm = ChatNVIDIA(model="microsoft/phi-3-mini-4k-instruct") | StrOutputParser()
@@ -105,8 +105,7 @@ answer_llm = ChatOpenAI(
105
  model="gpt-4o",
106
  temperature=0.3,
107
  openai_api_key=os.getenv("OPENAI_API_KEY"),
108
- streaming=True,
109
- callbacks=[StreamingStdOutCallbackHandler()]
110
  ) | StrOutputParser()
111
 
112
 
@@ -377,7 +376,7 @@ hybrid_chain = generate_rewrites_chain | retrieve_chain
377
  extract_validation_inputs = RunnableLambda(lambda x: {
378
  "query": x["query"],
379
  "contents": [c["content"] for c in x["chunks"]],
380
- "memory": knowledge_base.json()
381
  })
382
 
383
  validation_chain = (
@@ -398,7 +397,7 @@ def prepare_answer_inputs(x: Dict) -> Dict:
398
  "profile": KRISHNA_BIO,
399
  "context": context,
400
  "use_fallback": x["validation"]["is_out_of_scope"],
401
- "memory": knowledge_base.json()
402
  }
403
 
404
  select_and_prompt = RunnableLambda(lambda x:
@@ -436,31 +435,38 @@ def RExtract(pydantic_class: Type[BaseModel], llm, prompt):
436
 
437
  knowledge_extractor = RExtract(
438
  pydantic_class=KnowledgeBase,
439
- llm=relevance_llm,
440
  prompt=parser_prompt
441
  )
442
 
443
- def update_kb_after_answer(data: dict):
 
 
 
444
  try:
 
 
 
 
 
 
445
  kb_input = {
446
- "know_base": knowledge_base.json(),
447
- "input": data["query"],
448
- "output": data["answer"]
449
  }
450
 
 
451
  new_kb = knowledge_extractor.invoke(kb_input)
452
- knowledge_base.__dict__.update(new_kb.__dict__) # update in place
453
-
454
- # Optional: print or log updated KB
455
- # print("βœ… Knowledge base updated:", knowledge_base.dict())
456
 
 
 
 
457
  except Exception as e:
458
- print("❌ Failed to update knowledge base:", str(e))
459
-
460
- return data # Return unchanged so answer can flow forward
461
-
462
-
463
- update_kb_chain = RunnableLambda(update_kb_after_answer)
464
 
465
  # Full Pipeline
466
  full_pipeline = hybrid_chain | RunnableAssign({"validation": validation_chain}) | answer_chain
@@ -479,21 +485,25 @@ def chat_interface(message, history):
479
  full_response = ""
480
  collected = None
481
 
 
482
  for chunk in full_pipeline.stream(inputs):
483
  if isinstance(chunk, dict) and "answer" in chunk:
484
  full_response += chunk["answer"]
485
- collected = chunk # store result for memory update
486
  yield full_response
487
  elif isinstance(chunk, str):
488
  full_response += chunk
489
  yield full_response
490
 
491
- # After yielding the full response, run knowledge update in background
492
- if collected:
493
- update_kb_after_answer({
494
- "query": message,
495
- "answer": full_response
496
- })
 
 
 
497
 
498
  with gr.Blocks(css="""
499
  html, body, .gradio-container {
@@ -540,9 +550,9 @@ demo = gr.ChatInterface(
540
  description="πŸ’‘ Ask anything about Krishna Vamsi Dhulipalla",
541
  examples=[
542
  "What are Krishna's research interests?",
543
- "Where did Krishna work?",
544
  "What did he study at Virginia Tech?"
545
  ],
546
  )
547
 
548
- demo.launch(max_threads=4, prevent_thread_lock=True, debug=True)
 
3
  import re
4
  import hashlib
5
  import gradio as gr
6
+ import threading
7
  from functools import partial
8
  import concurrent.futures
9
  from collections import defaultdict
 
96
  # Initialize the knowledge base
97
  knowledge_base = KnowledgeBase()
98
 
 
99
  # LLMs
100
  # repharser_llm = ChatNVIDIA(model="mistralai/mistral-7b-instruct-v0.3") | StrOutputParser()
101
  repharser_llm = ChatNVIDIA(model="microsoft/phi-3-mini-4k-instruct") | StrOutputParser()
 
105
  model="gpt-4o",
106
  temperature=0.3,
107
  openai_api_key=os.getenv("OPENAI_API_KEY"),
108
+ streaming=True
 
109
  ) | StrOutputParser()
110
 
111
 
 
376
  extract_validation_inputs = RunnableLambda(lambda x: {
377
  "query": x["query"],
378
  "contents": [c["content"] for c in x["chunks"]],
379
+ "memory": knowledge_base.model_dump_json()
380
  })
381
 
382
  validation_chain = (
 
397
  "profile": KRISHNA_BIO,
398
  "context": context,
399
  "use_fallback": x["validation"]["is_out_of_scope"],
400
+ "memory": knowledge_base.model_dump_json()
401
  }
402
 
403
  select_and_prompt = RunnableLambda(lambda x:
 
435
 
436
  knowledge_extractor = RExtract(
437
  pydantic_class=KnowledgeBase,
438
+ llm=instruct_llm,
439
  prompt=parser_prompt
440
  )
441
 
442
+ def update_knowledge_base(user_input: str, assistant_response: str):
443
+ """Update the knowledge base asynchronously after response is sent"""
444
+ global knowledge_base
445
+
446
  try:
447
+ # print("\n" + "="*50)
448
+ # print("πŸ”₯ STARTING KNOWLEDGE BASE UPDATE")
449
+ # print(f"User Input: {user_input}")
450
+ # print(f"Assistant Response: {assistant_response[:100]}...")
451
+
452
+ # Prepare input for knowledge extractor
453
  kb_input = {
454
+ "know_base": knowledge_base.model_dump_json(), # Fixed deprecation
455
+ "input": user_input,
456
+ "output": assistant_response
457
  }
458
 
459
+ #print("🧠 Calling knowledge extractor...")
460
  new_kb = knowledge_extractor.invoke(kb_input)
461
+ knowledge_base = new_kb # Update global knowledge base
 
 
 
462
 
463
+ # Detailed debug output
464
+ print("βœ… KNOWLEDGE BASE UPDATED SUCCESSFULLY")
465
+
466
  except Exception as e:
467
+ print(f"❌ KNOWLEDGE BASE UPDATE FAILED: {str(e)}")
468
+ import traceback
469
+ traceback.print_exc()
 
 
 
470
 
471
  # Full Pipeline
472
  full_pipeline = hybrid_chain | RunnableAssign({"validation": validation_chain}) | answer_chain
 
485
  full_response = ""
486
  collected = None
487
 
488
+ # Stream the response to user
489
  for chunk in full_pipeline.stream(inputs):
490
  if isinstance(chunk, dict) and "answer" in chunk:
491
  full_response += chunk["answer"]
492
+ collected = chunk
493
  yield full_response
494
  elif isinstance(chunk, str):
495
  full_response += chunk
496
  yield full_response
497
 
498
+ # After streaming completes, update KB in background thread
499
+ if full_response:
500
+ import threading
501
+ update_thread = threading.Thread(
502
+ target=update_knowledge_base,
503
+ args=(message, full_response),
504
+ daemon=True
505
+ )
506
+ update_thread.start()
507
 
508
  with gr.Blocks(css="""
509
  html, body, .gradio-container {
 
550
  description="πŸ’‘ Ask anything about Krishna Vamsi Dhulipalla",
551
  examples=[
552
  "What are Krishna's research interests?",
553
+ "What are Krishna's skills?",
554
  "What did he study at Virginia Tech?"
555
  ],
556
  )
557
 
558
+ demo.launch(max_threads=4, prevent_thread_lock=True, debug=True)