Dahee_AI / gradio_app.py
resulmamiyev's picture
Upload folder using huggingface_hub
4ed309e verified
import gradio as gr
import utils
from app import question_graph, MemorySaver
from translation import LANGUAGES
import uuid
import os
from dotenv import load_dotenv
import tempfile
load_dotenv()
service_account_json = os.environ.get("GOOGLE_SERVICE_ACCOUNT_JSON")
PROJECT_ID = os.environ.get("GOOGLE_CLOUD_PROJECT")
if service_account_json:
# Write the JSON content to a temporary file
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".json")
temp_file.write(service_account_json.encode("utf-8"))
temp_file.close()
# Set the GOOGLE_APPLICATION_CREDENTIALS environment variable to the temp file path
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = temp_file.name
# -----------------------------
# In-Memory Storage for Feedback Flow
# -----------------------------
session_data = {}
session_data["en_topics"] = utils.get_topic_names("en")
session_data["az_topics"] = utils.get_topic_names("az")
session_data["ru_topics"] = utils.get_topic_names("ru")
# -----------------------------
# Graph Invocation Function
# -----------------------------
def run_graph(topic, subtopic, difficulty, lang):
session_id = str(uuid.uuid4()) # Unique session per question
memory = MemorySaver()
if lang == "az" or lang == "ru":
topic, subtopic, difficulty = utils.get_eng_names(
topic, subtopic, difficulty, lang
)
print("Topic:", topic, "Subtopic:", subtopic, "Difficulty:", difficulty)
inputs = {
"topic": topic,
"subtopic": subtopic,
"difficulty": difficulty,
"description": "",
"num_questions": 3,
"messages": [],
"context": [],
"relevant_questions": [],
"question": "",
"steps": [],
"tool_requests": [],
"tool_results": [],
"verified": False,
"solution": "",
"answer": "",
"error": "",
"human_feedback": "",
}
# Run up to feedback node (interrupt point)
partial_result = question_graph.invoke(
inputs, config={"configurable": {"thread_id": session_id}}
)
session_data[session_id] = {
"memory": memory,
"inputs": partial_result, # Store intermediate state
}
generated_question = partial_result.get("question", "No question generated.")
# Translate Question if English is not selected
if lang != "en":
generated_question = utils.translate_text(
generated_question, PROJECT_ID, target_lang=lang, source_lang="en"
)
return session_id, generated_question, LANGUAGES[lang]["feedback_placeholder"]
# -----------------------------
# Handle Feedback and Rerun Graph
# -----------------------------
def handle_feedback(session_id, feedback_text, lang):
data = session_data.get(session_id)
if not data:
return session_id, "Session expired or invalid.", ""
memory = data["memory"]
feedback_text = feedback_text.strip()
thread = {"configurable": {"thread_id": session_id}}
if feedback_text:
# Update state with feedback at node 'feedback'
feedback_text = utils.translate_text(
feedback_text, PROJECT_ID, target_lang="en"
)
question_graph.update_state(
thread, {"human_feedback": feedback_text}, as_node="feedback"
)
# Continue from feedback
final_result = question_graph.invoke(
None, config={"configurable": {"thread_id": session_id}}
)
new_question = final_result.get("question", "No question generated.")
session_data[session_id]["inputs"] = final_result
if final_result.get("steps"):
return session_id, new_question, "Proceeding to solve question..."
else:
return (
session_id,
new_question,
"Feedback applied. Refine again or click 'Solve Question'.",
)
else:
# No feedback provided, proceed immediately
question_graph.update_state(
thread,
{"human_feedback": None},
as_node="feedback",
)
final_result = question_graph.invoke(
None, config={"configurable": {"thread_id": session_id}}
)
solution_md = final_result.get("solution", "No solution generated.")
answer = final_result.get("answer", "No answer.")
# Translate solution and answer if lang is not English
if lang != "en":
solution_md = utils.translate_text(
solution_md, PROJECT_ID, target_lang=lang, source_lang="en"
)
answer = utils.translate_text(
answer, PROJECT_ID, target_lang=lang, source_lang="en"
)
return session_id, solution_md, answer
# -----------------------------
# Solve Question – Full Graph Run
# -----------------------------
def solve_question(session_id, lang):
data = session_data.get(session_id)
thread = {"configurable": {"thread_id": session_id}}
if not data:
return "Session expired or invalid.", "", ""
state = data["inputs"]
memory = data["memory"]
question_graph.update_state(
thread,
{"human_feedback": None},
as_node="feedback",
)
final_result = question_graph.invoke(
None, config={"configurable": {"thread_id": session_id}}
)
print("Final Result", final_result)
solution_md = final_result.get("solution", "No solution generated.")
answer = final_result.get("answer", "No answer.")
# Translate solution and answer if lang is not English
if lang != "en":
solution_md = utils.translate_text(
solution_md, PROJECT_ID, target_lang=lang, source_lang="en"
)
answer = utils.translate_text(
answer, PROJECT_ID, target_lang=lang, source_lang="en"
)
return solution_md
# Language toggle updates UI
def update_ui(lang):
return (
LANGUAGES[lang]["title"], # Markdown title
gr.update(visible=(lang == "az")), # Show Azerbaijani UI
gr.update(visible=(lang == "en")), # Show English UI
gr.update(visible=(lang == "ru")), # Show Russian UI
)
def update_subtopics(selected_topic, lang):
subtopics_list = utils.get_subtopics(selected_topic, lang)
return gr.update(
choices=subtopics_list, value=subtopics_list[0] if subtopics_list else ""
)
# -----------------------------
# Gradio UI Layout
# -----------------------------
with gr.Blocks(title="LangGraph Math Solver") as demo:
lang_toggle = gr.Dropdown(
label="🌍 Select Language", choices=["en", "az", "ru"], value="en"
)
title = gr.Markdown(LANGUAGES["en"]["title"])
# English UI Components
with gr.Column(visible=True) as english_ui:
with gr.Row():
topic_input_en = gr.Dropdown(
label=LANGUAGES["en"]["topic_label"],
choices=session_data["en_topics"],
value=None,
)
subtopic_input_en = gr.Dropdown(
label=LANGUAGES["en"]["subtopic_label"], choices=[], value=None
)
difficulty_input_en = gr.Dropdown(
label=LANGUAGES["en"]["difficulty_label"],
choices=["easy", "medium", "hard"],
value="medium",
)
generate_btn_en = gr.Button(LANGUAGES["en"]["generate_btn"])
question_output_en = gr.Markdown(
label=LANGUAGES["en"]["question_output"],
render=True,
latex_delimiters=[
{"left": "$$", "right": "$$", "display": True},
{"left": "$", "right": "$", "display": False},
],
)
feedback_note_en = gr.Textbox(
label=LANGUAGES["en"]["feedback_label"],
placeholder=LANGUAGES["en"]["feedback_placeholder"],
)
with gr.Row():
feedback_btn_en = gr.Button(LANGUAGES["en"]["feedback_btn"])
solve_btn_en = gr.Button(LANGUAGES["en"]["solve_btn"])
solution_output_en = gr.Markdown(
label=LANGUAGES["en"]["solution_output"],
render=True,
latex_delimiters=[
{"left": "$$", "right": "$$", "display": True},
{"left": "$", "right": "$", "display": False},
{"left": "[", "right": "]", "display": False},
],
)
# final_answer_en = gr.Markdown(
# label=LANGUAGES["en"]["final_answer"], render=True
# )
# Azerbaijani UI Components (Initially Hidden)
with gr.Column(visible=False) as azeri_ui:
with gr.Row():
topic_input_az = gr.Dropdown(
label=LANGUAGES["az"]["topic_label"],
choices=session_data["az_topics"],
value=None,
)
subtopic_input_az = gr.Dropdown(
label=LANGUAGES["az"]["subtopic_label"], choices=[], value=None
)
difficulty_input_az = gr.Dropdown(
label=LANGUAGES["az"]["difficulty_label"],
choices=["asan", "orta", "çətin"],
value="orta",
)
generate_btn_az = gr.Button(LANGUAGES["az"]["generate_btn"])
question_output_az = gr.Markdown(
label=LANGUAGES["az"]["question_output"],
render=True,
latex_delimiters=[
{"left": "$$", "right": "$$", "display": True},
{"left": "$", "right": "$", "display": False},
],
)
feedback_note_az = gr.Textbox(
label=LANGUAGES["az"]["feedback_label"],
placeholder=LANGUAGES["az"]["feedback_placeholder"],
)
with gr.Row():
feedback_btn_az = gr.Button(LANGUAGES["az"]["feedback_btn"])
solve_btn_az = gr.Button(LANGUAGES["az"]["solve_btn"])
solution_output_az = gr.Markdown(
label=LANGUAGES["az"]["solution_output"],
render=True,
latex_delimiters=[
{"left": "$$", "right": "$$", "display": True},
{"left": "$", "right": "$", "display": False},
{"left": "[", "right": "]", "display": False},
],
)
# final_answer_az = gr.Markdown(
# label=LANGUAGES["az"]["final_answer"], render=True
# )
# Russian UI Components (Initially Hidden)
with gr.Column(visible=False) as russian_ui:
with gr.Row():
topic_input_ru = gr.Dropdown(
label=LANGUAGES["ru"]["topic_label"],
choices=session_data["ru_topics"],
value=None,
)
subtopic_input_ru = gr.Dropdown(
label=LANGUAGES["ru"]["subtopic_label"], choices=[], value=None
)
difficulty_input_ru = gr.Dropdown(
label=LANGUAGES["ru"]["difficulty_label"],
choices=["легкий", "средний", "сложный"],
value="средний",
)
generate_btn_ru = gr.Button(LANGUAGES["ru"]["generate_btn"])
question_output_ru = gr.Markdown(
label=LANGUAGES["ru"]["question_output"],
render=True,
latex_delimiters=[
{"left": "$$", "right": "$$", "display": True},
{"left": "$", "right": "$", "display": False},
],
)
feedback_note_ru = gr.Textbox(
label=LANGUAGES["ru"]["feedback_label"],
placeholder=LANGUAGES["ru"]["feedback_placeholder"],
)
with gr.Row():
feedback_btn_ru = gr.Button(LANGUAGES["ru"]["feedback_btn"])
solve_btn_ru = gr.Button(LANGUAGES["ru"]["solve_btn"])
solution_output_ru = gr.Markdown(
label=LANGUAGES["ru"]["solution_output"],
render=True,
latex_delimiters=[
{"left": "$$", "right": "$$", "display": True},
{"left": "$", "right": "$", "display": False},
{"left": "[", "right": "]", "display": False},
],
)
# final_answer_ru = gr.Markdown(
# label=LANGUAGES["ru"]["final_answer"], render=True
# )
# Language Toggle
lang_toggle.change(
update_ui,
inputs=[lang_toggle],
outputs=[
title,
azeri_ui,
english_ui,
russian_ui,
], # Using .update() to toggle visibility
)
# Topic Selection Events
topic_input_en.change(
update_subtopics,
inputs=[topic_input_en, lang_toggle],
outputs=[subtopic_input_en],
)
topic_input_az.change(
update_subtopics,
inputs=[topic_input_az, lang_toggle],
outputs=[subtopic_input_az],
)
topic_input_ru.change(
update_subtopics,
inputs=[topic_input_ru, lang_toggle],
outputs=[subtopic_input_ru],
)
# Hidden session ID
session_state = gr.State()
# Events for English UI
generate_btn_en.click(
run_graph,
inputs=[topic_input_en, subtopic_input_en, difficulty_input_en, lang_toggle],
outputs=[session_state, question_output_en, feedback_note_en],
)
feedback_btn_en.click(
handle_feedback,
inputs=[session_state, feedback_note_en, lang_toggle],
outputs=[session_state, question_output_en, feedback_note_en],
)
solve_btn_en.click(
solve_question,
inputs=[session_state, lang_toggle],
outputs=[solution_output_en],
)
# Events for Azerbaijani UI
generate_btn_az.click(
run_graph,
inputs=[topic_input_az, subtopic_input_az, difficulty_input_az, lang_toggle],
outputs=[session_state, question_output_az, feedback_note_az],
)
feedback_btn_az.click(
handle_feedback,
inputs=[session_state, feedback_note_az, lang_toggle],
outputs=[session_state, question_output_az, feedback_note_az],
)
solve_btn_az.click(
solve_question,
inputs=[session_state, lang_toggle],
outputs=[solution_output_az],
)
# Events for Russian UI
generate_btn_ru.click(
run_graph,
inputs=[topic_input_ru, subtopic_input_ru, difficulty_input_ru, lang_toggle],
outputs=[session_state, question_output_ru, feedback_note_ru],
)
feedback_btn_ru.click(
handle_feedback,
inputs=[session_state, feedback_note_ru, lang_toggle],
outputs=[session_state, question_output_ru, feedback_note_ru],
)
solve_btn_ru.click(
solve_question,
inputs=[session_state, lang_toggle],
outputs=[solution_output_ru],
)
# -----------------------------
# Launch App
# -----------------------------
if __name__ == "__main__":
demo.launch()