├── README.md ├── LICENSE ├── templates └── home.html └── GPT-Journey.py /README.md: -------------------------------------------------------------------------------- 1 | # GPT-Journey 2 | Building a text and image-based journey game powered by, and with, GPT 3.5 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Harrison 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ title }} 5 | 6 | 7 | 8 | 9 |
10 |

{{ title }}

11 | My Image 12 |

{{ text }}

13 | {% for button_name, message in button_messages.items() %} 14 |
15 |
16 | 17 |
18 |
19 | {% if button_states[button_name] %} 20 |

{{ message }}

21 | {% endif %} 22 | {% endfor %} 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /GPT-Journey.py: -------------------------------------------------------------------------------- 1 | # For the UI 2 | from flask import Flask, render_template, request, session 3 | # OpenAI API 4 | import openai 5 | # Regular expressions: 6 | import re 7 | 8 | # Set the OpenAI API key 9 | openai.api_key = open("key.txt", "r").read().strip("\n") 10 | 11 | # Create a new Flask app and set the secret key 12 | app = Flask(__name__) 13 | app.secret_key = "mysecretkey" 14 | 15 | # Define a function to generate an image using the OpenAI API 16 | def get_img(prompt): 17 | try: 18 | response = openai.Image.create( 19 | prompt=prompt, 20 | n=1, 21 | size="512x512" 22 | ) 23 | img_url = response.data[0].url 24 | except Exception as e: 25 | # if it fails (e.g. if the API detects an unsafe image), use a default image 26 | img_url = "https://pythonprogramming.net/static/images/imgfailure.png" 27 | return img_url 28 | 29 | 30 | # Define a function to generate a chat response using the OpenAI API 31 | def chat(inp, message_history, role="user"): 32 | 33 | # Append the input message to the message history 34 | message_history.append({"role": role, "content": f"{inp}"}) 35 | 36 | # Generate a chat response using the OpenAI API 37 | completion = openai.ChatCompletion.create( 38 | model="gpt-3.5-turbo", 39 | messages=message_history 40 | ) 41 | 42 | # Grab just the text from the API completion response 43 | reply_content = completion.choices[0].message.content 44 | 45 | # Append the generated response to the message history 46 | message_history.append({"role": "assistant", "content": f"{reply_content}"}) 47 | 48 | # Return the generated response and the updated message history 49 | return reply_content, message_history 50 | 51 | 52 | # Define the homepage route for the Flask app 53 | @app.route('/', methods=['GET', 'POST']) 54 | def home(): 55 | # Page's title: 56 | title = "GPT-Journey" 57 | 58 | # Initialize the button messages and button states dictionaries 59 | button_messages = {} 60 | button_states = {} 61 | 62 | # If the request method is GET (i.e., the page has just been loaded), set up the initial chat 63 | if request.method == 'GET': 64 | 65 | # Initialize the message history 66 | session['message_history'] = [{"role": "user", "content": """You are an interactive story game bot that proposes some hypothetical fantastical situation where the user needs to pick from 2-4 options that you provide. Once the user picks one of those options, you will then state what happens next and present new options, and this then repeats. If you understand, say, OK, and begin when I say "begin." When you present the story and options, present just the story and start immediately with the story, no further commentary, and then options like "Option 1:" "Option 2:" ...etc."""}, 67 | {"role": "assistant", "content": f"""OK, I understand. Begin when you're ready."""}] 68 | 69 | # Retrieve the message history from the session 70 | message_history = session['message_history'] 71 | 72 | # Generate a chat response with an initial message ("Begin") 73 | reply_content, message_history = chat("Begin", message_history) 74 | 75 | # Extract the text from the response 76 | text = reply_content.split("Option 1")[0] 77 | 78 | # Using regex, grab the natural language options from the response 79 | options = re.findall(r"Option \d:.*", reply_content) 80 | 81 | # Create a dictionary of button messages 82 | for i, option in enumerate(options): 83 | button_messages[f"button{i+1}"] = option 84 | 85 | # Initialize the button states 86 | for button_name in button_messages.keys(): 87 | button_states[button_name] = False 88 | 89 | 90 | # If the request method is POST (i.e., a button has been clicked), update the chat 91 | message = None 92 | button_name = None 93 | if request.method == 'POST': 94 | 95 | # Retrieve the message history and button messages from the session 96 | message_history = session['message_history'] 97 | button_messages = session['button_messages'] 98 | 99 | # Get the name of the button that was clicked *** 100 | button_name = request.form.get('button_name') 101 | 102 | # Set the state of the button to "True" 103 | button_states[button_name] = True 104 | 105 | # Get the message associated with the clicked button 106 | message = button_messages.get(button_name) 107 | 108 | # Generate a chat response with the clicked message 109 | reply_content, message_history = chat(message, message_history) 110 | 111 | # Extract the text and options from the response 112 | text = reply_content.split("Option 1")[0] 113 | options = re.findall(r"Option \d:.*", reply_content) 114 | 115 | # Update the button messages and states 116 | button_messages = {} 117 | for i, option in enumerate(options): 118 | button_messages[f"button{i+1}"] = option 119 | for button_name in button_messages.keys(): 120 | button_states[button_name] = False 121 | 122 | # Store the updated message history and button messages in the session 123 | session['message_history'] = message_history 124 | session['button_messages'] = button_messages 125 | 126 | # Generate an image based on the chat response text 127 | image_url = get_img(text) 128 | 129 | # Render the template with the updated information 130 | return render_template('home.html', title=title, text=text, image_url=image_url, button_messages=button_messages, button_states=button_states, message=message) 131 | 132 | # Run the Flask app 133 | if __name__ == '__main__': 134 | app.run(debug=True, port=5001) 135 | --------------------------------------------------------------------------------