"""AutoStream AI Sales Agent — Streamlit UI.""" from __future__ import annotations import streamlit as st from dotenv import load_dotenv load_dotenv() from langchain_core.messages import HumanMessage, AIMessage from agent.graph import get_app from agent.state import AgentState st.set_page_config( page_title="AutoStream", layout="centered", initial_sidebar_state="expanded", ) # --------------------------------------------------------------------------- # # Theme — Claude-inspired dark with orange accent # --------------------------------------------------------------------------- # _CSS = """ """ st.markdown(_CSS, unsafe_allow_html=True) # --------------------------------------------------------------------------- # # Session state init # --------------------------------------------------------------------------- # def _initial_state() -> AgentState: return { "messages": [], "intent": "unknown", "collecting_lead": False, "lead_name": None, "lead_email": None, "lead_platform": None, "lead_captured": False, "rag_context": "", } if "agent_state" not in st.session_state: st.session_state.agent_state = _initial_state() if "display_messages" not in st.session_state: st.session_state.display_messages = [] # --------------------------------------------------------------------------- # # Sidebar # --------------------------------------------------------------------------- # with st.sidebar: st.markdown( '', unsafe_allow_html=True, ) st.markdown( '
' 'AI sales assistant
', unsafe_allow_html=True, ) st.divider() state = st.session_state.agent_state intent = state.get("intent", "unknown") st.markdown('
Current intent
', unsafe_allow_html=True) badge_class = "as-badge accent" if intent in ("high_intent", "collecting") else "as-badge" st.markdown(f'{intent}', unsafe_allow_html=True) if state.get("collecting_lead"): st.markdown( '
Lead collection
', unsafe_allow_html=True, ) fields = [ ("Name", state.get("lead_name")), ("Email", state.get("lead_email")), ("Platform", state.get("lead_platform")), ] rows = [] for key, val in fields: cls = "val done" if val else "val pending" display = val or "—" rows.append( f'
{key}' f'{display}
' ) st.markdown("".join(rows), unsafe_allow_html=True) if state.get("lead_captured"): st.markdown( '
Lead captured
', unsafe_allow_html=True, ) st.divider() if st.button("New conversation", use_container_width=True): st.session_state.agent_state = _initial_state() st.session_state.display_messages = [] st.rerun() # --------------------------------------------------------------------------- # # Main chat UI # --------------------------------------------------------------------------- # st.markdown( '

AutoStream

' '
' 'Ask about pricing, features, or start a plan.
', unsafe_allow_html=True, ) for msg in st.session_state.display_messages: with st.chat_message(msg["role"]): st.markdown(msg["content"]) if prompt := st.chat_input("Message AutoStream…", disabled=state.get("lead_captured", False)): st.session_state.display_messages.append({"role": "user", "content": prompt}) with st.chat_message("user"): st.markdown(prompt) with st.chat_message("assistant"): with st.spinner(""): app = get_app() current = st.session_state.agent_state invoke_state = { **current, "messages": list(current["messages"]) + [HumanMessage(content=prompt)], } result = app.invoke(invoke_state) st.session_state.agent_state = result reply = "" for msg in reversed(result["messages"]): if isinstance(msg, AIMessage): reply = msg.content break st.markdown(reply) st.session_state.display_messages.append({"role": "assistant", "content": reply}) st.rerun()