Spaces:
Sleeping
Sleeping
Faham
commited on
Commit
Β·
301ae3f
1
Parent(s):
65a44fe
FIX: response from LLM
Browse files
Home.py
CHANGED
|
@@ -8,7 +8,6 @@ import time
|
|
| 8 |
from datetime import timedelta
|
| 9 |
import gnews
|
| 10 |
from bs4 import BeautifulSoup
|
| 11 |
-
import importlib.util
|
| 12 |
import requests
|
| 13 |
import holidays
|
| 14 |
import pandas as pd
|
|
@@ -22,7 +21,6 @@ from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
| 22 |
from langgraph.prebuilt import create_react_agent
|
| 23 |
from langchain_groq import ChatGroq
|
| 24 |
|
| 25 |
-
|
| 26 |
# Load environment variables
|
| 27 |
load_dotenv()
|
| 28 |
|
|
@@ -959,53 +957,162 @@ Question: {user_query} for {selected_ticker}"""
|
|
| 959 |
{"messages": [{"role": "user", "content": full_query}]}
|
| 960 |
)
|
| 961 |
|
| 962 |
-
# Extract the final answer from the result
|
| 963 |
-
if isinstance(result, dict) and "output" in result:
|
| 964 |
-
final_response = result["output"]
|
| 965 |
-
elif isinstance(result, str):
|
| 966 |
-
final_response = result
|
| 967 |
-
else:
|
| 968 |
-
final_response = str(result)
|
| 969 |
-
|
| 970 |
# Debug: Print the raw result to see what we're getting
|
| 971 |
print("π Raw result type:", type(result))
|
| 972 |
print("π Raw result:", result)
|
| 973 |
|
| 974 |
-
#
|
| 975 |
-
final_response =
|
| 976 |
-
|
| 977 |
-
|
| 978 |
-
|
| 979 |
-
|
| 980 |
-
|
| 981 |
-
|
| 982 |
-
|
| 983 |
-
|
| 984 |
-
|
| 985 |
-
|
| 986 |
-
|
| 987 |
-
|
| 988 |
-
|
| 989 |
-
|
| 990 |
-
|
| 991 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 992 |
)
|
| 993 |
|
| 994 |
-
|
| 995 |
-
|
| 996 |
-
|
| 997 |
-
|
| 998 |
-
|
| 999 |
-
|
| 1000 |
-
|
| 1001 |
-
|
| 1002 |
-
|
| 1003 |
-
|
| 1004 |
-
|
| 1005 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1006 |
else:
|
| 1007 |
-
|
| 1008 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1009 |
|
| 1010 |
# Remove any remaining tool call artifacts
|
| 1011 |
final_response = re.sub(r"<\|.*?\|>", "", final_response)
|
|
|
|
| 8 |
from datetime import timedelta
|
| 9 |
import gnews
|
| 10 |
from bs4 import BeautifulSoup
|
|
|
|
| 11 |
import requests
|
| 12 |
import holidays
|
| 13 |
import pandas as pd
|
|
|
|
| 21 |
from langgraph.prebuilt import create_react_agent
|
| 22 |
from langchain_groq import ChatGroq
|
| 23 |
|
|
|
|
| 24 |
# Load environment variables
|
| 25 |
load_dotenv()
|
| 26 |
|
|
|
|
| 957 |
{"messages": [{"role": "user", "content": full_query}]}
|
| 958 |
)
|
| 959 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 960 |
# Debug: Print the raw result to see what we're getting
|
| 961 |
print("π Raw result type:", type(result))
|
| 962 |
print("π Raw result:", result)
|
| 963 |
|
| 964 |
+
# Try to extract AIMessages from structured data first
|
| 965 |
+
final_response = ""
|
| 966 |
+
if isinstance(result, dict) and "messages" in result:
|
| 967 |
+
# Work with structured data directly
|
| 968 |
+
messages = result["messages"]
|
| 969 |
+
print(f"π Found {len(messages)} messages in structured data")
|
| 970 |
+
|
| 971 |
+
# Filter for AIMessage instances
|
| 972 |
+
ai_messages = []
|
| 973 |
+
for msg in messages:
|
| 974 |
+
if (
|
| 975 |
+
hasattr(msg, "__class__")
|
| 976 |
+
and msg.__class__.__name__ == "AIMessage"
|
| 977 |
+
):
|
| 978 |
+
ai_messages.append(msg)
|
| 979 |
+
elif isinstance(msg, dict) and msg.get("type") == "AIMessage":
|
| 980 |
+
ai_messages.append(msg)
|
| 981 |
+
|
| 982 |
+
print(f"π Found {len(ai_messages)} AIMessages in structured data")
|
| 983 |
+
|
| 984 |
+
if len(ai_messages) >= 2:
|
| 985 |
+
# Get the second AIMessage (comprehensive analysis)
|
| 986 |
+
second_ai_message = ai_messages[1]
|
| 987 |
+
if hasattr(second_ai_message, "content"):
|
| 988 |
+
final_response = second_ai_message.content
|
| 989 |
+
elif isinstance(second_ai_message, dict):
|
| 990 |
+
final_response = second_ai_message.get("content", "")
|
| 991 |
+
print(f"π Selected message 2 (the comprehensive analysis)")
|
| 992 |
+
print(f"π Selected message starts with: {final_response[:50]}")
|
| 993 |
+
elif len(ai_messages) == 1:
|
| 994 |
+
# Fallback to first message if only one found
|
| 995 |
+
first_ai_message = ai_messages[0]
|
| 996 |
+
if hasattr(first_ai_message, "content"):
|
| 997 |
+
final_response = first_ai_message.content
|
| 998 |
+
elif isinstance(first_ai_message, dict):
|
| 999 |
+
final_response = first_ai_message.get("content", "")
|
| 1000 |
+
print(f"π Selected message 1 (only one found)")
|
| 1001 |
+
print(f"π Selected message starts with: {final_response[:50]}")
|
| 1002 |
+
else:
|
| 1003 |
+
# Fallback to string processing if no structured AIMessages found
|
| 1004 |
+
if isinstance(result, dict) and "output" in result:
|
| 1005 |
+
final_response = result["output"]
|
| 1006 |
+
elif isinstance(result, str):
|
| 1007 |
+
final_response = result
|
| 1008 |
+
else:
|
| 1009 |
+
final_response = str(result)
|
| 1010 |
+
|
| 1011 |
+
# Clean up the final response to remove escaped characters
|
| 1012 |
+
final_response = (
|
| 1013 |
+
final_response.replace("\\n", "\n")
|
| 1014 |
+
.replace("\\'", "'")
|
| 1015 |
+
.replace('\\"', '"')
|
| 1016 |
)
|
| 1017 |
|
| 1018 |
+
# Try regex extraction as fallback
|
| 1019 |
+
if "AIMessage" in final_response:
|
| 1020 |
+
# Look for AIMessages in JSON format - multiple patterns to catch different formats
|
| 1021 |
+
ai_messages = []
|
| 1022 |
+
|
| 1023 |
+
# Pattern 1: AIMessage with content in double quotes
|
| 1024 |
+
ai_messages.extend(
|
| 1025 |
+
re.findall(
|
| 1026 |
+
r'AIMessage\(content="([^"]*)"',
|
| 1027 |
+
final_response,
|
| 1028 |
+
re.DOTALL,
|
| 1029 |
+
)
|
| 1030 |
+
)
|
| 1031 |
+
|
| 1032 |
+
# Pattern 2: AIMessage with content in single quotes
|
| 1033 |
+
if not ai_messages:
|
| 1034 |
+
ai_messages.extend(
|
| 1035 |
+
re.findall(
|
| 1036 |
+
r"AIMessage\(content='([^']*)'",
|
| 1037 |
+
final_response,
|
| 1038 |
+
re.DOTALL,
|
| 1039 |
+
)
|
| 1040 |
+
)
|
| 1041 |
+
|
| 1042 |
+
# Pattern 3: AIMessage in JSON format with "content" field
|
| 1043 |
+
if not ai_messages:
|
| 1044 |
+
ai_messages.extend(
|
| 1045 |
+
re.findall(
|
| 1046 |
+
r'"content":\s*"([^"]*)"',
|
| 1047 |
+
final_response,
|
| 1048 |
+
re.DOTALL,
|
| 1049 |
+
)
|
| 1050 |
+
)
|
| 1051 |
+
|
| 1052 |
+
# Pattern 4: AIMessage in JSON format with 'content' field
|
| 1053 |
+
if not ai_messages:
|
| 1054 |
+
ai_messages.extend(
|
| 1055 |
+
re.findall(
|
| 1056 |
+
r"'content':\s*'([^']*)'",
|
| 1057 |
+
final_response,
|
| 1058 |
+
re.DOTALL,
|
| 1059 |
+
)
|
| 1060 |
+
)
|
| 1061 |
+
|
| 1062 |
+
if ai_messages:
|
| 1063 |
+
print(
|
| 1064 |
+
f"π Found {len(ai_messages)} AIMessages via regex"
|
| 1065 |
+
)
|
| 1066 |
+
for i, msg in enumerate(ai_messages):
|
| 1067 |
+
print(
|
| 1068 |
+
f"π Message {i+1} length: {len(msg.strip())}"
|
| 1069 |
+
)
|
| 1070 |
+
print(
|
| 1071 |
+
f"π Message {i+1} preview: {msg.strip()[:100]}..."
|
| 1072 |
+
)
|
| 1073 |
+
print(
|
| 1074 |
+
f"π Message {i+1} starts with: {msg.strip()[:20]}"
|
| 1075 |
+
)
|
| 1076 |
+
|
| 1077 |
+
# Select the second AIMessage (index 1) which contains the comprehensive analysis
|
| 1078 |
+
# The first AIMessage is usually just the tool-calling message
|
| 1079 |
+
if len(ai_messages) >= 2:
|
| 1080 |
+
final_response = ai_messages[
|
| 1081 |
+
1
|
| 1082 |
+
].strip() # Get the 2nd message
|
| 1083 |
+
print(
|
| 1084 |
+
f"π Selected message 2 (the comprehensive analysis)"
|
| 1085 |
+
)
|
| 1086 |
+
print(
|
| 1087 |
+
f"π Selected message starts with: {final_response[:50]}"
|
| 1088 |
+
)
|
| 1089 |
+
else:
|
| 1090 |
+
# Fallback to last message if only one found
|
| 1091 |
+
final_response = ai_messages[-1].strip()
|
| 1092 |
+
print(
|
| 1093 |
+
f"π Selected message {len(ai_messages)} (the last one)"
|
| 1094 |
+
)
|
| 1095 |
+
print(
|
| 1096 |
+
f"π Selected message starts with: {final_response[:50]}"
|
| 1097 |
+
)
|
| 1098 |
+
else:
|
| 1099 |
+
# If no AIMessage found, try to extract from the raw response
|
| 1100 |
+
final_response = final_response.strip()
|
| 1101 |
+
else:
|
| 1102 |
+
# Fallback for non-structured data
|
| 1103 |
+
if isinstance(result, dict) and "output" in result:
|
| 1104 |
+
final_response = result["output"]
|
| 1105 |
+
elif isinstance(result, str):
|
| 1106 |
+
final_response = result
|
| 1107 |
else:
|
| 1108 |
+
final_response = str(result)
|
| 1109 |
+
|
| 1110 |
+
# Clean up the final response to remove escaped characters
|
| 1111 |
+
final_response = (
|
| 1112 |
+
final_response.replace("\\n", "\n")
|
| 1113 |
+
.replace("\\'", "'")
|
| 1114 |
+
.replace('\\"', '"')
|
| 1115 |
+
)
|
| 1116 |
|
| 1117 |
# Remove any remaining tool call artifacts
|
| 1118 |
final_response = re.sub(r"<\|.*?\|>", "", final_response)
|