Spaces:
Sleeping
Sleeping
File size: 8,000 Bytes
f67e636 c17bbc4 f67e636 3a9a144 ee47ba2 f67e636 d621a9e 8538cd8 c17bbc4 d621a9e c17bbc4 d621a9e c17bbc4 d621a9e c17bbc4 d621a9e c17bbc4 3a9a144 c17bbc4 473cae6 c17bbc4 e8c424b c17bbc4 8538cd8 c17bbc4 a6006a0 c17bbc4 d621a9e c17bbc4 8538cd8 c17bbc4 473cae6 c17bbc4 12dfd0c c17bbc4 f67e636 8538cd8 798ac46 c17bbc4 f67e636 c17bbc4 f67e636 c17bbc4 e8c424b c17bbc4 f67e636 c17bbc4 a6006a0 c17bbc4 a6006a0 8538cd8 c17bbc4 a6006a0 c17bbc4 d621a9e c17bbc4 ae5d396 d621a9e a6006a0 c17bbc4 d621a9e c17bbc4 35e684c c17bbc4 7154687 473cae6 c17bbc4 f67e636 798ac46 2ea9d08 |
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 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
import streamlit as st
import requests
import json
# API URL
API_URL = "https://startrz-devi.hf.space/api/v1/prediction/e54adffc-ae77-42e5-9fc0-c4584e081093"
def safe_get(obj, *keys, default=None):
"""
Safely navigate through nested dictionaries
Args:
obj: Starting object
*keys: Sequence of keys to navigate
default: Value to return if navigation fails
Returns:
Value at the specified path or default
"""
try:
for key in keys:
obj = obj[key]
return obj
except (TypeError, KeyError, IndexError):
return default
def parse_text_content(data):
"""
Parse text content from the API response
Args:
data (dict): Full API response
Returns:
dict: Parsed text content with title and content
"""
try:
# Try to parse the text field as JSON
text_content = json.loads(safe_get(data, "text", default="{}"))
return {
"title": text_content.get("title", "No Title Available"),
"content": text_content.get("content", "No Content Available"),
"outline": text_content.get("outline", [])
}
except (json.JSONDecodeError, TypeError):
# Fallback if parsing fails
return {
"title": "Analysis Result",
"content": safe_get(data, "text", default="No content available"),
"outline": []
}
def parse_tool_details(tool):
"""
Parse tool details with robust handling of different input types
Args:
tool (dict): A single tool dictionary from the API response
Returns:
dict: Parsed tool details with consistent structure
"""
# Ensure tool is a dictionary
if not isinstance(tool, dict):
return {
"tool": "Unknown Tool",
"toolInput": "Invalid tool data",
"toolOutput": "No output available"
}
# Parse toolInput
input_value = ""
tool_input = tool.get("toolInput", {})
if isinstance(tool_input, dict):
input_value = tool_input.get("input", "")
# Fallback to full input dict as string if no 'input' key
if not input_value:
try:
input_value = json.dumps(tool_input, indent=2)
except Exception:
input_value = str(tool_input)
elif isinstance(tool_input, str):
input_value = tool_input
else:
input_value = str(tool_input) if tool_input is not None else "No input details"
# Parse toolOutput
output_value = tool.get("toolOutput")
# Flexible output handling
if output_value is None:
output_value = "No output available"
elif isinstance(output_value, (list, dict)):
# Convert to formatted JSON string for better readability
try:
output_value = json.dumps(output_value, indent=2)
except Exception:
output_value = str(output_value)
else:
# Convert to string for any other type
output_value = str(output_value)
return {
"tool": tool.get("tool", "Unknown Tool"),
"toolInput": input_value,
"toolOutput": output_value
}
def query(payload):
"""
Query the API and process the response
Args:
payload (dict): Question payload to send to the API
Returns:
dict: Processed response with tool details
"""
try:
# Send POST request to the API
response = requests.post(API_URL, json=payload)
response.raise_for_status()
# Parse the JSON response
data = response.json()
# Extract text content
text_content = parse_text_content(data)
# Extract tool details
tool_details = []
# Handle different potential response structures
agent_reasoning = safe_get(data, "agentReasoning", default=[])
for reasoning in agent_reasoning:
# Safely extract used tools
used_tools = safe_get(reasoning, "usedTools", default=[])
for tool in used_tools:
if tool is not None:
parsed_tool = parse_tool_details(tool)
tool_details.append(parsed_tool)
return {
"raw_response": data,
"text_content": text_content,
"tool_details": tool_details
}
except requests.exceptions.RequestException as e:
return {"error": f"API Request Error: {str(e)}"}
except json.JSONDecodeError as e:
return {"error": f"JSON Parsing Error: {str(e)}"}
except Exception as e:
return {"error": f"Unexpected Error: {str(e)}"}
def display_outline(outline):
"""
Display the document outline in an expandable section
Args:
outline (list): List of outline sections
"""
if not outline:
return
with st.expander("π Document Outline"):
for section in outline:
st.markdown(f"### {section.get('section_title', 'Untitled Section')}")
key_points = section.get('key_points', [])
for point in key_points:
st.markdown(f"- {point}")
def main():
"""
Main Streamlit application function
"""
st.set_page_config(
page_title="DEVI Research Assistant",
page_icon="π",
layout="wide"
)
st.title("π¬ DEVI RESEARCH ASSISTANT")
st.write("Explore insights by asking a research question!")
# User input section
user_input = st.text_input(
"What would you like to research?",
placeholder="Enter your research query here..."
)
# Submit button
if st.button("Explore Insights", type="primary"):
if user_input:
# Progress spinner during API call
with st.spinner("Gathering research insights..."):
response = query({"question": user_input})
# Error handling
if "error" in response:
st.error(response["error"])
return
# Display Text Content
st.header("π Research Insights")
# Extract text content
text_content = response.get("text_content", {})
# Display Title
st.subheader(text_content.get("title", "Research Analysis"))
# Display Content
st.write(text_content.get("content", "No content available"))
# Display Outline
display_outline(text_content.get("outline", []))
# Display Online Resources
st.header("π Online Resources")
tool_details = response.get("tool_details", [])
if tool_details:
# Create tabs for each resource
tabs = st.tabs([
f"{idx+1}. {tool.get('tool', 'Unknown')}"
for idx, tool in enumerate(tool_details)
])
# Populate each tab with resource details
for idx, (tool, tab) in enumerate(zip(tool_details, tabs)):
with tab:
st.subheader("Research Name")
st.code(tool.get('toolInput', 'No input'), language=None)
st.subheader("Research Findings")
# Use st.code for better formatting
st.code(tool.get('toolOutput', 'No output'), language=None)
else:
st.info("No resources found for this query.")
# Raw response in expander for advanced users
with st.expander("π Advanced: Full API Response"):
st.json(response.get("raw_response", {}))
else:
st.warning("Please enter a research question!")
if __name__ == "__main__":
main() |