Greasy Fork

Greasy Fork is available in English.

DeepSeeker

Prevents deletion of filtered/censored answers on DeepSeek. This is purely visual change. FILTERED ANSWERS WILL PERSIST ONLY UNTIL THE PAGE IS RELOADED.

目前为 2025-02-02 提交的版本,查看 最新版本

// ==UserScript==
// @name         DeepSeeker
// @namespace    https://github.com/qt-kaneko/DeepSeeker
// @version      1.0.0
// @description  Prevents deletion of filtered/censored answers on DeepSeek. This is purely visual change. FILTERED ANSWERS WILL PERSIST ONLY UNTIL THE PAGE IS RELOADED.
// @author       Kaneko Qt
// @license      GPL-3.0-or-later
// @match        https://chat.deepseek.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=deepseek.com
// @run-at       document-start
// @unwrap
// ==/UserScript==

(function() { "use strict";

let _addEventListener = XMLHttpRequest.prototype.addEventListener;
let _responseText = Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype, `responseText`);

/**
 * @this {XMLHttpRequest}
 * @template {keyof XMLHttpRequestEventMap} K
 * @param {K} type
 * @param {(this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any} listener
 * @param {boolean | AddEventListenerOptions | undefined} options
 */
XMLHttpRequest.prototype.addEventListener = function(type, listener, options) {
  if (type === `readystatechange`)
  {
    let originalListener = listener;

    listener = function(ev) {
      if (this.responseURL === `https://chat.deepseek.com/api/v0/chat/edit_message` || this.responseURL === `https://chat.deepseek.com/api/v0/chat/completion` && this.readyState === 4)
      {
        let eventsText = _responseText.get.call(this);
        let events = eventsText.split(`\n\n`);

        for (let [eventI, event] of events.entries())
        {
          if (event === ``) continue;
          if (event === `data: [DONE]`) continue;

          let eventJson = JSON.parse(event.slice(`data: `.length));
          if (eventJson.choices?.[0]?.finish_reason === `content_filter`)
          {
            // Get patched, idiot :P
            eventJson.choices[0].finish_reason = `stop`;
            events[eventI] = `data: ` + JSON.stringify(eventJson);
          }
        }

        eventsText = events.join(`\n\n`);
        Object.defineProperty(this, `response`, {value: eventsText, configurable: true});
        Object.defineProperty(this, `responseText`, {value: eventsText, configurable: true});
      }

      return originalListener.apply(this, arguments);
    };
  }

  return _addEventListener.apply(this, arguments);
};

})();