Spaces:
Running
Running
Delete interface
Browse files- interface/__init__.py +0 -0
- interface/app.py +0 -245
interface/__init__.py
DELETED
File without changes
|
interface/app.py
DELETED
@@ -1,245 +0,0 @@
|
|
1 |
-
import gradio as gr
|
2 |
-
from src.game_logic import RPGGame
|
3 |
-
from src.database import interactions
|
4 |
-
|
5 |
-
def create_interface():
|
6 |
-
game = RPGGame()
|
7 |
-
|
8 |
-
with gr.Blocks(theme=gr.themes.Base()) as demo:
|
9 |
-
# Header with title and description
|
10 |
-
gr.Markdown(
|
11 |
-
"""
|
12 |
-
<div style="margin-bottom: 20px;">
|
13 |
-
<h1 style="margin-bottom: 0.5em;">🎲 AI RPG Adventure</h1>
|
14 |
-
<p>An interactive RPG experience from Pixeltable and powered by OpenAI! Get started with an example below.</p>
|
15 |
-
</div>
|
16 |
-
"""
|
17 |
-
)
|
18 |
-
|
19 |
-
# Side-by-side accordions
|
20 |
-
with gr.Row():
|
21 |
-
with gr.Column():
|
22 |
-
with gr.Accordion("🎯 What does it do?", open=False):
|
23 |
-
gr.Markdown("""
|
24 |
-
This AI RPG Adventure demonstrates Pixeltable's capabilities:
|
25 |
-
|
26 |
-
- 🎮 Creates dynamic, AI-driven interactive stories
|
27 |
-
- 🔄 Maintains game state and history using Pixeltable tables
|
28 |
-
- 💭 Generates contextual options based on player actions
|
29 |
-
- 📝 Processes natural language inputs for custom actions
|
30 |
-
- 🤖 Uses LLMs to create engaging narratives
|
31 |
-
- 📊 Tracks and displays game progression
|
32 |
-
|
33 |
-
Perfect for understanding how Pixeltable can manage complex,
|
34 |
-
stateful applications with AI integration! ✨
|
35 |
-
""")
|
36 |
-
|
37 |
-
with gr.Column():
|
38 |
-
with gr.Accordion("🛠️ How does it work?", open=False):
|
39 |
-
gr.Markdown("""
|
40 |
-
The app leverages several Pixeltable features:
|
41 |
-
|
42 |
-
1. 📦 **Data Management**: Uses Pixeltable tables to store game state,
|
43 |
-
player actions, and AI responses
|
44 |
-
|
45 |
-
2. 🤖 **AI Integration**: Seamlessly connects with language models
|
46 |
-
for story generation and response processing
|
47 |
-
|
48 |
-
3. 🔄 **State Tracking**: Maintains session history and player
|
49 |
-
choices using Pixeltable's computed columns
|
50 |
-
|
51 |
-
4. ⚙️ **Custom Processing**: Uses Pixeltable UDFs to handle game
|
52 |
-
logic and AI prompt generation
|
53 |
-
|
54 |
-
5. 🎯 **Interactive Flow**: Processes player inputs and generates
|
55 |
-
contextual responses in real-time
|
56 |
-
""")
|
57 |
-
|
58 |
-
with gr.Row():
|
59 |
-
# Setup column
|
60 |
-
with gr.Column():
|
61 |
-
player_name = gr.Textbox(
|
62 |
-
label="👤 Your Character's Name",
|
63 |
-
placeholder="Enter your character's name..."
|
64 |
-
)
|
65 |
-
genre = gr.Dropdown(
|
66 |
-
choices=[
|
67 |
-
"🧙♂️ Fantasy",
|
68 |
-
"🚀 Sci-Fi",
|
69 |
-
"👻 Horror",
|
70 |
-
"🔍 Mystery",
|
71 |
-
"🌋 Post-Apocalyptic",
|
72 |
-
"🤖 Cyberpunk",
|
73 |
-
"⚙️ Steampunk"
|
74 |
-
],
|
75 |
-
label="🎭 Choose Your Genre"
|
76 |
-
)
|
77 |
-
scenario = gr.Textbox(
|
78 |
-
label="📖 Starting Scenario",
|
79 |
-
lines=3,
|
80 |
-
placeholder="Describe the initial setting and situation..."
|
81 |
-
)
|
82 |
-
start_button = gr.Button("🎮 Begin Adventure", variant="primary")
|
83 |
-
|
84 |
-
# Game interaction column
|
85 |
-
with gr.Column():
|
86 |
-
story_display = gr.Textbox(
|
87 |
-
label="📜 Story",
|
88 |
-
lines=8,
|
89 |
-
interactive=False
|
90 |
-
)
|
91 |
-
|
92 |
-
gr.Markdown("### 🎯 Choose Your Action")
|
93 |
-
|
94 |
-
with gr.Row():
|
95 |
-
with gr.Column():
|
96 |
-
action_input = gr.Radio(
|
97 |
-
choices=[],
|
98 |
-
label="🎲 Select an action or write your own below:",
|
99 |
-
interactive=True
|
100 |
-
)
|
101 |
-
custom_action = gr.Textbox(
|
102 |
-
label="✨ Custom Action",
|
103 |
-
placeholder="Write your own action here...",
|
104 |
-
lines=2
|
105 |
-
)
|
106 |
-
submit_action = gr.Button("⚡ Take Action", variant="secondary")
|
107 |
-
|
108 |
-
# History display
|
109 |
-
history_df = gr.Dataframe(
|
110 |
-
headers=["📅 Turn", "🎯 Player Action", "💬 Game Response"],
|
111 |
-
label="📚 Adventure History",
|
112 |
-
wrap=True,
|
113 |
-
row_count=5,
|
114 |
-
col_count=(3, "fixed")
|
115 |
-
)
|
116 |
-
def start_new_game(name, genre_choice, scenario_text):
|
117 |
-
if not name or not genre_choice or not scenario_text:
|
118 |
-
return "Please fill in all fields before starting.", [], "", []
|
119 |
-
|
120 |
-
try:
|
121 |
-
_, initial_response = game.start_game(name, genre_choice, scenario_text)
|
122 |
-
|
123 |
-
# Get options from the initial response
|
124 |
-
options = interactions.select(interactions.options).where(
|
125 |
-
(interactions.session_id == game.current_session_id) &
|
126 |
-
(interactions.turn_number == 0)
|
127 |
-
).collect()['options'][0]
|
128 |
-
|
129 |
-
# Get initial history
|
130 |
-
history_df = interactions.select(
|
131 |
-
turn=interactions.turn_number,
|
132 |
-
action=interactions.player_input,
|
133 |
-
response=interactions.story_text
|
134 |
-
).where(
|
135 |
-
interactions.session_id == game.current_session_id
|
136 |
-
).order_by(
|
137 |
-
interactions.turn_number
|
138 |
-
).collect().to_pandas()
|
139 |
-
|
140 |
-
history_data = [
|
141 |
-
[str(row['turn']), row['action'], row['response']]
|
142 |
-
for _, row in history_df.iterrows()
|
143 |
-
]
|
144 |
-
|
145 |
-
return initial_response, gr.Radio(choices=options, interactive=True), "", history_data
|
146 |
-
except Exception as e:
|
147 |
-
return f"Error starting game: {str(e)}", [], "", []
|
148 |
-
|
149 |
-
def process_player_action(action_choice, custom_action):
|
150 |
-
try:
|
151 |
-
# Use custom action if provided, otherwise use selected choice
|
152 |
-
action = custom_action if custom_action else action_choice
|
153 |
-
if not action:
|
154 |
-
return "Please either select an action or write your own.", [], "", []
|
155 |
-
|
156 |
-
response = game.process_action(action)
|
157 |
-
|
158 |
-
# Get new options
|
159 |
-
options = interactions.select(interactions.options).where(
|
160 |
-
(interactions.session_id == game.current_session_id) &
|
161 |
-
(interactions.turn_number == game.turn_number)
|
162 |
-
).collect()['options'][0]
|
163 |
-
|
164 |
-
# Get updated history
|
165 |
-
history_df = interactions.select(
|
166 |
-
turn=interactions.turn_number,
|
167 |
-
action=interactions.player_input,
|
168 |
-
response=interactions.story_text
|
169 |
-
).where(
|
170 |
-
interactions.session_id == game.current_session_id
|
171 |
-
).order_by(
|
172 |
-
interactions.turn_number
|
173 |
-
).collect().to_pandas()
|
174 |
-
|
175 |
-
history_data = [
|
176 |
-
[str(row['turn']), row['action'], row['response']]
|
177 |
-
for _, row in history_df.iterrows()
|
178 |
-
]
|
179 |
-
|
180 |
-
return response, gr.Radio(choices=options, interactive=True), "", history_data
|
181 |
-
except Exception as e:
|
182 |
-
return f"Error: {str(e)}", [], "", []
|
183 |
-
|
184 |
-
# Connect the start button
|
185 |
-
start_button.click(
|
186 |
-
start_new_game,
|
187 |
-
inputs=[player_name, genre, scenario],
|
188 |
-
outputs=[story_display, action_input, custom_action, history_df]
|
189 |
-
)
|
190 |
-
|
191 |
-
# Single action submit button
|
192 |
-
submit_action.click(
|
193 |
-
process_player_action,
|
194 |
-
inputs=[action_input, custom_action],
|
195 |
-
outputs=[story_display, action_input, custom_action, history_df]
|
196 |
-
)
|
197 |
-
|
198 |
-
# Example scenarios
|
199 |
-
gr.Markdown("### 💫 Example Adventures")
|
200 |
-
gr.Examples(
|
201 |
-
examples=[
|
202 |
-
["Eldric", "🧙♂️ Fantasy", "You find yourself in an ancient forest clearing, standing before a mysterious glowing portal. Your journey begins..."],
|
203 |
-
["Commander Nova", "🚀 Sci-Fi", "Aboard the starship Nebula, alarms blare as unknown entities approach. The fate of the crew rests in your hands..."],
|
204 |
-
["Detective Blake", "🔍 Mystery", "In the fog-shrouded streets of Victorian London, a peculiar letter arrives at your doorstep..."],
|
205 |
-
],
|
206 |
-
inputs=[player_name, genre, scenario]
|
207 |
-
)
|
208 |
-
|
209 |
-
# Footer with links
|
210 |
-
gr.HTML(
|
211 |
-
"""
|
212 |
-
<div style="margin-top: 2rem; padding-top: 1rem; border-top: 1px solid #e5e7eb;">
|
213 |
-
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 1rem;">
|
214 |
-
<div style="flex: 1;">
|
215 |
-
<h4 style="margin: 0; color: #374151;">🚀 Built with Pixeltable</h4>
|
216 |
-
<p style="margin: 0.5rem 0; color: #6b7280;">
|
217 |
-
AI Data infrastructure providing a declarative, incremental approach for multimodal workloads.
|
218 |
-
</p>
|
219 |
-
</div>
|
220 |
-
<div style="flex: 1;">
|
221 |
-
<h4 style="margin: 0; color: #374151;">🔗 Resources</h4>
|
222 |
-
<div style="display: flex; gap: 1.5rem; margin-top: 0.5rem;">
|
223 |
-
<a href="https://github.com/pixeltable/pixeltable" target="_blank" style="color: #4F46E5; text-decoration: none; display: flex; align-items: center; gap: 0.25rem;">
|
224 |
-
💻 GitHub
|
225 |
-
</a>
|
226 |
-
<a href="https://docs.pixeltable.com" target="_blank" style="color: #4F46E5; text-decoration: none; display: flex; align-items: center; gap: 0.25rem;">
|
227 |
-
📚 Documentation
|
228 |
-
</a>
|
229 |
-
<a href="https://huggingface.co/Pixeltable" target="_blank" style="color: #4F46E5; text-decoration: none; display: flex; align-items: center; gap: 0.25rem;">
|
230 |
-
🤗 Hugging Face
|
231 |
-
</a>
|
232 |
-
</div>
|
233 |
-
</div>
|
234 |
-
</div>
|
235 |
-
<p style="margin: 1rem 0 0; text-align: center; color: #9CA3AF; font-size: 0.875rem;">
|
236 |
-
✨ © 2024 Pixeltable. This demo is open source and available on
|
237 |
-
<a href="https://huggingface.co/spaces/Pixeltable/AI-RPG-Adventure" target="_blank" style="color: #4F46E5; text-decoration: none;">
|
238 |
-
Hugging Face Spaces 🚀
|
239 |
-
</a>
|
240 |
-
</p>
|
241 |
-
</div>
|
242 |
-
"""
|
243 |
-
)
|
244 |
-
|
245 |
-
return demo
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|