Injects a preset dropdown and autofills JanitorAI-style proxy forms
Verze ze dne
// ==UserScript==
// @name JanitorAI Proxy AutoFill w/ Preset Dropdown
// @namespace https://janitorai.com/
// @version 1.0
// @description Injects a preset dropdown and autofills JanitorAI-style proxy forms
// @match https://janitorai.com/chats/*
// @grant none
// @license MIT
// ==/UserScript==
(function () {
'use strict';
function getAllPresets() {
return JSON.parse(localStorage.getItem('user_presets') || '{}');
}
// Load from localStorage or use defaults
let customPresets = JSON.parse(localStorage.getItem('user_presets') || '{}');
const fireReactInput = (el, value) => {
const lastValue = el.value;
el.value = value;
const tracker = el._valueTracker;
if (tracker) {
tracker.setValue(lastValue);
}
el.dispatchEvent(
new Event('input', { bubbles: true, cancelable: false })
);
};
function injectDropdownOnceReady() {
const modelInput = document.querySelector('#model');
if (!modelInput) return;
// Prevent double injection
if (document.querySelector('#presetDropdown')) return;
const wrapperDiv = document.createElement('div');
wrapperDiv.style.marginBottom = '10px';
const label = document.createElement('label');
label.textContent = '🔥 Preset: ';
label.style.fontWeight = 'bold';
label.style.marginRight = '10px';
const dropdown = document.createElement('select');
dropdown.id = 'presetDropdown';
dropdown.style.padding = '4px';
dropdown.style.borderRadius = '4px';
dropdown.style.backgroundColor = '#111';
dropdown.style.color = '#fff';
const presets = getAllPresets();
for (const name in presets) {
const opt = document.createElement('option');
opt.value = name;
opt.textContent = name;
dropdown.appendChild(opt);
}
dropdown.addEventListener('change', () => {
const p = presets[dropdown.value];
fireReactInput(document.querySelector('#model'), p.model);
fireReactInput(document.querySelector('#open_ai_reverse_proxy'), p.proxy);
fireReactInput(document.querySelector('#reverseProxyKey'), p.key);
const jailbreakPromptBox = document.querySelector('#open_ai_jailbreak_prompt-label')?.parentElement?.querySelector('textarea');
if (jailbreakPromptBox) {
fireReactInput(jailbreakPromptBox, p.prompt);
}
});
wrapperDiv.appendChild(label);
wrapperDiv.appendChild(dropdown);
// Insert above the model input
modelInput.parentNode.insertBefore(wrapperDiv, modelInput);
// Trigger first preset
dropdown.dispatchEvent(new Event('change'));
console.log('%c[🔥 Preset dropdown injected successfully]', 'color: lime; font-weight: bold;');
}
function ensureRadiosChecked() {
const apiRadio = document.querySelector('input[name="api"][value="other"]');
if (apiRadio) apiRadio.checked = true;
const customRadio = document.querySelector('input[value="custom"]');
if (customRadio) customRadio.checked = true;
}
function applyPreset(name) {
const presets = getAllPresets();
const p = presets[name];
if (!p) return;
fireReactInput(document.querySelector('#model'), p.model);
fireReactInput(document.querySelector('#open_ai_reverse_proxy'), p.proxy);
fireReactInput(document.querySelector('#reverseProxyKey'), p.key);
const jailbreakPromptBox = document.querySelector('#open_ai_jailbreak_prompt-label')?.parentElement?.querySelector('textarea');
if (jailbreakPromptBox) {
fireReactInput(jailbreakPromptBox, p.prompt);
}
}
const injectDropdown = () => {
const modelField = document.querySelector('#model');
if (!modelField) return;
if (document.getElementById('presetDropdown')) return;
const dropdown = document.createElement('select');
dropdown.id = 'presetDropdown';
dropdown.style.marginBottom = '10px';
dropdown.style.padding = '6px';
dropdown.style.border = '1px solid #ccc';
dropdown.style.borderRadius = '4px';
dropdown.style.fontSize = '14px';
const presets = getAllPresets();
if (Object.keys(presets).length === 0) {
const emptyOption = document.createElement('option');
emptyOption.textContent = "No presets found";
emptyOption.disabled = true;
dropdown.appendChild(emptyOption);
}
for (const name in presets) {
const opt = document.createElement('option');
opt.value = name;
opt.textContent = name;
dropdown.appendChild(opt);
}
// Restore last used preset if exists
const saved = localStorage.getItem('custom_preset_choice');
if (saved && presets[saved]) {
dropdown.value = saved;
applyPreset(saved); // Apply it on load!
}
// When changed, apply and save
dropdown.addEventListener('change', () => {
localStorage.setItem('custom_preset_choice', dropdown.value);
applyPreset(dropdown.value);
});
modelField.parentElement.insertBefore(dropdown, modelField);
const saveButton = document.createElement('button');
saveButton.textContent = '💾 Save Current as Preset';
saveButton.style.marginLeft = '10px';
saveButton.style.padding = '5px 10px';
saveButton.style.border = '1px solid #ccc';
saveButton.style.borderRadius = '4px';
saveButton.style.cursor = 'pointer';
saveButton.addEventListener('click', () => {
const name = prompt("Enter a name for your preset:");
if (!name) return;
const model = document.querySelector('#model')?.value || "";
const proxy = document.querySelector('#open_ai_reverse_proxy')?.value || "";
const key = document.querySelector('#reverseProxyKey')?.value || "";
const promptBox = document.querySelector('#open_ai_jailbreak_prompt-label')?.parentElement?.querySelector('textarea');
const promptText = promptBox?.value || "";
let currentPresets = JSON.parse(localStorage.getItem('user_presets') || '{}');
currentPresets[name] = { model, proxy, key, prompt: promptText };
localStorage.setItem('user_presets', JSON.stringify(currentPresets));
// Add it to dropdown if not already
if (!document.querySelector(`#presetDropdown option[value="${name}"]`)) {
const opt = document.createElement('option');
opt.value = name;
opt.textContent = name;
document.getElementById('presetDropdown').appendChild(opt);
}
document.getElementById('presetDropdown').value = name;
localStorage.setItem('custom_preset_choice', name);
applyPreset(name);
alert(`Preset "${name}" saved!`);
});
modelField.parentElement.insertBefore(saveButton, modelField);
const deleteButton = document.createElement('button');
deleteButton.textContent = '🗑 Delete Preset';
deleteButton.style.marginLeft = '10px';
deleteButton.style.padding = '5px 10px';
deleteButton.style.border = '1px solid #ccc';
deleteButton.style.borderRadius = '4px';
deleteButton.style.cursor = 'pointer';
deleteButton.style.color = 'red';
deleteButton.addEventListener('click', () => {
const selected = document.getElementById('presetDropdown').value;
if (!confirm(`Are you sure you want to delete the preset "${selected}"?`)) return;
// Remove from localStorage
let currentPresets = JSON.parse(localStorage.getItem('user_presets') || '{}');
delete currentPresets[selected];
localStorage.setItem('user_presets', JSON.stringify(currentPresets));
// Remove from dropdown
const optionToRemove = document.querySelector(`#presetDropdown option[value="${selected}"]`);
if (optionToRemove) optionToRemove.remove();
// Reset to first preset
const dropdown = document.getElementById('presetDropdown');
dropdown.selectedIndex = 0;
localStorage.setItem('custom_preset_choice', dropdown.value);
applyPreset(dropdown.value);
alert(`Preset "${selected}" deleted.`);
});
modelField.parentElement.insertBefore(deleteButton, modelField);
};
// Observe for DOM changes to catch settings panel reloads
const observer = new MutationObserver(() => {
injectDropdown();
});
// Start observing once the body is ready
const startObserver = () => {
const target = document.body;
if (!target) return setTimeout(startObserver, 200);
observer.observe(target, { childList: true, subtree: true });
injectDropdown();
};
startObserver();
})();