DEV Community

Heena Meheraj
Heena Meheraj

Posted on

Building a Customer Support UI with Streamlit

Introduction
Customer support systems need to provide responses that are not only useful but also easy to understand. When an AI system uses customer-specific memory, the interface should make it clear what the customer asked, what the AI generated, and what information was recalled.

For our ResolveIQ Lite project, I worked on the UI layer using Streamlit. My main responsibility was to build an interface where users can select a customer, enable or disable memory, send support queries, and clearly see how memory affects the generated response.

The goal was to make the memory feature visible instead of keeping it hidden inside the backend.

My Role in ResolveIQ Lite
My contribution was focused on the Streamlit frontend/UI.

The main requirements were:
Customer selection
Hindsight memory ON/OFF toggle
Start new session functionality
Customer message input
Send button
Current query display
Generated response display
Recalled memory display
Session history

The interface was designed around a simple three-panel layout.

Designing the Streamlit Interface
I created the main application in:
app.py
The application uses Streamlit to create the interface.

The page configuration was kept simple:
`st.set_page_config(
page_title="ResolveIQ Lite",
layout="wide"
)

st.title("ResolveIQ Lite: Support agent with memory")`
I used a wide layout because the application needs to display three sections side by side.

Customer Selection and Memory Toggle
The sidebar contains the main controls.

The customer can be selected from the available customer data.
Customer
[C101 - Aarav Sharma ▼]

I also added a memory toggle:
Hindsight memory ON/OFF
This allows the same query to be tested with and without customer-specific memory.

The interface also contains a Start new session button.

The purpose of this button is to clear the current screen/session history while keeping the stored Hindsight memory available.

The Three-Panel UI
One of the main parts of my work was making the memory behavior visible through three separate sections.

1. Current Query
This displays exactly what the customer entered.

For example:

I still haven't received my replacement.
2. Generated Response
This displays the response generated by the AI agent.

When memory is available, the response can use information from the customer's previous interaction.

3. Recalled Memory
This shows the information retrieved from the customer's previous interactions.

For example:
Customer's order A104 arrived damaged
and they requested a replacement.

This makes it possible to see what information the system actually recalled.

Connecting the UI With the Backend
Initially, I used stand-in functions so that I could build and test the interface before the backend components were completed.

The temporary functions were later replaced with the actual functions from the team members' memory.py and agent.py.

The final application uses:
from memory import retain_incident, recall_incidents
from agent import generate_reply

This allowed the Streamlit UI to communicate with the actual memory and AI layers.

The overall flow became:
Customer
↓
Streamlit UI
↓
Recall Customer Memory
↓
Generate AI Response
↓
Display Response + Memory
↓
Store Interaction

Making Memory ON/OFF Visible
One of the important requirements was to demonstrate the difference between memory-enabled and memory-disabled responses.

Memory ON
The customer sends:
I still haven't received my replacement.
The UI can retrieve the previous A104 incident.

The recalled-memory section displays information such as:
Customer's order A104 arrived damaged
and they requested a replacement.

The generated response can then understand what replacement the customer is referring to.

Memory OFF
I then switched the memory toggle OFF and sent the same query again:
I still haven't received my replacement.
The UI displays:
Memory is OFF for this message
The response becomes more generic because the previous customer-specific memory is not supplied to the AI for that message.

This ON/OFF comparison makes the effect of memory easy to understand.

Testing the UI
I tested the application using the fictional customer data provided for the project.

The main test scenario was based on order A104.

First, the customer interaction established that:
My order A104 arrived damaged.
I want a replacement.

Later, the customer asked:
I still haven't received my replacement.
With memory enabled, the UI displayed the relevant previous information.

I then repeated the same query with memory disabled.

This allowed me to verify that the UI correctly reflected the difference between the two cases.

A Problem I Encountered
During integration, the UI initially produced an error when connecting to the memory layer.

The problem was related to the Hindsight configuration because the required environment variables were initially empty.

The project uses configuration values such as:
HINDSIGHT_BASE_URL
HINDSIGHT_API_KEY
GROQ_API_KEY

After the required configuration was added to the local .env file, the application was able to communicate with the Hindsight service.

Another integration issue occurred because the temporary retain_incident() function in the UI had a different function signature from the actual function in memory.py.

After the backend code was available, I removed the stand-in functions and connected the UI to the real implementations.

These issues helped me understand that integrating different modules requires the function interfaces and environment configuration to match correctly.

Making the UI Easy to Understand
The main design decision was to keep the interface simple rather than adding unnecessary features.
The user can immediately see:
Customer
Memory ON/OFF
New Session
↓
Customer Query
↓
Generated Response
↓
Recalled Memory

This makes the relationship between the customer query, AI response, and memory visible.

The UI therefore acts not only as the frontend but also as a simple demonstration of how the memory system affects the AI response.

Final UI
The completed interface contains:

Customer dropdown
Hindsight memory toggle
Start new session button
Customer message box
Send button
Current query panel
Generated response panel
Recalled memory panel
Session history

The final UI allowed us to demonstrate the main idea of ResolveIQ Lite without requiring the user to inspect the backend code.

What I Learned
Working on the Streamlit interface gave me practical experience with:

Streamlit UI development
Python application integration
Connecting frontend components with backend functions
Environment variables
API-based services
Session state
Testing AI application workflows
Git and GitHub collaboration
Debugging integration errors

One of the most useful things I learned was that an AI application's interface should make its behavior understandable.

Instead of simply showing an AI-generated answer, showing the current query, generated response, and recalled memory separately makes it much easier to understand why the system responded in a particular way.

Overall Architecture

Customer Message
↓
Streamlit UI
↓
Memory ON? ────── No ──────→ Generate Response
│
Yes
↓
Hindsight Recall
↓
Generate Response
↓
Display Response
↓
Display Recalled Memory
↓
Store Interaction

Conclusion
Working as the UI Engineer for ResolveIQ Lite gave me experience in building an interface around an AI-powered application rather than treating the AI model as a standalone component.

The main focus of my work was making customer-specific memory visible through the interface.

The three-panel design helped demonstrate the complete flow from the customer's query to the generated response and the memory used by the system.

The Memory ON vs Memory OFF test was especially useful because it made the difference between a context-aware response and a generic response clearly visible.

Overall, this project helped me understand how UI, AI, memory, APIs, and backend services need to work together to create a complete AI application.

Main UI

Memory ON

Memory OFF

Top comments (0)