ChatGPT Assistant

Bypasses page errors like 'conversation not found' + popup tools + model switcher + resume support after reloads

  1. // ==UserScript==
  2. // @name ChatGPT Assistant
  3. // @namespace http://tampermonkey.net/
  4. // @version v1.1
  5. // @description Bypasses page errors like 'conversation not found' + popup tools + model switcher + resume support after reloads
  6. // @author dylojestem
  7. // @license This script may be freely shared, but modification is not allowed. All rights reserved by dylojestem.
  8. // @match https://chatgpt.com/*
  9. // @icon https://static.vecteezy.com/system/resources/previews/021/608/790/non_2x/chatgpt-logo-chat-gpt-icon-on-black-background-free-vector.jpg
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. const style = document.createElement('style');
  15. style.textContent = `
  16. #chatgpt-menu {
  17. position: fixed;
  18. top: 0;
  19. right: -240px;
  20. width: 240px;
  21. height: 100%;
  22. background-color: #111;
  23. color: white;
  24. z-index: 10000;
  25. padding: 20px 10px;
  26. box-shadow: -2px 0 6px rgba(0,0,0,0.3);
  27. transition: right 0.3s ease;
  28. font-family: sans-serif;
  29. overflow-y: auto;
  30. }
  31. #chatgpt-menu.open {
  32. right: 0;
  33. }
  34. #chatgpt-toggle {
  35. position: fixed;
  36. bottom: 30px;
  37. right: 30px;
  38. z-index: 10001;
  39. background-color: #000;
  40. color: white;
  41. border: none;
  42. border-radius: 50%;
  43. width: 42px;
  44. height: 42px;
  45. font-size: 20px;
  46. cursor: pointer;
  47. box-shadow: 0 2px 6px rgba(0,0,0,0.3);
  48. }
  49. #chatgpt-menu button {
  50. width: 100%;
  51. margin: 6px 0;
  52. padding: 8px;
  53. font-size: 14px;
  54. border: none;
  55. border-radius: 6px;
  56. background-color: #222;
  57. color: white;
  58. cursor: pointer;
  59. transition: background-color 0.2s;
  60. }
  61. #chatgpt-menu button:hover {
  62. background-color: #333;
  63. }
  64. #chatgpt-menu .section-title {
  65. margin: 10px 0 5px;
  66. font-size: 12px;
  67. color: #aaa;
  68. text-transform: uppercase;
  69. }
  70. #chatgpt-menu .model-card {
  71. background-color: #1a1a1a;
  72. border-radius: 8px;
  73. padding: 10px;
  74. margin-bottom: 8px;
  75. box-shadow: 0 1px 3px rgba(0,0,0,0.4);
  76. }
  77. #chatgpt-menu .model-title {
  78. font-weight: bold;
  79. color: #fff;
  80. margin-bottom: 4px;
  81. }
  82. #chatgpt-menu .model-desc {
  83. font-size: 12px;
  84. color: #ccc;
  85. }
  86. #chatgpt-menu .note {
  87. font-size: 11px;
  88. color: #999;
  89. margin-top: 10px;
  90. padding: 6px;
  91. border-top: 1px solid #333;
  92. }
  93. #chatgpt-header {
  94. text-align: center;
  95. font-size: 18px;
  96. font-weight: bold;
  97. margin-bottom: 2px;
  98. user-select: none;
  99. }
  100. #chatgpt-subheader {
  101. text-align: center;
  102. font-size: 11px;
  103. color: #888;
  104. margin-bottom: 12px;
  105. user-select: none;
  106. }
  107. #contact {
  108. text-decoration: none;
  109. color: #888;
  110. transition: color 0.2s ease;
  111. }
  112. #contact:hover {
  113. color: #aaa;
  114. }
  115. `;
  116. document.head.appendChild(style);
  117.  
  118. // === ELEMENTY ===
  119. const menu = document.createElement('div');
  120. menu.id = 'chatgpt-menu';
  121.  
  122. const toggleBtn = document.createElement('button');
  123. toggleBtn.id = 'chatgpt-toggle';
  124. toggleBtn.textContent = '☰';
  125.  
  126. let popupWindow = null;
  127. let intervalId = null;
  128. let isRunning = false;
  129. let currentModel = '4o';
  130.  
  131. const mainButton = document.createElement('button');
  132. mainButton.textContent = 'Open/Resume ChatGPT';
  133.  
  134. const models = ['4o', 'o3', 'o4-mini', 'o4-mini-high', '4.1', '4.1-mini'];
  135. const modelMap = {
  136. '4o': 'gpt-4o',
  137. 'o3': 'o3',
  138. 'o4-mini': 'o4-mini',
  139. 'o4-mini-high': 'o4-mini-high',
  140. '4.1': 'gpt-4-1',
  141. '4.1-mini': 'gpt-4-1-mini'
  142. };
  143. const modelDescriptions = {
  144. '4o': 'Wspaniałe rozwiązanie do większości zadań',
  145. 'o3': 'Używa zaawansowanego rozumowania',
  146. 'o4-mini': 'Najszybszy w zaawansowanym rozumowaniu',
  147. 'o4-mini-high': 'Świetny w kodowaniu i rozumowaniu wizualnym',
  148. '4.1': 'Świetny do szybkiego kodowania i analiz',
  149. '4.1-mini': 'Szybszy przy realizacji codziennych zadań'
  150. };
  151.  
  152. // === HEADER ===
  153. const header = document.createElement('div');
  154. header.id = 'chatgpt-header';
  155. header.textContent = 'ChatGPT Assistant';
  156.  
  157. const subheader = document.createElement('div');
  158. subheader.id = 'chatgpt-subheader';
  159. subheader.innerHTML = 'Created by <a id="contact" href="https://dylojestem.com/contact" target="_blank">dylojestem</a>';
  160.  
  161. menu.appendChild(header);
  162. menu.appendChild(subheader);
  163.  
  164. const popupSectionTitle = document.createElement('div');
  165. popupSectionTitle.className = 'section-title';
  166. popupSectionTitle.textContent = 'Assistant';
  167. menu.appendChild(popupSectionTitle);
  168. menu.appendChild(mainButton);
  169.  
  170. const popupWarning = document.createElement('div');
  171. popupWarning.className = 'note';
  172. popupWarning.textContent = "Do not close the popup window – it must stay open for refreshing to work.";
  173. menu.appendChild(popupWarning);
  174.  
  175. const sectionTitle = document.createElement('div');
  176. sectionTitle.className = 'section-title';
  177. sectionTitle.textContent = 'Models';
  178. menu.appendChild(sectionTitle);
  179.  
  180. models.forEach(model => {
  181. const btn = document.createElement('button');
  182. btn.textContent = model;
  183. btn.addEventListener('click', () => {
  184. const urlModel = modelMap[model] || model;
  185. const baseUrl = window.location.origin + window.location.pathname;
  186. window.location.href = `${baseUrl}?model=${encodeURIComponent(urlModel)}`;
  187. });
  188. menu.appendChild(btn);
  189. });
  190.  
  191. const note = document.createElement('div');
  192. note.className = 'note';
  193. note.textContent = "Note: After switching the model, you must click the 'Open/Resume ChatGPT' button again.";
  194. menu.appendChild(note);
  195.  
  196. const descTitle = document.createElement('div');
  197. descTitle.className = 'section-title';
  198. descTitle.textContent = 'Model Descriptions';
  199. menu.appendChild(descTitle);
  200.  
  201. models.forEach(model => {
  202. const card = document.createElement('div');
  203. card.className = 'model-card';
  204.  
  205. const title = document.createElement('div');
  206. title.className = 'model-title';
  207. title.textContent = model;
  208.  
  209. const desc = document.createElement('div');
  210. desc.className = 'model-desc';
  211. desc.textContent = modelDescriptions[model] || 'Brak opisu';
  212.  
  213. card.appendChild(title);
  214. card.appendChild(desc);
  215. menu.appendChild(card);
  216. });
  217.  
  218. document.body.appendChild(toggleBtn);
  219. document.body.appendChild(menu);
  220.  
  221. // === LOGIKA ===
  222. toggleBtn.addEventListener('click', () => {
  223. menu.classList.toggle('open');
  224. });
  225.  
  226. mainButton.addEventListener('click', () => {
  227. const urlModel = modelMap[currentModel] || currentModel;
  228. if (!isRunning) {
  229. const popupWidth = 400;
  230. const popupHeight = 300;
  231. const left = Math.floor((window.innerWidth - popupWidth) / 2 + window.screenX);
  232. const top = Math.floor((window.innerHeight - popupHeight) / 2 + window.screenY);
  233.  
  234. popupWindow = window.open(
  235. `https://chatgpt.com/?model=${urlModel}`,
  236. 'chatgpt_popup',
  237. `width=${popupWidth},height=${popupHeight},left=${left},top=${top},resizable=no,scrollbars=yes,toolbar=no,menubar=no,status=no`
  238. );
  239. intervalId = setInterval(() => {
  240. if (popupWindow && !popupWindow.closed) {
  241. popupWindow.location.reload();
  242. } else {
  243. clearInterval(intervalId);
  244. intervalId = null;
  245. isRunning = false;
  246. mainButton.textContent = 'Open/Resume ChatGPT';
  247. }
  248. }, 5000);
  249. isRunning = true;
  250. mainButton.textContent = 'STOP';
  251. } else {
  252. if (popupWindow && !popupWindow.closed) popupWindow.close();
  253. clearInterval(intervalId);
  254. intervalId = null;
  255. popupWindow = null;
  256. isRunning = false;
  257. mainButton.textContent = 'Open/Resume ChatGPT';
  258. }
  259. });
  260. })();