Spaces:
Sleeping
Sleeping
Update src/streamlit_app.py
Browse files- src/streamlit_app.py +95 -117
src/streamlit_app.py
CHANGED
|
@@ -11,22 +11,31 @@ st.set_page_config(page_title="CX Architect Auto-Mapper", layout="wide", page_ic
|
|
| 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 |
-
#
|
| 15 |
with st.sidebar:
|
| 16 |
st.header("βοΈ Configuration")
|
| 17 |
-
|
| 18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
st.markdown("---")
|
| 20 |
-
st.markdown("**
|
| 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.
|
| 27 |
# ==========================================
|
| 28 |
def safe_read_file(file):
|
| 29 |
-
"""Reads input document content across varying extensions
|
| 30 |
name = file.name
|
| 31 |
try:
|
| 32 |
if name.endswith('.pdf'):
|
|
@@ -42,148 +51,117 @@ def safe_read_file(file):
|
|
| 42 |
else:
|
| 43 |
return file.getvalue().decode("utf-8", errors="ignore")
|
| 44 |
except Exception as e:
|
| 45 |
-
return f"Error reading file
|
| 46 |
|
| 47 |
def run_ai_engine(document_text, key):
|
| 48 |
-
"""Triggers
|
| 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
|
| 67 |
</TABLE>
|
| 68 |
|
| 69 |
-
Here is the
|
| 70 |
{document_text}
|
| 71 |
"""
|
| 72 |
response = model.generate_content(prompt)
|
| 73 |
return response.text
|
| 74 |
|
| 75 |
-
def
|
| 76 |
-
"""
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 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 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 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
|
| 131 |
# ==========================================
|
| 132 |
if st.button("π Generate Design Sheets & Flow"):
|
| 133 |
-
if not api_key:
|
| 134 |
-
st.
|
| 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
|
| 138 |
else:
|
| 139 |
-
with st.spinner("Processing
|
| 140 |
try:
|
| 141 |
-
|
| 142 |
-
|
| 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 |
-
#
|
| 148 |
-
|
|
|
|
| 149 |
|
| 150 |
-
#
|
| 151 |
-
|
| 152 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
|
| 154 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 155 |
|
| 156 |
-
|
| 157 |
-
|
|
|
|
| 158 |
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 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.")
|
|
|
|
| 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 |
+
# Configuration Sidebar
|
| 15 |
with st.sidebar:
|
| 16 |
st.header("βοΈ Configuration")
|
| 17 |
+
|
| 18 |
+
# Built-in Hackathon Fail-safe Switch
|
| 19 |
+
demo_mode = st.toggle("π Activate Demo Simulation Mode", value=False, help="Turn this ON if your Google API Key is restricted or unavailable.")
|
| 20 |
+
|
| 21 |
+
if not demo_mode:
|
| 22 |
+
api_key = st.text_input("Enter Gemini API Key", type="password")
|
| 23 |
+
if api_key.startswith("AQ."):
|
| 24 |
+
st.warning("β οΈ Warning: Your key uses the restricted 'AQ.' token format which might have 0 quota. Consider switching to Demo Mode or using an 'AIza' key.")
|
| 25 |
+
else:
|
| 26 |
+
st.success("π’ Demo Simulation Mode Active (No Key Required!)")
|
| 27 |
+
|
| 28 |
st.markdown("---")
|
| 29 |
+
st.markdown("**Framework: LAMF Process Automation Engine**")
|
| 30 |
|
| 31 |
# File Upload Support Box
|
| 32 |
uploaded_file = st.file_uploader("Drop your Lending Document here (PDF, TXT, or CSV)", type=["pdf", "txt", "csv"])
|
| 33 |
|
| 34 |
# ==========================================
|
| 35 |
+
# 2. RUNTIME AND MOCK SYSTEM MAPPING DATA
|
| 36 |
# ==========================================
|
| 37 |
def safe_read_file(file):
|
| 38 |
+
"""Reads input document content across varying extensions safely"""
|
| 39 |
name = file.name
|
| 40 |
try:
|
| 41 |
if name.endswith('.pdf'):
|
|
|
|
| 51 |
else:
|
| 52 |
return file.getvalue().decode("utf-8", errors="ignore")
|
| 53 |
except Exception as e:
|
| 54 |
+
return f"Error reading file: {str(e)}"
|
| 55 |
|
| 56 |
def run_ai_engine(document_text, key):
|
| 57 |
+
"""Triggers standard runtime calls using Gemini models"""
|
| 58 |
genai.configure(api_key=key)
|
| 59 |
model = genai.GenerativeModel('gemini-1.5-flash')
|
| 60 |
|
| 61 |
prompt = f"""
|
| 62 |
You are an elite Fintech CX Architect mapping a Virtual Assistant (VA) flow for Loan Against Mutual Funds (LAMF).
|
| 63 |
+
Analyze the following document data and produce exactly two outputs inside the requested XML tags. Do not use markdown backticks.
|
|
|
|
|
|
|
| 64 |
|
| 65 |
<FLOW>
|
| 66 |
+
Provide a step-by-step text breakdown mapping the User Journey. List the Happy Path milestones, and then list the Unhappy Path scenarios along with recommended Bot Actions.
|
|
|
|
| 67 |
</FLOW>
|
| 68 |
|
| 69 |
<TABLE>
|
| 70 |
Create a structured routing table using a pipe character (|) as a column separator. Use exactly these headers:
|
| 71 |
Current Milestone | Scenario | Context Message | User Selection | Short Note | Ticket Creation | Group | Issue / GTIS | TAG
|
| 72 |
+
Provide at least 4 detailed rows capturing high-friction unhappy paths.
|
| 73 |
</TABLE>
|
| 74 |
|
| 75 |
+
Here is the data text:
|
| 76 |
{document_text}
|
| 77 |
"""
|
| 78 |
response = model.generate_content(prompt)
|
| 79 |
return response.text
|
| 80 |
|
| 81 |
+
def get_simulated_outputs():
|
| 82 |
+
"""Generates high-fidelity mock data structures if API configurations are blocked"""
|
| 83 |
+
flow_data = (
|
| 84 |
+
"π MILESTONE 1: USER_AUTHENTICATION\n"
|
| 85 |
+
" - Happy Path: Identity verified instantly via API.\n"
|
| 86 |
+
" - Unhappy Scenario: Low Credit Profile or Verification Drop-off.\n\n"
|
| 87 |
+
"π MILESTONE 2: PV_KYC & KYC_VERIFICATION\n"
|
| 88 |
+
" - Happy Path: Live selfie matching passes parameters.\n"
|
| 89 |
+
" - Unhappy Scenario: Selfie image fails to be captured or device camera initializes incorrectly.\n"
|
| 90 |
+
" - Bot Intervention: Delivers dynamic framing tooltips and triggers alternative fallback flows.\n\n"
|
| 91 |
+
"π MILESTONE 3: CREDIT_LIMIT_SELECTION\n"
|
| 92 |
+
" - Happy Path: System establishes available loan limits cleanly.\n"
|
| 93 |
+
" - Unhappy Scenario: Screen encounters a generic 'Something went wrong' API glitch.\n"
|
| 94 |
+
" - Bot Intervention: Catch-all logic translates the network exception and informs user of bank status.\n\n"
|
| 95 |
+
"π MILESTONE 4: PLEDGE_OFFER & SIGNING\n"
|
| 96 |
+
" - Happy Path: Digital locks successfully bind mutual funds.\n"
|
| 97 |
+
" - Unhappy Scenario: User queries loan interest costs late or demands application cancellation.\n"
|
| 98 |
+
" - Bot Intervention: Intercepts drop-offs with micro-educational text clarifying asset earning structures."
|
| 99 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
|
| 101 |
+
table_rows = [
|
| 102 |
+
["Current Milestone", "Scenario", "Context Message", "User Selection", "Short Note", "Ticket Creation", "Group", "Issue / GTIS", "TAG"],
|
| 103 |
+
["PV_KYC", "Unhappy: Selfie Verification Failed", "We noticed you are facing issues capturing your live selfie for verification.", "1. How to capture correctly\n2. Retry Upload", "Ensure you are in a well-lit room and remove glasses. Click 'Retry' on the main window interface.", "No", "NA", "Pre disbursal_KYC", "first_response_by_app_bot"],
|
| 104 |
+
["PV_KYC", "Unhappy: Selfie Failed (Max Retries)", "If your camera link is still not responding, we can escalate for manual profile checks.", "1. Escalate Request", "Your request has been raised. Our operations support team will email a manual submission form link within 2 hours.", "Yes", "Pre disbursal", "KYC verification failed_To be escalated", "kyc_manual_escalation"],
|
| 105 |
+
["PLEDGE_OFFER", "Unhappy: Late Charge Discovery Queries", "You seem to have a question before pledging your mutual funds. What details would you like to review?", "1. Rate of Interest\n2. Processing Fees", "Interest builds daily only on balances you actively draw. Total processing fee calculation is βΉ1,500 + 18% GST (βΉ1,770 total).", "No", "NA", "Loan details_Info given", "first_response_by_app_bot"],
|
| 106 |
+
["PLEDGE_OFFER", "Unhappy: Data Deletion / Cancellation", "We notice you want to cancel your application. Your mutual funds remain perfectly secure and earn standard returns.", "1. Confirm Cancellation\n2. Talk to Agent", "Your application records have been safely cleared out. Click proceed if you want to wipe historically fetched portfolio rows.", "Yes", "Pre disbursal", "Cancellation request_Processed", "lamf_cancellation"],
|
| 107 |
+
["CREDIT_LIMIT", "Unhappy: Generic Technical Failure Screen", "We see your portfolio balance evaluation was interrupted due to a background system exception.", "1. Refresh Pipeline", "Lender communication arrays are undergoing a brief update sync. We have logged this block and will text you when open.", "Yes", "Pre disbursal", "Approval pending_Asked to wait", "tech_failure_limit"]
|
| 108 |
+
]
|
| 109 |
+
|
| 110 |
+
return flow_data, pd.DataFrame(table_rows[1:], columns=table_rows[0])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
|
| 112 |
# ==========================================
|
| 113 |
+
# 3. INTERFACE DISPLAY CONTROLLER
|
| 114 |
# ==========================================
|
| 115 |
if st.button("π Generate Design Sheets & Flow"):
|
| 116 |
+
if not demo_mode and not api_key:
|
| 117 |
+
st.error("Please enter your API Key or toggle 'Demo Simulation Mode' in the sidebar configuration.")
|
|
|
|
| 118 |
elif not uploaded_file:
|
| 119 |
+
st.error("Please drag and drop a document file into the application platform area first.")
|
| 120 |
else:
|
| 121 |
+
with st.spinner("Processing customer journey mappings..."):
|
| 122 |
try:
|
| 123 |
+
if demo_mode:
|
| 124 |
+
# Instant fail-safe data generation
|
| 125 |
+
flowchart_text, final_df = get_simulated_outputs()
|
|
|
|
|
|
|
| 126 |
else:
|
| 127 |
+
# Live API calling routing
|
| 128 |
+
extracted_text = safe_read_file(uploaded_file)
|
| 129 |
+
ai_response = run_ai_engine(extracted_text, api_key)
|
| 130 |
|
| 131 |
+
# Core String Parsing
|
| 132 |
+
def extract_tag(text, tag):
|
| 133 |
+
match = re.search(f"<{tag}>(.*?)</{tag}>", text, re.DOTALL)
|
| 134 |
+
return match.group(1).strip().replace("```", "") if match else ""
|
| 135 |
+
|
| 136 |
+
flowchart_text = extract_tag(ai_response, "FLOW")
|
| 137 |
+
raw_table = extract_tag(ai_response, "TABLE")
|
| 138 |
|
| 139 |
+
# Convert raw rows to DataFrame safely
|
| 140 |
+
lines = [l.strip() for l in raw_table.split('\n') if l.strip() and '---' not in l]
|
| 141 |
+
headers = [h.strip() for h in lines[0].split('|')]
|
| 142 |
+
rows = [[c.strip() for c in r.split('|')] for r in lines[1:] if '|' in r]
|
| 143 |
+
final_df = pd.DataFrame(rows, columns=headers)
|
| 144 |
+
|
| 145 |
+
# Render Deliverable Results Layout
|
| 146 |
+
st.success("π― Omni-Channel Assets Rendered Successfully!")
|
| 147 |
+
tab1, tab2 = st.tabs(["πΊοΈ Visual Journey Path", "π VA Design Sheet (Excel)"])
|
| 148 |
+
|
| 149 |
+
with tab1:
|
| 150 |
+
st.subheader("Process Flow Optimization Strategy")
|
| 151 |
+
st.info("Automated structural architecture generated from your source file data parameters:")
|
| 152 |
+
st.code(flowchart_text, language="text")
|
| 153 |
|
| 154 |
+
with tab2:
|
| 155 |
+
st.subheader("Automated Routing Matrix (GTIS Mapping)")
|
| 156 |
+
st.dataframe(final_df, use_container_width=True)
|
| 157 |
|
| 158 |
+
csv_buffer = final_df.to_csv(index=False).encode('utf-8')
|
| 159 |
+
st.download_button(
|
| 160 |
+
label="β¬οΈ Download Sheet as CSV/Excel",
|
| 161 |
+
data=csv_buffer,
|
| 162 |
+
file_name='Automated_VA_Design_Sheet.csv',
|
| 163 |
+
mime='text/csv',
|
| 164 |
+
)
|
| 165 |
+
except Exception as e:
|
| 166 |
+
st.error(f"Execution Error: {str(e)}")
|
| 167 |
+
st.info("π‘ Pro-Tip for Demo: Turn on 'Demo Simulation Mode' in the sidebar to bypass API connection restrictions instantly.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|