Spaces:
Running
Running
File size: 9,559 Bytes
a372a6a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
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() |