Notifications & Integrations

dsh-qqbot

tencent-connect/dsh-qqbot · ★ 468

tencent-connect

让 QQ Bot 接入 DeepSeek Harness(dsh)的官方插件

An English summary is not available; the Chinese summary is shown.

License
MIT
Added
2026-08-17
Maintenance
active
Install kind
github
npm
@tencent-connect/dsh-qqbot
Manifest status
Declared
Manifest path
package.json#dsh
Manifest checked
2026-08-19
Lifecycle scripts
None found

Static manifest checks report declarations only; they are not compatibility or security review.

安装

dsh plugin --profile web add github:tencent-connect/dsh-qqbot

GitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试

For install and environment setup, plus plugin development tutorials, see DSH community docs ↗

README

Source README · body: en · Read Chinese README

Table of contents
  1. Architecture
  2. Installation
  3. Method 1: Desktop install (recommended)
  4. Method 2: Manual
  5. Method 3: Local path
  6. Method 4: --patch dev mode
  7. Configuration
  8. Access control (access)
  9. Rich media (media)
  10. Vision (vision)
  11. File sending (sendFile)
  12. Built-in Commands
  13. Core Modules
  14. Session Routing
  15. Design Principles
  16. Local Development
  17. License

A QQ Bot plugin for deepseek-harness (dsh), connecting DeepSeek AI assistants to QQ private and group chats.

npm version License GitHub stars QQ Bot

简体中文 | English

Scan to join the QQ group / channel

Architecture

QQ User → QQ WebSocket → dsh-qqbot → ctx.agents → dsh agent loop → LLM
                                 ↑                           │
                                 └── session/event ──────────┘
                                       (assistant reply → QQ sendMarkdown)

Installation

No command line needed — everything happens inside the app:

  1. Install: click "Plugins" in the left sidebar → "Add plugin" → enter @tencent-connect/dsh-qqbot@latest → install and start now
  1. Connect: avatar at the bottom-left → Settings → "QQ Bots" → scan the QR code with mobile QQ

Credentials are saved automatically after the scan; later launches need no re-scan.

Method 2: Manual

# Add to a profile
npx @deepseek-ai/dsh plugin --profile qqbot add @tencent-connect/dsh-qqbot

# Start
npx @deepseek-ai/dsh --profile qqbot

On first launch, the plugin detects missing credentials and automatically starts the QR flow: a QR code is printed in the terminal → scan it with the QQ mobile app → credentials are saved to the profile, so subsequent launches require no re-scan.

In environments without the in-app binding page (pure CLI), set QQBOT_BIND_OPEN_BROWSER=1 to additionally open a browser QR page as a fallback.

Note: Upgrade to 0.4.0 or later for browser-link scanning, which avoids QR code misalignment in some terminals.

Method 3: Local path

# Build
cd /path/to/dsh-qqbot
pnpm install && pnpm build

# Add to a profile (local path)
npx @deepseek-ai/dsh plugin --profile qqbot add /path/to/dsh-qqbot

# Start
export QQBOT_APPID="yourAppID" QQBOT_SECRET="yourAppSecret"
npx @deepseek-ai/dsh --profile qqbot

Method 4: --patch dev mode

export QQBOT_APPID="yourAppID" QQBOT_SECRET="yourAppSecret"
npx @deepseek-ai/dsh web --patch /path/to/dsh-qqbot/cordis.dev.yml

Configuration

Config Type Default Description
appId string required QQ Bot AppID (or via QQBOT_APPID env var)
appSecret string required QQ Bot AppSecret (or via QQBOT_SECRET env var)
provider string deepseek-official LLM provider name
model string deepseek-chat Model name
preset string - Agent preset id
cwd string process.cwd() Agent working directory
requireMention boolean true Whether group messages require @bot to trigger
groupPrompt string - Extra system prompt for group chats
directPrompt string - Extra system prompt for direct chats
textChunkLimit number 4500 Max chars per message
streaming boolean true Enable streaming output (always disabled in groups)
sessionIdleTimeout number 1800000 Session idle timeout (ms), default 30 min
processingTimeoutMs number 1800000 Processing timeout (ms), aborts the current LLM call
maxQueue number 20 Max concurrent queue length
historyLimit number 10 Group history buffer size
askTimeoutMs number 300000 Question timeout (ms), default 5 min (ask_user_question)
showToolResults boolean false Show successful tool-call results (errors always shown)
debug boolean false Debug mode

Access control (access)

Config Type Default Description
access.c2cMode open/allowlist/disabled open Direct-chat access mode
access.c2cAllow string[] [] Direct-chat allowlist (user openid)
access.groupMode open/allowlist/disabled open Group access mode
access.groupAllow string[] [] Group allowlist (group openid)

Rich media (media)

Config Type Default Description
media.enabled boolean true Enable rich media understanding (image/video download + tool analysis)
media.maxMB number 200 Max download size (MB)
media.ttlHours number 24 Media lifetime (hours), 0 = never expire

Vision (vision)

Config Type Default Description
vision.enabled boolean false Enable vision (qqbot_describe_image tool)
vision.provider string - Vision model provider (e.g. pi-ai)
vision.model string - Vision model id (e.g. qwen-vl-max)
vision.maxBytes number 10MB Max image bytes
vision.maxTokens number 1024 Max output tokens
vision.timeoutMs number 120000 Vision call timeout (ms)

File sending (sendFile)

Config Type Default Description
sendFile.restrictPaths boolean true Enable path allowlist (media + cwd + extraRoots only)
sendFile.extraRoots string[] [] Extra allowed root directories

Built-in Commands

Command Description
/new (aliases /reset /clear) Start a new session (clear context)
/compact Compact session history (replace old records with a summary)
/model View or switch model
/preset View or switch agent preset (applies to new sessions)
/stop Abort the current generation
/bot-ping Network latency test (transport & processing time)
/bot-version View version info
/bot-status View current session status
/bot-help View all commands

Core Modules

src/
├── index.ts                    # Cordis plugin entry (async apply)
├── config.ts                   # Config schema
├── types.ts                    # Global types
├── setup.ts                    # Credential binding (QR)
├── gateway/                    # Gateway assembly
│   ├── bootstrap.ts            # Startup wiring (session/event listeners, etc.)
│   └── middleware-setup.ts     # Middleware chain config
├── transport/                  # Transport layer
│   ├── inbound.ts              # QQ inbound message → agent.followup()
│   ├── outbound.ts             # session/event → QQ sendMarkdown
│   ├── outbound-buffer.ts      # Streaming buffer
│   ├── streaming-writer.ts     # Streaming writer
│   ├── reply-target.ts         # Reply target resolution
│   ├── msgid-cache.ts          # Passive reply msgid cache
│   ├── reply-limiter.ts        # Passive reply rate limiter
│   ├── tool-presenter.ts       # Tool-call presentation
│   └── chunker.ts              # Markdown chunking
├── session/                    # Session management
│   ├── session-manager.ts      # QQ peer → Agent mapping
│   └── idle-evictor.ts         # Idle eviction
├── model/                      # Model routing
│   ├── model-resolver.ts       # Route resolution
│   ├── prefs-store.ts          # Per-peer preference persistence
│   └── settings-reader.ts      # settings.yaml read-only
├── features/                   # Interaction features
│   ├── question-channel.ts     # ask_user_question Q&A channel
│   ├── approval-channel.ts     # approval confirmation channel
│   └── answer-parser.ts        # Answer parsing
├── media/                      # Media
│   ├── vision-tool.ts          # Image vision understanding
│   ├── send-file-tool.ts       # Send local files
│   └── media-cleaner.ts        # Media TTL cleanup
├── middleware/                 # Middleware
│   ├── question-answer.ts      # Q&A answer handling
│   └── attachment.ts           # Attachment handling
├── shared/                     # Shared utilities
│   ├── utils.ts                # Common helpers
│   ├── scope.ts                # scope/peer extraction
│   └── send-helper.ts          # Chunked send
└── commands/                   # Slash commands

Session Routing

sessionKey: qqbot:${appId}:${scope}:${peerId}; a UUID session id is minted for new sessions and persisted to model-prefs.json, resuming by the persisted id after restarts; pre-0.6 sessions keep their originally derived ids.

Resolution strategy: in-process reuse → persisted resume → fresh create.

Design Principles

  • Pure Cordis plugin — follows the dsh "Plugins, not loop changes" principle
  • Declarative dependencies — inject = ['agents'], no direct coupling to other plugins
  • Session isolation — one independent Agent per QQ direct user / group
  • Preset support — mount presets (toolkits, prompts, etc.) via the agent-presets service
  • Idle eviction — auto-dispose Agents on timeout to prevent memory leaks
  • Markdown output — replies sent as Markdown with code-block/table-aware chunking
  • Image understanding — supports qqbot_describe_image vision to analyze images sent by users
  • File sending — supports qqbot_send_file to send local files to users (path allowlist enabled by default)
  • Question interaction — supports ask_user_question with inline keyboard buttons (mutually exclusive) or numbered replies, one question at a time with timeout
  • Approval confirmation — supports approval/request to ask for user confirmation on critical actions via allow/deny buttons

Local Development

# Install dependencies
pnpm install

# Build
pnpm build

# Dev mode (watch)
pnpm dev

# Debug via --patch
export QQBOT_APPID="xxx" QQBOT_SECRET="xxx"
npx @deepseek-ai/dsh web --patch /path/to/dsh-qqbot/cordis.dev.yml

License

MIT