SherinG-official/dsh-siyuan-api ↗★ 0
dsh-siyuan-api
DeepSeek Harness 思源笔记(SiYuan)插件:通过内核 HTTP API 搜索笔记、创建文档、读取与追加块内容,并支持只读 SQL 查询。 适合使用思源笔记、需要让AI搜索笔记、创建文档及读取或追加内容的用户。
インストール
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:SherinG-official/dsh-siyuan-apiドキュメント
README 全文を読む ↗然后在 profile 目录里装依赖(用 profile 自己的 pnpm 配置,不要加 --ignore-workspace)
cd "$DSH_HOME/profiles/desktop" && pnpm install
改完重启 DSH Desktop 生效。
### 1.3 依赖说明
运行时只需要 Node 内置 `fetch`。`@deepseek-ai/dsh-tools`、`@deepseek-ai/cordis`、
`@deepseek-ai/schemastery` 都由 **dsh 宿主**提供(通过 `$DSH_HOME/profiles/node_modules`
的符号链接解析),所以刻意**没有**写进 `dependencies`:
- 写成 `dependencies` 会让 profile 的 `pnpm install` 去 npm 拉一份宿主私有版本,直接失败;
- 写成 `peerDependencies` 同样会被 pnpm 解析并下载,还会锁死版本区间。
`schemastery` 保留为可选 peer(版本与宿主一致时用得上,缺了也不影响插件装载)。
---
## 2. 配置
### 2.1 思源侧准备
1. 思源要**处于运行状态**。窗口最小化到托盘也算(内核是独立进程),但真正退出就没了。
2. 记下内核地址。桌面端默认 `127.0.0.1:6806`;如果你在思源里改过端口或开了「网络伺服」,
就用实际地址(思源「设置 → 关于」能看到)。
3. 拿 API Token:思源「设置 → 关于 → API token」(老版本在「设置 → 关于」)。
- **没设锁屏密码时**,本机访问(127.0.0.1)免鉴权,Token 可以留空;
- 设了锁屏密码、或要让 dsh 走非 127.0.0.1 访问时,必须填 Token。
### 2.2 插件配置项
写进 profile 的 `cordis.patch.yml`(按行 id 覆盖),或用设置页:
```yaml
- id: dsh-siyuan-api
name: dsh-siyuan-api
config:
apiUrl: http://127.0.0.1:6806 # 内核地址;填 127.0.0.1:6806 这种简写也认
token: '' # 思源 API Token;留空 = 只访问免鉴权的本机内核
timeoutMs: 15000 # 单请求超时
maxRows: 64 # 搜索 / SQL 单次返回行数上限(1-1000)
defaultNotebook: '' # 默认笔记本(名称或 ID);留空则每次都要显式指定
prompt: true # 是否注入系统提示词使用规范
debug: false # 打开后在宿主日志里打印解析后的配置(不含 Token 明文)
也可以把 Token 放在环境变量 SIYUAN_TOKEN 里(配置文件里留空即可,配置文件优先)。
提示:
!!js表达式在 patch 里可用,所以 Token 不必落盘在配置里,例如token: !!js process.env.SIYUAN_TOKEN || ''。
2.3 自检
装好后先问一句「思源连上了吗」,或直接调 siyuan_status。也可以打开诊断路由
(仅 web profile 有):
http://127.0.0.1:/dsh-siyuan-api/status
它只报事实(地址、是否配 Token、工具清单、内核版本、笔记本数),不回显 Token。
3. 工具用法
siyuan_search —— 找内容
| 参数 | 说明 |
|---|---|
query | 必填。keyword 模式给关键词(中文 / 英文、不分大小写、支持子串);sql 模式给完整 SELECT |
mode | keyword(默认)/ sql |
notebook | 可选,限定笔记本(名称或 ID) |
limit | 可选,返回条数(默认 20,上限 = maxRows) |
关键词模式覆盖 blocks 表的 content(正文)、name(标题)、alias(别名)、memo(备注),
返回块 ID、所属文档、笔记本、路径、片段与更新时间 —— 这些 ID 就是后面
siyuan_block / siyuan_create_doc(parentID) 的输入。
sql 模式可查的表(blocks 为主):
blocks(id, parent_id, root_id, box, path, hpath, name, alias, memo, tag,
content, fcontent, markdown, length, type, subtype, ial, sort, created, updated)
spans(id, block_id, root_id, box, path, content, markdown, type, ial)
attributes(id, name, value, type, block_id, root_id, box, path)
refs(id, def_block_id, def_block_root_id, def_block_path, block_id, root_id, box, path, content, markdown, type)
assets(id, block_id, root_id, box, docpath, path, name, title, hash)
file_annotation_refs(...)
box= 笔记本 ID;root_id= 所属文档 ID;hpath= 人类可读路径;markdown= Markdown 源文;type:d文档、h标题、p段落、l列表、i列表项、b引述、t/tb表格、c代码块、m公式块、s超级块、av数据库;subtype:标题是h1..h6,列表 / 列表项是u(无序)o(有序),其余为空;- 行内标记(加粗、链接、标签)在
spans里,不在blocks;标签值在blocks.tag与ial里都有。
例子:
-- 最近改过的 10 篇文档
SELECT id, content, hpath, updated FROM blocks WHERE type = 'd' ORDER BY updated DESC LIMIT 10
-- 各笔记本的块数量
SELECT box, COUNT(*) AS n FROM blocks GROUP BY box ORDER BY n DESC
-- 带「TODO」的段落
SELECT id, hpath, content FROM blocks WHERE type = 'p' AND content LIKE '%TODO%' LIMIT 20
siyuan_create_doc —— 新建文档
| 参数 | 说明 |
|---|---|
title | 必填,文档标题(也是文件名)。写「父文档/子文档」可建一层子文档 |
notebook | 目标笔记本名称或 ID;不传则用 defaultNotebook |
markdown | 正文,标准 Markdown(省略则建空文档,之后用 siyuan_block 追加) |
parentID | 可选,父文档 ID(来自 siyuan_search),优先级高于标题里的 / |
写入前请确认目标:笔记本用 siyuan_notebooks 查,父文档用 siyuan_search 定位。
siyuan_block —— 读写某个块
| 参数 | 说明 |
|---|---|
id | 必填,块 ID(22 位,形如 20260919135122-lw63vfz)。传文档 ID 就是整篇文档 |
mode | read(默认)/ append(追加为子块)/ insert(前后插入同级块) |
data | append / insert 要写的内容(Markdown;dataType=dom 时是思源块 DOM) |
position | insert 的位置:before(默认)/ after |
confirm | append / insert 必须显式传 true,否则拒绝执行 |
confirm 是刻意的摩擦:先 mode=read 看清目标,再带着 confirm=true 落笔,
比事后回滚便宜。
4. 设计要点
错误处理:失败也是正常返回。 思源没启动、Token 不对、笔记本不存在 / 已关闭、
块 ID 抄错 —— 这些都变成一句能照着排查的 message,而不是抛异常打断整轮对话。
错误按原因分了码(SIYUAN_UNREACHABLE / SIYUAN_TIMEOUT / SIYUAN_AUTH_FAILED /
SIYUAN_BAD_RESPONSE / SIYUAN_API_ERROR / SIYUAN_INVALID_ARGUMENT),
文案里直接给出下一步动作,例如把 API 地址错配成思源 Web 界面地址时会明确说
「这个地址多半是 Web 界面,请改成内核地址」。
只读 SQL 是双保险。 插件侧先做「单条 + SELECT/WITH」预检(带注释 / 引号内分号处理),
再给没写 LIMIT 的语句补上上限;发请求时始终带 mode: "readonly" ——
思源 3.8.x 的内核只在 mode=readonly 时才真正做只读校验,默认 mode 并不拦写操作,
不能把「不写坏数据」寄托在自己的正则上。内核返回的 truncated / limit 也会转述给模型,
免得它把「被截断的结果」当成全部。
笔记本解析。 模型更可能说「运维笔记」而不是 22 位 ID,所以 notebook 参数
接受 ID、精确名称、唯一子串;匹配不到时报错里直接列出所有可用笔记本,
模型能立刻换个说法重试,不用回头问用户。
webServer 是延迟注入的。 dsh-host-webserver 属于 @deepseek-ai/dsh-web-app,
不在 dsh-base 里 —— headless / SDK / ACP 这些 profile 根本没有这个服务。
把 webServer 写进 inject 会让插件在那些宿主里永远停在 PENDING(工具也注册不上);
直接读 ctx.webServer 又会被 cordis 抛 cannot get property "webServer" without inject
并把装载搞挂。所以实现用 ctx.inject(['webServer'], …) 起一个子 fiber:
服务就绪才挂路由,没有就安静待命,工具在任何宿主都正常。
5. 开发
5.0 准备本地依赖
本仓库不提交 node_modules,但测试需要两个宿主包能被解析。一条命令搞定:
node scripts/dev-setup.mjs
它会:检查 @deepseek-ai/schemastery(缺了会提示你 npm install --no-save),
并把 @deepseek-ai/dsh-tools 就位 —— 优先链接本机 dsh 自带的真包,
找不到就退回复制 test/stubs/dsh-tools 里的替身(--stub 可强制走替身)。
为什么不是直接 npm i @deepseek-ai/dsh-tools:它运行时真的会 import '@deepseek-ai/cordis',
而每个 npm 版本都声明了一长串 @deepseek-ai/dsh-* peer 依赖,装它等于把整棵 dsh 依赖树拉下来。
替身只实现本插件依赖的部分,但编译规则与参数校验都照宿主实现 ——
作者侧的 required: true 会被编译成根节点的 required: [...] 数组,
test/schema.test.mjs 断言的正是这份「模型实际收到的 JSON Schema」。
替身与真包两条路都跑过,61 条测试结果一致。
5.1 跑验证
## 2. 配置
### 2.1 思源侧准备
1. 思源要**处于运行状态**。窗口最小化到托盘也算(内核是独立进程),但真正退出就没了。
2. 记下内核地址。桌面端默认 `127.0.0.1:6806`;如果你在思源里改过端口或开了「网络伺服」,
就用实际地址(思源「设置 → 关于」能看到)。
3. 拿 API Token:思源「设置 → 关于 → API token」(老版本在「设置 → 关于」)。
- **没设锁屏密码时**,本机访问(127.0.0.1)免鉴权,Token 可以留空;
- 设了锁屏密码、或要让 dsh 走非 127.0.0.1 访问时,必须填 Token。
### 2.2 插件配置项
写进 profile 的 `cordis.patch.yml`(按行 id 覆盖),或用设置页:
```yaml
- id: dsh-siyuan-api
name: dsh-siyuan-api
config:
apiUrl: http://127.0.0.1:6806 # 内核地址;填 127.0.0.1:6806 这种简写也认
token: '' # 思源 API Token;留空 = 只访问免鉴权的本机内核
timeoutMs: 15000 # 单请求超时
maxRows: 64 # 搜索 / SQL 单次返回行数上限(1-1000)
defaultNotebook: '' # 默认笔记本(名称或 ID);留空则每次都要显式指定
prompt: true # 是否注入系统提示词使用规范
debug: false # 打开后在宿主日志里打印解析后的配置(不含 Token 明文)
也可以把 Token 放在环境变量 SIYUAN_TOKEN 里(配置文件里留空即可,配置文件优先)。
提示:
!!js表达式在 patch 里可用,所以 Token 不必落盘在配置里,例如token: !!js process.env.SIYUAN_TOKEN || ''。
2.3 自检
装好后先问一句「思源连上了吗」,或直接调 siyuan_status。也可以打开诊断路由
(仅 web profile 有):
http://127.0.0.1:/dsh-siyuan-api/status
它只报事实(地址、是否配 Token、工具清单、内核版本、笔记本数),不回显 Token。
2.2 插件配置项
写进 profile 的 cordis.patch.yml(按行 id 覆盖),或用设置页:
- id: dsh-siyuan-api
name: dsh-siyuan-api
config:
apiUrl: http://127.0.0.1:6806 # 内核地址;填 127.0.0.1:6806 这种简写也认
token: '' # 思源 API Token;留空 = 只访问免鉴权的本机内核
timeoutMs: 15000 # 单请求超时
maxRows: 64 # 搜索 / SQL 单次返回行数上限(1-1000)
defaultNotebook: '' # 默认笔记本(名称或 ID);留空则每次都要显式指定
prompt: true # 是否注入系统提示词使用规范
debug: false # 打开后在宿主日志里打印解析后的配置(不含 Token 明文)
也可以把 Token 放在环境变量 SIYUAN_TOKEN 里(配置文件里留空即可,配置文件优先)。
提示:
!!js表达式在 patch 里可用,所以 Token 不必落盘在配置里,例如token: !!js process.env.SIYUAN_TOKEN || ''。