|
|
|
|
|
""" |
|
|
Conversation Manager for ΧΧ¨ΧΧΧͺ (Mirrors) - Hebrew Self-Reflective AI Agent |
|
|
Handles conversation context, history, and session state management |
|
|
""" |
|
|
|
|
|
from typing import Dict, List, Optional, Tuple |
|
|
from dataclasses import dataclass |
|
|
import json |
|
|
|
|
|
@dataclass |
|
|
class ConversationState: |
|
|
"""Tracks the current conversation state""" |
|
|
user_context: Optional[str] = None |
|
|
selected_part: Optional[str] = None |
|
|
persona_name: Optional[str] = None |
|
|
persona_age: Optional[str] = None |
|
|
persona_style: Optional[str] = None |
|
|
conversation_history: List[Dict] = None |
|
|
initial_prompt_choice: Optional[str] = None |
|
|
|
|
|
def __post_init__(self): |
|
|
if self.conversation_history is None: |
|
|
self.conversation_history = [] |
|
|
|
|
|
class ConversationManager: |
|
|
"""Manages conversation flow and context for the ΧΧ¨ΧΧΧͺ application""" |
|
|
|
|
|
def __init__(self, max_history_length: int = 50): |
|
|
""" |
|
|
Initialize conversation manager |
|
|
|
|
|
Args: |
|
|
max_history_length: Maximum number of messages to keep in history |
|
|
""" |
|
|
self.max_history_length = max_history_length |
|
|
|
|
|
def create_new_session(self) -> ConversationState: |
|
|
"""Create a new conversation session""" |
|
|
return ConversationState() |
|
|
|
|
|
def set_initial_context(self, state: ConversationState, prompt_choice: str, user_response: str) -> ConversationState: |
|
|
""" |
|
|
Set the initial context based on user's choice and response |
|
|
|
|
|
Args: |
|
|
state: Current conversation state |
|
|
prompt_choice: Which initial prompt was chosen |
|
|
user_response: User's response to the initial prompt |
|
|
""" |
|
|
state.initial_prompt_choice = prompt_choice |
|
|
state.user_context = user_response |
|
|
return state |
|
|
|
|
|
def set_selected_part(self, state: ConversationState, part_name: str, |
|
|
persona_name: Optional[str] = None, |
|
|
persona_age: Optional[str] = None, |
|
|
persona_style: Optional[str] = None) -> ConversationState: |
|
|
""" |
|
|
Set the selected part and its customization |
|
|
|
|
|
Args: |
|
|
state: Current conversation state |
|
|
part_name: Name of the selected part |
|
|
persona_name: Custom name for the persona |
|
|
persona_age: Custom age for the persona |
|
|
persona_style: Custom speaking style |
|
|
""" |
|
|
state.selected_part = part_name |
|
|
state.persona_name = persona_name |
|
|
state.persona_age = persona_age |
|
|
state.persona_style = persona_style |
|
|
return state |
|
|
|
|
|
def add_to_history(self, state: ConversationState, user_message: str, bot_response: str) -> ConversationState: |
|
|
""" |
|
|
Add a message exchange to conversation history |
|
|
|
|
|
Args: |
|
|
state: Current conversation state |
|
|
user_message: User's message |
|
|
bot_response: Bot's response |
|
|
""" |
|
|
|
|
|
state.conversation_history.append({ |
|
|
"role": "user", |
|
|
"content": user_message |
|
|
}) |
|
|
|
|
|
|
|
|
state.conversation_history.append({ |
|
|
"role": "assistant", |
|
|
"content": bot_response |
|
|
}) |
|
|
|
|
|
|
|
|
if len(state.conversation_history) > self.max_history_length: |
|
|
|
|
|
messages_to_remove = len(state.conversation_history) - self.max_history_length |
|
|
|
|
|
if messages_to_remove % 2 == 1: |
|
|
messages_to_remove += 1 |
|
|
state.conversation_history = state.conversation_history[messages_to_remove:] |
|
|
|
|
|
return state |
|
|
|
|
|
def get_conversation_context(self, state: ConversationState) -> str: |
|
|
""" |
|
|
Get formatted conversation context for prompt generation |
|
|
|
|
|
Args: |
|
|
state: Current conversation state |
|
|
|
|
|
Returns: |
|
|
Formatted context string |
|
|
""" |
|
|
context_parts = [] |
|
|
|
|
|
if state.user_context: |
|
|
context_parts.append(f"ΧΧ§Χ©Χ¨ Χ¨ΧΧ©ΧΧ Χ: {state.user_context}") |
|
|
|
|
|
if state.conversation_history: |
|
|
context_parts.append("ΧΧΧ‘ΧΧΧ¨ΧΧΧͺ ΧΧ©ΧΧΧ:") |
|
|
for msg in state.conversation_history[-10:]: |
|
|
role = "ΧΧ©ΧͺΧΧ©" if msg["role"] == "user" else "ΧΧΧ§ Χ€Χ ΧΧΧ" |
|
|
context_parts.append(f"{role}: {msg['content']}") |
|
|
|
|
|
return "\n".join(context_parts) |
|
|
|
|
|
def format_history_for_display(self, state: ConversationState) -> List[Tuple[str, str]]: |
|
|
""" |
|
|
Format conversation history for Gradio display |
|
|
|
|
|
Args: |
|
|
state: Current conversation state |
|
|
|
|
|
Returns: |
|
|
List of (user_message, bot_response) tuples |
|
|
""" |
|
|
formatted_history = [] |
|
|
|
|
|
for i in range(0, len(state.conversation_history), 2): |
|
|
if i + 1 < len(state.conversation_history): |
|
|
user_msg = state.conversation_history[i]["content"] |
|
|
bot_msg = state.conversation_history[i + 1]["content"] |
|
|
formatted_history.append((user_msg, bot_msg)) |
|
|
|
|
|
return formatted_history |
|
|
|
|
|
def get_session_summary(self, state: ConversationState) -> Dict: |
|
|
""" |
|
|
Get a summary of the current session |
|
|
|
|
|
Args: |
|
|
state: Current conversation state |
|
|
|
|
|
Returns: |
|
|
Dictionary with session summary |
|
|
""" |
|
|
return { |
|
|
"has_context": bool(state.user_context), |
|
|
"selected_part": state.selected_part, |
|
|
"persona_name": state.persona_name, |
|
|
"conversation_length": len(state.conversation_history), |
|
|
"initial_choice": state.initial_prompt_choice |
|
|
} |
|
|
|
|
|
def clear_conversation(self, state: ConversationState) -> ConversationState: |
|
|
""" |
|
|
Clear conversation history while keeping context and part selection |
|
|
|
|
|
Args: |
|
|
state: Current conversation state |
|
|
|
|
|
Returns: |
|
|
State with cleared conversation history |
|
|
""" |
|
|
state.conversation_history = [] |
|
|
return state |
|
|
|
|
|
def reset_session(self, state: ConversationState) -> ConversationState: |
|
|
""" |
|
|
Reset the entire session to start fresh |
|
|
|
|
|
Args: |
|
|
state: Current conversation state |
|
|
|
|
|
Returns: |
|
|
Fresh conversation state |
|
|
""" |
|
|
return ConversationState() |
|
|
|
|
|
def is_session_ready(self, state: ConversationState) -> bool: |
|
|
""" |
|
|
Check if session is ready for conversation (has context and selected part) |
|
|
|
|
|
Args: |
|
|
state: Current conversation state |
|
|
|
|
|
Returns: |
|
|
True if ready for conversation |
|
|
""" |
|
|
return bool(state.user_context and state.selected_part) |
|
|
|
|
|
def get_gradio_history(self, state: ConversationState) -> List[List[str]]: |
|
|
""" |
|
|
Format conversation history for Gradio ChatInterface |
|
|
|
|
|
Args: |
|
|
state: Current conversation state |
|
|
|
|
|
Returns: |
|
|
List of [user_message, bot_response] pairs for Gradio |
|
|
""" |
|
|
gradio_history = [] |
|
|
|
|
|
for i in range(0, len(state.conversation_history), 2): |
|
|
if i + 1 < len(state.conversation_history): |
|
|
user_msg = state.conversation_history[i]["content"] |
|
|
bot_msg = state.conversation_history[i + 1]["content"] |
|
|
gradio_history.append([user_msg, bot_msg]) |
|
|
|
|
|
return gradio_history |