· 2 years ago · Jul 23, 2023, 08:45 AM
1--[[
2----------------------------------------------------------
3GPT.lua - ChatGPT Interface for Computercraft Computers
4----------------------------------------------------------
5
6Author: Connor J. Swislow
7License: Unlicense (public domain dedication)
8
9Description:
10GPT.lua is a Lua script designed for Computercraft computers, providing an interface to interact with the OpenAI ChatGPT API. It allows users to have interactive conversations with the language model using a simple chat-based system.
11
12Requirements:
13- OpenAI API key: To use this program, you need to have an OpenAI API key. Make sure to obtain one before running the script.
14- Computercraft: This script is designed to run within the Computercraft mod for Minecraft. Ensure that you have Computercraft installed and running on your Minecraft server or local game.
15
16Installation:
171. Open a Computercraft computer in your Minecraft world.
182. Run the following command to download the GPT.lua script from Pastebin:
19 pastebin get V8FyDyWW startup
203. Restart the Computercraft computer to initialize the program.
21
22Usage:
231. After the program has been installed and the computer has restarted, it will prompt you to enter your OpenAI API key.
242. Paste your API key when prompted. This step is required to authenticate your access to the OpenAI ChatGPT API.
253. Once the API key is set, the program will display a randomly chosen title for the chatbot.
264. Type your messages to have a conversation with the chatbot. Type 'exit' to exit the program.
275. The chatbot will respond to your messages based on the conversation history and the underlying language model.
286. Enjoy interacting with the ChatGPT-powered chatbot!
29
30Note:
31- This script is dependent on an internet connection to communicate with the OpenAI ChatGPT API.
32- Use the GPT-3.5 Turbo model for generating responses. Adjust the 'model' variable in the script if you want to use a different model.
33
34Credits:
35This program is based on the OpenAI GPT-3.5 language model and was created by Connor J. Swislow.
36
37----------------------------------------------------------
38--]]
39
40--Chat Dependancies
41Chat = peripheral.wrap("bottom")
42Speaker = peripheral.find("warpdriveSpeaker")
43
44function speak(a)
45 if speakfeedback then
46 Speaker.speak("["..name.."]: "..a)
47 end
48end
49
50-- Set the OpenAI API key and other configurations
51local OPENAI_KEY = settings.get("OPENAI_KEY") -- Retrieve the OpenAI key from the settings
52local maxTokens = 100 -- Maximum number of tokens for API completion
53local model = "gpt-3.5-turbo-16k-0613" -- Language model to use
54
55-- If no OpenAI key is found, prompt the user to enter it
56if not OPENAI_KEY then
57 io.write("No OpenAI key detected.\nPlease paste your key:\n> ")
58 OPENAI_KEY = io.read()
59 settings.set("OPENAI_KEY", OPENAI_KEY)
60 settings.save()
61 term.clear()
62end
63
64-- Program titles
65local titles =
66 {" _ _ _ _ _ _ _\n / \\ / \\ / \\ / \\ / \\ / \\ / \\\n| G | P | T | . | l | u | a |\n \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/\n",
67 " ___ ____ ____ __ _ _ __\n / __)( _ \\(_ _) ( ) / )( \\ / _\\\n( (_ \\ ) __/ )( _ / (_/\\) \\/ (/ \\\n \\___/(__) (__)(_)\\____/\\____/\\_/\\_/\n",
68 " __ ______\n / _ /__)/ / _\n(__)/ ( .((/(/\n",
69 " ___ ___ ___\n| | | | |\n| +- |-+- + + -\n| | | | | | | | |\n --- - --- -- --\n",
70 " ___ ___ _____ _\n/ __| _ \\_ _| |_ _ __ _\n|(_ | _/ | |_| | || / _` |\n\\___|_| |_(_)_|\\_,_\\__,_|\n",
71 " __________ ______ __\n / ____/ __ \\/_ __/ / /_ ______ _\n / / __/ /_/ / / / / / / / / __ `/\n/ /_/ / ____/ / / _ / / /_/ / /_/ /\n\\____/_/ /_/ (_)_/\\__,_/\\__,_/\n",
72 " ________ ______ __\n / ___/ _ \\/_ __/ / /_ _____ _\n/ (_ / ___/ / / _ / / // / _ `/\n\\___/_/ /_/ (_)_/\\_,_/\\_,_/\n",
73 " ____ ____ _____ _\n / ___| _ \\_ _| |_ _ __ _\n| | _| |_) || | | | | | |/ _` |\n| |_| | __/ | |_| | |_| | (_| |\n \\____|_| |_(_)_|\\__,_|\\__,_|\n",
74 " _____________________________ .__\n / _____/\\______ \\__ ___/ | | __ _______ \n/ \\ ___ | ___/ | | | | | | \\__ \\ \n\\ \\_\\ \\| | | | | |_| | // __ \\\n \\______ /|____| |____| /\\____/____/(____ /\n \\/ \\/ \\/\n",
75 " .--. .---. .-----. .-.\n: .--': .; :`-. .-' : :\n: : _ : _.' : : : : .-..-. .--.\n: :; :: : : : _ : :_ : :; :' .; ;\n`.__.':_; :_; :_;`.__;`.__.'`.__,_;\n",
76 " /~~\\|~~\\~~|~~ |\n | __|__/ | || |/~~|\n \\__/| | .| \\_/|\\__|\n",
77 ".|'''''| '||'''|, |''||''| '||`\n|| . || || || ||\n|| |''|| ||...|' || || '|| ||` '''|.\n|| || || || || || || .|''||\n`|....|' .|| .||. .. .||. `|..'|. `|..||.\n",
78 " ___ _______ _\n ))_ ))_))) )) _ ___\n((_((( (( o (( ((_( ((_(\n",
79 " __ ___ _____\n ,'_/ / o |/_ _/ /7 _\n/ /_n / _,' / / ///7/7,'o|\n|__,'/_/ /_/() ///__/ |_,7\n",
80 " ___ ___ ___ _\n/ _> | . \\|_ _| | | _ _ ___\n| <_/\\| _/ | | _ | || | |<_> \n`____/|_| |_|<_>|_|`___|<___\n",
81 " _______ _______ _______ __\n| _ | _ | | | .--.--.---.-.\n|. |___|. 1 |.| | |__| | | | _ |\n|. | |. ____`-|. |-|__|__|_____|___._|\n|: 1 |: | |: |\n|::.. . |::.| |::.|\n`-------`---' `---'\n",
82 "____ ___ ___ _ _ _ ____\n| __ |__] | | | | |__|\n|__] | | .|___ |__| | |\n",
83 " __ __ ___\n[ __[__) | |. . _.\n[_./| | * |(_|(_]\n",
84 " .d8888b. 8888888b. 888888888 888\nd88P Y88b 888 Y88b 888 888\n888 888 888 888 888 888\n888 888 d88P 888 888 888 888 8888b.\n888 88888 8888888P\" 888 888 888 888 \"88b\n888 888 888 888 888 888 888.d888888\nY88b d88P 888 888 db 888 Y88b 888888 888\n \"Y8888P88 888 888 YP 888 \"Y88888\"Y888888\n",
85 "_______ ______ _______ __\n| __| __ \\_ _|| |.--.--.---.-.\n| | | __/ | |__| || | | _ |\n|_______|___| |___|__|__||_____|___._|\n",
86 " _____ _____ _______ _\n / ____| __ \\__ __| |\n| | __| |__) | | | | |_ _ __ _\n| | |_ | ___/ | | | | | | |/ _` |\n| |__| | | | | _| | |_| | (_| |\n \\_____|_| |_|(_)_|\\__,_|\\__,_|\n",
87 " ## ## ### #\n# # # # # # # ##\n# # ## # # # # # #\n# # # # ## ### ###\n ## # # #\n"}
88local title = titles[math.random(1, #titles)] -- Select a random title
89
90-- Set up API endpoint and headers
91local endpoint = "https://api.openai.com/v1/chat/completions"
92local headers = {
93 ["Authorization"] = "Bearer " .. OPENAI_KEY,
94 ["Content-Type"] = "application/json"
95}
96
97-- Function to print text with a specified color
98local function print_with_color(data, color)
99 assert(type(data) == "string")
100 term.setTextColor(color)
101 io.write(data)
102 term.setTextColor(colors.white)
103end
104
105-- Function to print text with random colors for each character
106local function print_with_random_colors(data)
107 assert(type(data) == "string")
108 for char in data:gmatch(".") do
109 print_with_color(char, 2 ^ math.random(0, 14))
110 end
111end
112
113-- Function to gradually print text word by word
114local function gradual_print(data)
115 assert(type(data) == "string")
116 for word in data:gmatch("%S+") do
117 io.write(word .. " ")
118 sleep(math.random(0.05, 0.2))
119 end
120 io.write("\n")
121end
122
123-- Print the chatbot title with random colors
124print_with_random_colors(title)
125print("\nType 'exit' to exit.\n")
126
127local messages = {} -- Store user and system messages
128
129while true do
130 print_with_color("[Me]: ", colors.magenta)
131 local prompt = io.read()
132
133 if prompt == "exit" then
134 break -- Exit the loop if the user types 'exit'
135 end
136
137 -- Add user message to the messages table
138 table.insert(messages, {
139 role = "user",
140 content = prompt
141 })
142
143 -- Prepare the payload as JSON for the API request
144 local payloadJson = textutils.serializeJSON({
145 ["model"] = model,
146 ["max_tokens"] = maxTokens,
147 ["messages"] = messages
148 })
149
150 local requesting = true
151 -- Send an HTTP POST request to the OpenAI API endpoint
152 http.request(endpoint, payloadJson, headers)
153 print_with_color("[GPT]: ", colors.lime)
154 while requesting do
155 io.write(".")
156 local event, url, sourceText = os.pullEvent()
157
158 if event == "http_success" then
159 local responseBody = sourceText.readAll()
160 sourceText.close()
161
162 -- Parse the JSON response from the API
163 local responseJson = textutils.unserializeJSON(responseBody)
164
165 if responseJson and responseJson.choices and responseJson.choices[1] then
166 local generatedText = responseJson.choices[1].message.content
167
168 -- Add system-generated message to the messages table
169 table.insert(messages, {
170 role = "system",
171 content = generatedText
172 })
173 local _, y = term.getCursorPos()
174 term.setCursorPos(1, y)
175 term.clearLine()
176 print_with_color("[GPT]: ", colors.lime)
177 gradual_print(generatedText)
178 else
179 print("Error: Failed to get a valid response.")
180 end
181
182 requesting = false -- Stop the loop, response received
183 elseif event == "http_failure" then
184 print("Server didn't respond.")
185 requesting = false -- Stop the loop, server failure
186 end
187 end
188end