Spaces:
Running
Running
add followup-agent
Browse files
main.py
CHANGED
|
@@ -377,6 +377,95 @@ async def search_assistant(query: SearchQueryModel, api_key: str = Depends(verif
|
|
| 377 |
|
| 378 |
return StreamingResponse(process_response(), media_type="text/event-stream")
|
| 379 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 380 |
if __name__ == "__main__":
|
| 381 |
import uvicorn
|
| 382 |
logger.info("Starting the application")
|
|
|
|
| 377 |
|
| 378 |
return StreamingResponse(process_response(), media_type="text/event-stream")
|
| 379 |
|
| 380 |
+
|
| 381 |
+
from pydantic import BaseModel, Field
|
| 382 |
+
import yaml
|
| 383 |
+
import json
|
| 384 |
+
|
| 385 |
+
class FollowupQueryModel(BaseModel):
|
| 386 |
+
query: str = Field(..., description="User's query for the followup agent")
|
| 387 |
+
model_id: ModelID = Field(
|
| 388 |
+
default="openai/gpt-4o-mini",
|
| 389 |
+
description="ID of the model to use for response generation"
|
| 390 |
+
)
|
| 391 |
+
conversation_id: str = Field(default_factory=lambda: str(uuid4()), description="Unique identifier for the conversation")
|
| 392 |
+
user_id: str = Field(..., description="Unique identifier for the user")
|
| 393 |
+
|
| 394 |
+
class Config:
|
| 395 |
+
schema_extra = {
|
| 396 |
+
"example": {
|
| 397 |
+
"query": "How can I improve my productivity?",
|
| 398 |
+
"model_id": "openai/gpt-4o-mini",
|
| 399 |
+
"conversation_id": "123e4567-e89b-12d3-a456-426614174000",
|
| 400 |
+
"user_id": "user123"
|
| 401 |
+
}
|
| 402 |
+
}
|
| 403 |
+
|
| 404 |
+
FOLLOWUP_AGENT_PROMPT = """
|
| 405 |
+
You are a helpful assistant with the following skills, use them, as necessary. If the user request needs further clarification, analyze it and generate clarifying questions with options. Else respond with a helpful answer. <response>response to user request in markdown</response> <clarification> questions: - text: [First clarifying question] options: - [Option 1] - [Option 2] - [Option 3] - [Option 4 (if needed)] - text: [Second clarifying question] options: - [Option 1] - [Option 2] - [Option 3] # Add more questions as needed # make sure this section is in valid YAML format </clarification>
|
| 406 |
+
"""
|
| 407 |
+
|
| 408 |
+
def parse_followup_response(response):
|
| 409 |
+
response_parts = response.split("<response>")
|
| 410 |
+
if len(response_parts) > 1:
|
| 411 |
+
response_content = response_parts[1].split("</response>")[0].strip()
|
| 412 |
+
else:
|
| 413 |
+
response_content = ""
|
| 414 |
+
|
| 415 |
+
clarification_parts = response.split("<clarification>")
|
| 416 |
+
if len(clarification_parts) > 1:
|
| 417 |
+
clarification_yaml = clarification_parts[1].split("</clarification>")[0].strip()
|
| 418 |
+
try:
|
| 419 |
+
clarification = yaml.safe_load(clarification_yaml)
|
| 420 |
+
except yaml.YAMLError:
|
| 421 |
+
clarification = None
|
| 422 |
+
else:
|
| 423 |
+
clarification = None
|
| 424 |
+
|
| 425 |
+
return response_content, clarification
|
| 426 |
+
|
| 427 |
+
@app.post("/followup-agent")
|
| 428 |
+
async def followup_agent(query: FollowupQueryModel, background_tasks: BackgroundTasks, api_key: str = Depends(verify_api_key)):
|
| 429 |
+
"""
|
| 430 |
+
Followup agent endpoint that provides helpful responses or generates clarifying questions based on user queries.
|
| 431 |
+
Requires API Key authentication via X-API-Key header.
|
| 432 |
+
"""
|
| 433 |
+
logger.info(f"Received followup agent query: {query.query}")
|
| 434 |
+
|
| 435 |
+
if query.conversation_id not in conversations:
|
| 436 |
+
conversations[query.conversation_id] = [
|
| 437 |
+
{"role": "system", "content": FOLLOWUP_AGENT_PROMPT}
|
| 438 |
+
]
|
| 439 |
+
|
| 440 |
+
conversations[query.conversation_id].append({"role": "user", "content": query.query})
|
| 441 |
+
last_activity[query.conversation_id] = time.time()
|
| 442 |
+
|
| 443 |
+
# Limit tokens in the conversation history
|
| 444 |
+
limited_conversation = conversations[query.conversation_id]
|
| 445 |
+
|
| 446 |
+
def process_response():
|
| 447 |
+
full_response = ""
|
| 448 |
+
for content in chat_with_llama_stream(limited_conversation, model=query.model_id):
|
| 449 |
+
full_response += content
|
| 450 |
+
yield content
|
| 451 |
+
|
| 452 |
+
response_content, clarification = parse_followup_response(full_response)
|
| 453 |
+
|
| 454 |
+
result = {
|
| 455 |
+
"response": response_content,
|
| 456 |
+
"clarification": clarification
|
| 457 |
+
}
|
| 458 |
+
|
| 459 |
+
yield "\n\n" + json.dumps(result)
|
| 460 |
+
|
| 461 |
+
# Add the assistant's response to the conversation history
|
| 462 |
+
conversations[query.conversation_id].append({"role": "assistant", "content": full_response})
|
| 463 |
+
|
| 464 |
+
background_tasks.add_task(update_db, query.user_id, query.conversation_id, query.query, full_response)
|
| 465 |
+
logger.info(f"Completed followup agent response for query: {query.query}")
|
| 466 |
+
|
| 467 |
+
return StreamingResponse(process_response(), media_type="text/event-stream")
|
| 468 |
+
|
| 469 |
if __name__ == "__main__":
|
| 470 |
import uvicorn
|
| 471 |
logger.info("Starting the application")
|