您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automatically removes <!-- HTML comments --> from bot responses (useful if you don't want CoT to remain in your prompt). Makes the deleted comments visible via a new [CoT] button on the UI as well as in the browser console
// ==UserScript== // @name Agnai: Clear CoT inside HTML comments from bot responses // @description Automatically removes <!-- HTML comments --> from bot responses (useful if you don't want CoT to remain in your prompt). Makes the deleted comments visible via a new [CoT] button on the UI as well as in the browser console // @author prkstop // @license MIT // @match https://agnai.chat/* // @version 0.0.1 // @namespace https://greasyfork.org/users/1124234 // ==/UserScript== (function() { // Settings const EMPTY_THE_COMMENT_INSTEAD_OF_DELETING = false // helpers const log = a => (console.log(a), a) const q = sel => document.querySelector(sel) const qAll = sel => document.querySelectorAll(sel) const last = arr => arr[arr.length-1] const sleep = ms => new Promise(res => setTimeout(res, ms)) const selStrs = { loadingAnim: '.dot-flashing', markdownClass: 'rendered-markdown', } const sels = { editBtns: () => [...qAll('.edit-btn')], editBtn: () => last([...qAll('.edit-btn')]), editBox: () => q('.msg-edit-text-box'), confirmEditBtn: () => q('.confirm-edit-btn'), cancelEditBtn: () => q('.cancel-edit-btn'), loadingAnim: () => q(selStrs.loadingAnim), lastIconList: () => last([...qAll('.flex.flex-row.justify-between.pb-1 > div.flex')]), streamingMarkdown: () => q('.streaming-markdown') } const loadingAnimRemoved = muts => muts .flatMap(m => [...m.removedNodes]) .find(n => n.querySelector?.(selStrs.loadingAnim)) const comments = {} let nextId = 0 let mustRefreshCotId = null const clearLatestHtmlComment = async () => { const chatEditingInitiallyEnabled = sels.editBtns().length > 0 if (!chatEditingInitiallyEnabled) { // TODO: handle this case by enabling it then re-disabling it later console.log("[HTML Comment Clearer] Enable chat editing if you haven't.") return } await sleep(0) sels.editBtn().click() if (!sels.editBox()?.innerHTML) return const htmlCommentRegex = /<![-–—]{1,2}[\s\S]*?[-–—]{1,2}>/g const found = sels.editBox().innerHTML.match(htmlCommentRegex)?.join('\n') ?? '' sels.editBox().innerHTML = sels.editBox().innerHTML .replace(htmlCommentRegex, EMPTY_THE_COMMENT_INSTEAD_OF_DELETING ? '<!-- -->' : '') .replace(/^(<br>\s*)+/i, '') .trim() sels.confirmEditBtn().click() const id = nextId nextId++ comments[id] = found.replace(/</g, '<').replace(/>/g, '>').trim() if (!comments[id]) return console.log(`[HTML Comment Clearer] Removed this comment:\n${comments[id].replace(/<br>/g, '\n')}`) ensureCotBtnIsShown(id) } const ensureCotBtnIsShown = async (id) => { q(`#show-comments-${id}`)?.remove() sels.lastIconList()?.insertAdjacentHTML('afterbegin', ` <div id="show-comments-${id}" style="cursor: pointer;">[CoT]</div> `) q(`#show-comments-${id}`).addEventListener('click', () => { alert(comments[id]?.replace(/<br>/g, '\n')) }) await sleep(0) mustRefreshCotId = id } let isStreaming = false let addingCot = false new MutationObserver(async muts => { const previouslyStreaming = isStreaming if (sels.streamingMarkdown()) { mustRefreshCotId = null isStreaming = true } else { isStreaming = false if (previouslyStreaming) { clearLatestHtmlComment() } } if (sels.loadingAnim()) { mustRefreshCotId = null } if (loadingAnimRemoved(muts)) { // await sleep(2000) if (sels.loadingAnim() || isStreaming) return clearLatestHtmlComment() } if (mustRefreshCotId !== null && !addingCot) { addingCot = true await ensureCotBtnIsShown(mustRefreshCotId) addingCot = false } }).observe(document.body, { childList: true, subtree: true }) })();