awacke1 commited on
Commit
44d79ad
·
verified ·
1 Parent(s): 13e539e

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +307 -0
app.py ADDED
@@ -0,0 +1,307 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import os
3
+ import re
4
+ import streamlit as st
5
+ import streamlit.components.v1 as components
6
+ from urllib.parse import quote
7
+ import pandas as pd
8
+ import torch
9
+ import torch.nn as nn
10
+ import torch.optim as optim
11
+ from torch.utils.data import DataLoader, TensorDataset
12
+ import base64
13
+ import glob
14
+ import time
15
+
16
+ # Page Configuration
17
+ st.set_page_config(
18
+ page_title="AI Knowledge Tree Builder 📈🌿",
19
+ page_icon="🌳✨",
20
+ layout="wide",
21
+ initial_sidebar_state="auto",
22
+ )
23
+
24
+ # Predefined Knowledge Trees
25
+ trees = {
26
+ "ML Engineering": """
27
+ 0. ML Engineering 🌐
28
+ 1. Data Preparation
29
+ - Load Data 📊
30
+ - Preprocess Data 🛠️
31
+ 2. Model Building
32
+ - Train Model 🤖
33
+ - Evaluate Model 📈
34
+ 3. Deployment
35
+ - Deploy Model 🚀
36
+ """,
37
+ "Health": """
38
+ 0. Health and Wellness 🌿
39
+ 1. Physical Health
40
+ - Exercise 🏋️
41
+ - Nutrition 🍎
42
+ 2. Mental Health
43
+ - Meditation 🧘
44
+ - Therapy 🛋️
45
+ """,
46
+ }
47
+
48
+ # Project Seeds
49
+ project_seeds = {
50
+ "Code Project": """
51
+ 0. Code Project 📂
52
+ 1. app.py 🐍
53
+ 2. requirements.txt 📦
54
+ 3. README.md 📄
55
+ """,
56
+ "Papers Project": """
57
+ 0. Papers Project 📚
58
+ 1. markdown 📝
59
+ 2. mermaid 🖼️
60
+ 3. huggingface.co 🤗
61
+ """,
62
+ "AI Project": """
63
+ 0. AI Project 🤖
64
+ 1. Streamlit Torch Transformers
65
+ - Streamlit 🌐
66
+ - Torch 🔥
67
+ - Transformers 🤖
68
+ 2. DistillKit MergeKit Spectrum
69
+ - DistillKit 🧪
70
+ - MergeKit 🔄
71
+ - Spectrum 📊
72
+ 3. Transformers Diffusers Datasets
73
+ - Transformers 🤖
74
+ - Diffusers 🎨
75
+ - Datasets 📊
76
+ """,
77
+ }
78
+
79
+ # Utility Functions
80
+ def sanitize_label(label):
81
+ """Remove invalid characters for Mermaid labels."""
82
+ return re.sub(r'[^\w\s-]', '', label).replace(' ', '_')
83
+
84
+ def sanitize_filename(label):
85
+ """Make a valid filename from a label."""
86
+ return re.sub(r'[^\w\s-]', '', label).replace(' ', '_')
87
+
88
+ def parse_outline_to_mermaid(outline_text, search_agent):
89
+ """Convert tree outline to Mermaid syntax with clickable nodes."""
90
+ lines = outline_text.strip().split('\n')
91
+ nodes, edges, clicks, stack = [], [], [], []
92
+ for line in lines:
93
+ indent = len(line) - len(line.lstrip())
94
+ level = indent // 4
95
+ label = re.sub(r'^[#*\->\d\.\s]+', '', line.strip())
96
+ if label:
97
+ node_id = f"N{len(nodes)}"
98
+ sanitized_label = sanitize_label(label)
99
+ nodes.append(f'{node_id}["{label}"]')
100
+ search_url = search_urls[search_agent](label)
101
+ clicks.append(f'click {node_id} "{search_url}" _blank')
102
+ if stack:
103
+ parent_level = stack[-1][0]
104
+ if level > parent_level:
105
+ edges.append(f"{stack[-1][1]} --> {node_id}")
106
+ stack.append((level, node_id))
107
+ else:
108
+ while stack and stack[-1][0] >= level:
109
+ stack.pop()
110
+ if stack:
111
+ edges.append(f"{stack[-1][1]} --> {node_id}")
112
+ stack.append((level, node_id))
113
+ else:
114
+ stack.append((level, node_id))
115
+ return "%%{init: {'themeVariables': {'fontSize': '18px'}}}%%\nflowchart LR\n" + "\n".join(nodes + edges + clicks)
116
+
117
+ def generate_mermaid_html(mermaid_code):
118
+ """Generate HTML to display Mermaid diagram."""
119
+ return f"""
120
+ <html><head><script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
121
+ <style>.centered-mermaid{{display:flex;justify-content:center;margin:20px auto;}}</style></head>
122
+ <body><div class="mermaid centered-mermaid">{mermaid_code}</div>
123
+ <script>mermaid.initialize({{startOnLoad:true}});</script></body></html>
124
+ """
125
+
126
+ def grow_tree(base_tree, new_node_name, parent_node):
127
+ """Add a new node to the tree under a specified parent."""
128
+ lines = base_tree.strip().split('\n')
129
+ new_lines = []
130
+ added = False
131
+ for line in lines:
132
+ new_lines.append(line)
133
+ if parent_node in line and not added:
134
+ indent = len(line) - len(line.lstrip())
135
+ new_lines.append(f"{' ' * (indent + 4)}- {new_node_name} 🌱")
136
+ added = True
137
+ return "\n".join(new_lines)
138
+
139
+ def get_download_link(file_path, mime_type="text/plain"):
140
+ """Generate a download link for a file."""
141
+ with open(file_path, 'rb') as f:
142
+ data = f.read()
143
+ b64 = base64.b64encode(data).decode()
144
+ return f'<a href="data:{mime_type};base64,{b64}" download="{file_path}">Download {file_path}</a>'
145
+
146
+ def save_tree_to_file(tree_text, parent_node, new_node):
147
+ """Save tree to a markdown file with name based on nodes."""
148
+ root_node = tree_text.strip().split('\n')[0].split('.')[1].strip() if tree_text.strip() else "Knowledge_Tree"
149
+ filename = f"{sanitize_filename(root_node)}_{sanitize_filename(parent_node)}_{sanitize_filename(new_node)}_{int(time.time())}.md"
150
+
151
+ mermaid_code = parse_outline_to_mermaid(tree_text, "🔮Google") # Default search engine for saved trees
152
+ export_md = f"# Knowledge Tree: {root_node}\n\n## Outline\n{tree_text}\n\n## Mermaid Diagram\n```mermaid\n{mermaid_code}\n```"
153
+
154
+ with open(filename, "w") as f:
155
+ f.write(export_md)
156
+ return filename
157
+
158
+ def load_trees_from_files():
159
+ """Load all saved tree markdown files."""
160
+ tree_files = glob.glob("*.md")
161
+ trees_dict = {}
162
+
163
+ for file in tree_files:
164
+ if file != "README.md" and file != "knowledge_tree.md": # Skip project README and temp export
165
+ try:
166
+ with open(file, 'r') as f:
167
+ content = f.read()
168
+ # Extract the tree name from the first line
169
+ match = re.search(r'# Knowledge Tree: (.*)', content)
170
+ if match:
171
+ tree_name = match.group(1)
172
+ else:
173
+ tree_name = os.path.splitext(file)[0]
174
+
175
+ # Extract the outline section
176
+ outline_match = re.search(r'## Outline\n(.*?)(?=\n## |$)', content, re.DOTALL)
177
+ if outline_match:
178
+ tree_outline = outline_match.group(1).strip()
179
+ trees_dict[f"{tree_name} ({file})"] = tree_outline
180
+ except Exception as e:
181
+ print(f"Error loading {file}: {e}")
182
+
183
+ return trees_dict
184
+
185
+ # Search Agents (Highest resolution social network default: X)
186
+ search_urls = {
187
+ "📚📖ArXiv": lambda k: f"/?q={quote(k)}",
188
+ "🔮Google": lambda k: f"https://www.google.com/search?q={quote(k)}",
189
+ "📺Youtube": lambda k: f"https://www.youtube.com/results?search_query={quote(k)}",
190
+ "🔭Bing": lambda k: f"https://www.bing.com/search?q={quote(k)}",
191
+ "💡Truth": lambda k: f"https://truthsocial.com/search?q={quote(k)}",
192
+ "📱X": lambda k: f"https://twitter.com/search?q={quote(k)}",
193
+ }
194
+
195
+ # Main App
196
+ st.title("🌳 AI Knowledge Tree Builder 🌱")
197
+
198
+ # Sidebar with saved trees
199
+ st.sidebar.title("Saved Trees")
200
+ saved_trees = load_trees_from_files()
201
+ selected_saved_tree = st.sidebar.selectbox("Select a saved tree", ["None"] + list(saved_trees.keys()))
202
+
203
+ # Select Project Type
204
+ project_type = st.selectbox("Select Project Type", ["Code Project", "Papers Project", "AI Project"])
205
+
206
+ # Initialize or load tree
207
+ if 'current_tree' not in st.session_state:
208
+ if selected_saved_tree != "None" and selected_saved_tree in saved_trees:
209
+ st.session_state['current_tree'] = saved_trees[selected_saved_tree]
210
+ else:
211
+ st.session_state['current_tree'] = trees.get("ML Engineering", project_seeds[project_type])
212
+ elif selected_saved_tree != "None" and selected_saved_tree in saved_trees:
213
+ st.session_state['current_tree'] = saved_trees[selected_saved_tree]
214
+
215
+ # Select Search Agent for Node Links
216
+ search_agent = st.selectbox("Select Search Agent for Node Links", list(search_urls.keys()), index=5) # Default to X
217
+
218
+ # Tree Growth
219
+ new_node = st.text_input("Add New Node")
220
+ parent_node = st.text_input("Parent Node")
221
+ if st.button("Grow Tree 🌱") and new_node and parent_node:
222
+ st.session_state['current_tree'] = grow_tree(st.session_state['current_tree'], new_node, parent_node)
223
+
224
+ # Save to a new file with the node names
225
+ saved_file = save_tree_to_file(st.session_state['current_tree'], parent_node, new_node)
226
+ st.success(f"Added '{new_node}' under '{parent_node}' and saved to {saved_file}!")
227
+
228
+ # Also update the temporary current_tree.md for compatibility
229
+ with open("current_tree.md", "w") as f:
230
+ f.write(st.session_state['current_tree'])
231
+
232
+ # Display Mermaid Diagram
233
+ st.markdown("### Knowledge Tree Visualization")
234
+ mermaid_code = parse_outline_to_mermaid(st.session_state['current_tree'], search_agent)
235
+ components.html(generate_mermaid_html(mermaid_code), height=600)
236
+
237
+ # Export Tree
238
+ if st.button("Export Tree as Markdown"):
239
+ export_md = f"# Knowledge Tree\n\n## Outline\n{st.session_state['current_tree']}\n\n## Mermaid Diagram\n```mermaid\n{mermaid_code}\n```"
240
+ with open("knowledge_tree.md", "w") as f:
241
+ f.write(export_md)
242
+ st.markdown(get_download_link("knowledge_tree.md", "text/markdown"), unsafe_allow_html=True)
243
+
244
+ # AI Project: Minimal ML Model Building
245
+ if project_type == "AI Project":
246
+ st.subheader("Build Minimal ML Model from CSV")
247
+ uploaded_file = st.file_uploader("Upload CSV", type="csv")
248
+ if uploaded_file:
249
+ df = pd.read_csv(uploaded_file)
250
+ st.write("Columns:", df.columns.tolist())
251
+ feature_cols = st.multiselect("Select feature columns", df.columns)
252
+ target_col = st.selectbox("Select target column", df.columns)
253
+ if st.button("Train Model"):
254
+ X = df[feature_cols].values
255
+ y = df[target_col].values
256
+ X_tensor = torch.tensor(X, dtype=torch.float32)
257
+ y_tensor = torch.tensor(y, dtype=torch.float32).view(-1, 1)
258
+ dataset = TensorDataset(X_tensor, y_tensor)
259
+ loader = DataLoader(dataset, batch_size=32, shuffle=True)
260
+ model = nn.Linear(X.shape[1], 1)
261
+ criterion = nn.MSELoss()
262
+ optimizer = optim.Adam(model.parameters(), lr=0.01)
263
+ for epoch in range(10):
264
+ for batch_X, batch_y in loader:
265
+ optimizer.zero_grad()
266
+ outputs = model(batch_X)
267
+ loss = criterion(outputs, batch_y)
268
+ loss.backward()
269
+ optimizer.step()
270
+ torch.save(model.state_dict(), "model.pth")
271
+ app_code = f"""
272
+ import streamlit as st
273
+ import torch
274
+ import torch.nn as nn
275
+
276
+ model = nn.Linear({len(feature_cols)}, 1)
277
+ model.load_state_dict(torch.load("model.pth"))
278
+ model.eval()
279
+
280
+ st.title("ML Model Demo")
281
+ inputs = []
282
+ for col in {feature_cols}:
283
+ inputs.append(st.number_input(col))
284
+ if st.button("Predict"):
285
+ input_tensor = torch.tensor([inputs], dtype=torch.float32)
286
+ prediction = model(input_tensor).item()
287
+ st.write(f"Predicted {target_col}: {{prediction}}")
288
+ """
289
+ with open("app.py", "w") as f:
290
+ f.write(app_code)
291
+ reqs = "streamlit\ntorch\npandas\n"
292
+ with open("requirements.txt", "w") as f:
293
+ f.write(reqs)
294
+ readme = """
295
+ # ML Model Demo
296
+
297
+ ## How to run
298
+ 1. Install requirements: `pip install -r requirements.txt`
299
+ 2. Run the app: `streamlit run app.py`
300
+ 3. Input feature values and click "Predict".
301
+ """
302
+ with open("README.md", "w") as f:
303
+ f.write(readme)
304
+ st.markdown(get_download_link("model.pth", "application/octet-stream"), unsafe_allow_html=True)
305
+ st.markdown(get_download_link("app.py", "text/plain"), unsafe_allow_html=True)
306
+ st.markdown(get_download_link("requirements.txt", "text/plain"), unsafe_allow_html=True)
307
+ st.markdown(get_download_link("README.md", "text/markdown"), unsafe_allow_html=True)