Dirk Haupt commited on
Commit
480eede
·
1 Parent(s): 2065479

add timer and game phases

Browse files
Files changed (2) hide show
  1. app_streamlit_old.py +79 -0
  2. timer.py +52 -0
app_streamlit_old.py CHANGED
@@ -3,6 +3,10 @@ import asyncio
3
  from quickstart import WebSocketHandler, AsyncHumeClient, ChatConnectOptions, MicrophoneInterface, SubscribeEvent
4
  import os
5
  from dotenv import load_dotenv
 
 
 
 
6
 
7
  # Page config
8
  st.set_page_config(
@@ -21,6 +25,18 @@ if 'messages' not in st.session_state:
21
  st.session_state.messages = []
22
  st.session_state.recording = False
23
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  class StreamlitWebSocketHandler(WebSocketHandler):
25
  async def on_message(self, message: SubscribeEvent):
26
  await super().on_message(message)
@@ -75,6 +91,21 @@ async def run_chat():
75
 
76
  await microphone_task
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  # Display welcome message
79
  if len(st.session_state.messages) == 0:
80
  st.info("Welcome to the Hume.ai Voice Chat Demo! Click the button below to start chatting.")
@@ -98,3 +129,51 @@ with col2:
98
  st.session_state.messages = []
99
  st.session_state.recording = False
100
  st.rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  from quickstart import WebSocketHandler, AsyncHumeClient, ChatConnectOptions, MicrophoneInterface, SubscribeEvent
4
  import os
5
  from dotenv import load_dotenv
6
+ from dataclasses import dataclass, field
7
+ from typing import List, Dict
8
+ import time
9
+ from timer import AsyncTimer
10
 
11
  # Page config
12
  st.set_page_config(
 
25
  st.session_state.messages = []
26
  st.session_state.recording = False
27
 
28
+ @dataclass
29
+ class GameState:
30
+ round: int = 1
31
+ chat_group_id: str = None
32
+ user_decisions: List[str] = field(default_factory=list)
33
+ ai_decisions: List[str] = field(default_factory=list)
34
+ conversation_history: List[Dict] = field(default_factory=list)
35
+ emotion_history: List[Dict] = field(default_factory=list)
36
+ scores: Dict[str, int] = field(default_factory=lambda: {"user": 0, "ai": 0})
37
+ phase: str = "INIT" # INIT, CONVERSATION, USER_DECISION, AI_DECISION, RESULTS, NEXT_ROUND
38
+ timer_start: float = None
39
+
40
  class StreamlitWebSocketHandler(WebSocketHandler):
41
  async def on_message(self, message: SubscribeEvent):
42
  await super().on_message(message)
 
91
 
92
  await microphone_task
93
 
94
+ async def handle_conversation_phase():
95
+ """Handle the CONVERSATION phase with timer and chat"""
96
+ timer_placeholder = st.empty()
97
+
98
+ async def on_timer_complete():
99
+ st.session_state.game.phase = "USER_DECISION"
100
+ st.session_state.game.timer_start = None
101
+ st.rerun()
102
+
103
+ timer = AsyncTimer(30, on_timer_complete, timer_placeholder)
104
+ await asyncio.gather(
105
+ timer.start(),
106
+ run_chat()
107
+ )
108
+
109
  # Display welcome message
110
  if len(st.session_state.messages) == 0:
111
  st.info("Welcome to the Hume.ai Voice Chat Demo! Click the button below to start chatting.")
 
129
  st.session_state.messages = []
130
  st.session_state.recording = False
131
  st.rerun()
132
+
133
+ # Initialize session state
134
+ if 'game' not in st.session_state:
135
+ st.session_state.game = GameState()
136
+
137
+ # Game UI based on phase
138
+ if st.session_state.game.phase == "INIT":
139
+ if st.button("Start Game"):
140
+ st.session_state.game.phase = "CONVERSATION"
141
+ st.session_state.game.timer_start = time.time()
142
+ st.rerun()
143
+
144
+ elif st.session_state.game.phase == "CONVERSATION":
145
+ asyncio.run(handle_conversation_phase())
146
+
147
+ elif st.session_state.game.phase == "USER_DECISION":
148
+ col1, col2 = st.columns(2)
149
+ with col1:
150
+ if st.button("Cooperate"):
151
+ st.session_state.game.user_decisions.append("C")
152
+ st.session_state.game.phase = "AI_DECISION"
153
+ st.rerun()
154
+ with col2:
155
+ if st.button("Defect"):
156
+ st.session_state.game.user_decisions.append("D")
157
+ st.session_state.game.phase = "AI_DECISION"
158
+ st.rerun()
159
+
160
+ elif st.session_state.game.phase == "AI_DECISION":
161
+ # Run AI decision chat
162
+ asyncio.run(run_chat())
163
+
164
+ elif st.session_state.game.phase == "RESULTS":
165
+ # Display round results
166
+ # Update scores
167
+ if st.button("Next Round"):
168
+ st.session_state.game.round += 1
169
+ st.session_state.game.phase = "CONVERSATION"
170
+ st.session_state.game.timer_start = time.time()
171
+ st.rerun()
172
+
173
+ def check_timer():
174
+ if st.session_state.game.timer_start:
175
+ elapsed = time.time() - st.session_state.game.timer_start
176
+ if elapsed >= 30:
177
+ st.session_state.game.phase = "USER_DECISION"
178
+ st.session_state.game.timer_start = None
179
+ st.rerun()
timer.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import time
3
+ import streamlit as st
4
+ from typing import Callable, Optional
5
+
6
+ class AsyncTimer:
7
+ def __init__(self, duration: int, on_complete: Callable, placeholder: Optional[st.empty] = None):
8
+ """
9
+ Initialize async timer
10
+
11
+ Args:
12
+ duration: Duration in seconds
13
+ on_complete: Callback function to run when timer completes
14
+ placeholder: Optional streamlit placeholder to display timer
15
+ """
16
+ self.duration = duration
17
+ self.on_complete = on_complete
18
+ self.placeholder = placeholder or st.empty()
19
+ self.start_time = None
20
+ self.is_running = False
21
+
22
+ def format_time(self, seconds: int) -> str:
23
+ """Format seconds into MM:SS"""
24
+ mm, ss = seconds//60, seconds%60
25
+ return f"{mm:02d}:{ss:02d}"
26
+
27
+ async def start(self):
28
+ """Start the countdown timer"""
29
+ self.start_time = time.time()
30
+ self.is_running = True
31
+
32
+ while self.is_running:
33
+ elapsed = int(time.time() - self.start_time)
34
+ remaining = max(0, self.duration - elapsed)
35
+
36
+ # Update display
37
+ self.placeholder.metric(
38
+ "Time Remaining",
39
+ self.format_time(remaining)
40
+ )
41
+
42
+ # Check if timer completed
43
+ if remaining <= 0:
44
+ self.is_running = False
45
+ await self.on_complete()
46
+ break
47
+
48
+ await asyncio.sleep(0.1) # Small delay to prevent excessive updates
49
+
50
+ def stop(self):
51
+ """Stop the timer"""
52
+ self.is_running = False