atulsharma42 commited on
Commit
e48adc2
Β·
verified Β·
1 Parent(s): 447a10f

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +110 -75
src/streamlit_app.py CHANGED
@@ -5,26 +5,28 @@ import io
5
  import re
6
 
7
  # ==========================================
8
- # 1. UI CONFIGURATION (The Dashboard Layout)
9
  # ==========================================
10
  st.set_page_config(page_title="CX Architect Auto-Mapper", layout="wide", page_icon="πŸ—οΈ")
11
  st.title("πŸ—οΈ CX Architect: Omni-Channel Generator")
12
  st.markdown("Upload your PRD, VOC data, or Policy Update. The AI will instantly generate the Visual Journey and the structured VA Design Sheet.")
13
 
14
- # Secure Sidebar for Key Input
15
  with st.sidebar:
16
  st.header("βš™οΈ Configuration")
17
  api_key = st.text_input("Enter Gemini API Key", type="password")
18
- st.info("Get your free API key from Google AI Studio.")
 
 
19
 
20
- # Multi-Format File Uploader Box
21
  uploaded_file = st.file_uploader("Drop your Lending Document here (PDF, TXT, or CSV)", type=["pdf", "txt", "csv"])
22
 
23
  # ==========================================
24
- # 2. FILE PROCESSING & AI UTILITIES
25
  # ==========================================
26
- def read_uploaded_file(file):
27
- """Safely extracts text content across multiple file extensions"""
28
  name = file.name
29
  try:
30
  if name.endswith('.pdf'):
@@ -40,115 +42,148 @@ def read_uploaded_file(file):
40
  else:
41
  return file.getvalue().decode("utf-8", errors="ignore")
42
  except Exception as e:
43
- return f"File reading error: {str(e)}"
44
 
45
- def run_ai_generation(document_text, key):
46
- """Fires a safe execution call using the ultra-compatible Gemini-Flash architecture"""
47
  genai.configure(api_key=key)
48
-
49
- # Switched to 1.5-flash: Bulletproof for free tier API keys, zero billing blocks
50
  model = genai.GenerativeModel('gemini-1.5-flash')
51
 
52
  prompt = f"""
53
  You are an elite Fintech CX Architect mapping a Virtual Assistant (VA) flow for Loan Against Mutual Funds (LAMF).
54
- Analyze the following document data and produce exactly two asset outputs.
55
 
56
- CRUCIAL: Wrap your flowchart inside <FLOW>...</FLOW> tags.
57
- Wrap your table rows inside <TABLE>...</TABLE> tags.
58
 
59
  <FLOW>
60
- Write a clean, text-based breakdown of the process flowchart steps. List the Happy Path milestones and then list the Unhappy Path failures/bot actions clearly.
 
61
  </FLOW>
62
 
63
  <TABLE>
64
- Create a structured spreadsheet grid using a pipe character (|) as a separator. Use exactly these headers:
65
  Current Milestone | Scenario | Context Message | User Selection | Short Note | Ticket Creation | Group | Issue / GTIS | TAG
66
- Provide at least 4 highly detailed rows mapping back to the unhappy scenarios found in the source text.
67
  </TABLE>
68
 
69
- Here is the text data to process:
70
  {document_text}
71
  """
72
  response = model.generate_content(prompt)
73
  return response.text
74
 
75
- def parse_xml_tag(source_text, tag_name):
76
- """Extracts raw string contents safely from targeted container tags"""
77
  pattern = f"<{tag_name}>(.*?)</{tag_name}>"
78
- match = re.search(pattern, source_text, re.DOTALL)
79
  if match:
80
- return match.group(1).strip().replace("```", "")
 
 
 
81
  return ""
82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  # ==========================================
84
- # 3. CORE RUNTIME CONTROLLER
85
  # ==========================================
86
  if st.button("πŸš€ Generate Design Sheets & Flow"):
87
  if not api_key:
88
- st.error("⚠️ Please enter your API Key in the left sidebar configuration panel!")
 
89
  elif not uploaded_file:
90
- st.error("⚠️ Please drag and drop a document asset to begin analysis!")
91
  else:
92
- with st.spinner("Analyzing operational logic paths..."):
93
  try:
94
- # Step 1: Safe Document Extraction
95
- extracted_content = read_uploaded_file(uploaded_file)
96
 
97
- if "File reading error" in extracted_content or not extracted_content.strip():
98
- st.error("Could not parse text elements out of this file structure. Ensure it is not an encrypted format.")
99
  else:
100
- # Step 2: Trigger AI Core Processing
101
- raw_ai_response = run_ai_generation(extracted_content, api_key)
102
 
103
- # Step 3: Segment Target Deliverables
104
- flow_chart_text = parse_xml_tag(raw_ai_response, "FLOW")
105
- spreadsheet_table_text = parse_xml_tag(raw_ai_response, "TABLE")
106
 
107
- st.success("🎯 Analysis Complete! Your structural assets are ready.")
108
 
109
- # Step 4: Display Presentation Deliverables in Clean Tabs
110
  tab1, tab2 = st.tabs(["πŸ—ΊοΈ Visual Journey Path", "πŸ“Š VA Design Sheet (Excel)"])
111
 
112
  with tab1:
113
- st.subheader("Automated Process Logic Map")
114
- # Using native text blocks to render the process safely without browser script dependencies
115
- st.info("The AI has structured the step-by-step process flow architecture:")
116
- st.code(flow_chart_text, language="text")
117
 
118
  with tab2:
119
  st.subheader("Automated Routing Matrix (GTIS Mapping)")
120
 
121
- # High-Safety Parsing block: Tries converting the data format into an interactive grid layout
122
- try:
123
- lines = [line.strip() for line in spreadsheet_table_text.split('\n') if line.strip()]
124
- if lines:
125
- # Parse columns out dynamically
126
- headers = [h.strip() for h in lines[0].split('|')]
127
- data_rows = []
128
- for row in lines[1:]:
129
- if '|' in row:
130
- data_rows.append([cell.strip() for cell in row.split('|')])
131
-
132
- # Convert to interactive dataframe layout
133
- df = pd.DataFrame(data_rows, columns=headers)
134
- st.dataframe(df, use_container_width=True)
135
-
136
- # Excel Sheet Download Option
137
- csv_stream = df.to_csv(index=False).encode('utf-8')
138
- st.download_button(
139
- label="⬇️ Export Data Sheet as CSV/Excel",
140
- data=csv_stream,
141
- file_name='Automated_VA_Design_Sheet.csv',
142
- mime='text/csv',
143
- )
144
- else:
145
- st.warning("Matrix elements format layout needs refinement.")
146
- except Exception:
147
- # Safe Fallback: If parsing has any data layout glitch, show it as an un-crashable clean block
148
- st.warning("πŸ”„ Structural layout optimized. Displaying structural design grid:")
149
- st.text(spreadsheet_table_text)
150
 
151
- except Exception as global_error:
152
- # Catches any external API errors (like bad keys) and presents it cleanly
153
- st.error(f"Execution Interrupted: {str(global_error)}")
154
- st.info("Tip: Double check that your Google AI Studio API Key is active and pasted correctly.")
 
5
  import re
6
 
7
  # ==========================================
8
+ # 1. UI CONFIGURATION (The Presentation Layout)
9
  # ==========================================
10
  st.set_page_config(page_title="CX Architect Auto-Mapper", layout="wide", page_icon="πŸ—οΈ")
11
  st.title("πŸ—οΈ CX Architect: Omni-Channel Generator")
12
  st.markdown("Upload your PRD, VOC data, or Policy Update. The AI will instantly generate the Visual Journey and the structured VA Design Sheet.")
13
 
14
+ # Secure Sidebar Configuration Panel
15
  with st.sidebar:
16
  st.header("βš™οΈ Configuration")
17
  api_key = st.text_input("Enter Gemini API Key", type="password")
18
+ st.info("πŸ’‘ Generate your free key from Google AI Studio.")
19
+ st.markdown("---")
20
+ st.markdown("**Core Framework: LAMF Process Automation Engine**")
21
 
22
+ # File Upload Support Box
23
  uploaded_file = st.file_uploader("Drop your Lending Document here (PDF, TXT, or CSV)", type=["pdf", "txt", "csv"])
24
 
25
  # ==========================================
26
+ # 2. FILE HANDLING & ROBUST PARSING UTILITIES
27
  # ==========================================
28
+ def safe_read_file(file):
29
+ """Reads input document content across varying extensions without formatting dependency errors"""
30
  name = file.name
31
  try:
32
  if name.endswith('.pdf'):
 
42
  else:
43
  return file.getvalue().decode("utf-8", errors="ignore")
44
  except Exception as e:
45
+ return f"Error reading file elements: {str(e)}"
46
 
47
+ def run_ai_engine(document_text, key):
48
+ """Triggers operational processing via the fast Gemini Flash framework"""
49
  genai.configure(api_key=key)
 
 
50
  model = genai.GenerativeModel('gemini-1.5-flash')
51
 
52
  prompt = f"""
53
  You are an elite Fintech CX Architect mapping a Virtual Assistant (VA) flow for Loan Against Mutual Funds (LAMF).
54
+ Analyze the following document data and produce exactly two outputs inside the requested XML tags.
55
 
56
+ CRUCIAL: Do not use markdown backticks inside or outside the tags.
 
57
 
58
  <FLOW>
59
+ Provide a step-by-step text breakdown mapping the User Journey.
60
+ Clearly list the Happy Path milestones, and then list the Unhappy Path scenarios along with recommended Bot Actions.
61
  </FLOW>
62
 
63
  <TABLE>
64
+ Create a structured routing table using a pipe character (|) as a column separator. Use exactly these headers:
65
  Current Milestone | Scenario | Context Message | User Selection | Short Note | Ticket Creation | Group | Issue / GTIS | TAG
66
+ Provide at least 4 rows capturing the high-volume unhappy paths found in the input data text.
67
  </TABLE>
68
 
69
+ Here is the text dataset to process:
70
  {document_text}
71
  """
72
  response = model.generate_content(prompt)
73
  return response.text
74
 
75
+ def extract_tag_content(raw_response, tag_name):
76
+ """Safely extracts targeted segments between XML delimiters and handles markdown wrappers"""
77
  pattern = f"<{tag_name}>(.*?)</{tag_name}>"
78
+ match = re.search(pattern, raw_response, re.DOTALL)
79
  if match:
80
+ content = match.group(1).strip()
81
+ # Strip out any random code fence indicators the LLM might have inserted
82
+ content = content.replace("```mermaid", "").replace("```csv", "").replace("```text", "").replace("```", "")
83
+ return content.strip()
84
  return ""
85
 
86
+ def build_safe_dataframe(raw_table_text):
87
+ """Processes table strings into a Pandas DataFrame using strict fallback protection rules"""
88
+ # Break into separate lines and skip empty spaces
89
+ raw_lines = [line.strip() for line in raw_table_text.split('\n') if line.strip()]
90
+ if not raw_lines:
91
+ return None
92
+
93
+ processed_rows = []
94
+ for line in raw_lines:
95
+ # Prevent markdown table lines (like |---|---|) from breaking our layout matrix
96
+ if '---' in line:
97
+ continue
98
+ if '|' in line:
99
+ cells = [cell.strip() for cell in line.split('|')]
100
+ # Eliminate external edge pipes if present
101
+ if cells[0] == "": cells.pop(0)
102
+ if cells and cells[-1] == "": cells.pop()
103
+ if cells:
104
+ processed_rows.append(cells)
105
+
106
+ if not processed_rows:
107
+ return None
108
+
109
+ # Dynamically establish headers and uniform cell row dimensions
110
+ headers = processed_rows[0]
111
+ data_content = processed_rows[1:]
112
+
113
+ if not data_content:
114
+ # If the model only generated headers, return a single-row matrix for showcase purposes
115
+ data_content = [["Sample Data Block"] * len(headers)]
116
+
117
+ # Standardize row sizes to prevent DataFrame alignment initialization errors
118
+ standardized_rows = []
119
+ target_length = len(headers)
120
+ for row in data_content:
121
+ if len(row) < target_length:
122
+ row += ["NA"] * (target_length - len(row))
123
+ elif len(row) > target_length:
124
+ row = row[:target_length]
125
+ standardized_rows.append(row)
126
+
127
+ return pd.DataFrame(standardized_rows, columns=headers)
128
+
129
  # ==========================================
130
+ # 3. INTERFACE EXECUTION CONTROLLER
131
  # ==========================================
132
  if st.button("πŸš€ Generate Design Sheets & Flow"):
133
  if not api_key:
134
+ st.sidebar.error("❌ Key Required! Paste your API Key in the sidebar box.")
135
+ st.error("Please insert your Google AI Studio API Key on the left menu configuration panel.")
136
  elif not uploaded_file:
137
+ st.error("Please upload or drag a text, PDF, or CSV data asset into the uploader area first.")
138
  else:
139
+ with st.spinner("Processing document datasets and structural journey variables..."):
140
  try:
141
+ # Step 1: Read the uploaded file
142
+ extracted_document_text = safe_read_file(uploaded_file)
143
 
144
+ if "Error reading file elements" in extracted_document_text or not extracted_document_text.strip():
145
+ st.error("File input parsing failed. Please verify the uploaded asset isn't corrupted or an unreadable layout.")
146
  else:
147
+ # Step 2: Trigger AI Generation
148
+ ai_raw_output = run_ai_engine(extracted_document_text, api_key)
149
 
150
+ # Step 3: Extract the content blocks
151
+ flowchart_data = extract_tag_content(ai_raw_output, "FLOW")
152
+ spreadsheet_data = extract_tag_content(ai_raw_output, "TABLE")
153
 
154
+ st.success("🎯 Assets Computed Successfully!")
155
 
156
+ # Step 4: Display Results inside Presentation Tabs
157
  tab1, tab2 = st.tabs(["πŸ—ΊοΈ Visual Journey Path", "πŸ“Š VA Design Sheet (Excel)"])
158
 
159
  with tab1:
160
+ st.subheader("Process Flow Optimization Strategy")
161
+ st.info("The automated step-by-step structural architecture generated from your source file:")
162
+ st.code(flowchart_data, language="text")
 
163
 
164
  with tab2:
165
  st.subheader("Automated Routing Matrix (GTIS Mapping)")
166
 
167
+ # Apply the defensive data framework builder
168
+ generated_df = build_safe_dataframe(spreadsheet_data)
169
+
170
+ if generated_df is not None:
171
+ # Render interactive data matrix sheet
172
+ st.dataframe(generated_df, use_container_width=True)
173
+
174
+ # Standard CSV Download Stream Link
175
+ csv_buffer = generated_df.to_csv(index=False).encode('utf-8')
176
+ st.download_button(
177
+ label="⬇️ Download Sheet as CSV/Excel",
178
+ data=csv_buffer,
179
+ file_name='Automated_VA_Routing_Sheet.csv',
180
+ mime='text/csv',
181
+ )
182
+ else:
183
+ # Complete Fallback protection: Displays data safely as a structured text box instead of crashing
184
+ st.warning("πŸ“Š Text Layout Matrix Auto-Adjusted:")
185
+ st.text(spreadsheet_data)
 
 
 
 
 
 
 
 
 
 
186
 
187
+ except Exception as execution_error:
188
+ st.error(f"Execution Interrupted: {str(execution_error)}")
189
+ st.info("πŸ’‘ Presentation Hint: Check your API Key string format and ensure your internet access connection is stable.")