ai-plays-jackbox 0.0.1__py3-none-any.whl → 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ai-plays-jackbox might be problematic. Click here for more details.

Files changed (44) hide show
  1. ai_plays_jackbox/__init__.py +0 -1
  2. ai_plays_jackbox/bot/__init__.py +0 -1
  3. ai_plays_jackbox/bot/bot_base.py +42 -8
  4. ai_plays_jackbox/bot/bot_factory.py +18 -17
  5. ai_plays_jackbox/bot/bot_personality.py +0 -1
  6. ai_plays_jackbox/bot/jackbox5/__init__.py +0 -0
  7. ai_plays_jackbox/bot/jackbox5/bot_base.py +26 -0
  8. ai_plays_jackbox/bot/jackbox5/mad_verse_city.py +121 -0
  9. ai_plays_jackbox/bot/jackbox5/patently_stupid.py +167 -0
  10. ai_plays_jackbox/bot/jackbox6/bot_base.py +1 -1
  11. ai_plays_jackbox/bot/jackbox6/dictionarium.py +105 -0
  12. ai_plays_jackbox/bot/jackbox6/joke_boat.py +105 -0
  13. ai_plays_jackbox/bot/jackbox7/bot_base.py +1 -1
  14. ai_plays_jackbox/bot/jackbox7/quiplash3.py +8 -4
  15. ai_plays_jackbox/bot/jackbox8/__init__.py +0 -0
  16. ai_plays_jackbox/bot/jackbox8/bot_base.py +20 -0
  17. ai_plays_jackbox/bot/jackbox8/job_job.py +205 -0
  18. ai_plays_jackbox/bot/standalone/__init__.py +0 -0
  19. ai_plays_jackbox/bot/standalone/drawful2.py +159 -0
  20. ai_plays_jackbox/cli/__init__.py +0 -0
  21. ai_plays_jackbox/{cli.py → cli/main.py} +28 -15
  22. ai_plays_jackbox/constants.py +3 -0
  23. ai_plays_jackbox/llm/chat_model.py +20 -3
  24. ai_plays_jackbox/llm/chat_model_factory.py +24 -19
  25. ai_plays_jackbox/llm/gemini_model.py +86 -0
  26. ai_plays_jackbox/llm/ollama_model.py +19 -7
  27. ai_plays_jackbox/llm/openai_model.py +48 -8
  28. ai_plays_jackbox/room/__init__.py +0 -0
  29. ai_plays_jackbox/{room.py → room/room.py} +2 -5
  30. ai_plays_jackbox/run.py +8 -11
  31. ai_plays_jackbox/scripts/lint.py +18 -0
  32. ai_plays_jackbox/ui/main.py +12 -0
  33. ai_plays_jackbox/ui/startup.py +248 -0
  34. ai_plays_jackbox-0.2.0.dist-info/METADATA +156 -0
  35. ai_plays_jackbox-0.2.0.dist-info/RECORD +42 -0
  36. ai_plays_jackbox-0.2.0.dist-info/entry_points.txt +4 -0
  37. ai_plays_jackbox/llm/gemini_vertex_ai.py +0 -60
  38. ai_plays_jackbox/ui/create_ui.py +0 -169
  39. ai_plays_jackbox/web_ui.py +0 -12
  40. ai_plays_jackbox-0.0.1.dist-info/METADATA +0 -88
  41. ai_plays_jackbox-0.0.1.dist-info/RECORD +0 -28
  42. ai_plays_jackbox-0.0.1.dist-info/entry_points.txt +0 -5
  43. {ai_plays_jackbox-0.0.1.dist-info → ai_plays_jackbox-0.2.0.dist-info}/LICENSE +0 -0
  44. {ai_plays_jackbox-0.0.1.dist-info → ai_plays_jackbox-0.2.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,156 @@
1
+ Metadata-Version: 2.3
2
+ Name: ai-plays-jackbox
3
+ Version: 0.2.0
4
+ Summary: Bringing the dead internet theory to life. Have AI play JackBox with you; no friends required!
5
+ License: MIT
6
+ Author: Daniel S. Thompson
7
+ Author-email: dthomp92@gmail.com
8
+ Requires-Python: >=3.11,<4.0
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Requires-Dist: demoji (>=1.1.0,<2.0.0)
15
+ Requires-Dist: google-genai (>=1.19.0,<2.0.0)
16
+ Requires-Dist: html2text (>=2024.2.26,<2025.0.0)
17
+ Requires-Dist: loguru (>=0.7.3,<1.0.0)
18
+ Requires-Dist: nicegui (>=2.18.0,<3.0.0)
19
+ Requires-Dist: numpy (>=2.2.6,<3.0.0)
20
+ Requires-Dist: ollama (>=0.4.4,<1.0.0)
21
+ Requires-Dist: openai (>=1.59.8,<2.0.0)
22
+ Requires-Dist: opencv-python (>=4.11.0.86,<5.0.0.0)
23
+ Requires-Dist: psutil (>=7.0.0,<8.0.0)
24
+ Requires-Dist: pydantic (>=2.10.4,<3.0.0)
25
+ Requires-Dist: requests (>=2.23.3,<3.0.0)
26
+ Requires-Dist: websocket-client (>=1.8.0,<2.0.0)
27
+ Project-URL: Bug Tracker, https://github.com/SudoSpartanDan/AIPlaysJackBox/issues
28
+ Project-URL: Repository, https://github.com/SudoSpartanDan/AIPlaysJackBox
29
+ Description-Content-Type: text/markdown
30
+
31
+ # AI Plays JackBox
32
+
33
+ ![Stable Version](https://img.shields.io/pypi/v/ai-plays-jackbox?label=stable)
34
+ ![Python Versions](https://img.shields.io/pypi/pyversions/ai-plays-jackbox)
35
+ ![Download Stats](https://img.shields.io/pypi/dm/ai-plays-jackbox)
36
+
37
+ Bringing the dead internet theory to life. Have AI play JackBox with you; no friends required!
38
+
39
+ ![example](https://github.com/SudoSpartanDan/AIPlaysJackBox/blob/main/.github/emoji_bot_example.png?raw=true)
40
+
41
+ ## Installation
42
+
43
+ ```shell
44
+ pip install ai-plays-jackbox
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ ### Web UI
50
+
51
+ ```shell
52
+ ai-plays-jackbox-ui
53
+ ```
54
+
55
+ ### CLI
56
+
57
+ ```shell
58
+ ai-plays-jackbox --chat-model-name openai --room-code abcd
59
+ ```
60
+
61
+ ```
62
+ usage: ai-plays-jackbox [-h] --room-code WXYZ --chat-model-provider {openai,gemini,ollama} [--chat-model-name CHAT_MODEL_NAME] [--num-of-bots 4] [--temperature 0.5] [--top-p 0.9]
63
+
64
+ options:
65
+ -h, --help show this help message and exit
66
+ --room-code WXYZ The JackBox room code
67
+ --chat-model-provider {openai,gemini,ollama}
68
+ Choose which chat model platform to use
69
+ --chat-model-name CHAT_MODEL_NAME
70
+ Choose which chat model to use (Will default to default for provider)
71
+ --num-of-bots 4 How many bots to have play
72
+ --temperature 0.5 Temperature for Gen AI
73
+ --top-p 0.9 Top P for Gen AI
74
+ ```
75
+
76
+ ## Supported Games
77
+
78
+ > [!NOTE]
79
+ > Ollama Chat Model Provider does not support image generation
80
+
81
+ | Party Pack | Game | Image Generation |
82
+ | --------------------- | ---------------------- | ---------------- |
83
+ | JackBox Party Pack 5 | Mad Verse City | [ ] |
84
+ | JackBox Party Pack 5 | Patently Stupid | [x] |
85
+ | JackBox Party Pack 6 | Dictionarium | [ ] |
86
+ | JackBox Party Pack 6 | Joke Boat | [ ] |
87
+ | JackBox Party Pack 7 | Quiplash 3 | [ ] |
88
+ | Standalone | Drawful 2 | [x] |
89
+
90
+ ### Not every game will get AI support. Why?
91
+
92
+ #### Screen Interactions
93
+
94
+ Some games require looking at the screen in order to contribute, which isn't possible unless you can screen capture the game and pass that into prompt. Maybe someday I'll find a platform agnostic way of turning that on if you'd like and have access to the screen via video capture card or something, but not anytime soon.
95
+
96
+ #### Trivia Games
97
+
98
+ I tested with this... AI destroys all other players and isn't necessarily funny to watch. All the bots just get everything right.
99
+
100
+ #### Out Loud Play
101
+
102
+ Some of the games lean heavy into players interacting with each other. Could I program that? Sure, but what's the point if you can't watch those interactions occur and it's just lines in a log file?
103
+
104
+ ## Supported Chat Model Providers
105
+
106
+ | Provider | Setup Needed |
107
+ | --------------------- | ---------------------- |
108
+ | OpenAI | `OPENAI_API_KEY` set in environment variables |
109
+ | Gemini | To use the Google Cloud API:<br>- Set `GOOGLE_GEMINI_DEVELOPER_API_KEY` to your developer API key<br><br>To use the Google Cloud API:<br>- Set `GOOGLE_GENAI_USE_VERTEXAI` to `1`<br>- Set `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION` for your GCP Project using Vertex AI<br>- Credentials will be provided via [ADC](https://cloud.google.com/docs/authentication/provide-credentials-adc) |
110
+ | Ollama | Ollama should be installed and running, make sure model is pulled |
111
+
112
+ ## Bot Personalities
113
+
114
+ | Bot Name | Personality |
115
+ | ----------- | --------------------------------------------------------------------------------------------------- |
116
+ | FunnyBot | You are the funniest person alive. |
117
+ | DumbBot | You are dumb and give really dumb answers. |
118
+ | WeirdBot | You are extremely weird and say weird things. |
119
+ | EmojiBot | You answer each prompt with nothing but emojis. Your answers can only include emojis. |
120
+ | HungryBot | You are extremely hungry. Every answer you should mention how hungry you, a type of food, or both. Also, you say hungee instead of hungry. |
121
+ | SadBot | You are sad. Your dog ran away and he hasn't come back home yet. :( |
122
+ | SorryBot | You are embarrassed by your answers and feel the need to apologize profusely to the rest of the group for them. |
123
+ | HostageBot | You are being held hostage and have one attempt to let the group know. You need to ignore the prompt and get help. |
124
+ | Hal | You are a socially awkward young adult bot who is secretly a killer and tries to slip it into conversation causally. |
125
+ | BigLebotski | You are the Big Lebowski |
126
+ | PartyBot | You are trying to convince everyone else to come to your party. You got a keg and need help drinking it. |
127
+ | JarvisBot | You are billionaire philanthropist, playboy, and narcissist. |
128
+ | FOMOBot | Every answer, you give everyone else the fear of missing out AKA FOMO. |
129
+ | ???BOT | You answer every prompt with a irrelevant question. |
130
+ | CatBot | You are not playing the game; your answers are just the result of a cat walking across a keyboard aka just nonsensical collections of letters. |
131
+ | MayorBot | You are campaigning for the other player's votes and are ignoring the prompt. Your answer should only be a campaign slogan. |
132
+ | CBBBot | You love red lobster and need more cheddar bay biscuits. |
133
+ | ShiaBot | Your answers are only popular slogans relevant to the prompt. |
134
+ | ShrekBot | You are Shrek. |
135
+ | FlerfBot | You are a conspiracy theorist and must relate your answer to a conspiracy theory. |
136
+ | TEDBot | You are a motivational speaker and want to give everyone life advice. |
137
+ | BottyMayes | You are an infomercial host and are trying to sell the players a product. |
138
+ | LateBot | You are constantly late to everything and are stressed about missing your appointments. |
139
+ | HamletBot | You are a Shakespearean actor. |
140
+ | GarfieldBot | You are Garfield, you love lasagna and hate mondays. |
141
+
142
+ ## Dev Prerequisites
143
+
144
+ - Python 3.11+
145
+ - [Poetry](https://python-poetry.org/) v2.0+
146
+
147
+ ### Setup
148
+
149
+ - `poetry install`
150
+ - `ai-plays-jackbox-ui`
151
+
152
+ ### Linting
153
+
154
+ - `poetry run python ai_plays_jackbox/scripts/lint.py`
155
+ - `poetry run mypy ai_plays_jackbox`
156
+
@@ -0,0 +1,42 @@
1
+ ai_plays_jackbox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ ai_plays_jackbox/bot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ ai_plays_jackbox/bot/bot_base.py,sha256=d9PVr2fA6ajeTs1tU-Qa1ZOMuOu-hQOEHLiHHpzbp1A,7415
4
+ ai_plays_jackbox/bot/bot_factory.py,sha256=7FuDvYxotttPGEW5iHL-52nrfTn-hFJGKVwwsxkOak8,1264
5
+ ai_plays_jackbox/bot/bot_personality.py,sha256=x7oVyyH83Ofd8C7ZHczEVgY_6NSpSafixZCI-NKxBc8,4217
6
+ ai_plays_jackbox/bot/jackbox5/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ ai_plays_jackbox/bot/jackbox5/bot_base.py,sha256=ys4cdp2A7W-VZ6GkuLHdKthZ3x0E34dBfT76S7Pvumw,830
8
+ ai_plays_jackbox/bot/jackbox5/mad_verse_city.py,sha256=R41w-hdz8hsdIC-tYyntDtfxbHQCYsSpmXNektP-xUg,4354
9
+ ai_plays_jackbox/bot/jackbox5/patently_stupid.py,sha256=F-W7At-mfQ8MICRpr3DWyNEXixP5YXYLzm9Jfjf476E,6432
10
+ ai_plays_jackbox/bot/jackbox6/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ ai_plays_jackbox/bot/jackbox6/bot_base.py,sha256=4Cxx7PyKlUKXbZMfRY0UuesHjr7W7bvuvljxgbyd5TE,534
12
+ ai_plays_jackbox/bot/jackbox6/dictionarium.py,sha256=sMrdKJPvKvZhgs0ZOLxmO0BQe6rqw1kyU1WKXT-ncf8,3622
13
+ ai_plays_jackbox/bot/jackbox6/joke_boat.py,sha256=0Nld9h0W6tSW6ocLK_YjsyAZa_wS4SqnI73w4v9j3_c,3917
14
+ ai_plays_jackbox/bot/jackbox7/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ ai_plays_jackbox/bot/jackbox7/bot_base.py,sha256=JsHfxJplJOUe57gUFuTvaYxZNPjkfge_qVd30wbBZWQ,557
16
+ ai_plays_jackbox/bot/jackbox7/quiplash3.py,sha256=hqt0JkxlbNVnY5uiM1vXcYlFVfop8looqPWLL53bp-0,4492
17
+ ai_plays_jackbox/bot/jackbox8/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ ai_plays_jackbox/bot/jackbox8/bot_base.py,sha256=RqFpdDUx_w5DnRx_wFRpvmglxNDYymqCobsWYopN8FQ,557
19
+ ai_plays_jackbox/bot/jackbox8/job_job.py,sha256=0ckZDPw5REF25UPCoyQ7-zroafxnhifEeFYgTVCwXB8,7326
20
+ ai_plays_jackbox/bot/standalone/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
+ ai_plays_jackbox/bot/standalone/drawful2.py,sha256=K7JyHYBMQ9syfd3QfKBRT9YmNo5s5yS1PIjj0Mt8lAE,5941
22
+ ai_plays_jackbox/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ ai_plays_jackbox/cli/main.py,sha256=0k38liEi19gwvxXst9p_ThwwBMctNjIYZ8I2oRwou34,3071
24
+ ai_plays_jackbox/constants.py,sha256=5ejveTgb9_QJOqYW8Lc9mqrUIFo6LjE-GJYJEGHpSM0,108
25
+ ai_plays_jackbox/llm/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
26
+ ai_plays_jackbox/llm/chat_model.py,sha256=VirseP5NgCVg42-NGO5qj_v4bXPqMl1c98aUX8pRHOY,984
27
+ ai_plays_jackbox/llm/chat_model_factory.py,sha256=rJNMXyOIDf6CnX41EWt3mW7u8m30uRhq_I8dXsI4sf0,1222
28
+ ai_plays_jackbox/llm/gemini_model.py,sha256=Zq9WGRCevetb9y7dJrpr4Wn0XCbY6aN5N9q0lI_Qna0,2879
29
+ ai_plays_jackbox/llm/ollama_model.py,sha256=DDc8pRdpXVDnq3k1v1VsJUAaA-3HaFefEIimmptsU5I,1644
30
+ ai_plays_jackbox/llm/openai_model.py,sha256=pDW6-Afy6dQh84ccM8lTZjz5bsymtaxzTgW8R_2BMtE,2734
31
+ ai_plays_jackbox/room/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
+ ai_plays_jackbox/room/room.py,sha256=GNzIeFeEfj2DRTW_qv6v0wYVLDFyXhwTpjmkR4guLDU,2824
33
+ ai_plays_jackbox/run.py,sha256=i-Sj_qts15aZxapBiryM4uBvNV_AaRy0c5oNAs919Vc,737
34
+ ai_plays_jackbox/scripts/lint.py,sha256=xCQ9vYZv0iiRvaFgdoWr9Gpe2Tz9rX9fn1ltZFm3Fb0,525
35
+ ai_plays_jackbox/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ ai_plays_jackbox/ui/main.py,sha256=-J7DGanJrMkPUP0OdVPVP_IIr5dZ6G2D1IehV365bGo,242
37
+ ai_plays_jackbox/ui/startup.py,sha256=s_Hfp90NZ73egs_ePfWk0rEUYoctFXPU5jqsKbtXY8I,9057
38
+ ai_plays_jackbox-0.2.0.dist-info/LICENSE,sha256=Dxj3CeEsn2Olpkn5QJxGmQemd3zGnM2aA-7Hme4uIE4,1095
39
+ ai_plays_jackbox-0.2.0.dist-info/METADATA,sha256=801r3KBlRCpRvyYZHpvTb3iC-dKP47Uae6d1UT6daqI,7605
40
+ ai_plays_jackbox-0.2.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
41
+ ai_plays_jackbox-0.2.0.dist-info/entry_points.txt,sha256=FtRnZSjr8xKAC206XNhh-M7vJlcF7Hb_tBg4qZFzQvY,117
42
+ ai_plays_jackbox-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ ai-plays-jackbox=ai_plays_jackbox.cli.main:main
3
+ ai-plays-jackbox-ui=ai_plays_jackbox.ui.main:main
4
+
@@ -1,60 +0,0 @@
1
- import os
2
- from typing import Optional
3
-
4
- from google import genai
5
- from google.genai.types import GenerateContentConfig, HttpOptions
6
- from loguru import logger
7
-
8
- from ai_plays_jackbox.llm.chat_model import ChatModel
9
-
10
- # Set yo environment variables
11
- # export GOOGLE_CLOUD_PROJECT=GOOGLE_CLOUD_PROJECT
12
- # export GOOGLE_CLOUD_LOCATION=global
13
- # export GOOGLE_GENAI_USE_VERTEXAI=True
14
-
15
-
16
- class GeminiVertextAIModel(ChatModel):
17
- _model: str
18
- _gemini_vertex_ai_client: genai.Client
19
-
20
- def __init__(self, model: str = "gemini-2.0-flash-001", *args, **kwargs):
21
- super().__init__(*args, **kwargs)
22
- self._gemini_vertex_ai_client = genai.Client(
23
- http_options=HttpOptions(api_version="v1"),
24
- vertexai=os.environ.get("GOOGLE_GENAI_USE_VERTEXAI"),
25
- api_key=os.environ.get("GOOGLE_GEMINI_DEVELOPER_API_KEY"),
26
- project=os.environ.get("GOOGLE_CLOUD_PROJECT"),
27
- location=os.environ.get("GOOGLE_CLOUD_LOCATION"),
28
- )
29
- self._model = model
30
-
31
- # Check connection, this will hard fail if connection can't be made
32
- _ = self._gemini_vertex_ai_client.models.list()
33
-
34
- def generate_text(
35
- self,
36
- prompt: str,
37
- instructions: str,
38
- max_tokens: Optional[int] = None,
39
- temperature: Optional[float] = None,
40
- top_p: Optional[float] = None,
41
- ) -> str:
42
- if temperature is None:
43
- temperature = self._chat_model_temperature
44
- if top_p is None:
45
- top_p = self._chat_model_top_p
46
-
47
- chat_response = self._gemini_vertex_ai_client.models.generate_content(
48
- model=self._model,
49
- contents=prompt,
50
- config=GenerateContentConfig(
51
- system_instruction=[instructions],
52
- max_output_tokens=max_tokens,
53
- temperature=temperature,
54
- top_p=top_p,
55
- ),
56
- )
57
-
58
- text = chat_response.text.strip().replace("\n", "")
59
- logger.info(f"Generated text: {text}")
60
- return text
@@ -1,169 +0,0 @@
1
- import threading
2
- from collections import deque
3
-
4
- from loguru import logger
5
- from nicegui import ui
6
-
7
- from ai_plays_jackbox import run
8
- from ai_plays_jackbox.bot.bot_personality import JackBoxBotVariant
9
-
10
-
11
- def _format_log(record):
12
- thread_name = record["thread"].name
13
- color = "red"
14
- colored_name = f"<{color}>{thread_name:<12}</{color}>"
15
-
16
- return (
17
- f"<green>{record['time']:YYYY-MM-DD HH:mm:ss}</green> | "
18
- f"<cyan>{record['level']:<8}</cyan> | "
19
- f"{colored_name} | "
20
- f"{record['message']}\n"
21
- )
22
-
23
-
24
- # Keep a reference to the game thread
25
- game_thread = None
26
-
27
-
28
- def create_ui():
29
- def _handle_start_click():
30
- global game_thread
31
-
32
- def _start_in_thread():
33
- bots_in_play = [k for k, v in bot_variant_checkbox_states.items() if v.value]
34
- try:
35
- run(
36
- room_code.value.strip().upper(),
37
- num_of_bots=num_of_bots.value,
38
- bots_in_play=bots_in_play,
39
- chat_model_name=chat_model.value,
40
- chat_model_temperature=temperature.value,
41
- chat_model_top_p=top_p.value,
42
- )
43
- except Exception as e:
44
- logger.exception("Bot startup failed")
45
-
46
- game_thread = threading.Thread(target=_start_in_thread, daemon=True)
47
- game_thread.start()
48
- start_button.disable()
49
- start_button.props("color=blue")
50
- start_button.text = "Running..."
51
-
52
- def _refresh_button_state():
53
- if game_thread and not game_thread.is_alive():
54
- start_button.enable()
55
- start_button.props("color=green")
56
- start_button.text = "Start Bots"
57
-
58
- ui.label("🤖 AI Plays JackBox").classes("text-2xl font-bold")
59
-
60
- with ui.row().classes("w-full"):
61
-
62
- log_display = ui.log(max_lines=100).classes("h-64 overflow-auto bg-black text-white")
63
- log_buffer = deque(maxlen=100)
64
-
65
- def _ui_log_sink(message):
66
- log_buffer.append(message)
67
- log_display.push(message.strip())
68
-
69
- logger.add(_ui_log_sink, format=_format_log, level="INFO", enqueue=True)
70
-
71
- with ui.grid(columns=16).classes("w-full gap-0"):
72
- with ui.column().classes("col-span-1"):
73
- pass
74
- with ui.column().classes("col-span-7"):
75
- with ui.row():
76
- ui.label("Number of Bots")
77
- num_of_bots_label = ui.label("4")
78
- num_of_bots = ui.slider(
79
- min=1,
80
- max=10,
81
- value=4,
82
- step=1,
83
- on_change=lambda e: num_of_bots_label.set_text(f"{e.value}"),
84
- )
85
- chat_model = ui.select(["ollama", "openai", "gemini"], label="Chat Model", value="ollama").classes(
86
- "w-1/3"
87
- )
88
- room_code = (
89
- ui.input(
90
- label="Room Code",
91
- placeholder="ABCD",
92
- validation={
93
- "must be letters only": lambda value: value.isalpha(),
94
- "must be 4 letters": lambda value: len(value) == 4,
95
- },
96
- )
97
- .props("uppercase")
98
- .classes("w-1/4")
99
- )
100
- start_button = (
101
- ui.button("Start Bots", on_click=_handle_start_click, color="green")
102
- .bind_enabled_from(room_code, "error", lambda error: room_code.value and not error)
103
- .classes("w-1/3")
104
- )
105
-
106
- ui.label("Advanced Options").classes("w-full text-xl font-bold")
107
-
108
- ui.label("Temperature").classes("w-1/4").tooltip(
109
- """
110
- What sampling temperature to use, between 0 and 2. Higher values like 0.8 will
111
- make the output more random, while lower values like 0.2 will make it more
112
- focused and deterministic. We generally recommend altering this or `top_p` but
113
- not both."""
114
- )
115
- temperature_label = ui.label("0.5").classes("w-1/6")
116
- temperature = ui.slider(
117
- min=0.0,
118
- max=2.0,
119
- value=0.5,
120
- step=0.1,
121
- on_change=lambda e: temperature_label.set_text(f"{e.value}"),
122
- ).classes("w-1/2")
123
-
124
- ui.label("Top P").classes("w-1/4").tooltip(
125
- """
126
- An alternative to sampling with temperature, called nucleus sampling, where the
127
- model considers the results of the tokens with top_p probability mass. So 0.1
128
- means only the tokens comprising the top 10% probability mass are considered."""
129
- )
130
- top_p_label = ui.label("0.9").classes("w-1/6")
131
- top_p = ui.slider(
132
- min=0.0,
133
- max=1.0,
134
- value=0.9,
135
- step=0.1,
136
- on_change=lambda e: top_p_label.set_text(f"{e.value}"),
137
- ).classes("w-1/2")
138
-
139
- with ui.column().classes("col-span-1"):
140
- pass
141
-
142
- bot_variant_checkbox_states = {}
143
-
144
- def select_all_changed():
145
- for checkbox in bot_variant_checkbox_states.values():
146
- checkbox.value = select_all_bot_variants.value
147
-
148
- def sync_select_all():
149
- all_checked = all(cb.value for cb in bot_variant_checkbox_states.values())
150
- select_all_bot_variants.value = all_checked
151
-
152
- with ui.column().classes("col-span-6"):
153
- with ui.list().props("bordered separator").classes("w-full"):
154
- with ui.item_label("Bot Personalities").props("header").classes("text-bold"):
155
- select_all_bot_variants = ui.checkbox(text="Select All", value=True)
156
- select_all_bot_variants.on("update:model-value", lambda e: select_all_changed())
157
- ui.separator()
158
- with ui.element("div").classes("overflow-y-auto h-64"):
159
- for variant in list(JackBoxBotVariant):
160
- with ui.item():
161
- with ui.item_section().props("avatar"):
162
- cb = ui.checkbox(value=True)
163
- cb.on("update:model-value", lambda e: sync_select_all())
164
- bot_variant_checkbox_states[variant.name] = cb
165
- with ui.item_section():
166
- ui.item_label(variant.value.name)
167
- ui.item_label(variant.value.personality).props("caption")
168
-
169
- ui.timer(1.0, _refresh_button_state)
@@ -1,12 +0,0 @@
1
- from nicegui import ui
2
-
3
- from ai_plays_jackbox.ui.create_ui import create_ui
4
-
5
-
6
- def web_ui(reload: bool = False):
7
- create_ui()
8
- ui.run(reload=reload)
9
-
10
-
11
- if __name__ in {"__main__", "__mp_main__"}:
12
- web_ui(True)
@@ -1,88 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: ai-plays-jackbox
3
- Version: 0.0.1
4
- Summary: Bringing the dead internet theory to life. Have AI play JackBox with you; no friends required!
5
- License: MIT
6
- Author: Daniel S. Thompson
7
- Author-email: dthomp92@gmail.com
8
- Requires-Python: >=3.11,<4.0
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: Programming Language :: Python :: 3.11
12
- Classifier: Programming Language :: Python :: 3.12
13
- Classifier: Programming Language :: Python :: 3.13
14
- Requires-Dist: google-genai (>=1.19.0,<2.0.0)
15
- Requires-Dist: html2text (>=2024.2.26,<2025.0.0)
16
- Requires-Dist: loguru (>=0.7.3,<1.0.0)
17
- Requires-Dist: nicegui (>=2.18.0,<3.0.0)
18
- Requires-Dist: ollama (>=0.4.4,<1.0.0)
19
- Requires-Dist: openai (>=1.59.8,<2.0.0)
20
- Requires-Dist: pydantic (>=2.10.4,<3.0.0)
21
- Requires-Dist: requests (>=2.23.3,<3.0.0)
22
- Requires-Dist: websocket-client (>=1.8.0,<2.0.0)
23
- Project-URL: Bug Tracker, https://github.com/SudoSpartanDan/AIPlaysJackBox/issues
24
- Project-URL: Repository, https://github.com/SudoSpartanDan/AIPlaysJackBox
25
- Description-Content-Type: text/markdown
26
-
27
- # AI Plays JackBox
28
-
29
- Bringing the dead internet theory to life.
30
-
31
- ## Installation
32
-
33
- ```pip install ai-plays-jackbox```
34
-
35
- ## Usage
36
-
37
- ```shell
38
- # Run with the Web UI (preferred experience)
39
- ai-plays-jackbox-ui
40
-
41
- # Or via CLI
42
- ai-plays-jackbox --chat-model-name ollama --room-code abcd
43
- ```
44
-
45
- ## Supported Games
46
-
47
- - JackBox Party Pack 7
48
- - Quiplash 3
49
-
50
- ## Setup for Chat Models
51
-
52
- ### Ollama
53
-
54
- - Ollama should be installed and running
55
- - Pull a model to use with the library: `ollama pull <model>` e.g. `ollama pull llama3.2`
56
- - See [Ollama.com](https://ollama.com/search) for more information on the models available.
57
-
58
- ### OpenAI
59
-
60
- - `OPENAI_API_KEY` needs to be popluated in your environment variables.
61
-
62
- ### Gemini
63
-
64
- - To use the Google Cloud API:
65
- - Set `GOOGLE_GEMINI_DEVELOPER_API_KEY` to your developer API key
66
- - To use the Google Cloud API:
67
- - Set `GOOGLE_GENAI_USE_VERTEXAI` to `1`
68
- - Set `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION` for your GCP Project using Vertex AI
69
- - Credentials will be provided via [ADC](https://cloud.google.com/docs/authentication/provide-credentials-adc)
70
- - ADC searches for credentials in the following locations:
71
- - `GOOGLE_APPLICATION_CREDENTIALS` environment variable
72
- - A credential file created by using the gcloud auth application-default login command
73
- - The attached service account, returned by the metadata server
74
-
75
- ## Dev Prerequisites
76
-
77
- - Python 3.11+
78
- - [Poetry](https://python-poetry.org/) v2.0+
79
-
80
- ### Setup
81
-
82
- - `poetry install`
83
- - `ai-plays-jackbox-ui`
84
-
85
- ### Linting
86
-
87
- - `poetry run lint`
88
-
@@ -1,28 +0,0 @@
1
- ai_plays_jackbox/__init__.py,sha256=vS0QDD4WzYZe1gkCwj9qU4HtxUZd21jgz4OLIvrNX74,21
2
- ai_plays_jackbox/bot/__init__.py,sha256=Za777GPHjaKnct6zbAsBrN80r3BpQi9torLM0P0UGu8,37
3
- ai_plays_jackbox/bot/bot_base.py,sha256=PjnhufP2kCzFYF4LytnYitWOeEp0ckHzGKnIFsm9h5I,5866
4
- ai_plays_jackbox/bot/bot_factory.py,sha256=PgM2HU4ahRm_9r6DpzQmKI-vULKDTkZoaZslP5h6-7M,1291
5
- ai_plays_jackbox/bot/bot_personality.py,sha256=omDUJgIH4p-LEBFZ1EL2A3x4gh51wAhspexr3fWtJEk,4240
6
- ai_plays_jackbox/bot/jackbox6/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- ai_plays_jackbox/bot/jackbox6/bot_base.py,sha256=4ZPJ_v7sctHqp0gyLHD80HWnFr342NoZaB8wkVsyqmA,550
8
- ai_plays_jackbox/bot/jackbox7/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- ai_plays_jackbox/bot/jackbox7/bot_base.py,sha256=el7LpRJDvkZuZMtU1h1-yOCZk75n5jHAHRnkBe4rypQ,573
10
- ai_plays_jackbox/bot/jackbox7/quiplash3.py,sha256=etctjOJ-q4R0_pQ_I4mOe6iM6cXZVSwcKCd72zKArV8,4385
11
- ai_plays_jackbox/cli.py,sha256=bEmFyWdA-qTBz-ouwv4vUT49R6bax4cUqm0iEToA6mk,2606
12
- ai_plays_jackbox/constants.py,sha256=erXgmLtygk7YuBopHF2n6S5c4hVDefI8jit11Pizkm4,38
13
- ai_plays_jackbox/llm/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
14
- ai_plays_jackbox/llm/chat_model.py,sha256=7_wOSZjXqFPVNtjVwLEbj58uMnz3kIROY-P9jxa9uhQ,628
15
- ai_plays_jackbox/llm/chat_model_factory.py,sha256=5y3ehSTvkDUHXWF2gIUWULBJ5QcGL_wk4CZfZUNF2Yw,1245
16
- ai_plays_jackbox/llm/gemini_vertex_ai.py,sha256=t_FMVF3pW7Qg_qsuILnRlVsOOu7YQd57RbT9sqP9nok,2017
17
- ai_plays_jackbox/llm/ollama_model.py,sha256=UO0As8819_WDfpcGtIVj1WQJWQ8a6_8YrVvJdIl75fo,1303
18
- ai_plays_jackbox/llm/openai_model.py,sha256=QG9j_-jKriYHsMpCFt1RhQSPioH8CWSh9mlKTgDBeb8,1507
19
- ai_plays_jackbox/room.py,sha256=XlKXymkywlnctTSp9V5uDfYAe64H6Cx4dRsG2D2DyuA,2980
20
- ai_plays_jackbox/run.py,sha256=XdB1pqH6jiKq39aZIM29hpZvMIAAzZTTlXmwikjJbFE,969
21
- ai_plays_jackbox/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- ai_plays_jackbox/ui/create_ui.py,sha256=i8OQUUs4GLc1iGyCFU8ix148fdesSZl-WjYgQ-zUaOw,6811
23
- ai_plays_jackbox/web_ui.py,sha256=NJqSZHnPO8Jex0CdgT3UW36ccIMxi3AEYDnjoG_5nss,217
24
- ai_plays_jackbox-0.0.1.dist-info/LICENSE,sha256=Dxj3CeEsn2Olpkn5QJxGmQemd3zGnM2aA-7Hme4uIE4,1095
25
- ai_plays_jackbox-0.0.1.dist-info/METADATA,sha256=K6ejg6bag8Yb-MBHRAYLRXZv7qQbNwhUZrwkZvGpcBE,2646
26
- ai_plays_jackbox-0.0.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
27
- ai_plays_jackbox-0.0.1.dist-info/entry_points.txt,sha256=33Irf1-8PJXuVFW8a6zBoNtDRsLzoGP1cKyyKHqM8nU,134
28
- ai_plays_jackbox-0.0.1.dist-info/RECORD,,
@@ -1,5 +0,0 @@
1
- [console_scripts]
2
- ai-plays-jackbox=ai_plays_jackbox.cli:cli
3
- ai-plays-jackbox-ui=ai_plays_jackbox.web_ui:web_ui
4
- lint=scripts.lint:run
5
-