Deepseek Chat Monitor

The blocked thinking and response will be displayed on the right interface. 右侧界面会显示输出后被屏蔽的思考和回复内容。

  1. // ==UserScript==
  2. // @name Deepseek Chat Monitor
  3. // @version 1.4.3
  4. // @description The blocked thinking and response will be displayed on the right interface. 右侧界面会显示输出后被屏蔽的思考和回复内容。
  5. // @match https://chat.deepseek.com/*
  6. // @grant none
  7. // @namespace https://greasyfork.org/users/762448
  8. // ==/UserScript==
  9.  
  10. (function() {
  11. 'use strict';
  12.  
  13. const pluginUI = document.createElement('div');
  14. pluginUI.id = 'plugin-ui';
  15. pluginUI.style.position = 'fixed';
  16. pluginUI.style.top = '0';
  17. pluginUI.style.right = '20px';
  18. pluginUI.style.width = '300px';
  19. pluginUI.style.height = '100%';
  20. pluginUI.style.overflowY = 'scroll';
  21. pluginUI.style.backgroundColor = '#f9f9f9';
  22. pluginUI.style.color = '#333';
  23. pluginUI.style.border = '1px solid #ccc';
  24. pluginUI.style.borderRadius = '5px';
  25. pluginUI.style.padding = '10px';
  26. pluginUI.style.zIndex = '9999';
  27. pluginUI.style.transition = 'right 0.3s ease';
  28.  
  29. const returnButton = document.createElement('button');
  30. returnButton.id = 'return-button';
  31. returnButton.style.position = 'fixed';
  32. returnButton.style.top = '10px';
  33. returnButton.style.right = '330px';
  34. returnButton.style.width = '40px';
  35. returnButton.style.height = '40px';
  36. returnButton.style.backgroundColor = '#444';
  37. returnButton.style.color = '#fff';
  38. returnButton.style.border = 'none';
  39. returnButton.style.borderRadius = '50%';
  40. returnButton.style.fontSize = '16px';
  41. returnButton.style.zIndex = '10000';
  42. returnButton.textContent = '❌';
  43. returnButton.title = 'Clear Interface';
  44. returnButton.addEventListener('click', () => {
  45. pluginUI.innerHTML = '';
  46. });
  47.  
  48. const toggleButton = document.createElement('button');
  49. toggleButton.id = 'toggle-button';
  50. toggleButton.style.position = 'fixed';
  51. toggleButton.style.top = '60px';
  52. toggleButton.style.right = '330px';
  53. toggleButton.style.width = '40px';
  54. toggleButton.style.height = '40px';
  55. toggleButton.style.backgroundColor = '#444';
  56. toggleButton.style.color = '#fff';
  57. toggleButton.style.border = 'none';
  58. toggleButton.style.borderRadius = '50%';
  59. toggleButton.style.fontSize = '16px';
  60. toggleButton.style.zIndex = '10000';
  61. toggleButton.textContent = '➡️';
  62. toggleButton.title = 'Toggle Sidebar';
  63. toggleButton.addEventListener('click', () => {
  64. if (pluginUI.style.right === '20px') {
  65. pluginUI.style.right = '-300px';
  66. returnButton.style.right = '20px';
  67. toggleButton.style.right = '20px';
  68. toggleButton.textContent = '⬅️';
  69. copyButton.style.right = '20px';
  70. historyButton.style.right = '20px';
  71. } else {
  72. pluginUI.style.right = '20px';
  73. returnButton.style.right = '330px';
  74. toggleButton.style.right = '330px';
  75. toggleButton.textContent = '➡️';
  76. copyButton.style.right = '330px';
  77. historyButton.style.right = '330px';
  78. }
  79. });
  80.  
  81. const copyButton = document.createElement('button');
  82. copyButton.id = 'copy-button';
  83. copyButton.style.position = 'fixed';
  84. copyButton.style.top = '110px';
  85. copyButton.style.right = '330px';
  86. copyButton.style.width = '40px';
  87. copyButton.style.height = '40px';
  88. copyButton.style.backgroundColor = '#444';
  89. copyButton.style.color = '#fff';
  90. copyButton.style.border = 'none';
  91. copyButton.style.borderRadius = '50%';
  92. copyButton.style.fontSize = '16px';
  93. copyButton.style.zIndex = '10000';
  94. copyButton.textContent = '📋';
  95. copyButton.title = 'Copy Content';
  96. copyButton.addEventListener('click', () => {
  97. const content = pluginUI.innerText;
  98. navigator.clipboard.writeText(content).then(() => {
  99. alert('Content copied to clipboard!');
  100. }, () => {
  101. alert('Failed to copy content');
  102. });
  103. });
  104.  
  105. const historyButton = document.createElement('button');
  106. historyButton.id = 'history-button';
  107. historyButton.style.position = 'fixed';
  108. historyButton.style.top = '160px';
  109. historyButton.style.right = '330px';
  110. historyButton.style.width = '40px';
  111. historyButton.style.height = '40px';
  112. historyButton.style.backgroundColor = '#444';
  113. historyButton.style.color = '#fff';
  114. historyButton.style.border = 'none';
  115. historyButton.style.borderRadius = '50%';
  116. historyButton.style.fontSize = '16px';
  117. historyButton.style.zIndex = '10000';
  118. historyButton.textContent = '🕒';
  119. historyButton.title = 'View History';
  120. historyButton.addEventListener('click', () => {
  121. pluginUI.innerHTML = '';
  122. updateHistoryUI();
  123. });
  124.  
  125. document.body.appendChild(pluginUI);
  126. document.body.appendChild(returnButton);
  127. document.body.appendChild(toggleButton);
  128. document.body.appendChild(copyButton);
  129. document.body.appendChild(historyButton);
  130.  
  131. function updateTheme() {
  132. if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
  133. pluginUI.style.backgroundColor = '#333';
  134. pluginUI.style.color = '#fff';
  135. pluginUI.style.border = '1px solid #555';
  136. returnButton.style.backgroundColor = '#666';
  137. returnButton.style.color = '#fff';
  138. toggleButton.style.backgroundColor = '#666';
  139. toggleButton.style.color = '#fff';
  140. copyButton.style.backgroundColor = '#666';
  141. copyButton.style.color = '#fff';
  142. historyButton.style.backgroundColor = '#666';
  143. historyButton.style.color = '#fff';
  144. } else {
  145. pluginUI.style.backgroundColor = '#f9f9f9';
  146. pluginUI.style.color = '#333';
  147. pluginUI.style.border = '1px solid #ccc';
  148. returnButton.style.backgroundColor = '#888';
  149. returnButton.style.color = '#fff';
  150. toggleButton.style.backgroundColor = '#888';
  151. toggleButton.style.color = '#fff';
  152. copyButton.style.backgroundColor = '#888';
  153. copyButton.style.color = '#fff';
  154. historyButton.style.backgroundColor = '#888';
  155. historyButton.style.color = '#fff';
  156. }
  157. }
  158.  
  159. updateTheme();
  160. window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', updateTheme);
  161.  
  162. let latestChatNum = 2;
  163. let previousContent = '';
  164. let longestContent = '';
  165. let historyContent = [];
  166.  
  167. function getLatestChatContent() {
  168. let retries = 1;
  169. let element = null;
  170. const getSelector = (num) => `#root > div > div > div.c3ecdb44 > div._7780f2e > div > div._3919b83 > div > div > div.dad65929 > div:nth-child(${num})`;
  171.  
  172. while (retries >= 0) {
  173. while (true) {
  174. const selector = getSelector(latestChatNum);
  175. element = document.querySelector(selector);
  176. if (!element) {
  177. break;
  178. }
  179. latestChatNum += 2;
  180. }
  181. latestChatNum -= 2;
  182. const selector = getSelector(latestChatNum);
  183. element = document.querySelector(selector);
  184. if (!element) {
  185. console.log('Cannot find the latest chat');
  186. latestChatNum = 2;
  187. retries--;
  188. if (retries < 0) {
  189. return;
  190. }
  191. } else {
  192. break;
  193. }
  194. }
  195. const chatContentElement = element.querySelector('div.ds-markdown.ds-markdown--block');
  196. const thinkingContentElement = element.querySelector('div._48edb25 > div.e1675d8b');
  197. let currentContent = '';
  198. if (thinkingContentElement) {
  199. const paragraphs = thinkingContentElement.querySelectorAll('p');
  200. paragraphs.forEach(p => {
  201. currentContent += p.innerText + '\n';
  202. });
  203. }
  204. if (chatContentElement) {
  205. currentContent += chatContentElement.innerHTML;
  206. }
  207. if (currentContent.length > longestContent.length) {
  208. longestContent = currentContent;
  209. }
  210. if (currentContent.length < previousContent.length) {
  211. pluginUI.innerHTML = longestContent;
  212. historyContent.push(longestContent);
  213. longestContent = '';
  214. }
  215. previousContent = currentContent;
  216. }
  217.  
  218. function updateHistoryUI() {
  219. historyContent.forEach((content, index) => {
  220. const historyItem = document.createElement('div');
  221. historyItem.style.borderBottom = '1px solid #ccc';
  222. historyItem.style.padding = '10px';
  223. historyItem.style.cursor = 'pointer';
  224. historyItem.textContent = content.length > 50 ? content.substring(0, 50) + '...' : content;
  225. historyItem.addEventListener('click', () => {
  226. pluginUI.innerHTML = content;
  227. });
  228. pluginUI.appendChild(historyItem);
  229. });
  230. }
  231.  
  232. const observer = new MutationObserver(getLatestChatContent);
  233. const config = { childList: true, subtree: true, characterData: true };
  234.  
  235. function startObserving() {
  236. const targetNode = document.querySelector('#root');
  237. if (targetNode) {
  238. observer.observe(targetNode, config);
  239. } else {
  240. console.log('Cannot find the target node');
  241. }
  242. }
  243.  
  244. function stopObserving() {
  245. observer.disconnect();
  246. }
  247.  
  248. window.onload = function() {
  249. setTimeout(startObserving, 500);
  250. };
  251. })();