Spaces:
Sleeping
Sleeping
File size: 6,080 Bytes
444082b bbfc899 444082b 34a6b67 10d008c 444082b ae7d952 444082b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
import streamlit as st
from streamlit_chat import message
import requests
import pandas as pd
import plotly.express as px
st.set_page_config(layout="wide")
API_URL = "https://virtual-eng-expert-api-v1.greensea-b20be511.northeurope.azurecontainerapps.io/api"
headers = {"Content-Type": "application/json"}
def query(payload, retries=2):
"""Query the API with retry logic"""
for attempt in range(retries + 1):
try:
response = requests.post(API_URL, headers=headers, json=payload, timeout=60)
response.raise_for_status() # Raise an exception for bad status codes
# Check if response is actually JSON before parsing
content_type = response.headers.get('Content-Type', '')
if 'application/json' not in content_type:
# Response is not JSON - likely HTML error page
error_text = response.text[:1000]
st.error(f"API returned non-JSON response (Content-Type: {content_type})")
st.error(f"Response preview: {error_text[:500]}")
with st.expander("Debug: View full response"):
st.text(error_text)
with st.expander("Debug: View request payload"):
st.json(payload)
raise ValueError(f"API returned non-JSON response. Status: {response.status_code}")
# Try to parse JSON
try:
return response.json()
except ValueError as json_error:
# Response claims to be JSON but isn't valid
st.error(f"API returned invalid JSON. Response text: {response.text[:500]}")
with st.expander("Debug: View request payload"):
st.json(payload)
raise ValueError(f"Invalid JSON response: {str(json_error)}")
except requests.exceptions.HTTPError as e:
if attempt < retries:
st.warning(f"Attempt {attempt + 1} failed with {e.response.status_code}. Retrying...")
continue
error_msg = f"API Error {e.response.status_code}"
try:
# Try to get JSON error if available
error_json = e.response.json()
if isinstance(error_json, dict):
error_msg += f": {error_json.get('error', error_json.get('message', str(error_json)))}"
else:
error_msg += f": {error_json}"
except:
# Not JSON, show text response
error_text = e.response.text[:500]
if error_text:
error_msg += f": {error_text}"
st.error(error_msg)
with st.expander("Debug: View request payload"):
st.json(payload)
raise
except requests.exceptions.Timeout:
if attempt < retries:
st.warning(f"Attempt {attempt + 1} timed out. Retrying...")
continue
st.error("Request timed out. The API may be slow or unavailable. Please try again.")
raise
except requests.exceptions.RequestException as e:
if attempt < retries:
st.warning(f"Attempt {attempt + 1} failed: {str(e)[:100]}. Retrying...")
continue
st.error(f"Connection Error: {str(e)}")
raise
def generate_response(user,prompt):
output = query({"namespace":"virtualEngineer","version":1,"messages":[{"role":user, "content": prompt}]})
return output
#Creating the chatbot interface
st.title("Engineering Expert")
st.caption("Problem: A major facilities engineering provider with over 40,000 field-based engineers and a large PDF-based knowledge repository of over 100,000 pages of documents faced significant challenges. The existing system used a metadata-driven search, which was highly manual to maintain and inefficient for engineers needing quick access to relevant information. This inefficiency led to delays in field operations and difficulties in maintaining up-to-date knowledge across the organization.")
st.caption("Solution: To address this challenge, the engineering provider implemented a Virtual Engineering Assistant powered by Generative AI (GenAI). The solution involved developing an advanced information science strategy that leveraged a vector database and unique memory architectures to improve information retrieval and decision support.")
col1, col2 = st.columns(2)
# Storing the chat
if 'generated' not in st.session_state:
st.session_state['generated'] = []
if 'past' not in st.session_state:
st.session_state['past'] = []
with col1:
with st.form(key='my_form'):
User = st.text_input("Step 1 Set Engineer Name","", key="user")
input_text = st.text_input("Step 2 How can I help today?","", key="input")
submit_button = st.form_submit_button(label='Submit')
if submit_button:
output = generate_response(User,input_text)
# store the output
st.session_state.past.append(input_text)
st.session_state.generated.append(output['choices'][0]['message']['content'])
df = pd.DataFrame(output["sources"])
fig = px.scatter(df, y="Score",color="Source", hover_data=['Insight'])
fig.update_layout(showlegend=False)
# Layout the columns
st.subheader("Response Data")
st.caption(f"Overall Answer Confidence: {output['accuracy']}%")
st.caption(f"Time Taken: {round(output['timeTaken'],1)} Seconds")
st.caption(f"Cognitive Cache Hit: {output['cacheHit']}")
st.caption('The below chart shows the distribution of knowledge in the knowledge store. This is used to supply expert information to answer your specific question. We request the top 100 results to speed up this demo, but analysing the knowledge store is an important part of maintaining high quality knowledge base which is key to high alignment, minimising hallucinations and ensuring safety.')
st.plotly_chart(fig, theme=None, use_container_width=True)
st.caption('Sources:')
st.caption('This table represents the books and their page numbers that were used to create the expert answer')
st.table(df.loc[:, ['Score', 'Source', 'startpage']].head(5))
if st.session_state['generated']:
for i in range(len(st.session_state['generated'])-1, -1, -1):
with col2:
message(st.session_state["generated"][i], key=str(i),avatar_style="identicon",seed="Socks")
message(st.session_state['past'][i], is_user=True, key=str(i) + '_user',avatar_style="identicon",seed="Mittens")
|