updated memory
Browse files
fiscal.py
CHANGED
|
@@ -161,6 +161,67 @@ def clear_memory(user_id: str) -> None:
|
|
| 161 |
|
| 162 |
|
| 163 |
def stream_answer(message: str, user_id: str, financial_context: str = "") -> Generator:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
"""Stream answer token by token."""
|
| 165 |
|
| 166 |
# Same error detection as get_answer
|
|
|
|
| 161 |
|
| 162 |
|
| 163 |
def stream_answer(message: str, user_id: str, financial_context: str = "") -> Generator:
|
| 164 |
+
"""Stream answer token by token with conversation memory."""
|
| 165 |
+
|
| 166 |
+
# Same error detection as get_answer
|
| 167 |
+
if not financial_context or financial_context == "NO_BANK_DATA" or "Unable to fetch" in financial_context or "Bad Request" in financial_context or "access token" in financial_context.lower():
|
| 168 |
+
context_block = "The user has not connected their bank account yet. If relevant, gently mention they can connect their bank account in the Options menu to get personalized advice based on their real transactions and balances."
|
| 169 |
+
else:
|
| 170 |
+
context_block = f"The user has connected their bank account. Here is their live financial data:\n{financial_context}"
|
| 171 |
+
|
| 172 |
+
filled_template = QA_TEMPLATE.replace(
|
| 173 |
+
"{financial_context}",
|
| 174 |
+
context_block
|
| 175 |
+
)
|
| 176 |
+
|
| 177 |
+
prompt = PromptTemplate(
|
| 178 |
+
template=filled_template,
|
| 179 |
+
input_variables=["context", "question"],
|
| 180 |
+
)
|
| 181 |
+
|
| 182 |
+
# Get conversation history
|
| 183 |
+
memory = _get_memory(user_id)
|
| 184 |
+
chat_history = memory.chat_memory.messages
|
| 185 |
+
|
| 186 |
+
# Build history string
|
| 187 |
+
history_str = ""
|
| 188 |
+
for msg in chat_history[-6:]: # Last 3 exchanges (6 messages)
|
| 189 |
+
if msg.type == "human":
|
| 190 |
+
history_str += f"User: {msg.content}\n"
|
| 191 |
+
else:
|
| 192 |
+
history_str += f"FISCAL: {msg.content}\n"
|
| 193 |
+
|
| 194 |
+
# Condense follow-up question using history
|
| 195 |
+
if history_str:
|
| 196 |
+
condense_input = f"""Given the conversation below and a follow-up question, rephrase the follow-up as a standalone question that captures all relevant context.
|
| 197 |
+
|
| 198 |
+
Chat History:
|
| 199 |
+
{history_str}
|
| 200 |
+
|
| 201 |
+
Follow-up Question: {message}
|
| 202 |
+
|
| 203 |
+
Standalone Question:"""
|
| 204 |
+
|
| 205 |
+
condensed = llm.invoke(condense_input)
|
| 206 |
+
standalone_question = condensed.content if hasattr(condensed, 'content') else str(condensed)
|
| 207 |
+
else:
|
| 208 |
+
standalone_question = message
|
| 209 |
+
|
| 210 |
+
# Retrieve docs using the standalone question
|
| 211 |
+
docs = retriever.invoke(standalone_question)
|
| 212 |
+
context = "\n\n".join([doc.page_content for doc in docs])
|
| 213 |
+
filled_prompt = prompt.format(context=context, question=standalone_question)
|
| 214 |
+
|
| 215 |
+
# Stream the response and collect full answer for memory
|
| 216 |
+
full_response = ""
|
| 217 |
+
for chunk in llm.stream(filled_prompt):
|
| 218 |
+
content = chunk.content if hasattr(chunk, 'content') else str(chunk)
|
| 219 |
+
full_response += content
|
| 220 |
+
yield content
|
| 221 |
+
|
| 222 |
+
# Save to memory after streaming completes
|
| 223 |
+
memory.chat_memory.add_user_message(message)
|
| 224 |
+
memory.chat_memory.add_ai_message(full_response)
|
| 225 |
"""Stream answer token by token."""
|
| 226 |
|
| 227 |
# Same error detection as get_answer
|