shukdevdatta123 commited on
Commit
300b2d5
·
verified ·
1 Parent(s): 39b5ad3

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +347 -0
app.py ADDED
@@ -0,0 +1,347 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ from langchain.chat_models import ChatOpenAI
4
+ from langchain.prompts import ChatPromptTemplate
5
+ from langchain.chains import LLMChain, SequentialChain
6
+ from langchain.memory import ConversationBufferMemory
7
+ import random
8
+
9
+ # Global variables
10
+ current_story = ""
11
+ story_branches = {}
12
+ story_history = []
13
+
14
+ def generate_story_idea(llm, genre, theme, length):
15
+ """Generate a story idea based on user inputs"""
16
+ idea_prompt = ChatPromptTemplate.from_template(
17
+ """You are a creative writing assistant.
18
+ Generate a compelling story idea for a {length} story in the {genre} genre
19
+ that explores the theme of {theme}.
20
+ Include a brief plot outline, main character, and setting.
21
+ Respond with just the idea, no additional commentary.
22
+ """
23
+ )
24
+
25
+ idea_chain = LLMChain(llm=llm, prompt=idea_prompt, output_key="story_idea")
26
+ return idea_chain.run(genre=genre, theme=theme, length=length)
27
+
28
+ def create_story_beginning(llm, story_idea):
29
+ """Create the beginning of a story based on the idea"""
30
+ beginning_prompt = ChatPromptTemplate.from_template(
31
+ """You are a creative writing assistant.
32
+ Based on this story idea: {story_idea}
33
+
34
+ Write an engaging opening for this story that introduces the main character and setting.
35
+ Make it compelling and hook the reader immediately.
36
+ Write approximately 250-350 words.
37
+ """
38
+ )
39
+
40
+ beginning_chain = LLMChain(llm=llm, prompt=beginning_prompt, output_key="story_beginning")
41
+ return beginning_chain.run(story_idea=story_idea)
42
+
43
+ def continue_linear_story(llm, story_so_far):
44
+ """Continue a linear story based on the story so far"""
45
+ continue_prompt = ChatPromptTemplate.from_template(
46
+ """You are a creative writing assistant.
47
+ Continue this story:
48
+
49
+ {story_so_far}
50
+
51
+ Write the next part of the story (approximately 250-350 words), advancing the plot in an interesting way.
52
+ End at a point that feels satisfying but leaves room for more story.
53
+ """
54
+ )
55
+
56
+ continue_chain = LLMChain(llm=llm, prompt=continue_prompt, output_key="story_continuation")
57
+ return continue_chain.run(story_so_far=story_so_far)
58
+
59
+ def generate_story_branches(llm, story_so_far):
60
+ """Generate three possible story continuations as branches"""
61
+ branch_prompt = ChatPromptTemplate.from_template(
62
+ """You are a creative writing assistant.
63
+ Based on this story so far:
64
+
65
+ {story_so_far}
66
+
67
+ Generate THREE possible directions the story could take next. For each:
68
+ 1. Provide a brief title (10 words or less)
69
+ 2. Write a short description (1-2 sentences)
70
+
71
+ Format as:
72
+ Option 1: [Title]
73
+ [Description]
74
+
75
+ Option 2: [Title]
76
+ [Description]
77
+
78
+ Option 3: [Title]
79
+ [Description]
80
+ """
81
+ )
82
+
83
+ branch_chain = LLMChain(llm=llm, prompt=branch_prompt, output_key="story_branches")
84
+ branches_text = branch_chain.run(story_so_far=story_so_far)
85
+
86
+ # Parse the branches
87
+ branches = []
88
+ lines = branches_text.strip().split('\n')
89
+ current_option = None
90
+ current_description = ""
91
+
92
+ for line in lines:
93
+ if line.startswith("Option "):
94
+ if current_option:
95
+ branches.append((current_option, current_description.strip()))
96
+ current_option = line.split(": ", 1)[1] if ": " in line else line
97
+ current_description = ""
98
+ elif current_option is not None:
99
+ current_description += line + " "
100
+
101
+ if current_option:
102
+ branches.append((current_option, current_description.strip()))
103
+
104
+ return branches
105
+
106
+ def continue_branch(llm, story_so_far, branch_title, branch_description):
107
+ """Continue the story based on the selected branch"""
108
+ branch_continue_prompt = ChatPromptTemplate.from_template(
109
+ """You are a creative writing assistant.
110
+ Continue this story:
111
+
112
+ {story_so_far}
113
+
114
+ The story should now follow this direction:
115
+ {branch_title} - {branch_description}
116
+
117
+ Write the next part of the story (approximately 250-350 words) following this direction.
118
+ Make it engaging and consistent with what came before.
119
+ """
120
+ )
121
+
122
+ branch_chain = LLMChain(llm=llm, prompt=branch_continue_prompt, output_key="branch_continuation")
123
+ return branch_chain.run(
124
+ story_so_far=story_so_far,
125
+ branch_title=branch_title,
126
+ branch_description=branch_description
127
+ )
128
+
129
+ def initialize_story(api_key, genre, theme, length):
130
+ """Initialize a new story with the given parameters"""
131
+ global current_story, story_branches, story_history
132
+
133
+ try:
134
+ # Initialize LLM
135
+ llm = ChatOpenAI(
136
+ openai_api_key=api_key,
137
+ model="gpt-4-turbo",
138
+ temperature=0.7
139
+ )
140
+
141
+ # Reset story state
142
+ current_story = ""
143
+ story_branches = {}
144
+ story_history = []
145
+
146
+ # Generate story idea and beginning
147
+ story_idea = generate_story_idea(llm, genre, theme, length)
148
+ story_beginning = create_story_beginning(llm, story_idea)
149
+
150
+ current_story = story_beginning
151
+ story_history.append(current_story)
152
+
153
+ # Return the story beginning and available actions
154
+ return (
155
+ f"Story Idea:\n{story_idea}\n\n" +
156
+ f"Story Beginning:\n{story_beginning}",
157
+ gr.update(visible=True),
158
+ gr.update(visible=True),
159
+ gr.update(visible=True)
160
+ )
161
+ except Exception as e:
162
+ return f"Error initializing story: {str(e)}", gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)
163
+
164
+ def continue_story(api_key):
165
+ """Continue the linear story"""
166
+ global current_story, story_history
167
+
168
+ try:
169
+ # Initialize LLM
170
+ llm = ChatOpenAI(
171
+ openai_api_key=api_key,
172
+ model="gpt-4-turbo",
173
+ temperature=0.7
174
+ )
175
+
176
+ # Continue the story
177
+ continuation = continue_linear_story(llm, current_story)
178
+ current_story += "\n\n" + continuation
179
+ story_history.append(continuation)
180
+
181
+ return current_story, gr.update(value="Story continued successfully!")
182
+ except Exception as e:
183
+ return current_story, gr.update(value=f"Error continuing story: {str(e)}")
184
+
185
+ def generate_branches(api_key):
186
+ """Generate branching options for the story"""
187
+ global current_story, story_branches
188
+
189
+ try:
190
+ # Initialize LLM
191
+ llm = ChatOpenAI(
192
+ openai_api_key=api_key,
193
+ model="gpt-4-turbo",
194
+ temperature=0.8 # Higher temperature for more creative branches
195
+ )
196
+
197
+ # Generate branches
198
+ branches = generate_story_branches(llm, current_story)
199
+ story_branches = {f"Option {i+1}: {title}": (title, desc) for i, (title, desc) in enumerate(branches)}
200
+
201
+ # Create formatted output for display
202
+ branches_output = "\n\n".join([f"{option}\n{desc}" for option, (_, desc) in story_branches.items()])
203
+
204
+ # Create radio options
205
+ radio_options = list(story_branches.keys())
206
+
207
+ return branches_output, gr.update(choices=radio_options, value=radio_options[0] if radio_options else None, visible=True), gr.update(visible=True)
208
+ except Exception as e:
209
+ return f"Error generating branches: {str(e)}", gr.update(visible=False), gr.update(visible=False)
210
+
211
+ def select_branch(api_key, selected_branch):
212
+ """Continue the story based on the selected branch"""
213
+ global current_story, story_branches, story_history
214
+
215
+ try:
216
+ if not selected_branch or selected_branch not in story_branches:
217
+ return current_story, "Please select a valid branch."
218
+
219
+ # Initialize LLM
220
+ llm = ChatOpenAI(
221
+ openai_api_key=api_key,
222
+ model="gpt-4-turbo",
223
+ temperature=0.7
224
+ )
225
+
226
+ # Get branch details
227
+ branch_title, branch_description = story_branches[selected_branch]
228
+
229
+ # Continue along the selected branch
230
+ continuation = continue_branch(llm, current_story, branch_title, branch_description)
231
+
232
+ # Update story state
233
+ current_story += f"\n\n[{selected_branch}]\n\n" + continuation
234
+ story_history.append(f"[Branch: {branch_title}] {continuation}")
235
+
236
+ return current_story, gr.update(value="Branch selected and story continued!")
237
+ except Exception as e:
238
+ return current_story, gr.update(value=f"Error selecting branch: {str(e)}")
239
+
240
+ def create_app():
241
+ """Create the Gradio interface"""
242
+ with gr.Blocks(title="AI Story Generator", theme=gr.themes.Soft()) as app:
243
+ gr.Markdown("# 📚 AI-Powered Story Generator")
244
+ gr.Markdown("Create interactive stories with branching narratives using OpenAI and LangChain")
245
+
246
+ with gr.Row():
247
+ with gr.Column(scale=1):
248
+ api_key = gr.Textbox(
249
+ label="OpenAI API Key",
250
+ placeholder="Enter your OpenAI API key here",
251
+ type="password"
252
+ )
253
+
254
+ with gr.Group():
255
+ gr.Markdown("### Story Parameters")
256
+ genre = gr.Dropdown(
257
+ label="Genre",
258
+ choices=[
259
+ "Fantasy", "Science Fiction", "Mystery", "Romance",
260
+ "Horror", "Adventure", "Historical Fiction", "Comedy"
261
+ ],
262
+ value="Fantasy"
263
+ )
264
+ theme = gr.Textbox(
265
+ label="Theme",
266
+ placeholder="e.g., Redemption, Loss, Discovery",
267
+ value="Adventure"
268
+ )
269
+ length = gr.Radio(
270
+ label="Story Length",
271
+ choices=["Short Story", "Novella", "Novel Chapter"],
272
+ value="Short Story"
273
+ )
274
+
275
+ with gr.Row():
276
+ start_btn = gr.Button("Start New Story", variant="primary")
277
+
278
+ with gr.Row():
279
+ continue_btn = gr.Button("Continue Story", visible=False)
280
+ branch_btn = gr.Button("Generate Branch Options", visible=False)
281
+
282
+ status = gr.Textbox(label="Status", value="", visible=True)
283
+
284
+ with gr.Group(visible=False) as branch_group:
285
+ branch_output = gr.Textbox(label="Story Branches")
286
+ branch_selection = gr.Radio(label="Select a Branch", choices=[])
287
+ select_branch_btn = gr.Button("Continue with Selected Branch")
288
+
289
+ with gr.Column(scale=2):
290
+ story_output = gr.Textbox(
291
+ label="Generated Story",
292
+ placeholder="Your story will appear here...",
293
+ lines=20
294
+ )
295
+
296
+ # Define button click events
297
+ start_btn.click(
298
+ initialize_story,
299
+ inputs=[api_key, genre, theme, length],
300
+ outputs=[story_output, continue_btn, branch_btn, branch_group]
301
+ )
302
+
303
+ continue_btn.click(
304
+ continue_story,
305
+ inputs=[api_key],
306
+ outputs=[story_output, status]
307
+ )
308
+
309
+ branch_btn.click(
310
+ generate_branches,
311
+ inputs=[api_key],
312
+ outputs=[branch_output, branch_selection, select_branch_btn]
313
+ )
314
+
315
+ select_branch_btn.click(
316
+ select_branch,
317
+ inputs=[api_key, branch_selection],
318
+ outputs=[story_output, status]
319
+ )
320
+
321
+ # Example usage
322
+ gr.Examples(
323
+ examples=[
324
+ ["Fantasy", "Coming of age", "Short Story"],
325
+ ["Science Fiction", "Artificial intelligence", "Novella"],
326
+ ["Mystery", "Betrayal", "Novel Chapter"]
327
+ ],
328
+ inputs=[genre, theme, length],
329
+ outputs=[]
330
+ )
331
+
332
+ gr.Markdown("""
333
+ ## How to Use
334
+ 1. Enter your OpenAI API key
335
+ 2. Select a genre, theme, and length
336
+ 3. Click "Start New Story" to begin
337
+ 4. Continue the linear story or generate branching options
338
+ 5. If you chose branching, select a branch to follow
339
+
340
+ This app uses LangChain to orchestrate the story generation process and OpenAI's models to create the content.
341
+ """)
342
+
343
+ return app
344
+
345
+ if __name__ == "__main__":
346
+ app = create_app()
347
+ app.launch()