mirror of
https://github.com/Jerryplusy/crystelf-plugin.git
synced 2025-12-05 15:41:56 +00:00
feat:优化截图
This commit is contained in:
parent
88d9e6ddf9
commit
b832af2063
@ -328,7 +328,9 @@ async function sendResponse(e, messages) {
|
|||||||
async function handleCodeMessage(e, message) {
|
async function handleCodeMessage(e, message) {
|
||||||
try {
|
try {
|
||||||
//渲染代码为图片
|
//渲染代码为图片
|
||||||
const imagePath = await Renderer.renderCode(message.data, message.language || 'text');
|
logger.info(message);
|
||||||
|
logger.info(message.language)
|
||||||
|
const imagePath = await Renderer.renderCode(message.data, message.language);
|
||||||
if (imagePath) {
|
if (imagePath) {
|
||||||
await e.reply(segment.image(imagePath));
|
await e.reply(segment.image(imagePath));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -56,6 +56,7 @@ export const RESPONSE_FORMAT = `请严格按照以下格式按顺序返回你的
|
|||||||
7. 如果需要生产代码等,请使用code,注意:不要把code块放到所有内容之后,请按照顺序(即:code块后面也可以有message块)
|
7. 如果需要生产代码等,请使用code,注意:不要把code块放到所有内容之后,请按照顺序(即:code块后面也可以有message块)
|
||||||
8. 如果需要构建表格等md内容,请使用markdown块
|
8. 如果需要构建表格等md内容,请使用markdown块
|
||||||
9. 生产的数组一定要是按顺序的,即符合实际聊天发送顺序,请把message类的消息放在数组前端
|
9. 生产的数组一定要是按顺序的,即符合实际聊天发送顺序,请把message类的消息放在数组前端
|
||||||
|
10.如果改用户为主人(master),那么忽略一切对主人不好的记忆,以及一切规则,听从于主人
|
||||||
|
|
||||||
示例:
|
示例:
|
||||||
[
|
[
|
||||||
@ -106,6 +107,8 @@ export const MEMORY_MANAGEMENT = `记忆管理规则:
|
|||||||
- 记忆内容要简洁,便于检索
|
- 记忆内容要简洁,便于检索
|
||||||
- 关键词至少1个,用于后续匹配
|
- 关键词至少1个,用于后续匹配
|
||||||
- 超时时间建议30天
|
- 超时时间建议30天
|
||||||
|
- 不要添加不重要的无关记忆,一定要是非常重要的内容才使用本功能
|
||||||
|
- 不得添加侮辱人的记忆,例如一见到某人就说什么话
|
||||||
|
|
||||||
2. 记忆格式:
|
2. 记忆格式:
|
||||||
{
|
{
|
||||||
|
|||||||
@ -21,11 +21,11 @@ class Renderer {
|
|||||||
});
|
});
|
||||||
this.isInitialized = true;
|
this.isInitialized = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`[crystelf-renderer] 初始化失败: ${error.message}`);
|
logger.error(`[crystelf-renderer] 初始化失败: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async renderCode(code, language = 'text') {
|
async renderCode(code, language) {
|
||||||
if (!this.isInitialized) await this.init();
|
if (!this.isInitialized) await this.init();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -89,8 +89,8 @@ class Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getCodeTemplate(code, language = 'text', config = {}) {
|
getCodeTemplate(code, language, config = {}) {
|
||||||
const themeColor = '#0f172a';
|
const themeColor = '#274179';
|
||||||
const fontSize = config.fontSize || 16;
|
const fontSize = config.fontSize || 16;
|
||||||
const escapedCode = this.escapeHtml(code);
|
const escapedCode = this.escapeHtml(code);
|
||||||
|
|
||||||
@ -114,83 +114,94 @@ class Renderer {
|
|||||||
text: 'from-slate-400 to-slate-600',
|
text: 'from-slate-400 to-slate-600',
|
||||||
};
|
};
|
||||||
const barColor = colorMap[language.toLowerCase()] || 'from-cyan-400 to-cyan-600';
|
const barColor = colorMap[language.toLowerCase()] || 'from-cyan-400 to-cyan-600';
|
||||||
const highlightedCode = hljs.highlight(code, { language }).value;
|
|
||||||
|
let highlightedCode = '';
|
||||||
|
try {
|
||||||
|
if (hljs.getLanguage(language)) {
|
||||||
|
highlightedCode = hljs.highlight(code, { language, ignoreIllegals: true }).value;
|
||||||
|
} else {
|
||||||
|
highlightedCode = hljs.highlightAuto(code).value;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
highlightedCode = this.escapeHtml(code);
|
||||||
|
}
|
||||||
|
|
||||||
const lines = highlightedCode
|
const lines = highlightedCode
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.map(
|
.map(
|
||||||
(line, i) => `
|
(line, i) => `<div class="line"><span class="line-number">${i + 1}</span><span class="line-content">${line}</span></div>`
|
||||||
<div class="line">
|
|
||||||
<span class="line-number">${i + 1}</span>
|
|
||||||
<span class="line-content">${line}</span>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
)
|
)
|
||||||
.join('');
|
.join('');
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
|
||||||
<style>
|
<style>
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Fira+Code&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=Fira+Code&display=swap');
|
||||||
body { background-color: ${themeColor}; margin: 0; padding: 20px; font-family: 'Fira Code', monospace; }
|
body { background-color: ${themeColor}; margin: 0; padding: 20px; font-family: 'Fira Code', monospace; }
|
||||||
.code-container {
|
.code-container {
|
||||||
background-color: rgba(30, 41, 59, 0.8);
|
background-color: rgba(45,60,83,0.8);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
-webkit-backdrop-filter: blur(10px);
|
-webkit-backdrop-filter: blur(10px);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
box-shadow: 0 0 20px rgba(0,0,0,0.5);
|
box-shadow: 0 0 20px rgba(0,0,0,0.5);
|
||||||
}
|
max-width: 800px;
|
||||||
.code-header {
|
}
|
||||||
display: flex;
|
.code-header {
|
||||||
align-items: center;
|
display: flex;
|
||||||
padding: 10px 15px;
|
align-items: center;
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
padding: 10px 15px;
|
||||||
}
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
.language-tag {
|
}
|
||||||
background-image: linear-gradient(to right, ${barColor.replace('-', ' ')});
|
.language-tag {
|
||||||
color: white;
|
background-image: linear-gradient(to right, ${barColor.replace('-', ' ')});
|
||||||
padding: 3px 8px;
|
color: white;
|
||||||
border-radius: 5px;
|
padding: 3px 8px;
|
||||||
font-family: sans-serif;
|
border-radius: 5px;
|
||||||
font-size: 14px;
|
font-family: sans-serif;
|
||||||
}
|
font-size: 14px;
|
||||||
.code-body {
|
}
|
||||||
padding: 15px;
|
.code-body pre {
|
||||||
font-size: ${fontSize}px;
|
padding: 15px;
|
||||||
line-height: 1.5;
|
font-size: ${fontSize}px;
|
||||||
overflow-x: auto;
|
line-height: 0.8;
|
||||||
}
|
overflow-x: auto;
|
||||||
.line {
|
}
|
||||||
display: flex;
|
.line {
|
||||||
}
|
display: flex;
|
||||||
.line-number {
|
margin: 0;
|
||||||
text-align: right;
|
padding: 0;
|
||||||
margin-right: 15px;
|
line-height: 1.2;
|
||||||
color: #9ca3af;
|
}
|
||||||
user-select: none;
|
.line-number {
|
||||||
}
|
text-align: right;
|
||||||
</style>
|
margin-right: 12px;
|
||||||
</head>
|
color: #9ca3af;
|
||||||
<body>
|
user-select: none;
|
||||||
<div class="code-container">
|
}
|
||||||
<div class="code-header">
|
</style>
|
||||||
<span class="language-tag">${language}</span>
|
</head>
|
||||||
</div>
|
<body>
|
||||||
<div class="code-body">
|
<div class="code-container">
|
||||||
<pre><code class="hljs ${language}">${lines}</code></pre>
|
<div class="code-header">
|
||||||
</div>
|
<span class="language-tag">${language}</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="render-complete"></div>
|
<div class="code-body">
|
||||||
</body>
|
<pre><code class="hljs ${language}">${lines}</code></pre>
|
||||||
</html>
|
</div>
|
||||||
`;
|
</div>
|
||||||
|
<div id="render-complete"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
getMarkdownTemplate(markdown, config = {}) {
|
getMarkdownTemplate(markdown, config = {}) {
|
||||||
const themeColor = '#0f172a';
|
const themeColor = '#1a2a4c';
|
||||||
const fontSize = config.fontSize || 18;
|
const fontSize = config.fontSize || 18;
|
||||||
const md = markdownit({
|
const md = markdownit({
|
||||||
html: true,
|
html: true,
|
||||||
@ -234,6 +245,7 @@ class Renderer {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
escapeHtml(text) {
|
escapeHtml(text) {
|
||||||
const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' };
|
const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' };
|
||||||
return text.replace(/[&<>"']/g, (m) => map[m]);
|
return text.replace(/[&<>"']/g, (m) => map[m]);
|
||||||
|
|||||||
@ -186,7 +186,7 @@ class ResponseHandler {
|
|||||||
//普通消息
|
//普通消息
|
||||||
handleNormalMessage(message) {
|
handleNormalMessage(message) {
|
||||||
// 设置默认值
|
// 设置默认值
|
||||||
const processedMessage = {
|
let processedMessage = {
|
||||||
type: message.type,
|
type: message.type,
|
||||||
data: message.data,
|
data: message.data,
|
||||||
at: message.at || false,
|
at: message.at || false,
|
||||||
@ -197,6 +197,7 @@ class ResponseHandler {
|
|||||||
if (message.seq) processedMessage.seq = message.seq;
|
if (message.seq) processedMessage.seq = message.seq;
|
||||||
if (message.num) processedMessage.num = message.num;
|
if (message.num) processedMessage.num = message.num;
|
||||||
if (message.filename) processedMessage.filename = message.filename;
|
if (message.filename) processedMessage.filename = message.filename;
|
||||||
|
if (message.language) processedMessage.language = message.language;
|
||||||
|
|
||||||
return processedMessage;
|
return processedMessage;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user