Commit
Β·
aedbc59
1
Parent(s):
7a5116e
fixed KB
Browse files
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.
|
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.
|
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=
|
440 |
prompt=parser_prompt
|
441 |
)
|
442 |
|
443 |
-
def
|
|
|
|
|
|
|
444 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
445 |
kb_input = {
|
446 |
-
"know_base": knowledge_base.
|
447 |
-
"input":
|
448 |
-
"output":
|
449 |
}
|
450 |
|
|
|
451 |
new_kb = knowledge_extractor.invoke(kb_input)
|
452 |
-
knowledge_base
|
453 |
-
|
454 |
-
# Optional: print or log updated KB
|
455 |
-
# print("β
Knowledge base updated:", knowledge_base.dict())
|
456 |
|
|
|
|
|
|
|
457 |
except Exception as e:
|
458 |
-
print("β
|
459 |
-
|
460 |
-
|
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
|
486 |
yield full_response
|
487 |
elif isinstance(chunk, str):
|
488 |
full_response += chunk
|
489 |
yield full_response
|
490 |
|
491 |
-
# After
|
492 |
-
if
|
493 |
-
|
494 |
-
|
495 |
-
|
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 |
-
"
|
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)
|