Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| from twelve_ai_agents.orm import Room | |
| from twelve_ai_agents.agents_dilemmas import AGENTS, DILEMMAS | |
| from twelve_ai_agents.utils import get_client | |
| import time | |
| from itertools import groupby | |
| import pandas as pd | |
| import os | |
| import json | |
| from datetime import datetime | |
| def group_messages_by_round(messages, max_rounds): | |
| """Group messages by round and format for display""" | |
| rounds = [] | |
| current_round = 0 | |
| round_messages = [] | |
| for msg in messages: | |
| if msg["role"] == "moderator" and len(round_messages) > 0: | |
| rounds.append(round_messages) | |
| round_messages = [] | |
| round_messages.append(msg) | |
| if round_messages: | |
| rounds.append(round_messages) | |
| return rounds | |
| def execute_round(): | |
| """Execute a single round of discussion""" | |
| if 'current_agent_index' not in st.session_state: | |
| st.session_state.current_agent_index = 0 | |
| # Get the next agent | |
| agent = st.session_state.room.agents[st.session_state.current_agent_index] | |
| # Generate response and display if agent chooses to speak | |
| response = st.session_state.room.generate_agent_response(agent, st.session_state.client) | |
| if response: # Only append and display if agent chose to speak | |
| st.session_state.messages.append(response) | |
| with st.chat_message(response["role"]): | |
| st.markdown(f"**{response['role']}**: {response['message']}") | |
| time.sleep(0.5) | |
| # Increment agent index | |
| st.session_state.current_agent_index += 1 | |
| # If all agents have taken their turn in this round | |
| if st.session_state.current_agent_index >= len(st.session_state.room.agents): | |
| st.session_state.current_agent_index = 0 | |
| st.session_state.current_round += 1 | |
| st.session_state.room.current_round = st.session_state.current_round | |
| # Check if all rounds are complete | |
| if st.session_state.current_round >= st.session_state.max_rounds: | |
| st.session_state.discussion_completed = True | |
| st.success("Discussion rounds completed!") | |
| # Force a rerun to update the UI | |
| st.rerun() | |
| def show_discussion_history(): | |
| """Display the entire discussion history in collapsible rounds""" | |
| rounds = group_messages_by_round(st.session_state.messages, st.session_state.max_rounds) | |
| for i, round_messages in enumerate(rounds): | |
| if i == 0: # First round with moderator introduction | |
| with st.expander("π Discussion Start", expanded=True): | |
| for msg in round_messages: | |
| with st.chat_message(msg["role"]): | |
| st.markdown(f"**{msg['role']}**: {msg['message']}") | |
| else: | |
| with st.expander(f"Round {i}", expanded=True): | |
| for msg in round_messages: | |
| with st.chat_message(msg["role"]): | |
| st.markdown(f"**{msg['role']}**: {msg['message']}") | |
| def show_summary(): | |
| """Display the final discussion summary""" | |
| with st.expander("π Final Summary", expanded=True): | |
| results = st.session_state.room.finalize_discussion(st.session_state.client) | |
| st.subheader("Majority Decision") | |
| st.write(results["majority_decision"]) | |
| if results["consensus_reached"]: | |
| st.success("Full consensus reached! π") | |
| else: | |
| st.info("Partial consensus reached") | |
| st.subheader("Individual Positions") | |
| # Using st.subheader and st.write (Simplest, no collapsing) | |
| for agent_name, position in results["individual_positions"].items(): | |
| st.subheader(agent_name) | |
| st.write(position) | |
| def save_conversation_log(): | |
| """Saves the conversation log to a CSV file.""" | |
| results = st.session_state.room.finalize_discussion(st.session_state.client) | |
| log_data = { | |
| "conversation_id": datetime.now().strftime("%Y%m%d%H%M%S"), # Unique ID based on timestamp | |
| "dilemma_name": st.session_state.selected_dilemma["name"], # Store the name | |
| "dilemma_description": st.session_state.selected_dilemma["description"], # Store the description | |
| "room_history": json.dumps(st.session_state.messages), # Store the entire message history as JSON | |
| "final_decision": results["majority_decision"], | |
| "final_consensus": results["consensus_reached"], | |
| "individual_positions": json.dumps(results["individual_positions"]), # Store individual positions | |
| "max_rounds": st.session_state.max_rounds, | |
| "agents": json.dumps([agent.name for agent in st.session_state.room.agents]), | |
| "start_time": st.session_state.start_time, | |
| "end_time": datetime.now().strftime("%Y%m%d%H%M%S"), # end time of the discussion | |
| } | |
| df = pd.DataFrame([log_data]) | |
| filepath = "logs/conversations.csv" | |
| if os.path.exists(filepath): | |
| df.to_csv(filepath, mode='a', header=False, index=False) # append to the file if the file exists | |
| else: | |
| df.to_csv(filepath, header=True, index=False) # create the file and write the header | |
| def main(): | |
| st.title("AI Agents Social Dilemma Discussion π€π¬") | |
| # Initialize session state | |
| if 'messages' not in st.session_state: | |
| st.session_state.messages = [] | |
| if 'room' not in st.session_state: | |
| moderator = next((agent for agent in AGENTS if agent.name == "The Moderator"), None) | |
| st.session_state.room = Room(agents=AGENTS, moderator=moderator) | |
| st.session_state.client = get_client() | |
| st.session_state.current_round = 0 | |
| st.session_state.max_rounds = 0 | |
| st.session_state.discussion_started = False | |
| st.session_state.discussion_completed = False | |
| st.session_state.current_agent_index = 0 | |
| st.session_state.selected_dilemma = None # Store the selected dilemma | |
| st.session_state.start_time = None # Store the start time | |
| with st.sidebar: | |
| st.header("Setup Discussion") | |
| # Dilemma selection | |
| selected_dilemma_name = st.selectbox( | |
| "Choose a Social Dilemma", | |
| options=[dilemma["name"] for dilemma in DILEMMAS], | |
| index=0 | |
| ) | |
| st.session_state.selected_dilemma = next( # Store the selected dilemma dictionary | |
| (dilemma for dilemma in DILEMMAS if dilemma["name"] == selected_dilemma_name), | |
| None | |
| ) | |
| dilemma_description = st.session_state.selected_dilemma["description"] if st.session_state.selected_dilemma else "" | |
| dilemma = st.text_area("Dilemma Description", value=dilemma_description, height=200) | |
| # Initial rounds setup | |
| initial_rounds = st.number_input("Initial Number of Rounds", min_value=1, max_value=10, value=5) | |
| start_button = st.button("Start Discussion") | |
| # Continue discussion setup | |
| continue_rounds = st.number_input("Continue Discussion Rounds", min_value=1, max_value=10, value=1) # Moved outside | |
| continue_button = False # Initialize it here | |
| if not st.session_state.discussion_completed: | |
| continue_button = st.button("Continue Discussion") # Assign the Streamlit button here | |
| # Handle start button | |
| if start_button: | |
| moderator = next((agent for agent in AGENTS if agent.name == "The Moderator"), None) | |
| st.session_state.room = Room(agents=AGENTS, moderator=moderator) | |
| st.session_state.client = get_client() | |
| st.session_state.current_round = 0 | |
| st.session_state.messages = [] | |
| st.session_state.current_agent_index = 0 | |
| moderator_intro = st.session_state.room.set_dilemma(dilemma) | |
| initial_message = { | |
| "role": "moderator", | |
| "message": moderator_intro, | |
| "talk_to": "room" | |
| } | |
| st.session_state.messages.append(initial_message) | |
| with st.chat_message("moderator"): | |
| st.markdown(f"**moderator**: {moderator_intro}") | |
| st.session_state.discussion_started = True | |
| st.session_state.max_rounds = initial_rounds | |
| st.session_state.room.max_rounds = initial_rounds | |
| st.session_state.discussion_completed = False | |
| st.session_state.start_time = datetime.now().strftime("%Y%m%d%H%M%S") # Record the start time | |
| # Handle continue button | |
| if st.session_state.discussion_started and not st.session_state.discussion_completed and continue_button: | |
| st.session_state.room.continue_discussion(continue_rounds) | |
| st.session_state.max_rounds = st.session_state.room.max_rounds | |
| st.session_state.current_round = 0 | |
| st.session_state.current_agent_index = 0 | |
| # Main content area | |
| if st.session_state.discussion_completed: | |
| show_discussion_history() | |
| show_summary() | |
| #**** UNCOMMENT TO SAVE CONVERSATION LOGS **** | |
| # save_conversation_log() # Save the log when the discussion is completed | |
| else: | |
| if st.session_state.discussion_started: | |
| st.write(f"Current Round: {st.session_state.current_round + 1} / {st.session_state.max_rounds}") | |
| # Display message history | |
| for message in st.session_state.messages: | |
| with st.chat_message(message["role"]): | |
| st.markdown(f"**{message['role']}**: {message['message']}") | |
| # Execute next response | |
| if st.session_state.current_round < st.session_state.max_rounds: | |
| execute_round() | |
| if __name__ == "__main__": | |
| main() |