DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

QQPilotOrganization /

QQPilotOrganization/qqpilot-dsh-plugin

Verified

把 QQPilot 的 QQ 消息接入 DeepSeek Harness(DSH)的桥接插件: 对 QQPilot 暴露一个 OpenAI Chat Completion 兼容端点,由 DSH 里配置的模型通过智能体工具决定 「回复什么 / 不回复 / 附带图片」;提供 工具 / 兼容 / 静默 三种运行模式,并在设置页内置 可视化聊天动态(实时看到收到的 QQ 消息、AI 的决定、回复内容、耗时与 token)。

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@9516c293

qqpilot-dsh-plugin

把 QQPilot 的 QQ 消息接入 DeepSeek Harness(DSH)的桥接插件: 对 QQPilot 暴露一个 OpenAI Chat Completion 兼容端点,由 DSH 里配置的模型通过智能体工具决定 「回复什么 / 不回复 / 附带图片」;提供 工具 / 兼容 / 静默 三种运行模式,并在设置页内置 可视化聊天动态(实时看到收到的 QQ 消息、AI 的决定、回复内容、耗时与 token)。

QQPilot 原本只会把聊天记录 POST 给一个 OpenAI 兼容的 /chat/completions 并取回文本。 本插件接管这个端点后,把请求转成一次 DSH 模型调用,再把模型的决定收敛回 OpenAI 响应:

QQPilot ──POST /qqpilot/v1/chat/completions──▶ 本插件(DSH Host)
                                                   │
                                    ┌──────────────┴───────────────┐
                                    │ 工具模式(默认)              │ 兼容模式 / 静默模式
                                    │ 给模型 2 个工具:             │ 兼容:不给工具,直接返回文本
                                    │  qqpilot_reply(text, images)  │ 静默:不调用模型,只记录消息
                                    │  qqpilot_do_not_reply         │
                                    └──────────────┬───────────────┘
                                                   ▼
                                   DSH llm.stream(使用 DSH 当前默认模型)
                                                   │
             ◀── choices[0].message.content(字符串)+ 可选 message.images[] ──┘

功能

  • OpenAI 兼容端点:POST /qqpilot/v1/chat/completions(非流式),另提供 GET /qqpilot/v1/models。
  • 三种运行模式(设置页可切换)
    • 工具模式(默认,agent):模型通过 qqpilot_reply / qqpilot_do_not_reply 决定是否回复、回什么。
    • 兼容模式(compat):不给工具,直接把模型输出作为回复返回,适合不支持 tool calling 的模型。
    • 静默模式(silent):不调用模型、不消耗 token,只把收到的消息记录到聊天动态里(观察/挂机用)。
  • 智能体工具(工具模式)
    • qqpilot_reply:模型决定回复时调用;参数 text(正文)与 images(图片路径 / http(s) URL / data URL)。
    • qqpilot_do_not_reply:模型决定保持沉默时调用,插件返回空 content,QQPilot 跳过发送。
    • 模型没有调用工具而是直接输出文本时,文本仍然会作为回复返回(不会因模型“忘记调工具”而丢消息)。
    • 多轮工具循环上限可配置;工具调用失败时可自动回退到兼容输出。
  • 可视化聊天状态(两种入口,均已内置)
    • DSH 聊天窗口内:聊天输入框上方常驻一条可折叠的「QQPilot」状态条,显示当前模式、最新一条 QQ 消息与 AI 决策;展开后可看最近 6 条收/发记录(含 DSH 工具调用),每 2 秒自动刷新。
    • 设置页 → 聊天动态:完整记录视图,支持暂停刷新、查看耗时/token/工具调用与错误。
  • 可调用 DSH 工具:工具模式下可把 DSH 的工具(默认只读 + 联网:read / glob / grep / read_image / web_search / web_fetch)一并提供给桥接后的 AI;AI 可先查资料/读文件,再用 qqpilot_reply 回复。可在设置页选择「关闭 / 安全 / 全部」策略,危险工具(pwsh / bash / write / edit / subagent / workflow / plugin_manager)默认拒绝。
  • 模型选择:默认跟随 DSH 全局默认模型;设置页「模型」卡片可改为仅 QQPilot 指定的 provider/model(下拉框,保存后下一轮生效),也可在 cordis.patch.yml 固定。
  • 返回图片:回复图片会被规范化成 data:image/...;base64,... 放进 choices[0].message.images[].image_url.url(QQPilot 唯一稳妥的图片返回形式);仅有图片没有文本时会自动 补一个短 caption,避免 QQPilot 把整条回复当作空内容跳过。
  • 接收图片:QQPilot 的 vision 请求(content 分段数组中的 image_url)会通过 DSH attachments 服务转成模型可读的图片块;没有附件服务时退化为文字占位,不会让请求失败。
  • 设置页:DSH 设置 →「QQPilot 接入」,含「概览 / 聊天动态 / 设置」三个页签:端点地址、运行模式、 附加指令、请求统计、测试连接与实时聊天状态。
  • 运行时状态:设置页的修改持久化在 ~/.dsh/qqpilot-dsh-plugin.json(mode、compatibilityMode、 extraInstructions),重启 DSH 后仍生效。

安装

本仓库就是一个 DSH bundle 包(package.json 里 dsh.bundle.patch 指向 cordis.patch.yml),无需构建步骤。

方式一: alt text

方式二:在 DSH 当前 profile 里安装本目录(推荐,开发时本地链接):

plugin_manager → install_bundle → target = <本目录绝对路径>

或命令行:

dsh plugin --profile <profile> add C:\path\to\qqpilot-dsh-plugin
dsh --profile <profile>

方式二:已安装后直接启用/停用 bundle(插件会热加载,无需改代码):

plugin_manager → set_bundle / set_plugin

安装成功后宿主日志会出现:

[qqpilot] QQPilot 接入已就绪 endpoint=http://127.0.0.1:<端口>/qqpilot/v1 模型=<provider>/<model> 兼容模式=false

配置 QQPilot

编辑 QQPilot 的 config.ini([general] 段):

# 指向本插件暴露的地址;末尾不要带 /,QQPilot 会直接拼 "/chat/completions"
server_url = http://127.0.0.1:55068/qqpilot/v1

# QQPilot 对 127.0.0.1 / localhost 不会发送 Authorization,这里留空即可
api_key =

# 本插件使用 DSH 当前默认模型;QQPilot 里的 modelname 不会被用于路由
modelname = deepseek-flash

# 需要把 QQ 里的图片也交给模型时开启(插件会把 image_url 转成 DSH 图片块)
isvisionmodel = true
remote_server_timeout = 300

端口以 DSH Web 实际监听为准(设置页里会显示完整端点)。如果 DSH 换了端口,QQPilot 的 server_url 也要同步改。 QQPilot 的 Ollama / builtin 后端不会走本插件,请保持 forceollamaapi = false。

三种运行模式

工具模式(默认,agent) 兼容模式(compat) 静默模式(silent)
是否调用模型 是 是 否(不消耗 token)
模型收到的工具 qqpilot_reply / qqpilot_do_not_reply 无 无
决定回复 模型调用 qqpilot_reply 模型直接输出文本 永不回复
决定沉默 模型调用 qqpilot_do_not_reply(返回空 content) 模型输出空文本 总是返回空 content
图片 qqpilot_reply.images 支持本地路径 / URL / data URL 不支持(只返回文本) 不支持
聊天动态 记录完整决策 记录完整决策 只记录收到的消息(观察用)
适合 支持 tool calling 的模型;希望“该不该插话”由模型自己判断 不支持工具的模型;或希望完全沿用 QQPilot system.txt 的直接输出 挂机观察 / 临时静音,不花钱

在 DSH 设置 → QQPilot 接入 → 概览(或设置) 里切换运行模式,立即生效并持久化; 也可以在该页「聊天动态」页签实时查看收到的消息与 AI 的回复/沉默/错误。

选择模型(三层,按优先级从高到低)

  1. 插件设置页 →「模型」卡片(推荐):默认「跟随 DSH 默认模型」;关掉开关后可从下拉框选择 provider 与 model(例如 deepseek-official/deepseek-flash、llamacpp/MiniCPM5-1B-F16.gguf、 xiaomi/mimo-v2.6-flash),点「保存模型」后下一轮请求生效,持久化到 ~/.dsh/qqpilot-dsh-plugin.json。
  2. DSH 全局默认模型:未指定时插件实时读取 DSH 当前的默认模型,随 DSH 底部模型选择器 / Settings → Models 变化。
  3. cordis.patch.yml 的 provider / model:给默认值用;设置页的显式指定会覆盖它。

模型列表通过 DSH llm 服务的 listProviders() / listModels() 实时读取;某个 provider 读取失败会在设置页提示。 不同模型能力差异较大:工具调用建议使用支持 tool calling 的模型(如 DeepSeek 系列);本地小模型(1B 级)在 多工具场景下可能很慢甚至超时,可把 DSH 工具策略设为「关闭」或改用更大模型。

配置项

cordis.patch.yml 中 config: 支持以下字段(设置页暴露运行模式与附加指令):

字段 默认 说明
mode agent 运行模式:agent(工具)/ compat(兼容)/ silent(静默)
compatibilityMode false 旧版兼容字段;true 等价于 mode: compat(仍可用,会被 mode 覆盖)
provider / model 空 空 = 跟随 DSH 默认模型;也可在这里给默认值(设置页「模型」卡片可覆盖)
reasoningEffort 空 推理强度,空 = 跟随服务商默认
extraInstructions 空 追加到系统指令里的额外要求(三种模式都生效)
maxToolRounds 4 工具循环最大轮数
dshTools safe 是否向桥接后的 AI 提供 DSH 工具:off / safe(只读+联网)/ all(除危险工具外全部)
dshToolDeny ["pwsh","bash","write","edit","subagent","workflow","plugin_manager"] 始终拒绝的 DSH 工具名
maxDshToolCalls 6 单次请求内最多执行多少次 DSH 工具
historyLimit 40 最多转发的历史消息条数
requestTimeoutMs 180000 单次请求的模型调用超时(毫秒)
fallbackToCompat true 工具模式调用报错时是否回退为兼容输出
temperature 0 >0 时发送;0 表示不发送该参数
maxTokens 0 >0 时发送;0 表示使用服务商默认
maxInboundImages 8 单次请求最多读取几张入站图片
maxReplyImages 4 单次回复最多附带几张图片
maxReplyChars 500 回复长度上限(Unicode 字符),按 [[NEXT]] / 换行边界优雅截断;0 = 不截断(QQPilot 自身仍会硬截断到 500)
maxImageBytes 8388608 单张图片大小上限(8 MiB)
imageRoots [] 允许读取本地图片的根目录;默认允许 DSH 工作区 / cwd
imageOnlyCaption 🖼️ 只有图片没有文本时的占位 caption
logRequests false 是否打印每次请求的摘要到宿主日志

HTTP 接口

方法 & 路径 用途
POST /qqpilot/v1/chat/completions QQPilot 使用的 OpenAI 兼容端点
GET /qqpilot/v1/models 模型目录(返回 DSH 当前模型)
GET /qqpilot/api/config 设置页读取配置 / 端点 / 统计 / 运行时长 / 可用 DSH 工具列表
POST /qqpilot/api/config 设置页写入 {mode?, compatibilityMode?, extraInstructions?, dshTools?}
GET /qqpilot/api/activity?since=&limit= 设置页「聊天动态」轮询:最近的消息 + AI 决策
POST /qqpilot/api/test 设置页“测试连接”:走一遍完整回复流程
GET /qqpilot/api/status 统计信息
GET /qqpilot/api/tools DSH 工具桥诊断:策略、可见工具、专用 bridge agent、全局/作用域工具
POST /qqpilot/api/tools/test 通过真实工具管线执行一次 read(读插件自身 package.json),验证 DSH 工具调用链路
GET /qqpilot/api/models 模型目录:DSH provider/model 列表、当前默认选择、生效模型

与 QQPilot 的输出约定

  • choices[0].message.content 必须是字符串;空字符串表示这次不回复(QQPilot 会静默跳过)。
  • 回复文本会被 QQPilot 按 [[NEXT]] 拆成多条消息、按 \n 每行拆成一条消息,并硬截断到 500 字符。 所以模型输出应是纯文本、不要依赖 Markdown 换行排版。
  • 图片放在非标准扩展字段 choices[0].message.images[],值必须是 data:image/<ext>;base64,... data URL; 文本为空时 QQPilot 不会上传图片,因此插件会在“只有图片”时补 caption。
  • 更精确的协议依据(源码行号、字段硬性要求、失败时的静默行为)见 PROTOCOL.md。

验证

# 离线:用假 ctx / 假 llm 直接跑路由与工具循环(无需安装)
node test/host-unit.mjs

# 在线:模拟 QQPilot 发真实请求并严格校验响应形状
node test/mock-qqpilot.mjs --url http://127.0.0.1:55068/qqpilot/v1

# 在线:多场景验收(回复 / 文本路径 / 模式探测 / 图片)
node test/verify.mjs --url http://127.0.0.1:55068/qqpilot/v1

故障排查

现象 可能原因
设置页显示“加载失败” 插件未加载 / 路由未注册;看宿主日志有无 [qqpilot] 报错
QQPilot 端“机器人不理人” server_url 写错(多了 /、端口不对);模型调用报错被记为 500;看宿主日志 [qqpilot] 请求处理失败
模型总是沉默 工具模式提示词让模型判断“不必插话”;可换成兼容性模式,或在 extraInstructions 里要求更积极回复
图片没发出去 图片路径不在 imageRoots / 工作区内;图片超过 maxImageBytes;模型只给了文本
模型调用报 401 / 无可用模型 DSH 里没有可用的默认模型或凭据;先在 DSH 设置里选好模型

安全与兼容性

  • 端点注册在 DSH 的 webServer 上,默认仅本机可访问;QQPilot 走回环地址,不需要 API key。 如需从其它机器接入,请在网络层限制访问,并自行评估 server_url 使用非回环地址时 QQPilot 会发送 Authorization: Bearer <api_key> 的行为。
  • 目标环境:DSH 0.2.1-rc.2 系列(使用公开服务 webServer / llm / attachments / agentDefaultModel), Node.js >=22.13.0。无第三方运行时依赖。
  • 插件卸载/热重载时自动注销所有路由与资源(ctx.effect 管理)。

验收结果(2026-10-24,DSH 0.2.1-rc.2 / 本机)

已通过 plugin_manager install_bundle 安装进 desktop profile 并热加载(application: applied):

检查 结果
GET /qqpilot/api/config 200,endpoint=http://127.0.0.1:55068/qqpilot/v1,模型 deepseek-official/deepseek-flash
POST /qqpilot/api/test(工具模式) {"ok":true,"mode":"tool","reply":{"text":"连接正常,测试通过。"}},约 1s
兼容性模式切换 + 持久化 POST 开关生效;~/.dsh/qqpilot-dsh-plugin.json 写入 {"compatibilityMode":true},切回 false 正常
test/mock-qqpilot.mjs PASS:HTTP 200,content="等于2",响应形状符合 QQPilot 契约
test/verify.mjs PASS:硬场景 2/2;基础回复 / 文本路径 / 模式探测 / 图片返回全部通过
返回图片 模型调用 qqpilot_reply(images=[data:image/png;...]) 后响应带 1 张 message.images[] data URL(是否发图由模型决定:另一次运行模型选择只发文字,属模型行为,不算协议失败)
接收图片 入站 image_url data URL 经 attachments 转成图片块,模型正确回答了图片内容
静默 模型调用 qqpilot_do_not_reply 时返回空 content(统计 silences≥1)
设置页 Web Client settings.section 已出现 qqpilot(order 62,label「QQPilot 接入」),active=true
离线单测 node test/host-unit.mjs 全部 PASS(路由、系统消息合并、工具循环、图片、三种模式、聊天动态、旧配置升级、[[NEXT]] 清洗、400 校验)

端口和模型取决于当前 DSH 会话,重启后以设置页显示的 endpoint 为准。

第二轮(可视化聊天状态 + 运行模式 + 深色模式修复)

检查 结果
运行模式切换 POST /qqpilot/api/config {mode} 在 silent / compat / agent 间即时切换并持久化到 ~/.dsh/qqpilot-dsh-plugin.json
静默模式 请求 1ms 返回空 content,usage=0,不调用模型;聊天动态记录 mode=silent, kind=silence
兼容模式 返回模型直出文本;聊天动态记录 mode=compat, kind=reply
工具模式 模型经工具决定回复;聊天动态记录 mode=agent, kind=reply、耗时与 tokens
聊天动态接口 GET /qqpilot/api/activity?since=0&limit=10 返回 3 条(静默/兼容/工具),含 sender(从 [username] 解析)、入站文本、回复、图片数、elapsedMs、usage;增量 since=latestId 正常
设置页 设置页出现「概览 / 聊天动态 / 设置」页签与运行模式选择器;Web Client Slot 仍为 active(HMR 重载后)
深色模式按钮 主按钮文字与开启态开关圆点改用 --dsw-alias-label-primary-foreground(浅色=白、深色=近黑),不再出现白字白底

可视化聊天状态为浏览器渲染;Slot 注册与接口数据已验证,实际视觉效果请在 DSH 设置页确认(必要时刷新页面加载最新客户端代码)。

第三轮(聊天窗口状态条 + DSH 工具调用)

检查 结果
聊天窗口状态条 Web Client conversation.input.dock 中已注册 qqpilot-status(order 70,active);输入框上方显示 QQPilot 模式与最新消息,展开看最近 6 条,2 秒自动刷新
设置页并存 settings.section 的 qqpilot 仍 active(两个入口同时保留)
DSH 工具可见 GET /qqpilot/api/config 的 availableDshTools 返回 read, glob, grep, web_search, web_fetch, read_image(安全策略)
DSH 工具作用域 插件自动创建专用 qqpilot-bridge Agent(挂载当前默认 preset),工具在该 Agent 作用域内执行,不污染用户会话;GET /qqpilot/api/tools 可看到 35 个可见工具与过滤结果
DSH 工具真实调用 POST /qqpilot/api/tools/test → ok:true,read 读取插件 package.json,9ms 返回内容(真实 ctx.tools.execute 管线)
危险工具拒绝 pwsh / bash / write / edit / subagent / workflow / plugin_manager 默认在 dshToolDeny,不会提供给模型
离线单测 新增“安全工具可见并可执行”“关闭策略不提供工具”“未知工具不执行”场景,全部 PASS

工具调用发生在工具模式下;兼容模式与静默模式不会向模型提供任何工具。首次进入聊天窗口若看不到状态条,刷新一次页面即可加载新的客户端代码。

第四轮(模型选择)

检查 结果
模型目录接口 GET /qqpilot/api/models 返回 7 个 provider(deepseek-official / deepseek-account / xiaomi / llamacpp / spark-x2 / qwen35 / deepseek-r1-0528-qwen3-8b)及各自模型
设置页模型卡片 设置 → QQPilot 接入 → 设置 → 模型:跟随 DSH 默认模型开关 + provider/model 下拉 + 保存模型
指定模型生效 POST {provider:"deepseek-official",model:"deepseek-flash"} 后,config.modelSource=override,QQPilot 模拟请求 954ms 返回 "等于2"
恢复默认 POST {provider:"",model:""} 后 modelSource=default,当前默认 llamacpp/MiniCPM5-1B-F16.gguf
持久化 provider / model / reasoningEffort 写入 ~/.dsh/qqpilot-dsh-plugin.json
离线单测 新增模型目录 + 指定/恢复模型场景,全部 PASS

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit 9516c2938f72

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout