feat:优化截图

This commit is contained in:
Jerry 2025-10-19 02:16:56 +08:00
parent 88d9e6ddf9
commit b832af2063
4 changed files with 90 additions and 72 deletions

View File

@ -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 {

View File

@ -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. 记忆格式
{ {

View File

@ -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,16 +114,22 @@ 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('');
@ -136,12 +142,13 @@ class Renderer {
@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 { .code-header {
display: flex; display: flex;
@ -157,18 +164,21 @@ class Renderer {
font-family: sans-serif; font-family: sans-serif;
font-size: 14px; font-size: 14px;
} }
.code-body { .code-body pre {
padding: 15px; padding: 15px;
font-size: ${fontSize}px; font-size: ${fontSize}px;
line-height: 1.5; line-height: 0.8;
overflow-x: auto; overflow-x: auto;
} }
.line { .line {
display: flex; display: flex;
margin: 0;
padding: 0;
line-height: 1.2;
} }
.line-number { .line-number {
text-align: right; text-align: right;
margin-right: 15px; margin-right: 12px;
color: #9ca3af; color: #9ca3af;
user-select: none; user-select: none;
} }
@ -189,8 +199,9 @@ class Renderer {
`; `;
} }
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 = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#039;' }; const map = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#039;' };
return text.replace(/[&<>"']/g, (m) => map[m]); return text.replace(/[&<>"']/g, (m) => map[m]);

View File

@ -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;
} }