AI Fuck CC - Simplify Module

简化脚本

  1. // ==UserScript==
  2. // @name AI Fuck CC - Simplify Module
  3. // @version 1.3
  4. // @license MIT
  5. // @match *
  6. // @description 简化脚本
  7. // @namespace https://greasyfork.org/users/1462884
  8. // ==/UserScript==
  9.  
  10. var SimplifyModule = (function() { // 使用 var 或 const/let 取决于你的环境和偏好
  11. 'use strict';
  12.  
  13. // --- 配置 (可以设为默认值,允许外部覆盖) ---
  14. const DEFAULT_CONFIG = {
  15. tokenKey: 'console_token',
  16. convMapKey: 'conversationIdInfo',
  17. aiReplySelector: 'div#ai-chat-answer',
  18. contentContainerSelector: '.undefined.markdown-body',
  19. selectorsToRemoveLatest: 'details.thinking, details.statusbar',
  20. selectorsToRemoveSecondLatest: 'details.optionsarea, details.memoryarea, details.thinking, details.statusbar',
  21. apiBaseUrl: 'https://aifuck.cc/console/api/installed-apps/',
  22. tryVisualUpdate: false // 新增配置:是否尝试直接更新页面DOM
  23. };
  24.  
  25. // --- 内部辅助函数 ---
  26. function logDebug(...args) { console.log('[SimplifyMod DEBUG]', ...args); }
  27. function logInfo(...args) { console.log('[SimplifyMod INFO]', ...args); }
  28. function logError(...args) { console.error('[SimplifyMod ERROR]', ...args); }
  29.  
  30. // ... (getAuthToken, getAppId, getConversationId - 可能需要接收 config) ...
  31. // ... (fetchMessages - 可能需要接收 config) ...
  32. // ... (updateMessageApi - 可能需要接收 config) ...
  33. // ... (extractSimplifiedContent - 不变) ...
  34. // ... (updatePageElementVisuals - 如果保留,基本不变) ...
  35.  
  36. // --- 核心处理函数 (修改自 processLastTwoReplies) ---
  37. async function simplifyReplies(userConfig = {}) {
  38. const config = { ...DEFAULT_CONFIG, ...userConfig }; // 合并配置
  39. logInfo('Starting simplification process with config:', config);
  40.  
  41. let processedCount = 0;
  42. let failedCount = 0;
  43. let simplifiedResults = []; // 存储简化结果
  44.  
  45. // --- 1. 获取必要信息 ---
  46. const authToken = getAuthToken(config.tokenKey); // 修改 getAuthToken 以接受 key
  47. const appId = getAppId();
  48. const conversationId = getConversationId(appId, config.convMapKey); // 修改 getConversationId
  49.  
  50. if (!authToken || !appId || !conversationId) {
  51. const errorMsg = 'Missing essential info (Token, App ID, or Conv ID).';
  52. logError(errorMsg);
  53. // 返回一个 rejected Promise
  54. return Promise.reject({ success: false, message: errorMsg });
  55. }
  56.  
  57. try {
  58. // --- 2. 获取消息和页面元素 ---
  59. logInfo('Fetching message list...');
  60. const apiMessages = await fetchMessages(appId, conversationId, authToken, config.apiBaseUrl); // 修改 fetchMessages
  61. const pageReplies = document.querySelectorAll(config.aiReplySelector);
  62. logInfo(`Found ${pageReplies.length} AI reply elements on page.`);
  63. // ... (处理消息数量不匹配的警告日志) ...
  64.  
  65. if (pageReplies.length === 0) {
  66. logInfo('No AI replies found on page. Nothing to do.');
  67. return Promise.resolve({ success: true, message: 'No AI replies found on page.', processedCount: 0, failedCount: 0 });
  68. }
  69.  
  70. // --- 3. 确定处理目标 ---
  71. const repliesToProcess = [];
  72. // ... (基本同原 processLastTwoReplies 确定 latest 和 second latest 逻辑) ...
  73. // 确保使用 config 中的选择器
  74.  
  75. // --- 4. 依次处理 ---
  76. for (const target of repliesToProcess) {
  77. logInfo(`--- Processing ${target.label} Reply (Page Index: ${target.index}) ---`);
  78. const contentContainer = target.element.querySelector(config.contentContainerSelector);
  79. if (!contentContainer) {
  80. logError(` - Could not find content container for ${target.label} reply. Skipping.`);
  81. failedCount++;
  82. continue;
  83. }
  84.  
  85. // 4.1 提取简化内容
  86. const originalHtml = contentContainer.innerHTML; // 保存原始HTML供返回
  87. const simplifiedHtml = extractSimplifiedContent(contentContainer, target.selectorsToRemove);
  88.  
  89. if (simplifiedHtml !== null && simplifiedHtml !== "") {
  90. try {
  91. // 4.2 API 更新
  92. await updateMessageApi(appId, target.apiMessage.id, simplifiedHtml, authToken, config.apiBaseUrl); // 修改 updateMessageApi
  93.  
  94. // 4.3 (可选) 尝试视觉更新
  95. if (config.tryVisualUpdate) {
  96. updatePageElementVisuals(target.element.querySelector(config.contentContainerSelector), simplifiedHtml); // 调用修改后的视觉更新函数
  97. }
  98.  
  99. // 4.4 记录成功
  100. processedCount++;
  101. simplifiedResults.push({
  102. messageId: target.apiMessage.id,
  103. index: target.index,
  104. originalHtml: originalHtml,
  105. simplifiedHtml: simplifiedHtml
  106. });
  107. logInfo(` - Successfully processed ${target.label} reply.`);
  108.  
  109. } catch (updateError) {
  110. logError(` - Failed to update ${target.label} reply (API or Visual):`, updateError);
  111. failedCount++;
  112. }
  113. } else {
  114. logError(` - Failed to extract valid content for ${target.label} reply. Skipping update.`);
  115. failedCount++;
  116. }
  117. await new Promise(resolve => setTimeout(resolve, 150)); // 保留延迟
  118. }
  119.  
  120. // --- 5. 返回最终结果 ---
  121. const finalMessage = `Simplification finished. Success: ${processedCount}, Failed: ${failedCount}.`;
  122. logInfo(`--- Processing Finished --- ${finalMessage}`);
  123. return Promise.resolve({
  124. success: processedCount > 0 || failedCount === 0, // 至少处理成功一个算成功,或者没有失败也算成功
  125. message: finalMessage,
  126. processedCount: processedCount,
  127. failedCount: failedCount,
  128. simplifiedData: simplifiedResults,
  129. visualUpdateAttempted: config.tryVisualUpdate
  130. });
  131.  
  132. } catch (error) {
  133. logError('An overall error occurred during simplification:', error);
  134. return Promise.reject({
  135. success: false,
  136. message: `An unexpected error occurred: ${error.message || error}`,
  137. error: error
  138. });
  139. }
  140. }
  141.  
  142. // --- 返回模块的公共接口 ---
  143. return {
  144. // 提供简化函数
  145. simplify: simplifyReplies,
  146.  
  147. // (可选)如果主脚本需要,可以暴露一些配置或内部函数,但不推荐
  148. // getConfigDefaults: () => ({ ...DEFAULT_CONFIG }),
  149. };
  150.  
  151. })(); // 立即执行
  152.  
  153. // 注意:在 Tampermonkey 中,如果主脚本使用 @require 引入这个文件,
  154. // 主脚本可以直接使用 SimplifyModule 这个变量。