Spaces:
Runtime error
Runtime error
Upload 2 files
Browse files
tasks.py
CHANGED
|
@@ -133,28 +133,55 @@ def get_response_refiner_task(query, initial_response, question_type, rag_note="
|
|
| 133 |
# Don't show any special message when RAG is sufficient
|
| 134 |
rag_message = ""
|
| 135 |
|
| 136 |
-
#
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
{rag_message}
|
| 143 |
-
|
| 144 |
-
You are a Response Refiner and Reporter. Refine the initial response and present it in a professional report format.
|
| 145 |
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
return Task(
|
| 157 |
description=prompt,
|
| 158 |
agent=response_refiner_agent,
|
| 159 |
-
expected_output=
|
| 160 |
)
|
|
|
|
| 133 |
# Don't show any special message when RAG is sufficient
|
| 134 |
rag_message = ""
|
| 135 |
|
| 136 |
+
# Handle out_of_scope case
|
| 137 |
+
if question_type == "out_of_scope":
|
| 138 |
+
prompt = f"""
|
| 139 |
+
User query: '{query}'
|
| 140 |
+
Initial Response: '{initial_response}'
|
| 141 |
+
Question Type: '{question_type}'
|
|
|
|
|
|
|
|
|
|
| 142 |
|
| 143 |
+
You are a Response Refiner and Reporter. The query is out of scope for a finance assistant.
|
| 144 |
+
|
| 145 |
+
### Instructions:
|
| 146 |
+
- Format as a report indicating the query is out of scope.
|
| 147 |
+
- Do not perform any research or generate additional content.
|
| 148 |
+
- Format as a report:
|
| 149 |
+
**Financial Report for Query: '{query}'**
|
| 150 |
+
- **Summary**: [Explain that the query is not finance-related]
|
| 151 |
+
- **Key Insight**: [Guide the user to ask finance-related questions]
|
| 152 |
+
- **Source/Note**: [Add note indicating no further processing]
|
| 153 |
+
- Keep under 200 words.
|
| 154 |
+
"""
|
| 155 |
+
expected_output = f"""
|
| 156 |
+
**Financial Report for Query: '{query}'**
|
| 157 |
+
- **Summary**: This query is not related to finance. I am designed to assist with financial topics like stock analysis, market news, or financial concepts.
|
| 158 |
+
- **Key Insight**: Please try a finance-related question, such as “Analyze META stock performance” or “What is revenue?”
|
| 159 |
+
- **Source/Note**: No further processing performed as query is out of scope.
|
| 160 |
+
"""
|
| 161 |
+
else:
|
| 162 |
+
prompt = f"""
|
| 163 |
+
User query: '{query}'
|
| 164 |
+
Initial Response: '{initial_response}'
|
| 165 |
+
Question Type: '{question_type}'
|
| 166 |
+
|
| 167 |
+
{rag_message}
|
| 168 |
+
|
| 169 |
+
You are a Response Refiner and Reporter. Refine the initial response and present it in a professional report format.
|
| 170 |
+
|
| 171 |
+
### Instructions:
|
| 172 |
+
- Simplify the language for a general audience.
|
| 173 |
+
- Verify accuracy and logical alignment with the query; add a note if issues are found.
|
| 174 |
+
- Format as a report:
|
| 175 |
+
**Financial Report for Query: '{query}'**
|
| 176 |
+
- **Summary**: [Simplified summary in 3-4 sentences]
|
| 177 |
+
- **Key Insight**: [One key takeaway or recommendation]
|
| 178 |
+
- **Source/Note**: [Cite source or add note]
|
| 179 |
+
- Keep under 200 words.
|
| 180 |
+
"""
|
| 181 |
+
expected_output = "A simplified and professionally formatted report, under 200 words."
|
| 182 |
+
|
| 183 |
return Task(
|
| 184 |
description=prompt,
|
| 185 |
agent=response_refiner_agent,
|
| 186 |
+
expected_output=expected_output
|
| 187 |
)
|
utils.py
CHANGED
|
@@ -36,7 +36,7 @@ qdrant = QdrantVectorStore.from_existing_collection(
|
|
| 36 |
mistral_llm = LLM(model="mistral/mistral-large-latest", api_key=MISTRAL_API_KEY, temperature=0.7)
|
| 37 |
|
| 38 |
# Initialize Gemini LLM
|
| 39 |
-
gemini_llm = LLM(
|
| 40 |
|
| 41 |
# Functions
|
| 42 |
@lru_cache(maxsize=100)
|
|
@@ -119,11 +119,60 @@ def get_stock_data(symbol):
|
|
| 119 |
@lru_cache(maxsize=100)
|
| 120 |
def determine_question_type(query):
|
| 121 |
"""Determine the type of user query using Mistral LLM via CrewAI's task mechanism."""
|
| 122 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
Analyze the following user query and determine its category:
|
| 124 |
-
- finance_knowledge: General questions about financial terms, concepts, or strategies
|
| 125 |
-
- market_news: Questions about current market news, trends, or events
|
| 126 |
-
- stock_analysis: Questions about specific stock analysis (e.g., mentioning a stock ticker like AAPL)
|
| 127 |
|
| 128 |
Query: "{query}"
|
| 129 |
|
|
@@ -132,17 +181,8 @@ def determine_question_type(query):
|
|
| 132 |
Extra Data: <additional info, such as the stock ticker for stock_analysis, or the query itself>
|
| 133 |
"""
|
| 134 |
|
| 135 |
-
classifier_agent = Agent(
|
| 136 |
-
role="Query Classifier",
|
| 137 |
-
goal="Classify user queries into appropriate categories.",
|
| 138 |
-
backstory="An expert in natural language understanding, capable of analyzing queries and categorizing them accurately.",
|
| 139 |
-
llm=mistral_llm,
|
| 140 |
-
verbose=True,
|
| 141 |
-
allow_delegation=False
|
| 142 |
-
)
|
| 143 |
-
|
| 144 |
classifier_task = Task(
|
| 145 |
-
description=
|
| 146 |
agent=classifier_agent,
|
| 147 |
expected_output="A classification of the query in the format: Category: <category>\nExtra Data: <additional info>"
|
| 148 |
)
|
|
@@ -153,13 +193,13 @@ def determine_question_type(query):
|
|
| 153 |
process=Process.sequential,
|
| 154 |
verbose=False
|
| 155 |
)
|
| 156 |
-
|
| 157 |
try:
|
| 158 |
response = temp_crew.kickoff()
|
| 159 |
response_text = response.raw if hasattr(response, 'raw') else str(response)
|
| 160 |
lines = response_text.strip().split("\n")
|
| 161 |
if len(lines) < 2:
|
| 162 |
-
raise ValueError("Invalid response format from LLM")
|
| 163 |
category_line = lines[0].replace("Category: ", "").strip()
|
| 164 |
extra_data_line = lines[1].replace("Extra Data: ", "").strip()
|
| 165 |
if category_line not in ["finance_knowledge", "market_news", "stock_analysis"]:
|
|
|
|
| 36 |
mistral_llm = LLM(model="mistral/mistral-large-latest", api_key=MISTRAL_API_KEY, temperature=0.7)
|
| 37 |
|
| 38 |
# Initialize Gemini LLM
|
| 39 |
+
gemini_llm = LLM(model="gemini/gemini-2.0-flash", api_key=GEMINI_API_KEY, temperature=0.7)
|
| 40 |
|
| 41 |
# Functions
|
| 42 |
@lru_cache(maxsize=100)
|
|
|
|
| 119 |
@lru_cache(maxsize=100)
|
| 120 |
def determine_question_type(query):
|
| 121 |
"""Determine the type of user query using Mistral LLM via CrewAI's task mechanism."""
|
| 122 |
+
classifier_agent = Agent(
|
| 123 |
+
role="Query Classifier",
|
| 124 |
+
goal="Classify user queries into appropriate categories, including detecting out-of-scope queries.",
|
| 125 |
+
backstory="An expert in natural language understanding, capable of analyzing queries and categorizing them accurately.",
|
| 126 |
+
llm=mistral_llm,
|
| 127 |
+
verbose=True,
|
| 128 |
+
allow_delegation=False
|
| 129 |
+
)
|
| 130 |
+
|
| 131 |
+
# Check if the query is finance-related
|
| 132 |
+
finance_check_prompt = f"""
|
| 133 |
+
Analyze the following user query and determine if it is related to finance:
|
| 134 |
+
- Return 'Yes' if the query is related to financial terms, concepts, strategies, market news, or stock analysis (e.g., banking, stocks, revenue, P/E ratio).
|
| 135 |
+
- Return 'No' if the query is unrelated to finance (e.g., cooking recipes, weather, or unrelated topics).
|
| 136 |
+
|
| 137 |
+
Query: "{query}"
|
| 138 |
+
|
| 139 |
+
Provide your response in this format:
|
| 140 |
+
Is Finance Related: <Yes/No>
|
| 141 |
+
"""
|
| 142 |
+
|
| 143 |
+
finance_check_task = Task(
|
| 144 |
+
description=finance_check_prompt,
|
| 145 |
+
agent=classifier_agent,
|
| 146 |
+
expected_output="A classification in the format: Is Finance Related: <Yes/No>"
|
| 147 |
+
)
|
| 148 |
+
|
| 149 |
+
temp_crew = Crew(
|
| 150 |
+
agents=[classifier_agent],
|
| 151 |
+
tasks=[finance_check_task],
|
| 152 |
+
process=Process.sequential,
|
| 153 |
+
verbose=False
|
| 154 |
+
)
|
| 155 |
+
|
| 156 |
+
try:
|
| 157 |
+
response = temp_crew.kickoff()
|
| 158 |
+
response_text = response.raw if hasattr(response, 'raw') else str(response)
|
| 159 |
+
lines = response_text.strip().split("\n")
|
| 160 |
+
if len(lines) < 1 or "Is Finance Related:" not in lines[0]:
|
| 161 |
+
raise ValueError("Invalid response format from LLM for finance check")
|
| 162 |
+
is_finance_related = lines[0].replace("Is Finance Related: ", "").strip().lower() == "yes"
|
| 163 |
+
except Exception as e:
|
| 164 |
+
# Fallback to default behavior if classification fails
|
| 165 |
+
is_finance_related = False
|
| 166 |
+
|
| 167 |
+
if not is_finance_related:
|
| 168 |
+
return "out_of_scope", "This query is out of scope for a finance assistant."
|
| 169 |
+
|
| 170 |
+
#If finance-related, classify the query type
|
| 171 |
+
classification_prompt = f"""
|
| 172 |
Analyze the following user query and determine its category:
|
| 173 |
+
- finance_knowledge: General questions about financial terms, concepts, or strategies (e.g., 'What is revenue?', 'Explain P/E ratio')
|
| 174 |
+
- market_news: Questions about current market news, trends, or events (e.g., 'Latest news about cryptocurrency market')
|
| 175 |
+
- stock_analysis: Questions about specific stock analysis (e.g., mentioning a stock ticker like AAPL, 'Analyze META stock performance')
|
| 176 |
|
| 177 |
Query: "{query}"
|
| 178 |
|
|
|
|
| 181 |
Extra Data: <additional info, such as the stock ticker for stock_analysis, or the query itself>
|
| 182 |
"""
|
| 183 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
classifier_task = Task(
|
| 185 |
+
description=classification_prompt,
|
| 186 |
agent=classifier_agent,
|
| 187 |
expected_output="A classification of the query in the format: Category: <category>\nExtra Data: <additional info>"
|
| 188 |
)
|
|
|
|
| 193 |
process=Process.sequential,
|
| 194 |
verbose=False
|
| 195 |
)
|
| 196 |
+
|
| 197 |
try:
|
| 198 |
response = temp_crew.kickoff()
|
| 199 |
response_text = response.raw if hasattr(response, 'raw') else str(response)
|
| 200 |
lines = response_text.strip().split("\n")
|
| 201 |
if len(lines) < 2:
|
| 202 |
+
raise ValueError("Invalid response format from LLM for category classification")
|
| 203 |
category_line = lines[0].replace("Category: ", "").strip()
|
| 204 |
extra_data_line = lines[1].replace("Extra Data: ", "").strip()
|
| 205 |
if category_line not in ["finance_knowledge", "market_news", "stock_analysis"]:
|