File size: 12,222 Bytes
134cc0c 19b8d26 134cc0c 017de5c 134cc0c 017de5c cf0a35b 017de5c d9680ae 134cc0c a8453ea 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c d9680ae 017de5c 134cc0c 9a41d1c 134cc0c 460cc3e 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c 017de5c 134cc0c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
# app.py
import os
import json
import streamlit as st
from app_assets import app_logo
import io
from app_utils import parse_data_dictionary, display_notebook, style_css
from workflow_nodes import (
think_sections_node,
enhance_plan_node,
write_code_node,
modify_notebook_node,
execute_notebook_node,
correct_notebook_node,
write_insights_node
)
from workflow_nodes import InteractiveCaseStudyState
st.set_page_config(layout="wide")
# Apply CSS styling
# This will apply the styles defined in style.css to the Streamlit app
style_css("/home/user/app/src/style.css")
st.title("π NBforge")
#st.logo(app_logo, size='large', link='https://www.mygreatlearning.com/')
# βββ Session State Initialization βββββββββββββββββββββββββββββββββββββββββββββ
if "state" not in st.session_state:
st.session_state.state = InteractiveCaseStudyState()
st.session_state.plan_ready = False
st.session_state.plan_approved = None
st.session_state.notebook_ready = False
st.session_state.notebook_approved = None
st.session_state.exec_ready = False
st.session_state.execution_approved = None
s = st.session_state.state
# βββ 1) Collect Inputs ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
st.header("1. π§ Provide Your Inputs")
s["domain"] = st.selectbox("π Select Domain", [
"EDA", "Machine Learning", "Deep Learning", "Natural Language Processing",
"Computer Vision", "Generative AI Prompt Engineering", "Generative AI RAG"
])
s["topics_and_subtopics"] = st.text_area("π Topics & Subtopics", height=80)
s["problem_statement"] = st.text_area("π§© Problem Statement", height=80)
s["dataset_type"] = st.selectbox("π Dataset Type", ["csv", "pdf", "images", "json"])
uploaded = st.file_uploader("β¬οΈ Upload Dataset", accept_multiple_files=False)
if uploaded:
os.makedirs("data", exist_ok=True)
path = f"data/{uploaded.name}"
with open(path, "wb") as f:
f.write(uploaded.getbuffer())
s["dataset_file_path"] = path
st.success(f"Dataset saved to `{path}`")
s["data_dictionary"] = {}
dd = st.text_area("π Data Dictionary")
s["data_dictionary"] = parse_data_dictionary(dd)
s["additional_instructions"] = st.text_area(
"π Additional Instructions (optional)", height=68
)
# Kick off plan generation
if not st.session_state.plan_ready:
if st.button("π Generate Plan") and uploaded:
with st.spinner("Designing notebook planβ¦"):
s = think_sections_node(s)
st.session_state.plan_ready = True
st.session_state.plan_approved = None
st.session_state.notebook_ready = False
st.session_state.exec_ready = False
# βββ 2) Review & Enhance Plan ββββββββββββββββββββββββββββββββββββββββββββββββ
if st.session_state.plan_ready:
st.subheader("2. π Review Notebook Plan")
with st.expander("π View Generated Plan"):
st.json(s["plan"])
# ask approval once
if st.session_state.plan_approved is None:
st.session_state.plan_approved = st.radio("Approve this plan?", index=None, options=["YES", "NO"])
st.write(f"Plan approved: {st.session_state.plan_approved}")
# on approval, let user move on
if st.session_state.plan_approved == "YES":
if st.button("β‘οΈ Next: Write Code"):
with st.spinner("Writing notebook skeletonβ¦"):
s = write_code_node(s)
st.session_state.notebook_ready = True
st.session_state.notebook_approved = None
# on rejection, collect feedback & loop back
elif st.session_state.plan_approved == "NO":
st.text_area("What should be changed in the plan?", key="plan_fb")
st.write(f"Plan feedback: {st.session_state.plan_fb}")
if st.button("π Apply Plan Changes"):
s["plan_feedback"] = st.session_state.plan_fb
with st.spinner("Modifying notebook planβ¦"):
s = enhance_plan_node(s)
# reset approval so we review again
st.session_state.plan_approved = None
st.rerun()
# βββ 3) Review & Modify Notebook βββββββββββββββββββββββββββββββββββββββββββββ
if st.session_state.notebook_ready:
st.subheader("3. π» Review Notebook Skeleton")
with st.expander("π View Notebook Skeleton"):
display_notebook(io.StringIO(json.dumps(s["raw_notebook"], indent=2)))
st.info("----------------------------------------------------------------")
st.write("**NOTE**: If itβs hard to read here, download and open in Colab:")
st.download_button(
"Download raw_notebook.ipynb",
data=json.dumps(s["raw_notebook"], indent=2),
file_name="raw_notebook.ipynb",
mime="application/json",
)
if st.session_state.notebook_approved is None:
st.session_state.notebook_approved = st.radio("Looks good?", index=None, options=["YES", "NO"])
st.write(f"notebook approved: {st.session_state.notebook_approved}")
if st.session_state.notebook_approved == "YES":
if st.button("β‘οΈ Next: Execute Notebook"):
with st.spinner("Executing notebookβ¦"):
s = execute_notebook_node(s)
st.session_state.exec_ready = True
st.session_state.execution_approved = None
elif st.session_state.notebook_approved == "NO":
st.write("π Please provide your feedback on the notebook skeleton:")
st.text_area("What needs changing in the notebook skeleton?", key="nb_fb")
st.write(f"Notebook feedback: {st.session_state.nb_fb}")
if st.button("π Apply Notebook Changes"):
s["notebook_feedback"] = st.session_state.nb_fb
with st.spinner("Modifying notebook skeletonβ¦"):
s = modify_notebook_node(s)
st.session_state.notebook_approved = None
st.rerun()
# βββ 4) Review & Correct Execution βββββββββββββββββββββββββββββββββββββββββββ
if st.session_state.exec_ready:
st.subheader("4. π Execution Results")
with st.expander("π View Executed Notebook"):
display_notebook(io.StringIO(s["executed_notebook"]))
st.info("----------------------------------------------------------------")
st.write("**NOTE**: If itβs hard to read here, download and open in Colab:")
st.download_button(
"Download executed_notebook.ipynb",
data=s["executed_notebook"],
file_name="executed_notebook.ipynb",
mime="application/json",
)
if s.get("execution_error"):
# Always reset approval until they choose Download As-Is
st.session_state.execution_approved = False
st.error(f"β Execution failed:\n{s['execution_error']}")
# Three-way branching
st.session_state.exec_action = st.radio(
"What would you like to do with this broken notebook?", index=None,
options=["Download As-Is", "Provide Feedback", "Auto-Correct & Retry"]
)
st.write(f"Execution action: {st.session_state.exec_action}")
if st.session_state.exec_action == "Download As-Is":
# mark approved so we fall through to downloads
st.session_state.execution_approved = True
elif st.session_state.exec_action == "Provide Feedback":
fb = st.text_area("π Describe how I should fix the error:", height=80, key="exec_feedback")
st.write(f"Execution feedback: {st.session_state.exec_feedback}")
if st.button("π Apply Feedback"):
s["execution_feedback"] = fb
with st.spinner("Applying your feedback and re-executingβ¦"):
s = correct_notebook_node(s)
s = execute_notebook_node(s)
# loop back into this block
st.session_state.exec_ready = True
st.session_state.execution_approved = None
st.rerun()
elif st.session_state.exec_action == "Auto-Correct & Retry":
if st.button("π§ Auto-Correct & Retry"):
s["execution_feedback"] = ""
with st.spinner("Auto-correcting and re-executingβ¦"):
s = correct_notebook_node(s)
s = execute_notebook_node(s)
# loop back into this block
st.session_state.exec_ready = True
st.session_state.execution_approved = None
st.rerun()
# If execution succeeded OR user chose βDownload As-Isβ, show downloads
if not s.get("execution_error") or st.session_state.execution_approved:
st.success("β
Ready to download your artifacts!")
st.download_button("π₯ Download plan.json",
data=json.dumps(s["plan"], indent=2),
file_name="plan.json",
mime="application/json"
)
st.download_button("π₯ Download raw_notebook.ipynb",
data=json.dumps(s["raw_notebook"], indent=2),
file_name="raw_notebook.ipynb",
mime="application/json"
)
st.download_button("π₯ Download executed_notebook.ipynb",
data=s["executed_notebook"],
file_name="executed_notebook.ipynb",
mime="application/json"
)
# βββ 5) Generate Insights (Optional) ββββββββββββββββββββββββββββββββββββββββββ
# Only show this once the user has downloaded (or chosen) the executed notebook
if st.session_state.exec_ready and (
not s.get("execution_error") or st.session_state.execution_approved
):
st.markdown("---")
st.subheader("5. βοΈ Generate Insights (Optional)")
# If there was an error and they chose Download As-Is, still allow insights
if s.get("execution_error"):
st.info("Your notebook contains errors, but you can still generate insights on available outputs.")
else:
st.success("Notebook executed end-to-end without errors!")
st.info("You can now generate insights and conclusions based on the executed notebook.")
# Ask permission
st.session_state.insights_opt = st.radio(
"Shall I proceed to write the insights and conclusion for this notebook?", index=None,
options=["YES", "NO"]
)
if st.session_state.insights_opt == "YES":
if st.button("π Generate Insights Now"):
with st.spinner("Writing observations & final recommendationsβ¦"):
s = write_insights_node(s)
st.success("π Insights generated!")
# Render the final notebook with insights inline
st.markdown("#### Final Notebook with Insights")
with st.expander("π View Final Notebook with Insights"):
display_notebook(io.StringIO(json.dumps(s["final_notebook"], indent=2)))
# Offer download
st.download_button(
"π₯ Download Final Notebook (.ipynb)",
data=json.dumps(s["final_notebook"], indent=2),
file_name="final_notebook.ipynb",
mime="application/json",
)
st.balloons()
st.write("Thanks for using NBforge! π")
elif st.session_state.insights_opt == "NO":
st.snow()
st.write("π No problem! Feel free to revisit this notebook later or download any artifact above.") |