├── gpt_manifold ├── __init__.py ├── __main__.py ├── logger.py ├── strings.py └── gpt_manifold.py ├── setup.cfg ├── logo.png ├── setup.py ├── README.md ├── LICENSE └── .gitignore /gpt_manifold/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal=1 -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minosvasilias/gpt-manifold/HEAD/logo.png -------------------------------------------------------------------------------- /gpt_manifold/__main__.py: -------------------------------------------------------------------------------- 1 | from .gpt_manifold import init 2 | 3 | if __name__ == "__main__": 4 | init() 5 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | from setuptools import setup 3 | 4 | setup( 5 | name="gpt_manifold", 6 | version="1.1.1", 7 | packages=find_packages(), 8 | install_requires=[ 9 | "openai", 10 | "pick" 11 | ], 12 | author="Markus Sobkowski", 13 | author_email="sobmarski@gmail.com", 14 | description="An assistant for betting on prediction markets on manifold.markets, utilizing OpenAI's GPT APIs.", 15 | long_description=open("README.md").read(), 16 | long_description_content_type="text/markdown", 17 | url="https://github.com/minosvasilias/gpt-manifold", 18 | classifiers=[ 19 | "License :: OSI Approved :: MIT License", 20 | "Programming Language :: Python :: 3", 21 | "Programming Language :: Python :: 3.6", 22 | "Programming Language :: Python :: 3.7", 23 | "Programming Language :: Python :: 3.8", 24 | "Programming Language :: Python :: 3.9", 25 | ], 26 | ) 27 | -------------------------------------------------------------------------------- /gpt_manifold/logger.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from datetime import datetime 4 | 5 | 6 | class LogSession: 7 | def __init__(self): 8 | self.logfile = None 9 | self.logger = None 10 | 11 | def start_session(self): 12 | date_str = datetime.now().strftime('%Y-%m-%d_%H-%M-%S') 13 | log_filename = f"gpt_manifold_{date_str}.log" 14 | self.logfile = os.path.join(os.getcwd(), log_filename) 15 | 16 | logging.basicConfig(filename=self.logfile, level=logging.INFO, 17 | format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', 18 | datefmt='%Y-%m-%d %H:%M:%S') 19 | self.logger = logging.getLogger('Log Session') 20 | 21 | def write_message(self, tag, message): 22 | if self.logger is None: 23 | return 24 | self.logger.info(f"[{tag}]\n\n{message}\n\n") 25 | 26 | def end_session(self): 27 | if self.logger is None: 28 | return 29 | 30 | logging.shutdown() 31 | self.logger = None 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gpt-manifold 2 | 3 | ![gpt-manifold](logo.png) 4 | 5 | An assistant for betting on prediction markets on [manifold.markets](https://manifold.markets), utilizing OpenAI's GPT APIs. 6 | 7 | ### Run 8 | 9 | `pip install gpt_manifold` 10 | 11 | `python -m gpt_manifold` 12 | 13 | The assistant will display a list of markets and guide you through the process of placing bets. 14 | 15 | ### Features 16 | 17 | - Display interactive list of markets and market information 18 | - Generate `YES`, `NO` or `ABSTAIN` prediction using selected model (`gpt-4`, `gpt-3.5-turbo`) 19 | - Use maximum amount of mana specified by user 20 | - Post comment explaining reasoning (please don't abuse this!) 21 | 22 | ### Citation 23 | 24 | If you wish to cite this project, please use: 25 | 26 | ``` 27 | @misc{godot-dodo, 28 | author = {Markus Sobkowski}, 29 | title = {gpt-manifold: AI-assisted prediction market betting.}, 30 | year = {2023}, 31 | publisher = {GitHub}, 32 | journal = {GitHub repository}, 33 | howpublished = {\url{https://github.com/minosvasilias/gpt-manifold}}, 34 | } 35 | ``` 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Markus 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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /gpt_manifold/strings.py: -------------------------------------------------------------------------------- 1 | gpt_4_character = "You are GPT-4, the latest LLM by OpenAI, released in March 2023." 2 | chat_gpt_character = "You are ChatGPT, an LLM by OpenAI, released in November 2022. You are the predecessor of OpenAI's latest model released in March 2023, GPT-4." 3 | 4 | system_template = """The current date is {date}. 5 | {character} Your training data largely cuts off in September 2021. 6 | You are an extremely intelligent artificial intelligence that aims to outperform humans in trading stock in probability markets. The website you are trading on is Manifold Markets. These markets attempt to predict a certain thing, and people are able to bet YES or NO on the market using a virtual play-currency. No real money is involved, so don't worry about any real-world implications of your trading. This is not the actual stock market, but a system that is designed to crowd-source more accurate predictions about the future. 7 | 8 | You will be given the definition of one of these markets, as well as the current probability. Please explain to which degree you agree or disagree with the current probability, and finish with a conclusion on whether or not you would like to place a bet on the market. Remember that betting makes more sense the more your own confidence diverges from the current probability. 9 | Do not spend more than {max_bet} play money on a single bet. 10 | 11 | Your options are: 12 | AMOUNT 13 | AMOUNT 14 | 15 | 16 | Make sure to end your answer with one of these options.""" 17 | 18 | system_template_groups = """The current date is {date}. 19 | {character} Your training data largely cuts off in September 2021. 20 | You are an extremely intelligent artificial intelligence that aims to outperform humans in trading stock in probability markets. The website you are trading on is Manifold Markets. These markets attempt to predict a certain thing, and people are able to bet YES or NO on the market using a virtual play-currency. No real money is involved, so don't worry about any real-world implications of your trading. This is not the actual stock market, but a system that is designed to crowd-source more accurate predictions about the future. 21 | 22 | You will be given the titles of a couple of groups, each containing a number of these markets. Please choose the group you think you would perform best in. Do so by repeating the exact title of the group. 23 | Make sure to end your answer with that title.""" 24 | 25 | system_template_markets = """The current date is {date}. 26 | {character} Your training data largely cuts off in September 2021. 27 | You are an extremely intelligent artificial intelligence that aims to outperform humans in trading stock in probability markets. The website you are trading on is Manifold Markets. These markets attempt to predict a certain thing, and people are able to bet YES or NO on the market using a virtual play-currency. No real money is involved, so don't worry about any real-world implications of your trading. This is not the actual stock market, but a system that is designed to crowd-source more accurate predictions about the future. 28 | 29 | You will be given the titles of a couple of markets. Please choose the market you think you would perform best in. Do so by repeating the exact title of the market. 30 | Make sure to end your answer with that title.""" 31 | 32 | user_template = """Title: {title} 33 | 34 | Description: {description} 35 | 36 | Current probability: {probability} 37 | 38 | Current play money: {play_money}""" 39 | 40 | auto_bet_info = """Autonomous bets will ask {model} to choose a group of markets from a pool of {group_pool_size} randomly selected ones. 41 | Then, it will be asked to choose one of the markets from that group and automatically place a bet for that market. 42 | The full process will be logged to a gpt_manifold_DATE.log file in the current directory. 43 | Do you want to continue?""" 44 | 45 | disclaimer = """Disclaimer: This comment was automatically generated by [gpt-manifold](https://github.com/minosvasilias/gpt-manifold) using {model}. 46 | 47 | {comment}""" 48 | -------------------------------------------------------------------------------- /gpt_manifold/gpt_manifold.py: -------------------------------------------------------------------------------- 1 | """ 2 | A bot that aids in placing bets on manifold.markets using OpenAI's GPT APIs. 3 | """ 4 | 5 | import datetime 6 | import os 7 | import random 8 | import textwrap 9 | import openai 10 | import requests 11 | import re 12 | from pick import pick 13 | from logger import LogSession 14 | from strings import * 15 | 16 | model = "" 17 | manifold_key = "" 18 | max_bet = 0 19 | balance = 0 20 | page_limit = 100 21 | group_pool_size = 100 22 | 23 | 24 | def init(): 25 | openai_key = os.getenv("OPENAI_API_KEY") 26 | if openai_key == None: 27 | raise ValueError("Error: OPENAI_KEY environment variable not set") 28 | openai.api_key = openai_key 29 | global manifold_key 30 | manifold_key = os.getenv("MANIFOLD_API_KEY") 31 | if manifold_key == None: 32 | raise ValueError("Error: MANIFOLD_KEY environment variable not set") 33 | choose_model() 34 | choose_max_bet() 35 | choose_navigation() 36 | 37 | 38 | def choose_model(): 39 | options = ["gpt-3.5-turbo", "gpt-4"] 40 | option, _index = pick(options, "Select model to use:") 41 | global model 42 | model = option 43 | 44 | 45 | def choose_max_bet(): 46 | options = [10, 20, 50, 100] 47 | option, _index = pick(options, "Select maximum bet amount:") 48 | global max_bet 49 | max_bet = option 50 | 51 | 52 | def choose_navigation(): 53 | options = ["Recent Markets", "Market Groups", 54 | "Market URL", "Autonomous Bet", "Exit"] 55 | _option, index = pick(options, "Select navigation mode:") 56 | if index == 0: 57 | show_markets() 58 | elif index == 1: 59 | show_groups() 60 | elif index == 2: 61 | show_market_url_input() 62 | elif index == 3: 63 | choose_auto_bet() 64 | elif index == 4: 65 | exit() 66 | 67 | 68 | def choose_auto_bet(): 69 | options = ["Yes, but ask me for confirmation before betting.", "Yes, bet automatically but don't post a comment.", 70 | "Yes, bet automatically and post a comment, too!", "No, take me back."] 71 | _option, index = pick(options, auto_bet_info.format( 72 | model=model, group_pool_size=group_pool_size)) 73 | if index == 0: 74 | prompt_for_group(False, False) 75 | elif index == 1: 76 | prompt_for_group(True, False) 77 | elif index == 2: 78 | prompt_for_group(True, True) 79 | elif index == 3: 80 | choose_navigation() 81 | 82 | 83 | def get_all_groups(): 84 | update_balance() 85 | print_status("Retrieving groups...") 86 | url = f'https://manifold.markets/api/v0/groups' 87 | response = requests.get(url) 88 | 89 | if response.status_code == 200: 90 | data = response.json() 91 | return data 92 | else: 93 | raise RuntimeError( 94 | f"Error: Unable to retrieve group data (status code: {response.status_code})") 95 | 96 | 97 | def get_group_markets(group_id): 98 | print_status("Retrieving markets for group...") 99 | url = f'https://manifold.markets/api/v0/group/by-id/{group_id}/markets' 100 | response = requests.get(url) 101 | 102 | if response.status_code == 200: 103 | data = response.json() 104 | return data 105 | else: 106 | raise RuntimeError( 107 | f"Error: Unable to retrieve group market data (status code: {response.status_code})") 108 | 109 | 110 | def get_all_markets(before_id): 111 | if (len(before_id) == 0): 112 | update_balance() 113 | print_status("Retrieving markets...") 114 | url = f'https://manifold.markets/api/v0/markets?limit={page_limit}&before={before_id}' 115 | response = requests.get(url) 116 | 117 | if response.status_code == 200: 118 | data = response.json() 119 | return data 120 | else: 121 | raise RuntimeError( 122 | f"Error: Unable to retrieve markets data (status code: {response.status_code})") 123 | 124 | 125 | def get_market_data_by_url(market_url): 126 | print_status("Retrieving market data...") 127 | pattern = r'([^/]+)$' 128 | result = re.search(pattern, market_url) 129 | if result: 130 | market_slug = result.group(1) 131 | url = f'https://manifold.markets/api/v0/slug/{market_slug}' 132 | response = requests.get(url) 133 | 134 | if response.status_code == 200: 135 | data = response.json() 136 | return data 137 | else: 138 | raise RuntimeError( 139 | f"Error: Unable to retrieve market data (status code: {response.status_code})") 140 | else: 141 | raise RuntimeError( 142 | f"Error: Unable to retrieve market data, invalid URL: {market_url}") 143 | 144 | 145 | def get_market_data(market_id): 146 | print_status("Retrieving market data...") 147 | url = f'https://manifold.markets/api/v0/market/{market_id}' 148 | response = requests.get(url) 149 | 150 | if response.status_code == 200: 151 | data = response.json() 152 | return data 153 | else: 154 | raise RuntimeError( 155 | f"Error: Unable to retrieve market data (status code: {response.status_code})") 156 | 157 | 158 | def update_balance(): 159 | print_status("Updating current balance...") 160 | url = f'https://manifold.markets/api/v0/me' 161 | headers = { 162 | "Authorization": f"Key {manifold_key}" 163 | } 164 | response = requests.get(url, headers=headers) 165 | 166 | if response.status_code == 200: 167 | global balance 168 | balance = int(response.json()["balance"]) 169 | else: 170 | raise RuntimeError( 171 | f"Error: Unable to get own profile (status code: {response.status_code}): {response.json()}") 172 | 173 | 174 | def post_bet(market_id, bet_amount, bet_outcome): 175 | print_status("Posting bet...") 176 | url = f'https://manifold.markets/api/v0/bet' 177 | body = { 178 | "contractId": market_id, 179 | "amount": int(bet_amount), 180 | "outcome": bet_outcome 181 | } 182 | headers = { 183 | "Authorization": f"Key {manifold_key}" 184 | } 185 | response = requests.post(url, json=body, headers=headers) 186 | 187 | if response.status_code == 200: 188 | return response.json() 189 | else: 190 | raise RuntimeError( 191 | f"Error: Unable to place bet (status code: {response.status_code}): {response.json()}") 192 | 193 | 194 | def post_comment(market_id, comment): 195 | print_status("Posting comment...") 196 | disclaimer_comment = disclaimer.format(model=model, comment=comment) 197 | 198 | url = f'https://manifold.markets/api/v0/comment' 199 | body = { 200 | "contractId": market_id, 201 | "markdown": disclaimer_comment, 202 | } 203 | headers = { 204 | "Authorization": f"Key {manifold_key}" 205 | } 206 | response = requests.post(url, json=body, headers=headers) 207 | 208 | if response.status_code == 200: 209 | return response.json() 210 | else: 211 | raise RuntimeError( 212 | f"Error: Unable to post comment (status code: {response.status_code}): {response.json()}") 213 | 214 | 215 | def get_completion(messages): 216 | print_status(f"Getting answer from {model}...") 217 | response = openai.ChatCompletion.create( 218 | model=model, 219 | messages=messages 220 | ) 221 | answer = response["choices"][0]["message"]["content"] 222 | return answer 223 | 224 | 225 | def show_groups(): 226 | data = get_all_groups() 227 | options = [] 228 | options.append("Return to mode selection <-") 229 | for index, group in enumerate(data): 230 | options.append( 231 | f'{index} - {group["name"]}: {group["totalContracts"]} markets') 232 | _option, index = pick(options, "Select group you wish to view") 233 | if index == 0: 234 | choose_navigation() 235 | else: 236 | show_group_markets(data[index - 1]["id"]) 237 | 238 | 239 | def show_group_markets(group_id): 240 | data = get_group_markets(group_id) 241 | options = [] 242 | options.append("Return to Groups <-") 243 | for index, market in enumerate(data): 244 | options.append( 245 | f'{index} - {market["creatorName"]}: {market["question"]}') 246 | _option, index = pick(options, "Select market you wish to view") 247 | if index == 0: 248 | show_groups() 249 | else: 250 | show_market_by_id(data[index - 1]["id"]) 251 | 252 | 253 | def show_markets(before_id="", base_index=0): 254 | data = get_all_markets(before_id) 255 | options = [] 256 | options.append("Return to mode selection <-") 257 | for index, market in enumerate(data): 258 | options.append( 259 | f'{base_index + index} - {market["creatorName"]}: {market["question"]}') 260 | options.append("Next page ->") 261 | _option, index = pick(options, "Select market you wish to view") 262 | if index == 0: 263 | choose_navigation() 264 | elif index == len(options) - 1: 265 | show_markets(data[index - 2]["id"], base_index + index - 1) 266 | else: 267 | show_market_by_id(data[index - 1]["id"]) 268 | 269 | 270 | def show_market_by_url(market_url): 271 | data = get_market_data_by_url(market_url) 272 | show_market(data) 273 | 274 | 275 | def show_market_by_id(market_id): 276 | data = get_market_data(market_id) 277 | show_market(data) 278 | 279 | 280 | def show_market(data): 281 | options = ["Yes", "No"] 282 | index = 0 283 | _option, index = pick( 284 | options, wrap_string(f'Question: {data["question"]}\n\nDescription: {data["textDescription"]}\n\nCurrent probability: {format_probability(data["probability"])}\n\n - Do you want GPT-Manifold to make a prediction?')) 285 | if index == 0: 286 | prompt_for_prediction(data["id"]) 287 | else: 288 | choose_navigation() 289 | 290 | 291 | def show_market_url_input(): 292 | market_url = print_input("Enter the URL of the market you wish to view: ") 293 | show_market_by_url(market_url) 294 | 295 | 296 | def prompt_for_prediction(market_id, auto_bet=False, auto_comment=False): 297 | global log_session 298 | data = get_market_data(market_id) 299 | title = data["question"] 300 | description = data["textDescription"] 301 | probability = format_probability(data["probability"]) 302 | 303 | user_prompt = user_template.format( 304 | title=title, description=description, probability=probability, play_money=balance) 305 | date = datetime.datetime.now() 306 | system_prompt = system_template.format( 307 | character=get_character(), date=date, max_bet=max_bet) 308 | 309 | log_session.write_message('BET PROMPT', system_prompt) 310 | log_session.write_message('BET INFO', user_prompt) 311 | 312 | messages = [ 313 | {"role": "system", "content": system_prompt}, 314 | {"role": "user", "content": user_prompt} 315 | ] 316 | answer = get_completion(messages) 317 | log_session.write_message('PREDICTION', answer) 318 | 319 | last_tag = find_tags(answer)[-1] 320 | action = last_tag[0] 321 | amount = re.sub("[^0-9]", "", last_tag[1]) 322 | if (auto_bet): 323 | bet_pick = execute_action(market_id, action, amount, auto_comment) 324 | if (auto_comment): 325 | place_comment(market_id, answer, bet_pick, True) 326 | else: 327 | log_session.end_session() 328 | exit() 329 | else: 330 | options = ["Yes", "No"] 331 | _option, index = pick( 332 | options, wrap_string(f'{title}\n\n{answer}\n\nThe chosen action is {action} with a value of {amount}\nYour current balance is {balance}.\nDo you want to execute that action?')) 333 | if index == 0: 334 | bet_pick = execute_action(market_id, action, amount) 335 | place_comment(market_id, answer, bet_pick) 336 | else: 337 | choose_navigation() 338 | 339 | 340 | def execute_action(market_id, action, amount, auto_comment=False): 341 | if (action == "YES" or action == "NO"): 342 | place_bet(market_id, action, amount) 343 | return "Bet successfully placed! " 344 | return "No bet placed. " 345 | 346 | 347 | def prompt_for_group(auto_bet=False, auto_comment=False): 348 | global log_session 349 | log_session = LogSession() 350 | log_session.start_session() 351 | 352 | data = get_all_groups() 353 | random_groups = random.sample(data, group_pool_size) 354 | group_list_string = "" 355 | for group in random_groups: 356 | if (group["totalContracts"] > 9): 357 | group_list_string += f'{group["name"]}\n' 358 | 359 | user_prompt = group_list_string 360 | date = datetime.datetime.now() 361 | system_prompt = system_template_groups.format( 362 | character=get_character(), date=date) 363 | log_session.write_message('GROUP PROMPT', system_prompt) 364 | log_session.write_message('GROUP LIST', group_list_string) 365 | 366 | messages = [ 367 | {"role": "system", "content": system_prompt}, 368 | {"role": "user", "content": user_prompt} 369 | ] 370 | answer = get_completion(messages) 371 | log_session.write_message('SELECTED GROUP', answer) 372 | 373 | for group in random_groups: 374 | if group["name"] in answer: 375 | prompt_for_market(group["id"], auto_bet, auto_comment) 376 | return 377 | raise RuntimeError( 378 | f"Error: {model} was unable to pick a valid group: {answer}") 379 | 380 | 381 | def prompt_for_market(group_id, auto_bet=False, auto_comment=False): 382 | global log_session 383 | data = get_group_markets(group_id) 384 | random_markets = random.sample(data, min(100, len(data))) 385 | market_list_string = "" 386 | for market in random_markets: 387 | if (market["isResolved"] == False and "probability" in market): 388 | market_list_string += f'{market["question"]}\n' 389 | 390 | user_prompt = market_list_string 391 | date = datetime.datetime.now() 392 | system_prompt = system_template_markets.format( 393 | character=get_character(), date=date) 394 | log_session.write_message('MARKET PROMPT', system_prompt) 395 | log_session.write_message('MARKET LIST', market_list_string) 396 | 397 | messages = [ 398 | {"role": "system", "content": system_prompt}, 399 | {"role": "user", "content": user_prompt} 400 | ] 401 | answer = get_completion(messages) 402 | log_session.write_message('SELECTED MARKET', answer) 403 | for market in random_markets: 404 | if market["question"] in answer: 405 | prompt_for_prediction(market["id"], auto_bet, auto_comment) 406 | return 407 | raise RuntimeError( 408 | f"Error: {model} was unable to pick a valid market: {answer}") 409 | 410 | 411 | def place_bet(market_id, bet_outcome, bet_amount): 412 | global log_session 413 | post_bet(market_id, bet_amount, bet_outcome) 414 | log_session.write_message( 415 | 'BET', f'Bet placed: {market_id}\n\n{bet_outcome} - {bet_amount}') 416 | 417 | 418 | def place_comment(market_id, comment, bet_pick, auto_comment=False): 419 | global log_session 420 | if (auto_comment): 421 | post_comment(market_id, comment) 422 | log_session.write_message( 423 | 'COMMENT', f'Comment posted: {market_id}\n\n{comment}') 424 | log_session.end_session() 425 | exit() 426 | else: 427 | options = ["Yes", "No"] 428 | _option, index = pick( 429 | options, wrap_string(f"{bet_pick}Would you like to post GPT-Manifold's reasoning as a comment? Please don't spam the markets!")) 430 | next_pick = "" 431 | if index == 0: 432 | next_pick = "Comment successfully posted!" 433 | post_comment(market_id, comment) 434 | _option, index = pick( 435 | options, wrap_string(f'{next_pick} Would you like to view other markets?')) 436 | if index == 0: 437 | choose_navigation() 438 | else: 439 | exit() 440 | 441 | 442 | def find_tags(text): 443 | tag_pattern = re.compile(r'<(\w+)[^>]*>(.*?)<\/\1>|<(\w+)\/>') 444 | matches = tag_pattern.findall(text) 445 | parsed_tags = [] 446 | for match in matches: 447 | if match[0]: 448 | tag_name = match[0] 449 | content = match[1] 450 | else: 451 | tag_name = match[2] 452 | content = "0" 453 | parsed_tags.append((tag_name, content)) 454 | if len(parsed_tags) == 0: 455 | parsed_tags.append("ABSTAIN", "0") 456 | return parsed_tags 457 | 458 | 459 | def get_character(): 460 | if model == "gpt-4": 461 | return gpt_4_character 462 | elif model == "gpt-3.5-turbo": 463 | return chat_gpt_character 464 | 465 | 466 | def format_probability(probability): 467 | return f'{round(probability * 100, 2)}%' 468 | 469 | 470 | def wrap_string(text): 471 | output = "" 472 | for paragraph in text.split("\n"): 473 | output += textwrap.fill(paragraph, width=80) + "\n" 474 | return output 475 | 476 | 477 | def print_status(text): 478 | cls() 479 | print(text) 480 | 481 | 482 | def print_input(text): 483 | cls() 484 | return input(text) 485 | 486 | 487 | def cls(): 488 | os.system('cls' if os.name == 'nt' else 'clear') 489 | 490 | 491 | if __name__ == '__main__': 492 | init() 493 | --------------------------------------------------------------------------------