Greasy Fork is available in English.
增强版Deepseek API对话助手,支持历史记录和更多参数设置
当前为
// ==UserScript==
// @name Deepseek Chat Assistant Plus
// @namespace shy
// @version 1.1
// @description 增强版Deepseek API对话助手,支持历史记录和更多参数设置
// @author shy
// @match *://*/*
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_xmlhttpRequest
// @grant GM_registerMenuCommand
// @grant GM_addStyle
// @connect api.deepseek.com
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 添加CSS样式
GM_addStyle(`
.ds-chat-icon {
position: fixed;
bottom: 20px;
right: 20px;
width: 50px;
height: 50px;
background-color: #007bff;
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 24px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: transform 0.2s, box-shadow 0.2s;
z-index: 9999;
}
.ds-chat-icon:hover {
transform: scale(1.05);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
.ds-chat-window {
position: fixed;
bottom: 80px;
right: 20px;
width: 350px;
height: 450px;
background-color: #f9f9f9;
border: 1px solid #ddd;
border-radius: 15px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
display: none;
flex-direction: column;
overflow: hidden;
transition: opacity 0.3s, transform 0.3s;
opacity: 0;
transform: translateY(20px);
z-index: 9998;
}
.ds-chat-window.active {
display: flex;
opacity: 1;
transform: translateY(0);
}
.ds-chat-header {
padding: 10px 15px;
background-color: #007bff;
color: white;
display: flex;
justify-content: space-between;
align-items: center;
}
.ds-chat-title {
font-weight: bold;
}
.ds-chat-close {
cursor: pointer;
font-size: 18px;
}
.ds-chat-content {
flex: 1;
padding: 15px;
overflow-y: auto;
background-color: #fff;
border-bottom: 1px solid #ddd;
}
.ds-chat-message {
margin-bottom: 10px;
padding: 8px 12px;
border-radius: 8px;
line-height: 1.4;
word-wrap: break-word;
}
.ds-user-message {
background-color: #e3f2fd;
margin-left: 20%;
}
.ds-ai-message {
background-color: #f1f1f1;
margin-right: 20%;
}
.ds-chat-input-area {
padding: 10px;
display: flex;
flex-direction: column;
}
.ds-chat-input {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 8px;
margin-bottom: 8px;
outline: none;
transition: border-color 0.3s;
}
.ds-chat-input:focus {
border-color: #007bff;
}
.ds-chat-settings {
display: flex;
justify-content: space-between;
font-size: 12px;
color: #666;
}
.ds-chat-settings-btn {
cursor: pointer;
text-decoration: underline;
}
.ds-thinking {
color: #666;
font-style: italic;
}
.ds-error {
color: #ff0000;
}
`);
// 初始化配置
let config = {
apiKey: GM_getValue('apiKey', ''),
model: GM_getValue('model', 'deepseek-chat'),
temperature: GM_getValue('temperature', 0.7),
maxTokens: GM_getValue('maxTokens', 1024),
chatHistory: GM_getValue('chatHistory', [])
};
// 创建UI元素
const icon = document.createElement('div');
icon.className = 'ds-chat-icon';
icon.innerText = 'AI';
document.body.appendChild(icon);
const chatWindow = document.createElement('div');
chatWindow.className = 'ds-chat-window';
document.body.appendChild(chatWindow);
// 聊天窗口头部
const chatHeader = document.createElement('div');
chatHeader.className = 'ds-chat-header';
chatWindow.appendChild(chatHeader);
const chatTitle = document.createElement('div');
chatTitle.className = 'ds-chat-title';
chatTitle.innerText = 'Deepseek Chat';
chatHeader.appendChild(chatTitle);
const closeBtn = document.createElement('div');
closeBtn.className = 'ds-chat-close';
closeBtn.innerText = '×';
chatHeader.appendChild(closeBtn);
// 聊天内容区域
const chatContent = document.createElement('div');
chatContent.className = 'ds-chat-content';
chatWindow.appendChild(chatContent);
// 输入区域
const inputArea = document.createElement('div');
inputArea.className = 'ds-chat-input-area';
chatWindow.appendChild(inputArea);
const inputBox = document.createElement('textarea');
inputBox.className = 'ds-chat-input';
inputBox.placeholder = '输入你的问题...';
inputBox.rows = 3;
inputArea.appendChild(inputBox);
const settingsArea = document.createElement('div');
settingsArea.className = 'ds-chat-settings';
inputArea.appendChild(settingsArea);
const settingsBtn = document.createElement('span');
settingsBtn.className = 'ds-chat-settings-btn';
settingsBtn.innerText = '设置';
settingsArea.appendChild(settingsBtn);
const clearBtn = document.createElement('span');
clearBtn.className = 'ds-chat-settings-btn';
clearBtn.innerText = '清空历史';
settingsArea.appendChild(clearBtn);
// 显示历史消息
function displayHistory() {
chatContent.innerHTML = '';
config.chatHistory.forEach(msg => {
const msgDiv = document.createElement('div');
msgDiv.className = `ds-chat-message ds-${msg.role}-message`;
msgDiv.innerText = msg.content;
chatContent.appendChild(msgDiv);
});
chatContent.scrollTop = chatContent.scrollHeight;
}
// 初始化显示历史消息
displayHistory();
// 图标点击事件
icon.addEventListener('click', () => {
chatWindow.classList.toggle('active');
});
// 关闭按钮事件
closeBtn.addEventListener('click', () => {
chatWindow.classList.remove('active');
});
// 设置按钮事件
settingsBtn.addEventListener('click', () => {
const newApiKey = prompt('DeepSeek API密钥:', config.apiKey);
if (newApiKey !== null) {
config.apiKey = newApiKey;
GM_setValue('apiKey', config.apiKey);
}
const newModel = prompt('模型 (deepseek-chat, deepseek-coder等):', config.model);
if (newModel !== null) {
config.model = newModel;
GM_setValue('model', config.model);
}
const newTemp = parseFloat(prompt('Temperature (0-2):', config.temperature));
if (!isNaN(newTemp) && newTemp >= 0 && newTemp <= 2) {
config.temperature = newTemp;
GM_setValue('temperature', config.temperature);
}
const newMaxTokens = parseInt(prompt('最大令牌数:', config.maxTokens));
if (!isNaN(newMaxTokens) && newMaxTokens > 0) {
config.maxTokens = newMaxTokens;
GM_setValue('maxTokens', config.maxTokens);
}
});
// 清空历史按钮事件
clearBtn.addEventListener('click', () => {
if (confirm('确定要清空聊天历史吗?')) {
config.chatHistory = [];
GM_setValue('chatHistory', config.chatHistory);
chatContent.innerHTML = '';
}
});
// 发送消息函数
function sendMessage(message) {
if (!message.trim()) return;
if (!config.apiKey) {
alert('请先设置API密钥!');
settingsBtn.click();
return;
}
// 添加用户消息到历史和UI
const userMsg = { role: 'user', content: message };
config.chatHistory.push(userMsg);
GM_setValue('chatHistory', config.chatHistory);
const userMsgDiv = document.createElement('div');
userMsgDiv.className = 'ds-chat-message ds-user-message';
userMsgDiv.innerText = message;
chatContent.appendChild(userMsgDiv);
// 添加AI思考中的提示
const thinkingMsgDiv = document.createElement('div');
thinkingMsgDiv.className = 'ds-chat-message ds-thinking';
thinkingMsgDiv.innerText = '思考中...';
chatContent.appendChild(thinkingMsgDiv);
chatContent.scrollTop = chatContent.scrollHeight;
// 准备API请求数据
const requestData = {
model: config.model,
messages: config.chatHistory,
temperature: config.temperature,
max_tokens: config.maxTokens
};
// 发送API请求
GM_xmlhttpRequest({
method: 'POST',
url: 'https://api.deepseek.com/v1/chat/completions',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${config.apiKey}`
},
data: JSON.stringify(requestData),
onload: function(response) {
try {
const data = JSON.parse(response.responseText);
if (data.choices && data.choices[0]) {
const aiMessage = data.choices[0].message.content;
// 移除"思考中"提示
chatContent.removeChild(thinkingMsgDiv);
// 添加AI响应到历史和UI
const aiMsg = { role: 'assistant', content: aiMessage };
config.chatHistory.push(aiMsg);
GM_setValue('chatHistory', config.chatHistory);
const aiMsgDiv = document.createElement('div');
aiMsgDiv.className = 'ds-chat-message ds-ai-message';
aiMsgDiv.innerText = aiMessage;
chatContent.appendChild(aiMsgDiv);
} else {
throw new Error('无效的API响应');
}
} catch (e) {
showError(`错误: ${e.message}`);
}
chatContent.scrollTop = chatContent.scrollHeight;
},
onerror: function(error) {
showError(`请求失败: ${error.statusText || '网络错误'}`);
}
});
}
// 显示错误消息
function showError(message) {
const errorMsgDiv = document.createElement('div');
errorMsgDiv.className = 'ds-chat-message ds-error';
errorMsgDiv.innerText = message;
chatContent.appendChild(errorMsgDiv);
chatContent.scrollTop = chatContent.scrollHeight;
}
// 输入框事件
inputBox.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
const message = inputBox.value.trim();
if (message) {
sendMessage(message);
inputBox.value = '';
}
}
});
// 注册菜单命令
GM_registerMenuCommand("设置DeepSeek API", () => settingsBtn.click());
GM_registerMenuCommand("清空聊天历史", () => clearBtn.click());
})();