Liss, Alex (NYC-HUG) commited on
Commit
50ab217
·
1 Parent(s): bb4fc9d

added static component for UI layout

Browse files
components/game_recap_component.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import os
4
+
5
+ def create_game_recap_component(game_data=None):
6
+ """
7
+ Creates a Gradio component to display game information.
8
+ Args:
9
+ game_data (dict, optional): Game data to display. If None, loads from CSV.
10
+ Returns:
11
+ gr.Column: A Gradio component displaying the game recap.
12
+ """
13
+ try:
14
+ # Load game schedule if no game data provided
15
+ if game_data is None:
16
+ current_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17
+ schedule_path = os.path.join(current_dir, "data", "april_11_multimedia_data_collect", "schedule_with_result_and_logo_urls.csv")
18
+ df = pd.read_csv(schedule_path)
19
+ game_data = df.iloc[0].to_dict() # Get first game
20
+
21
+ # Extract game details
22
+ match_number = game_data.get('Match Number', 'N/A')
23
+ date = game_data.get('Date', 'N/A')
24
+ location = game_data.get('Location', 'N/A')
25
+ home_team = game_data.get('Home Team', 'N/A')
26
+ away_team = game_data.get('Away Team', 'N/A')
27
+ home_logo = game_data.get('home_team_logo_url', '')
28
+ away_logo = game_data.get('away_team_logo_url', '')
29
+ result = game_data.get('Result', 'N/A')
30
+ game_outcome = game_data.get('game_result', 'N/A')
31
+
32
+ # Determine winner
33
+ winner = None
34
+ if result != 'N/A':
35
+ home_score, away_score = map(int, result.split('-'))
36
+ winner = home_team if home_score > away_score else away_team
37
+
38
+ # Create the component
39
+ with gr.Column(elem_classes=["game-recap-container"]) as game_recap:
40
+ # Date and Location
41
+ gr.Markdown(f"### Game {match_number} - {date}")
42
+ gr.Markdown(f"**Location:** {location}")
43
+
44
+ # Teams and Scores
45
+ with gr.Row(elem_classes=["game-recap-row"]):
46
+ # Home Team
47
+ with gr.Column(elem_classes=["team-info"]):
48
+ if home_logo:
49
+ gr.Image(home_logo, elem_classes=["team-logo"])
50
+ gr.Markdown(f"**{home_team}**", elem_classes=["team-name"] + (["winner"] if winner == home_team else []))
51
+ gr.Markdown(result.split('-')[0], elem_classes=["team-score"])
52
+
53
+ # Away Team
54
+ with gr.Column(elem_classes=["team-info"]):
55
+ if away_logo:
56
+ gr.Image(away_logo, elem_classes=["team-logo"])
57
+ gr.Markdown(f"**{away_team}**", elem_classes=["team-name"] + (["winner"] if winner == away_team else []))
58
+ gr.Markdown(result.split('-')[1], elem_classes=["team-score"])
59
+
60
+ # Game Outcome
61
+ if game_outcome != 'N/A':
62
+ gr.Markdown(f"**{game_outcome}**")
63
+
64
+ # Video Highlights (placeholder)
65
+ with gr.Row(elem_classes=["video-preview"]):
66
+ gr.Markdown("🎥 Video highlights coming soon...")
67
+
68
+ return game_recap
69
+
70
+ except Exception as e:
71
+ print(f"Error creating game recap component: {str(e)}")
72
+ # Return a simple error message component
73
+ with gr.Column() as error_component:
74
+ gr.Markdown("⚠️ Error loading game recap. Please try again later.")
75
+ return error_component
76
+
77
+ # Test the component when run directly
78
+ if __name__ == "__main__":
79
+ demo = gr.Blocks()
80
+ with demo:
81
+ game_recap = create_game_recap_component()
82
+ demo.launch()
data/april_11_multimedia_data_collect/merge_schedule_logos.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import os
3
+
4
+ # Read the CSV files
5
+ schedule_df = pd.read_csv('data/april_11_multimedia_data_collect/nfl-2024-san-francisco-49ers-with-results.csv')
6
+ logos_df = pd.read_csv('data/april_11_multimedia_data_collect/nfl_team_logos_revised.csv')
7
+
8
+ # Create dictionaries to map team names to logo URLs
9
+ home_logos = {}
10
+ away_logos = {}
11
+
12
+ for _, row in logos_df.iterrows():
13
+ home_logos[row['team_name']] = row['logo_url']
14
+ away_logos[row['team_name']] = row['logo_url']
15
+
16
+ # Add logo URL columns to the schedule dataframe
17
+ schedule_df['home_team_logo_url'] = schedule_df['Home Team'].map(home_logos)
18
+ schedule_df['away_team_logo_url'] = schedule_df['Away Team'].map(away_logos)
19
+
20
+ # Save the merged dataframe to a new CSV file
21
+ output_path = 'data/april_11_multimedia_data_collect/schedule_with_result_and_logo_urls.csv'
22
+ schedule_df.to_csv(output_path, index=False)
23
+
24
+ print(f'CSV file created successfully at {output_path}!')
data/april_11_multimedia_data_collect/schedule_with_result_and_logo_urls.csv ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Match Number,Round Number,Date,Location,Home Team,Away Team,Result,game_result,home_team_logo_url,away_team_logo_url
2
+ 1,1,10/09/2024 00:15,Levi's Stadium,San Francisco 49ers,New York Jets,32 - 19,Win,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png,https://a.espncdn.com/i/teamlogos/nfl/500/nyj.png
3
+ 28,2,15/09/2024 17:00,U.S. Bank Stadium,Minnesota Vikings,San Francisco 49ers,23 - 17,Loss,https://a.espncdn.com/i/teamlogos/nfl/500/min.png,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png
4
+ 38,3,22/09/2024 20:25,SoFi Stadium,Los Angeles Rams,San Francisco 49ers,27 - 24,Loss,https://a.espncdn.com/i/teamlogos/nfl/500/lar.png,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png
5
+ 55,4,29/09/2024 20:05,Levi's Stadium,San Francisco 49ers,New England Patriots,30 - 13,Win,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png,https://a.espncdn.com/i/teamlogos/nfl/500/ne.png
6
+ 70,5,06/10/2024 20:05,Levi's Stadium,San Francisco 49ers,Arizona Cardinals,23 - 24,Loss,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png,https://a.espncdn.com/i/teamlogos/nfl/500/ari.png
7
+ 92,6,11/10/2024 00:15,Lumen Field,Seattle Seahawks,San Francisco 49ers,24 - 36,Win,https://a.espncdn.com/i/teamlogos/nfl/500/sea.png,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png
8
+ 96,7,20/10/2024 20:25,Levi's Stadium,San Francisco 49ers,Kansas City Chiefs,18 - 28,Loss,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png,https://a.espncdn.com/i/teamlogos/nfl/500/kc.png
9
+ 109,8,28/10/2024 00:20,Levi's Stadium,San Francisco 49ers,Dallas Cowboys,30 - 24,Win,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png,https://a.espncdn.com/i/teamlogos/nfl/500/dal.png
10
+ 149,10,10/11/2024 18:00,Raymond James Stadium,Tampa Bay Buccaneers,San Francisco 49ers,20 - 23,Win,https://a.espncdn.com/i/teamlogos/nfl/500/tb.png,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png
11
+ 158,11,17/11/2024 21:05,Levi's Stadium,San Francisco 49ers,Seattle Seahawks,17 - 20,Loss,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png,https://a.espncdn.com/i/teamlogos/nfl/500/sea.png
12
+ 169,12,24/11/2024 21:25,Lambeau Field,Green Bay Packers,San Francisco 49ers,38 - 10,Loss,https://a.espncdn.com/i/teamlogos/nfl/500/gb.png,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png
13
+ 181,13,02/12/2024 01:20,Highmark Stadium,Buffalo Bills,San Francisco 49ers,35 - 10,Loss,https://a.espncdn.com/i/teamlogos/nfl/500/buf.png,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png
14
+ 199,14,08/12/2024 21:25,Levi's Stadium,San Francisco 49ers,Chicago Bears,38 - 13,Win,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png,https://a.espncdn.com/i/teamlogos/nfl/500/chi.png
15
+ 224,15,13/12/2024 01:15,Levi's Stadium,San Francisco 49ers,Los Angeles Rams,6 - 12,Loss,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png,https://a.espncdn.com/i/teamlogos/nfl/500/lar.png
16
+ 228,16,22/12/2024 21:25,Hard Rock Stadium,Miami Dolphins,San Francisco 49ers,29 - 17,Loss,https://a.espncdn.com/i/teamlogos/nfl/500/mia.png,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png
17
+ 246,17,31/12/2024 01:15,Levi's Stadium,San Francisco 49ers,Detroit Lions,34 - 40,Loss,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png,https://a.espncdn.com/i/teamlogos/nfl/500/det.png
18
+ 257,18,05/01/2025 21:25,State Farm Stadium,Arizona Cardinals,San Francisco 49ers,47 - 24,Loss,https://a.espncdn.com/i/teamlogos/nfl/500/ari.png,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png
docs/requirements.md CHANGED
@@ -359,7 +359,7 @@ Based on a review of the existing codebase and requirements, here's a structured
359
 
360
  ## 11. Feature Work Log
361
 
362
- ### Step 1.2: Team Search Feature Implementation
363
 
364
  #### Objective
365
  Implement the Team Search feature (Feature 1 from Feature Overview) with focus on game recap display functionality.
@@ -373,26 +373,29 @@ Implement the Team Search feature (Feature 1 from Feature Overview) with focus o
373
 
374
  #### Implementation Steps
375
 
376
- 1. **CSS Integration**
377
  - Add required CSS styles to the Gradio app
378
  - Ensure styles support responsive layout
379
  - Implement 49ers theme colors from Design System section
 
380
 
381
- 2. **Data Requirements Enhancement**
382
  - Review existing game score & result data
383
  - Identify home team name and logo source
384
  - Identify away team name and logo source
385
  - Document data structure requirements
 
386
 
387
- 3. **CSV File Update**
388
  - Open `schedule_with_result_april_11.csv`
389
  - Add columns for home team logo
390
  - Add columns for away team logo
391
  - Merge data from `nfl_team_logos_revised.csv`
392
  - Validate data integrity
393
  - Save as new version
 
394
 
395
- 4. **Static Gradio Component Development**
396
  - Create new component file
397
  - Implement layout matching `game recap layout example.png`:
398
  - Top row: away team elements
@@ -401,6 +404,7 @@ Implement the Team Search feature (Feature 1 from Feature Overview) with focus o
401
  - Video preview box
402
  - Use static assets for 49ers first game
403
  - Implement responsive design
 
404
 
405
  5. **Component Testing**
406
  - Add component as first element in Gradio app
 
359
 
360
  ## 11. Feature Work Log
361
 
362
+ ### Phase 1, Step 1.2: Team Search Feature Implementation
363
 
364
  #### Objective
365
  Implement the Team Search feature (Feature 1 from Feature Overview) with focus on game recap display functionality.
 
373
 
374
  #### Implementation Steps
375
 
376
+ 1. **CSS Integration ✅**
377
  - Add required CSS styles to the Gradio app
378
  - Ensure styles support responsive layout
379
  - Implement 49ers theme colors from Design System section
380
+ - **Implementation:** CSS styles were embedded directly in the Gradio app as a string variable, ensuring compatibility with both local development and Hugging Face Spaces deployment. The implementation includes comprehensive styling for all UI components with the 49ers theme colors.
381
 
382
+ 2. **Data Requirements Enhancement ✅**
383
  - Review existing game score & result data
384
  - Identify home team name and logo source
385
  - Identify away team name and logo source
386
  - Document data structure requirements
387
+ - **Implementation:** Analyzed the schedule CSV file and identified that home team names are in the "Home Team" column and away team names are in the "Away Team" column. Logo sources were identified in the "logo_url" column of the team logos CSV file, which provides direct URLs to team logos from ESPN's CDN.
388
 
389
+ 3. **CSV File Update ✅**
390
  - Open `schedule_with_result_april_11.csv`
391
  - Add columns for home team logo
392
  - Add columns for away team logo
393
  - Merge data from `nfl_team_logos_revised.csv`
394
  - Validate data integrity
395
  - Save as new version
396
+ - **Implementation:** Created a Python script to merge the schedule data with team logo URLs. The script maps team names to their corresponding logo URLs and adds two new columns to the schedule CSV: 'home_team_logo_url' and 'away_team_logo_url'. The merged data was saved as 'schedule_with_result_and_logo_urls.csv'.
397
 
398
+ 4. **Static Gradio Component Development ✅**
399
  - Create new component file
400
  - Implement layout matching `game recap layout example.png`:
401
  - Top row: away team elements
 
404
  - Video preview box
405
  - Use static assets for 49ers first game
406
  - Implement responsive design
407
+ - **Implementation:** Created a reusable game recap component in `components/game_recap_component.py` that displays team logos, names, scores, and highlights the winning team. The component uses the data from the merged CSV file and applies the 49ers theme styling. The component was integrated into the main Gradio app and tested independently.
408
 
409
  5. **Component Testing**
410
  - Add component as first element in Gradio app
gradio_app.py CHANGED
@@ -6,11 +6,10 @@ from zep_cloud.client import AsyncZep
6
  from zep_cloud.types import Message
7
 
8
  # Import our components
9
- # We need to modify the agent import to use our Gradio-compatible modules
10
- # But we can't modify agent.py directly, so we'll import it and patch it
11
  import agent
12
  from gradio_graph import graph
13
  import gradio_utils
 
14
 
15
  # Patch the agent module to use our Gradio-compatible modules
16
  import sys
@@ -21,6 +20,113 @@ sys.modules['llm'] = importlib.import_module('gradio_llm')
21
  # Now we can safely import generate_response
22
  from agent import generate_response
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  # Initialize Zep client
25
  zep_api_key = os.environ.get("ZEP_API_KEY")
26
  if not zep_api_key:
@@ -29,15 +135,25 @@ if not zep_api_key:
29
  else:
30
  zep = AsyncZep(api_key=zep_api_key)
31
 
32
- # Global state management (replacing Streamlit's session_state)
33
  class AppState:
34
  def __init__(self):
35
- self.messages = []
 
36
  self.initialized = False
37
  self.user_id = None
38
  self.session_id = None
 
 
 
 
 
 
 
 
 
 
39
 
40
- # Create a global state instance
41
  state = AppState()
42
 
43
  # Add welcome message to state
@@ -52,9 +168,9 @@ I can help you with:
52
  What would you like to know about today?
53
  """
54
 
55
- # Function to initialize the chat session
56
  async def initialize_chat():
57
- """Set up the chat session when a user connects"""
58
  try:
59
  # Generate unique identifiers for the user and session
60
  state.user_id = gradio_utils.get_user_id()
@@ -77,8 +193,8 @@ async def initialize_chat():
77
  user_id=state.user_id,
78
  )
79
 
80
-
81
- state.messages.append({"role": "assistant", "content": welcome_message})
82
  state.initialized = True
83
 
84
  return welcome_message
@@ -88,14 +204,12 @@ async def initialize_chat():
88
  print(f"Error in initialize_chat: {str(e)}")
89
  print(f"Traceback: {traceback.format_exc()}")
90
  error_message = "There was an error starting the chat. Please refresh the page and try again."
91
- state.messages.append({"role": "system", "content": error_message})
92
  return error_message
93
 
94
- # Function to process user messages
95
  async def process_message(message):
96
- """Process user messages and generate responses with the agent"""
97
- print("Starting message processing...")
98
-
99
  try:
100
  # Store user message in Zep memory if available
101
  if zep:
@@ -106,7 +220,7 @@ async def process_message(message):
106
  )
107
 
108
  # Add user message to state
109
- state.messages.append({"role": "user", "content": message})
110
 
111
  # Process with the agent
112
  print('Calling generate_response function...')
@@ -120,7 +234,7 @@ async def process_message(message):
120
  print(f"Extracted metadata: {metadata}")
121
 
122
  # Add assistant response to state
123
- state.messages.append({"role": "assistant", "content": output})
124
 
125
  # Store assistant's response in Zep memory if available
126
  if zep:
@@ -138,53 +252,53 @@ async def process_message(message):
138
  print(f"Error in process_message: {str(e)}")
139
  print(f"Traceback: {traceback.format_exc()}")
140
  error_message = "I apologize, but I encountered an error. Could you please try again?"
141
- state.messages.append({"role": "assistant", "content": error_message})
142
  return error_message
143
 
144
  # Function to handle user input in Gradio
145
  def user_input(message, history):
146
- """Handle user input and update chat history"""
147
- # Return immediately to update the UI with user message
 
 
 
 
 
 
148
  history.append({"role": "user", "content": message})
 
 
149
  return "", history
150
 
151
  # Function to generate bot response in Gradio
152
  def bot_response(history):
153
- """Generate bot response and update chat history"""
154
  # Get the last user message
155
  user_message = history[-1]["content"]
156
 
157
- # Process the message using asyncio.run
158
  response = asyncio.run(process_message(user_message))
159
 
160
- # Add the assistant's response to history
161
  history.append({"role": "assistant", "content": response})
162
 
163
  return history
164
 
165
- # Function to initialize the chat when the app starts
166
- #async def on_app_start():
167
- """Initialize the chat when the app starts"""
168
- #if not state.initialized:
169
- # welcome_message = await initialize_chat()
170
- # return [{"role": "assistant", "content": welcome_message}]
171
- #return []
172
-
173
- # Initialize the chat before creating the interface
174
- #initial_messages = asyncio.run(on_app_start())
175
- initial_messages = [{"role": "assistant", "content": welcome_message}]
176
-
177
  # Create the Gradio interface
178
- with gr.Blocks(title="49ers FanAI Hub", theme=gr.themes.Soft()) as demo:
179
  gr.Markdown("# 🏈 49ers FanAI Hub")
180
 
 
 
 
 
181
  # Chat interface
182
  chatbot = gr.Chatbot(
183
- value=initial_messages,
184
  height=500,
185
  show_label=False,
186
  elem_id="chatbot",
187
- type="messages" # Use the new messages format
188
  )
189
 
190
  # Input components
@@ -210,8 +324,6 @@ with gr.Blocks(title="49ers FanAI Hub", theme=gr.themes.Soft()) as demo:
210
  history.append({"role": "assistant", "content": response})
211
 
212
  return "", history
213
-
214
-
215
 
216
  # Set up event handlers with the combined function - explicitly disable queue
217
  msg.submit(process_and_respond, [msg, chatbot], [msg, chatbot], queue=False)
@@ -223,6 +335,4 @@ with gr.Blocks(title="49ers FanAI Hub", theme=gr.themes.Soft()) as demo:
223
 
224
  # Launch the app
225
  if __name__ == "__main__":
226
- # Disable the queue completely
227
- #demo.queue(enabled=False)
228
  demo.launch(share=True)
 
6
  from zep_cloud.types import Message
7
 
8
  # Import our components
 
 
9
  import agent
10
  from gradio_graph import graph
11
  import gradio_utils
12
+ from components.game_recap_component import create_game_recap_component
13
 
14
  # Patch the agent module to use our Gradio-compatible modules
15
  import sys
 
20
  # Now we can safely import generate_response
21
  from agent import generate_response
22
 
23
+ # Define CSS directly
24
+ css = """
25
+ /* Base styles */
26
+ body {
27
+ font-family: 'Arial', sans-serif;
28
+ background-color: #111111;
29
+ color: #E6E6E6;
30
+ }
31
+
32
+ /* Headings */
33
+ h1, h2, h3 {
34
+ color: #AA0000;
35
+ }
36
+
37
+ /* Buttons */
38
+ button {
39
+ background-color: #AA0000;
40
+ color: #FFFFFF;
41
+ border: none;
42
+ padding: 10px 20px;
43
+ border-radius: 5px;
44
+ cursor: pointer;
45
+ }
46
+
47
+ button:hover {
48
+ background-color: #B3995D;
49
+ }
50
+
51
+ /* Game Recap Component */
52
+ .game-recap-container {
53
+ background-color: #111111;
54
+ padding: 20px;
55
+ margin: 20px 0;
56
+ border-radius: 10px;
57
+ }
58
+
59
+ .game-recap-row {
60
+ display: flex;
61
+ justify-content: space-between;
62
+ align-items: center;
63
+ margin: 20px 0;
64
+ }
65
+
66
+ .team-info {
67
+ text-align: center;
68
+ }
69
+
70
+ .team-logo {
71
+ width: 100px;
72
+ height: 100px;
73
+ margin-bottom: 10px;
74
+ }
75
+
76
+ .team-name {
77
+ font-size: 1.2em;
78
+ color: #E6E6E6;
79
+ }
80
+
81
+ .team-score {
82
+ font-size: 2em;
83
+ color: #FFFFFF;
84
+ font-weight: bold;
85
+ }
86
+
87
+ .winner {
88
+ color: #B3995D;
89
+ }
90
+
91
+ .video-preview {
92
+ background-color: #222222;
93
+ padding: 15px;
94
+ border-radius: 5px;
95
+ margin-top: 20px;
96
+ }
97
+
98
+ /* Chat Interface */
99
+ .chatbot {
100
+ background-color: #111111;
101
+ border: 1px solid #333333;
102
+ border-radius: 10px;
103
+ padding: 20px;
104
+ margin: 20px 0;
105
+ }
106
+
107
+ .message-input {
108
+ background-color: #222222;
109
+ color: #E6E6E6;
110
+ border: 1px solid #333333;
111
+ border-radius: 5px;
112
+ padding: 10px;
113
+ }
114
+
115
+ .clear-button {
116
+ background-color: #AA0000;
117
+ color: #FFFFFF;
118
+ border: none;
119
+ padding: 10px 20px;
120
+ border-radius: 5px;
121
+ cursor: pointer;
122
+ margin-top: 10px;
123
+ }
124
+
125
+ .clear-button:hover {
126
+ background-color: #B3995D;
127
+ }
128
+ """
129
+
130
  # Initialize Zep client
131
  zep_api_key = os.environ.get("ZEP_API_KEY")
132
  if not zep_api_key:
 
135
  else:
136
  zep = AsyncZep(api_key=zep_api_key)
137
 
 
138
  class AppState:
139
  def __init__(self):
140
+ self.chat_history = []
141
+ self.current_game = None
142
  self.initialized = False
143
  self.user_id = None
144
  self.session_id = None
145
+ self.zep_client = None
146
+
147
+ def add_message(self, role, content):
148
+ self.chat_history.append({"role": role, "content": content})
149
+
150
+ def get_chat_history(self):
151
+ return self.chat_history
152
+
153
+ def set_current_game(self, game_data):
154
+ self.current_game = game_data
155
 
156
+ # Initialize global state
157
  state = AppState()
158
 
159
  # Add welcome message to state
 
168
  What would you like to know about today?
169
  """
170
 
171
+ # Initialize the chat session
172
  async def initialize_chat():
173
+ """Initialize the chat session with Zep and return a welcome message."""
174
  try:
175
  # Generate unique identifiers for the user and session
176
  state.user_id = gradio_utils.get_user_id()
 
193
  user_id=state.user_id,
194
  )
195
 
196
+ # Add welcome message to state
197
+ state.add_message("assistant", welcome_message)
198
  state.initialized = True
199
 
200
  return welcome_message
 
204
  print(f"Error in initialize_chat: {str(e)}")
205
  print(f"Traceback: {traceback.format_exc()}")
206
  error_message = "There was an error starting the chat. Please refresh the page and try again."
207
+ state.add_message("system", error_message)
208
  return error_message
209
 
210
+ # Process a message and return a response
211
  async def process_message(message):
212
+ """Process a message and return a response."""
 
 
213
  try:
214
  # Store user message in Zep memory if available
215
  if zep:
 
220
  )
221
 
222
  # Add user message to state
223
+ state.add_message("user", message)
224
 
225
  # Process with the agent
226
  print('Calling generate_response function...')
 
234
  print(f"Extracted metadata: {metadata}")
235
 
236
  # Add assistant response to state
237
+ state.add_message("assistant", output)
238
 
239
  # Store assistant's response in Zep memory if available
240
  if zep:
 
252
  print(f"Error in process_message: {str(e)}")
253
  print(f"Traceback: {traceback.format_exc()}")
254
  error_message = "I apologize, but I encountered an error. Could you please try again?"
255
+ state.add_message("assistant", error_message)
256
  return error_message
257
 
258
  # Function to handle user input in Gradio
259
  def user_input(message, history):
260
+ """Handle user input and update the chat history."""
261
+ # Check if this is the first message (initialization)
262
+ if not state.initialized:
263
+ # Initialize the chat session
264
+ asyncio.run(initialize_chat())
265
+ state.initialized = True
266
+
267
+ # Add the user message to the history
268
  history.append({"role": "user", "content": message})
269
+
270
+ # Clear the input field
271
  return "", history
272
 
273
  # Function to generate bot response in Gradio
274
  def bot_response(history):
275
+ """Generate a response from the bot and update the chat history."""
276
  # Get the last user message
277
  user_message = history[-1]["content"]
278
 
279
+ # Process the message and get a response
280
  response = asyncio.run(process_message(user_message))
281
 
282
+ # Add the bot response to the history
283
  history.append({"role": "assistant", "content": response})
284
 
285
  return history
286
 
 
 
 
 
 
 
 
 
 
 
 
 
287
  # Create the Gradio interface
288
+ with gr.Blocks(title="49ers FanAI Hub", theme=gr.themes.Soft(), css=css) as demo:
289
  gr.Markdown("# 🏈 49ers FanAI Hub")
290
 
291
+ # Game Recap Component
292
+ with gr.Row():
293
+ game_recap = create_game_recap_component(state.current_game)
294
+
295
  # Chat interface
296
  chatbot = gr.Chatbot(
297
+ value=state.get_chat_history(),
298
  height=500,
299
  show_label=False,
300
  elem_id="chatbot",
301
+ type="messages"
302
  )
303
 
304
  # Input components
 
324
  history.append({"role": "assistant", "content": response})
325
 
326
  return "", history
 
 
327
 
328
  # Set up event handlers with the combined function - explicitly disable queue
329
  msg.submit(process_and_respond, [msg, chatbot], [msg, chatbot], queue=False)
 
335
 
336
  # Launch the app
337
  if __name__ == "__main__":
 
 
338
  demo.launch(share=True)