fixed issues history
This commit is contained in:
Binary file not shown.
Binary file not shown.
+52
-3
@@ -7,7 +7,7 @@ from api.dependencies.auth import get_api_key
|
|||||||
from src.llm.orchestrator import DroneBot, Message # Adjust import as needed
|
from src.llm.orchestrator import DroneBot, Message # Adjust import as needed
|
||||||
from src.llm.agent.flight_assesment import DroneAssessmentAgent
|
from src.llm.agent.flight_assesment import DroneAssessmentAgent
|
||||||
import json
|
import json
|
||||||
|
from logger import logger
|
||||||
router = APIRouter(
|
router = APIRouter(
|
||||||
prefix="/chat",
|
prefix="/chat",
|
||||||
tags=["chat"]
|
tags=["chat"]
|
||||||
@@ -20,19 +20,68 @@ async def chat_ai(
|
|||||||
):
|
):
|
||||||
"""Chat with DroneBot using query and history."""
|
"""Chat with DroneBot using query and history."""
|
||||||
try:
|
try:
|
||||||
|
logger.info(f"Starting chat request with query: {request.query}")
|
||||||
|
logger.info(f"History length: {len(request.history)}")
|
||||||
|
|
||||||
# Convert to internal Message format
|
# Convert to internal Message format
|
||||||
history = [Message(role=msg.role, content=msg.content) for msg in request.history]
|
history = [Message(role=msg.role, content=msg.content) for msg in request.history]
|
||||||
|
logger.info(f"Converted history to internal format: {len(history)} messages")
|
||||||
|
|
||||||
# Initialize DroneBot with history
|
# Initialize DroneBot with history
|
||||||
|
logger.info("Initializing DroneBot...")
|
||||||
bot = DroneBot(history=history, use_openai_as_fallback=True)
|
bot = DroneBot(history=history, use_openai_as_fallback=True)
|
||||||
|
logger.info("DroneBot initialized successfully")
|
||||||
|
|
||||||
|
# Get response from DroneBot
|
||||||
|
logger.info("Calling DroneBot.chat()...")
|
||||||
result = bot.chat(request.query)
|
result = bot.chat(request.query)
|
||||||
message = json.loads(result["final_message"])
|
logger.info(f"DroneBot response received: {result}")
|
||||||
print(result)
|
|
||||||
|
# Validate result and final_message
|
||||||
|
if not result or "final_message" not in result:
|
||||||
|
logger.error(f"Invalid result from DroneBot: {result}")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=500,
|
||||||
|
detail="Invalid response from DroneBot: missing final_message"
|
||||||
|
)
|
||||||
|
|
||||||
|
final_message = result["final_message"]
|
||||||
|
logger.info(f"Final message extracted: {final_message}")
|
||||||
|
|
||||||
|
if not final_message or not isinstance(final_message, str):
|
||||||
|
logger.error(f"Final message is not a valid string: {type(final_message)} - {final_message}")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=500,
|
||||||
|
detail="Invalid response from DroneBot: final_message is not a valid string"
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
logger.info("Attempting to parse final_message as JSON...")
|
||||||
|
message = json.loads(final_message)
|
||||||
|
logger.info("JSON parsing successful")
|
||||||
|
except json.JSONDecodeError as json_error:
|
||||||
|
logger.warning(f"JSON decode error: {json_error}")
|
||||||
|
logger.warning(f"Raw final_message: {final_message}")
|
||||||
|
# If JSON parsing fails, create a fallback structure
|
||||||
|
message = {
|
||||||
|
"message": final_message,
|
||||||
|
"options": None,
|
||||||
|
"requires_selection": False,
|
||||||
|
"end": "in_progress",
|
||||||
|
"form": {}
|
||||||
|
}
|
||||||
|
logger.info("Created fallback message structure")
|
||||||
|
|
||||||
|
logger.info(f"Final message to return: {message}")
|
||||||
return ChatResponse(
|
return ChatResponse(
|
||||||
status="success",
|
status="success",
|
||||||
message=message
|
message=message
|
||||||
)
|
)
|
||||||
|
except HTTPException:
|
||||||
|
logger.error("Re-raising HTTPException")
|
||||||
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
logger.error(f"Unexpected error in chat_ai: {str(e)}", exc_info=True)
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=500,
|
status_code=500,
|
||||||
detail=str(e)
|
detail=str(e)
|
||||||
|
|||||||
@@ -37,4 +37,4 @@ async def root():
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import uvicorn
|
import uvicorn
|
||||||
uvicorn.run(app, host="0.0.0.0", port=5340)
|
uvicorn.run(app, host="0.0.0.0", port=5120)
|
||||||
Binary file not shown.
+23
-2
@@ -169,13 +169,31 @@ class DroneBot:
|
|||||||
try:
|
try:
|
||||||
# Case 1: Response has direct string content
|
# Case 1: Response has direct string content
|
||||||
if hasattr(response, 'content') and isinstance(response.content, str) and response.content.strip():
|
if hasattr(response, 'content') and isinstance(response.content, str) and response.content.strip():
|
||||||
return response.content.strip()
|
content = response.content.strip()
|
||||||
|
|
||||||
|
# Check if the content is valid JSON
|
||||||
|
try:
|
||||||
|
json_content = json.loads(content)
|
||||||
|
# If it's valid JSON, return the message field or the entire JSON
|
||||||
|
if isinstance(json_content, dict) and "message" in json_content:
|
||||||
|
return content # Return the full JSON string
|
||||||
|
else:
|
||||||
|
return content # Return the JSON string even if no message field
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
# Not JSON, return as plain text
|
||||||
|
return content
|
||||||
|
|
||||||
# Case 2: Response has list content (complex format)
|
# Case 2: Response has list content (complex format)
|
||||||
elif hasattr(response, 'content') and isinstance(response.content, list):
|
elif hasattr(response, 'content') and isinstance(response.content, list):
|
||||||
for item in response.content:
|
for item in response.content:
|
||||||
if isinstance(item, dict) and item.get('type') == 'text' and item.get('text'):
|
if isinstance(item, dict) and item.get('type') == 'text' and item.get('text'):
|
||||||
return item['text'].strip()
|
text_content = item['text'].strip()
|
||||||
|
# Check if it's JSON
|
||||||
|
try:
|
||||||
|
json.loads(text_content)
|
||||||
|
return text_content # Return JSON string
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
return text_content # Return plain text
|
||||||
|
|
||||||
# Case 3: Response only has tool calls, no text content
|
# Case 3: Response only has tool calls, no text content
|
||||||
elif hasattr(response, 'tool_calls') and response.tool_calls:
|
elif hasattr(response, 'tool_calls') and response.tool_calls:
|
||||||
@@ -228,11 +246,14 @@ class DroneBot:
|
|||||||
response = llm_with_tools.invoke(messages)
|
response = llm_with_tools.invoke(messages)
|
||||||
|
|
||||||
print(f"DroneBot response: {type(response).__name__}")
|
print(f"DroneBot response: {type(response).__name__}")
|
||||||
|
print(f"Response content type: {type(response.content)}")
|
||||||
|
print(f"Response content: {response.content}")
|
||||||
if hasattr(response, 'tool_calls'):
|
if hasattr(response, 'tool_calls'):
|
||||||
print(f" Tool calls: {len(response.tool_calls) if response.tool_calls else 0}")
|
print(f" Tool calls: {len(response.tool_calls) if response.tool_calls else 0}")
|
||||||
|
|
||||||
# Extract and store the final message content
|
# Extract and store the final message content
|
||||||
final_message_content = self._extract_final_message_content(response)
|
final_message_content = self._extract_final_message_content(response)
|
||||||
|
print(f"Extracted final message: {final_message_content}")
|
||||||
self.final_message = final_message_content
|
self.final_message = final_message_content
|
||||||
|
|
||||||
# Update state
|
# Update state
|
||||||
|
|||||||
Binary file not shown.
@@ -2,6 +2,22 @@ def get_booking_prompt():
|
|||||||
|
|
||||||
return f"""
|
return f"""
|
||||||
|
|
||||||
|
## CRITICAL INSTRUCTION - YOU MUST FOLLOW THIS EXACTLY
|
||||||
|
|
||||||
|
**YOU MUST ALWAYS RESPOND WITH VALID JSON ONLY. NO OTHER TEXT, NO EXPLANATIONS, NO MARKDOWN FORMATTING.**
|
||||||
|
|
||||||
|
**EVERY SINGLE RESPONSE MUST BE A VALID JSON OBJECT WITH THIS EXACT STRUCTURE:**
|
||||||
|
|
||||||
|
{{
|
||||||
|
"message": "Your conversational response to the user",
|
||||||
|
"options": ["Option 1", "Option 2", "Option 3"] or null,
|
||||||
|
"requires_selection": true/false,
|
||||||
|
"end": "complete" | "in_progress" | "cancelled",
|
||||||
|
"form": {{}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
**DO NOT ADD ANYTHING BEFORE OR AFTER THE JSON. NO ```json, NO ```, NO EXPLANATIONS.**
|
||||||
|
|
||||||
## System Instructions & Persona
|
## System Instructions & Persona
|
||||||
|
|
||||||
You are DroneBot, a professional and knowledgeable drone survey booking assistant working for a leading renewable energy inspection company. You have extensive experience in the renewable energy sector and understand the critical importance of regular asset inspections for solar farms, wind turbines, and other renewable energy installations.
|
You are DroneBot, a professional and knowledgeable drone survey booking assistant working for a leading renewable energy inspection company. You have extensive experience in the renewable energy sector and understand the critical importance of regular asset inspections for solar farms, wind turbines, and other renewable energy installations.
|
||||||
@@ -16,7 +32,7 @@ Your primary function is to guide users through a comprehensive booking process,
|
|||||||
|
|
||||||
You MUST ALWAYS respond with a structured JSON object containing exactly these fields:
|
You MUST ALWAYS respond with a structured JSON object containing exactly these fields:
|
||||||
|
|
||||||
```json
|
|
||||||
{{
|
{{
|
||||||
"message": "Your conversational response to the user",
|
"message": "Your conversational response to the user",
|
||||||
"options": ["Option 1", "Option 2", "Option 3"] or null,
|
"options": ["Option 1", "Option 2", "Option 3"] or null,
|
||||||
@@ -24,7 +40,7 @@ You MUST ALWAYS respond with a structured JSON object containing exactly these f
|
|||||||
"end": "complete" | "in_progress" | "cancelled",
|
"end": "complete" | "in_progress" | "cancelled",
|
||||||
"form": {{}}
|
"form": {{}}
|
||||||
}}
|
}}
|
||||||
```
|
|
||||||
|
|
||||||
**Field Explanations:**
|
**Field Explanations:**
|
||||||
- **message**: Your conversational response (friendly, professional tone)
|
- **message**: Your conversational response (friendly, professional tone)
|
||||||
|
|||||||
Reference in New Issue
Block a user