// ==UserScript== // @name 一个优化你使用AI时候的prompt智能体。 // @namespace prompt-agent // @version 0.0.2 // @description prompt-agent // @author LLinkedList771 // @run-at document-end // @match https://chat.deepseek.com/* // @homepageURL https://github.com/linkedlist771/prompt-agent // @supportURL https://github.com/linkedlist771/prompt-agent/issues // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; // 配置变量 let isEnabled = false; let apiKey = localStorage.getItem('ai-script-apikey') || ''; let isProcessing = false; // 创建浮动UI function createFloatingUI() { const container = document.createElement('div'); container.id = 'ai-floating-ui'; container.style.cssText = ` position: fixed; top: 20px; right: 20px; width: 280px; background: #ffffff; border: 1px solid #ddd; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 10000; font-family: Arial, sans-serif; font-size: 14px; `; container.innerHTML = `
Prompt Agent
`; document.body.appendChild(container); // 事件监听 document.getElementById('ai-minimize').addEventListener('click', toggleMinimize); document.getElementById('ai-enable').addEventListener('change', toggleEnable); document.getElementById('ai-apikey').addEventListener('input', saveApiKey); document.getElementById('ai-test').addEventListener('click', testConnection); document.getElementById('ai-manual-send').addEventListener('click', manualSend); // 监听Ctrl+Enter组合键 document.addEventListener('keydown', handleKeyDown); } function toggleMinimize() { const content = document.getElementById('ai-content'); const button = document.getElementById('ai-minimize'); if (content.style.display === 'none') { content.style.display = 'block'; button.textContent = '−'; } else { content.style.display = 'none'; button.textContent = '+'; } } function toggleEnable(e) { isEnabled = e.target.checked; updateStatus(isEnabled ? '已启用 - 按Ctrl+Enter发送' : '已禁用'); } function saveApiKey(e) { apiKey = e.target.value; localStorage.setItem('ai-script-apikey', apiKey); } function updateStatus(message, isError = false) { const status = document.getElementById('ai-status'); if (status) { status.textContent = message; status.style.color = isError ? '#d32f2f' : '#666'; } } function handleKeyDown(e) { if (e.ctrlKey && e.key === 'Enter' && isEnabled && !isProcessing) { const textarea = document.querySelector('textarea:focus'); if (textarea && textarea.value.trim()) { e.preventDefault(); sendRequest(textarea); } } } async function testConnection() { if (!apiKey.trim()) { updateStatus('请先输入API Key', true); return; } updateStatus('测试连接中...'); try { const response = await fetch("https://promptagent.qqyunsd.com/api/v1/chat/completions", { method: 'POST', headers: { "authorization": `Bearer ${apiKey}`, "User-Agent": "Apifox/1.0.0 (https://apifox.com)", "Content-Type": "application/json" }, body: JSON.stringify({ "model": "mock-gpt-model", "messages": [ { "role": "user", "content": "test" } ], "max_tokens": 10, "temperature": 0.1, "stream": false }) }); if (response.ok) { updateStatus('连接成功!'); } else { updateStatus(`连接失败: ${response.status}`, true); } } catch (error) { updateStatus(`连接错误: ${error.message}`, true); } } function manualSend() { if (isProcessing) { updateStatus('正在处理中,请稍后...', true); return; } // 查找当前页面中聚焦的textarea或者最后一个textarea let textarea = document.querySelector('textarea:focus'); if (!textarea) { // 如果没有聚焦的textarea,尝试找到页面上的textarea const textareas = document.querySelectorAll('textarea'); if (textareas.length > 0) { textarea = textareas[textareas.length - 1]; // 选择最后一个textarea } } if (!textarea) { updateStatus('未找到输入框', true); return; } if (!textarea.value.trim()) { updateStatus('请先输入内容', true); return; } sendRequest(textarea); } async function sendRequest(textarea) { if (!apiKey.trim()) { updateStatus('请先输入API Key', true); return; } isProcessing = true; updateStatus('处理中...'); const userInput = textarea.value.trim(); // 清空textarea textarea.value = ''; const myHeaders = new Headers(); myHeaders.append("authorization", `Bearer ${apiKey}`); myHeaders.append("User-Agent", "Apifox/1.0.0 (https://apifox.com)"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "model": "mock-gpt-model", "messages": [ { "role": "user", "content": userInput } ], "max_tokens": 512, "temperature": 0.1, "stream": true }); const requestOptions = { method: 'POST', headers: myHeaders, body: raw, redirect: 'follow' }; try { const response = await fetch("http://localhost:3648/api/v1/chat/completions", requestOptions); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const reader = response.body.getReader(); const decoder = new TextDecoder(); updateStatus('接收响应中...'); while (true) { const { done, value } = await reader.read(); if (done) { break; } const chunk = decoder.decode(value, { stream: true }); const lines = chunk.split('\n'); for (const line of lines) { if (line.startsWith('data: ')) { const jsonStr = line.substring(6).trim(); if (jsonStr === '[DONE]') { continue; } try { const data = JSON.parse(jsonStr); if (data.choices && data.choices[0] && data.choices[0].delta && data.choices[0].delta.content) { const content = data.choices[0].delta.content; // 逐字添加到textarea for (const char of content) { textarea.value += char; // 模拟打字效果 await new Promise(resolve => setTimeout(resolve, 20)); // 滚动到底部 textarea.scrollTop = textarea.scrollHeight; } } } catch (parseError) { console.log('JSON解析错误:', parseError, jsonStr); } } } } updateStatus('完成!'); } catch (error) { updateStatus(`错误: ${error.message}`, true); console.error('请求错误:', error); } finally { isProcessing = false; } } // 初始化 function init() { // 等待页面加载完成 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', createFloatingUI); } else { createFloatingUI(); } updateStatus('就绪 - 在textarea中输入后按Ctrl+Enter'); } init(); })();