DN 流程,在笔记内让 ai 根据当前笔记内容进行回复,内部 ai 回复框

注意注意,别把这个语句放在有隐私的笔记里面!!!

原有功能与实现教程:
思源笔记页面内实现 ai 聊天与 ai 读取笔记内容进行回复(自动)! - 链滴

让 ai 根据当前笔记内容进行回复

代码功能:
在创建日记的时候进行回复

在每天写完日记以后,让 ai 根据日记内容进行回复

image.png

//!js // Function to get context from recently updated documents (Keep as is) async function getDocumentContext() { try { let currentDocId = Query.root_id(protyle); const sqlQuery = ` select * from blocks where root_id = '${currentDocId}' order by sort ASC limit 9999 `; let blocks = await Query.sql(sqlQuery); if (blocks && blocks.length > 0) { let contextEntries = blocks.map(block => { const content = block.markdown || block.content || '[No Content]'; return `Document Path: ${block.hpath || 'N/A'}\nContent:\n---\n${content}\n---`; }); return "以下是当前文档的内容,请参考:\n==========\n" + contextEntries.join('\n\n') + "\n==========\n"; } else { return "当前文档没有内容可供参考。\n"; } } catch (error) { console.error("查询文档时出错:", error); return "查询参考文档时出现错误。\n"; } } // Function to create the UI elements (Keep as is) const ui = () => { const textarea = document.createElement('textarea'); textarea.className = "fn__block b3-text-field"; textarea.rows = 3; textarea.placeholder = "继续提问..."; const buttonContainer = document.createElement('div'); buttonContainer.style.display = 'flex'; buttonContainer.style.justifyContent = 'flex-end'; buttonContainer.style.gap = '8px'; buttonContainer.style.marginTop = '8px'; const removeLastButton = document.createElement('button'); removeLastButton.className = "b3-button"; removeLastButton.textContent = "我不会和别人说的🌹"; buttonContainer.appendChild(removeLastButton); const sendButton = document.createElement('button'); sendButton.className = "b3-button"; sendButton.textContent = "是这样的😄"; buttonContainer.appendChild(sendButton); return { textarea, buttonContainer, sendButton, removeLastButton }; } // Main chat function (Modified to fix null querySelector error) const chat = async () => { let dv = Query.DataView(protyle, item, top); const messages = dv.useState('messages', []); const msgIds = dv.useState('msgIds', []); // --- Initial Rendering Structure --- dv.addmd(`#### 向我分享你的一天吧!`); // 1. Render existing messages from state const initialMsgIds = []; messages().forEach(msg => { try { let el = dv.addmd(`**${msg.role === 'user' ? 'You' : 'GPT'}**: ${msg.content}`); if (el && el.dataset && el.dataset.id) { initialMsgIds.push(el.dataset.id); } } catch (e) { console.error("Error rendering message:", e); } }); if (msgIds().length === 0 && initialMsgIds.length > 0) { msgIds(initialMsgIds); } // 2. Add Separator dv.addmd('---'); // 3. Create UI Elements but don't store unnecessary references const { textarea, buttonContainer, sendButton, removeLastButton } = ui(); // Just add them directly without storing the references dv.addele(textarea); dv.addele(buttonContainer); // --- Function to perform AI query (Modified with better error handling) --- const performAIQuery = async (prompt, isInitialQuery = false) => { try { sendButton.disabled = true; removeLastButton.disabled = true; // Add placeholder with better error handling let respondPlaceholder; let gptMsgId = null; try { respondPlaceholder = dv.addmd(`**GPT**: 正在检索参考资料并思考... 🤔`); if (respondPlaceholder && respondPlaceholder.dataset) { gptMsgId = respondPlaceholder.dataset.id; // Add placeholder ID to state only if it's valid if (gptMsgId) { msgIds([...msgIds(), gptMsgId]); } } } catch (e) { console.error("Error adding placeholder:", e); // If we can't add a placeholder, we'll just add a new message later } // Safe function to replace or add content const updateContent = (id, content) => { try { if (id) { dv.replaceView(id, dv.md(`**GPT**: ${content}`)); } else { // If no ID, add as new message let newEl = dv.addmd(`**GPT**: ${content}`); if (newEl && newEl.dataset && newEl.dataset.id) { msgIds([...msgIds(), newEl.dataset.id]); } } } catch (e) { console.error("Error updating content:", e); // Last resort fallback - just add a new message try { dv.addmd(`**GPT**: ${content}`); } catch (e) { console.error("Failed to add fallback message:", e); } } }; const docReference = await getDocumentContext(); const prefixText = `${docReference}\n这是我的提问背景信息:`; const suffixText = "\n请基于以上参考信息,回复我的问题。注意:多用表情,尽量简短且切中要点。"; const fullPrompt = `${prefixText}\n${prompt}\n${suffixText}`; const response = await Query.gpt(fullPrompt, { stream: true, streamInterval: 3, streamMsg: (content) => { // Safely update with streaming content updateContent(gptMsgId, content); } }); // Update state with final response const gptMessage = { role: 'assistant', content: response }; const currentMessages = messages(); if (isInitialQuery) { messages([gptMessage]); } else { messages([...currentMessages, gptMessage]); } // Final update with safe function updateContent(gptMsgId, response); } catch (error) { console.error("GPT 调用或处理失败:", error); const errorMessageContent = `抱歉,处理时遇到问题: ${error.message}`; try { if (gptMsgId) { dv.replaceView(gptMsgId, dv.md(`**GPT**: ${errorMessageContent}`)); } else { dv.addmd(`**GPT**: ${errorMessageContent}`); } const errorMessage = { role: 'assistant', content: errorMessageContent }; const currentMessages = messages(); if (isInitialQuery) { messages([errorMessage]); } else { messages([...currentMessages, errorMessage]); } } catch (e) { console.error("Error handling GPT failure:", e); // Try one more time with a simple message try { dv.addmd(`**Error**: ${error.message}`); } catch (finalError) { console.error("Failed all error handling attempts:", finalError); } } } finally { // Re-enable buttons regardless of outcome try { sendButton.disabled = false; removeLastButton.disabled = false; // Safely repaint dv.repaint(); } catch (e) { console.error("Error in finally block:", e); } } }; // --- Initial Query Logic --- if (messages().length === 0) { const predefinedPrompt = "今天真是美好的一天,请你基于参考内容,激励我度过美好的一天吧!请你用满满的正能量激励我,并且要加入很多的表情,让我的心情愉快!"; try { await performAIQuery(predefinedPrompt, true); } catch (e) { console.error("Initial query failed:", e); // Try to add a fallback message dv.addmd("**System**: 初始查询失败,但你仍然可以开始对话。"); } } // --- Button Handlers --- sendButton.onclick = async () => { const userInput = textarea.value.trim(); if (!userInput) return; // 1. Add user message to state and UI with better error handling const userMessage = { role: 'user', content: userInput }; messages([...messages(), userMessage]); let userEl; let userMsgId = null; try { userEl = dv.addmd(`**You**: ${userInput}`); if (userEl && userEl.dataset) { userMsgId = userEl.dataset.id; if (userMsgId) { msgIds([...msgIds(), userMsgId]); } } } catch (e) { console.error("Error adding user message:", e); } textarea.value = ''; // 2. Perform AI query with error handling try { await performAIQuery(userInput, false); } catch (e) { console.error("Query failed:", e); dv.addmd(`**System**: 查询失败,请重试。错误: ${e.message}`); } }; // Remove last button click handler (with better error handling) removeLastButton.onclick = () => { try { const currentMessages = messages(); let currentMsgIds = [...msgIds()]; if (currentMessages.length < 2 || currentMsgIds.length < 2) return; // Update messages state first (in case view operations fail) messages(currentMessages.slice(0, -2)); // Then try to remove the views try { const lastGptId = currentMsgIds.pop(); const lastUserId = currentMsgIds.pop(); if (lastGptId) dv.removeView(lastGptId); if (lastUserId) dv.removeView(lastUserId); // Update msgIds state only after successful removal msgIds(currentMsgIds); } catch (e) { console.error("Error removing views:", e); } // Always try to repaint dv.repaint(); } catch (e) { console.error("Error in removeLastButton handler:", e); } }; // --- Final Render --- try { dv.render(); } catch (e) { console.error("Error rendering DataView:", e); } } // Execute the chat function with error handling try { return chat(); } catch (e) { console.error("Fatal error in chat function:", e); return "Error initializing chat. Please check console for details."; }
  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    25408 引用 • 105048 回帖 • 1 关注
1 操作
TangQi 在 2025-04-20 21:14:41 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖
  • Gzip

    gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

    9 引用 • 12 回帖 • 166 关注
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    7 引用 • 69 回帖
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    143 引用 • 442 回帖 • 1 关注
  • Solidity

    Solidity 是一种智能合约高级语言,运行在 [以太坊] 虚拟机(EVM)之上。它的语法接近于 JavaScript,是一种面向对象的语言。

    3 引用 • 18 回帖 • 436 关注
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 77 关注
  • Vim

    Vim 是类 UNIX 系统文本编辑器 Vi 的加强版本,加入了更多特性来帮助编辑源代码。Vim 的部分增强功能包括文件比较(vimdiff)、语法高亮、全面的帮助系统、本地脚本(Vimscript)和便于选择的可视化模式。

    29 引用 • 66 回帖 • 1 关注
  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    24 引用 • 241 回帖 • 1 关注
  • FreeMarker

    FreeMarker 是一款好用且功能强大的 Java 模版引擎。

    23 引用 • 20 回帖 • 467 关注
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    173 引用 • 414 回帖 • 364 关注
  • 笔记

    好记性不如烂笔头。

    310 引用 • 794 回帖
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    211 引用 • 358 回帖 • 1 关注
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 384 回帖 • 10 关注
  • ActiveMQ

    ActiveMQ 是 Apache 旗下的一款开源消息总线系统,它完整实现了 JMS 规范,是一个企业级的消息中间件。

    19 引用 • 13 回帖 • 679 关注
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    76 引用 • 258 回帖 • 628 关注
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    22 引用 • 148 回帖 • 16 关注
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    32 引用 • 108 回帖
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 85 关注
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖
  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 385 关注
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    21 引用 • 31 回帖
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    133 引用 • 1124 回帖 • 111 关注
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 106 关注
  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    730 引用 • 1280 回帖 • 5 关注
  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    116 引用 • 54 回帖 • 4 关注
  • 一些有用的避坑指南。

    69 引用 • 93 回帖 • 1 关注