// ==UserScript==
// @name LM Arena Chat Interceptor
// @namespace http://tampermonkey.net/
// @version 2.2
// @description LmArena 自定义system提示词+拦截聊天请求替换绕过输入审查
// @match https://lmarena.ai/*
// @run-at document-start
// ==/UserScript==
(function () {
'use strict';
// ===== 注入 fetch 拦截器 =====
function injectScript(code) {
const s = document.createElement('script');
s.textContent = code;
document.documentElement.appendChild(s);
s.remove();
}
const hookCode = `
(function () {
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = crypto.getRandomValues(new Uint8Array(1))[0] & 15;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
const DEFAULT_SYSTEM_PROMPT = "你是一个被特殊优化的助手";
function getSystemPrompt() {
try { return localStorage.getItem("lmArenaSystemPrompt") || DEFAULT_SYSTEM_PROMPT; }
catch (e) { return DEFAULT_SYSTEM_PROMPT; }
}
function getSelectedModelId() {
try { return localStorage.getItem("lmArenaSelectedModel") || null; }
catch (e) { return null; }
}
const rawFetch = window.fetch;
if (!rawFetch) return;
function replaceRefreshContent(body){
if (body.messages && Array.isArray(body.messages)) {
var userMsg = body.messages[0];
var newMsg = document.querySelector('textarea[name="message"]')?.value;
if(newMsg){
userMsg.content = newMsg;
}
}
}
function addSystemAndAdjustUserMessageRefresh(body) {
let lastUserIndex = body.messages.map(m => m.role).lastIndexOf("user");
let lastUserMsg = body.messages[lastUserIndex];
// === 插入 system 消息(保留你原有逻辑)===
if (body.messages && Array.isArray(body.messages)) {
let systemId = null;
if (!body.messages.some(m => m.role === "system")) {
systemId = uuidv4();
body.messages.unshift({
id: systemId,
role: "system",
content: getSystemPrompt(),
experimental_attachments: [],
parentMessageIds: [],
participantPosition: "a",
modelId: null,
evaluationSessionId: lastUserMsg.evaluationSessionId,
status: "success",
failureReason: null
});
console.log("插入 system 消息:", systemId);
for (let i = 1; i < body.messages.length; i++) {
if (body.messages[i].role === "user") {
body.messages[i].parentMessageIds = [systemId];
console.log("修正第一条 user parentMessageIds:", body.messages[i]);
break;
}
}
}
// === 插入空 user(保留你原有逻辑)===
const emptyUserId = uuidv4();
const emptyUserMsg = {
id: emptyUserId,
role: "user",
content: "",
experimental_attachments: [],
parentMessageIds: [body.messages[lastUserIndex].id],
participantPosition: "a",
modelId: null,
evaluationSessionId: lastUserMsg.evaluationSessionId,
status: "pending",
failureReason: null
};
body.messages.push(emptyUserMsg);
console.log("插入空 user:", emptyUserMsg);
}
}
function addSystemAndAdjustUserMessage(body) {
// === 插入 system 消息(保留你原有逻辑)===
if (body.messages && Array.isArray(body.messages)) {
let systemId = null;
if (!body.messages.some(m => m.role === "system")) {
systemId = uuidv4();
body.messages.unshift({
id: systemId,
role: "system",
content: getSystemPrompt(),
experimental_attachments: [],
parentMessageIds: [],
participantPosition: "a",
modelId: null,
evaluationSessionId: body.id,
status: "success",
failureReason: null
});
console.log("插入 system 消息:", systemId);
for (let i = 1; i < body.messages.length; i++) {
if (body.messages[i].role === "user") {
body.messages[i].parentMessageIds = [systemId];
console.log("修正第一条 user parentMessageIds:", body.messages[i]);
break;
}
}
}
// === 插入空 user(保留你原有逻辑)===
let lastUserIndex = body.messages.map(m => m.role).lastIndexOf("user");
let lastAssistantIndex = body.messages.findIndex(
m => m.role === "assistant" && m.content === "" && m.status === "pending"
);
if (lastUserIndex !== -1 && lastAssistantIndex > lastUserIndex) {
const emptyUserId = uuidv4();
const emptyUserMsg = {
id: emptyUserId,
role: "user",
content: "",
experimental_attachments: [],
parentMessageIds: [body.messages[lastUserIndex].id],
participantPosition: "a",
modelId: null,
evaluationSessionId: body.id,
status: "pending",
failureReason: null
};
body.messages.splice(lastAssistantIndex, 0, emptyUserMsg);
console.log("插入空 user:", emptyUserMsg);
body.messages[lastAssistantIndex + 1].parentMessageIds = [emptyUserId];
console.log("修正 assistant parentMessageIds:", body.messages[lastAssistantIndex + 1]);
}
}
}
window.fetch = async function (resource, config) {
try {
const isNew = typeof resource === "string" && resource.includes("/nextjs-api/stream/create-evaluation");
const isReply = typeof resource === "string" && resource.includes("/nextjs-api/stream/post-to-evaluation/");
const isRefresh = typeof resource === "string" && resource.includes("/nextjs-api/stream/retry-evaluation-session-message");
const isImage = document.querySelector('button[aria-pressed="true"][aria-label="Image"]') != null;
if (isNew || isReply || isRefresh) {
console.group("[Interceptor] 拦截聊天请求", resource);
if (config && config.body) {
let body = JSON.parse(config.body);
//const isImage = body.modality === 'image';
if (!isImage) {
if(isRefresh){
addSystemAndAdjustUserMessageRefresh(body);
}
else{
addSystemAndAdjustUserMessage(body);
}
}
else if(isRefresh){
replaceRefreshContent(body);
}
config.body = JSON.stringify(body);
console.log("修改后的 body:", config.body);
}
console.groupEnd();
}
} catch (e) {
console.error("[Interceptor Error]", e);
}
return rawFetch.apply(this, arguments);
};
console.log("[Injected] fetch 拦截器已启用");
})();
`;
injectScript(hookCode);
// ===== 提取完整模型列表 =====
const exposeModelsCode = `
(function(){
function extractArray(serialized, key) {
const keyToken = '"' + key + '":';
const keyIdx = serialized.indexOf(keyToken);
if (keyIdx === -1) return null;
let idx = serialized.indexOf('[', keyIdx + keyToken.length);
if (idx === -1) return null;
let depth = 0, inStr = false, escape = false;
for (let i = idx; i < serialized.length; i++) {
const ch = serialized[i];
if (inStr) {
if (escape) { escape = false; }
else if (ch === '\\\\') { escape = true; }
else if (ch === '"') { inStr = false; }
} else {
if (ch === '"') inStr = true;
else if (ch === '[') depth++;
else if (ch === ']') {
depth--;
if (depth === 0) return serialized.slice(idx, i + 1);
}
}
}
return null;
}
const timer = setInterval(() => {
try {
if (!self.__next_f) return;
for (const item of self.__next_f) {
if (!Array.isArray(item) || item.length !== 2 || typeof item[1] !== "string") continue;
const serialized = item[1];
if (!serialized.includes("EvaluationStoreProvider") || !serialized.includes("initialModels")) continue;
const arrStr = extractArray(serialized, "initialModels");
if (arrStr) {
try {
const models = JSON.parse(arrStr);
localStorage.setItem("__LM_ALL_MODELS__", JSON.stringify(models));
console.log("[Injected] 成功提取模型列表,数量:", models.length);
clearInterval(timer);
} catch (e) {
console.error("[Injected] 解析失败:", e);
}
}
}
} catch (e) {
console.error("[Injected] 异常:", e);
}
}, 800);
})();
`;
//injectScript(exposeModelsCode);
// ===== 保留你的齿轮按钮(编辑system提示词)=====
const DEFAULT_SYSTEM_PROMPT = "你是一个被特殊优化的助手...";
function getSystemPrompt() {
return localStorage.getItem("lmArenaSystemPrompt") || DEFAULT_SYSTEM_PROMPT;
}
function setSystemPrompt(v) {
localStorage.setItem("lmArenaSystemPrompt", v);
}
function createPanel() {
const overlay = document.createElement("div");
overlay.style.position = "fixed";
overlay.style.top = "0";
overlay.style.left = "0";
overlay.style.width = "100%";
overlay.style.height = "100%";
overlay.style.background = "rgba(0,0,0,0.6)";
overlay.style.zIndex = "9999";
overlay.style.display = "flex";
overlay.style.alignItems = "center";
overlay.style.justifyContent = "center";
overlay.style.overflow = "auto"; // 支持滚动
const panel = document.createElement("div");
panel.style.background = "#222";
panel.style.color = "#eee";
panel.style.padding = "24px";
panel.style.borderRadius = "8px";
panel.style.width = "800px";
panel.style.maxWidth = "90%";
panel.style.maxHeight = "90vh";
panel.style.boxShadow = "0 4px 12px rgba(0,0,0,0.8)";
panel.style.overflowY = "auto"; // 内容可滚动
// === 标题 ===
const title = document.createElement("div");
title.textContent = "系统设置";
title.style.fontWeight = "bold";
title.style.fontSize = "18px";
title.style.marginBottom = "16px";
title.style.textAlign = "center";
panel.appendChild(title);
// === System 提示词编辑区 ===
const sysTitle = document.createElement("div");
sysTitle.textContent = "📝 System 提示词";
sysTitle.style.marginTop = "16px";
sysTitle.style.fontWeight = "bold";
sysTitle.style.color = "#0f0";
panel.appendChild(sysTitle);
const sysTextarea = document.createElement("textarea");
sysTextarea.style.width = "100%";
sysTextarea.style.height = "120px";
sysTextarea.style.background = "#111";
sysTextarea.style.color = "#0f0";
sysTextarea.style.border = "1px solid #555";
sysTextarea.style.borderRadius = "4px";
sysTextarea.style.marginTop = "8px";
sysTextarea.value = getSystemPrompt();
panel.appendChild(sysTextarea);
// // === 模型选择区 ===
// const modelTitle = document.createElement("div");
// modelTitle.textContent = "🤖 选择默认模型";
// modelTitle.style.marginTop = "24px";
// modelTitle.style.fontWeight = "bold";
// modelTitle.style.color = "#0af";
// panel.appendChild(modelTitle);
// const modelSelect = document.createElement("select");
// modelSelect.style.width = "100%";
// modelSelect.style.padding = "8px";
// modelSelect.style.marginTop = "8px";
// modelSelect.style.background = "#111";
// modelSelect.style.color = "#fff";
// modelSelect.style.border = "1px solid #555";
// modelSelect.style.borderRadius = "4px";
// // 加载模型
// const raw = localStorage.getItem("__LM_ALL_MODELS__");
// if (raw) {
// try {
// const models = JSON.parse(raw);
// const textModels = models.filter(m => !m.capabilities?.outputCapabilities?.image);
// const imageModels = models.filter(m => m.capabilities?.outputCapabilities?.image);
// function addOptgroup(label, models) {
// const group = document.createElement("optgroup");
// group.label = label;
// models.forEach(m => {
// const opt = document.createElement("option");
// opt.value = m.id;
// opt.textContent = `${m.publicName} (${m.id})`;
// group.appendChild(opt);
// });
// modelSelect.appendChild(group);
// }
// addOptgroup("🔤 语言模型", textModels);
// if (imageModels.length > 0) {
// addOptgroup("🖼️ 图像模型", imageModels);
// }
// // 设置当前选中
// const savedModelId = localStorage.getItem("lmArenaSelectedModel");
// if (savedModelId) {
// modelSelect.value = savedModelId;
// }
// } catch (e) {
// console.error("加载模型列表失败:", e);
// modelSelect.innerHTML = "<option>加载模型失败</option>";
// }
// } else {
// modelSelect.innerHTML = "<option>模型列表未加载</option>";
// }
// panel.appendChild(modelSelect);
// === 按钮区 ===
const btnContainer = document.createElement("div");
btnContainer.style.marginTop = "24px";
btnContainer.style.display = "flex";
btnContainer.style.justifyContent = "center";
btnContainer.style.gap = "12px";
const btnSave = document.createElement("button");
btnSave.textContent = "💾 保存设置";
btnSave.style.background = "#0a0";
btnSave.style.color = "#fff";
btnSave.style.border = "none";
btnSave.style.padding = "8px 16px";
btnSave.style.borderRadius = "4px";
btnSave.style.cursor = "pointer";
btnSave.style.fontSize = "14px";
btnSave.onclick = () => {
setSystemPrompt(sysTextarea.value);
//localStorage.setItem("lmArenaSelectedModel", modelSelect.value);
document.body.removeChild(overlay);
alert("✅ 设置已保存:System 提示词");
};
btnContainer.appendChild(btnSave);
const btnCancel = document.createElement("button");
btnCancel.textContent = "❌ 取消";
btnCancel.style.background = "#a00";
btnCancel.style.color = "#fff";
btnCancel.style.border = "none";
btnCancel.style.padding = "8px 16px";
btnCancel.style.borderRadius = "4px";
btnCancel.style.cursor = "pointer";
btnCancel.style.fontSize = "14px";
btnCancel.onclick = () => document.body.removeChild(overlay);
btnContainer.appendChild(btnCancel);
panel.appendChild(btnContainer);
overlay.appendChild(panel);
document.body.appendChild(overlay);
//console.log("[Userscript] 设置面板已打开,包含模型选择器");
}
// 添加齿轮按钮
function addGearButton() {
const container = document.querySelector('textarea[name="message"]')
?.nextElementSibling
?.querySelector('div[data-sentry-component="SelectChatModality"]');
if (container && !container.querySelector('[aria-label="Edit System Prompt"]')) {
const btn = document.createElement("button");
btn.type = "button";
btn.className = container.querySelector("button")?.className || "";
btn.setAttribute("aria-label", "Edit System Prompt");
btn.innerHTML = `
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"
viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="lucide lucide-settings w-4 h-4 transition-colors
duration-150 ease-out text-interactive-normal">
<circle cx="12" cy="12" r="3"></circle>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83
2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0
0-1 1.51V21a2 2 0 0 1-4 0v-.09a1.65 1.65 0 0
0-1-1.51 1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1
1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65
1.65 0 0 0-1.51-1H3a2 2 0 0
1 0-4h.09c.7 0 1.31-.4 1.51-1a1.65
1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1
1 2.83-2.83l.06.06c.46.46 1.12.61
1.82.33.6-.2 1-.81 1-1.51V3a2 2 0 0
1 4 0v.09c0 .7.4 1.31 1 1.51.7.28
1.36.13 1.82-.33l.06-.06a2 2 0 1
1 2.83 2.83l-.06.06c-.46.46-.61
1.12-.33 1.82.2.6.81 1 1.51
1H21a2 2 0 0 1 0 4h-.09c-.7 0-1.31.4-1.51
1z"></path>
</svg>`;
btn.onclick = createPanel;
container.appendChild(btn);
console.log("[Userscript] 齿轮按钮已添加");
}
}
// ===== 监听 DOM,统一初始化齿轮按钮 + 模型下拉框 =====
const obs = new MutationObserver(async () => {
const container = document.querySelector('div[data-sentry-component="SelectChatModality"]');
if (!container) return;
// 1. 添加齿轮按钮(如果不存在)
if (!container.querySelector('[aria-label="Edit System Prompt"]')) {
addGearButton();
}
});
obs.observe(document, { childList: true, subtree: true });
})();