@hedeqiang/dsh-nl2sql 0.11.1 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +66 -31
- package/README.md +144 -58
- package/README.zh-CN.md +175 -0
- package/channels/dingtalk.js +3 -3
- package/channels/index.js +1 -1
- package/channels/lark.js +35 -7
- package/channels/message.js +19 -2
- package/channels/telegram.js +20 -4
- package/channels/wecom.js +2 -2
- package/im.js +1 -1
- package/index.js +3 -1
- package/lark-bot.js +1 -1
- package/lib/client.js +188 -28
- package/package.json +8 -4
- package/service/access.js +38 -1
- package/service/bots.js +77 -10
- package/service/channels.js +23 -7
- package/service/push.js +2 -2
- package/service/suggestions.js +1 -1
- package/README.en.md +0 -63
- /package/docs/{CHANNELS.md → channels.md} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,52 +1,87 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
4
5
|
|
|
5
|
-
## [
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
## [0.12.0] - 2026-11-12
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- One-click member adding: people and groups that talked to a bot, and the groups a bot is in, are offered in the member form with their ids, names and emails filled in. People and groups refused because they are not members yet are listed at the top of **Members & access**.
|
|
12
|
+
- Bots know the member's data sources: every question carries a catalog of the sources the member may use (type, database, description, main tables); the agent switches to the matching source and states which one it used. A source named in the question, or one whose business knowledge matches, is selected automatically.
|
|
13
|
+
- Bot commands: `数据源` lists sources with descriptions, `切换 <name>` pins a source (fuzzy match), `自动` returns to automatic selection. The reply footer shows the source actually used.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- README rewritten in English (Chinese in `README.zh-CN.md`) with screenshots, security model and installation from npm; added a Code of Conduct, issue and pull request templates, and an English development guide (`docs/development.md`). `docs/CHANNELS.md` moved to `docs/channels.md`.
|
|
17
|
+
- List separators and label colons in the page follow the UI language.
|
|
18
|
+
|
|
19
|
+
## [0.11.2] - 2026-11-12
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- Dashboards show each chart's data source (and flag deleted sources); a dashboard that mixes sources lists them and can be scoped to *All sources* or *Only the current source* (remembered per browser). Reordering while scoped keeps hidden charts in place.
|
|
23
|
+
- Large results in IM messages: messages say how many rows are shown (Lark cards up to 50 rows with paging, Telegram 20, WeCom and DingTalk 10). Lark app bots and Telegram attach the full data as an Excel file (`attachFull`, on by default); a failed attachment does not fail the message and is noted in the delivery log.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- README installation instructions now use npm (**Plugins → Add plugin** or `dsh plugin add`), with upgrade, uninstall and from-source steps.
|
|
6
27
|
|
|
7
28
|
## [0.11.1] - 2026-11-12
|
|
8
29
|
|
|
9
|
-
###
|
|
10
|
-
-
|
|
30
|
+
### Added
|
|
31
|
+
- Release workflow: pushing a `v*` tag checks, packs and publishes to npm with trusted publishing and provenance, and creates the GitHub release.
|
|
11
32
|
|
|
12
|
-
###
|
|
13
|
-
-
|
|
33
|
+
### Fixed
|
|
34
|
+
- Channel catalog text, suggested questions and number units showed in English in the Chinese UI (the UI read the wrong field of the Harness locale snapshot).
|
|
14
35
|
|
|
15
36
|
## [0.11.0] - 2026-11-12
|
|
16
37
|
|
|
17
|
-
###
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
38
|
+
### Added
|
|
39
|
+
- Channel adapter architecture (`channels/`): a platform-neutral message model, capability declarations, form schemas and a bot interface ([docs/channels.md](docs/channels.md)).
|
|
40
|
+
- Telegram (push, long-polling bot, inline buttons), WeCom (group webhook push; AI bot over the long connection) and DingTalk (custom robot push; internal app robot over Stream mode). These adapters are tested against local fakes only.
|
|
41
|
+
- Multi-platform member identities; one bot per channel, several bots at once.
|
|
42
|
+
- Redesigned pages: channels grouped by platform with a two-step add dialog, a bots overview, an identities editor, and a *Channels & bots* settings group.
|
|
43
|
+
- Ask page: shuffle suggested questions, delete single history entries, show more recent questions.
|
|
23
44
|
|
|
24
|
-
###
|
|
25
|
-
-
|
|
45
|
+
### Changed
|
|
46
|
+
- Existing Lark channels, bot settings, member fields and settings are migrated on first load; old RPCs and payloads keep working.
|
|
26
47
|
|
|
27
48
|
## [0.10.0] - 2026-11-12
|
|
28
49
|
|
|
29
|
-
###
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
50
|
+
### Added
|
|
51
|
+
- Interactive buttons on Lark answer cards: break down by a dimension, why did it change, details, pin to dashboard (via the long connection, re-authorized per click).
|
|
52
|
+
- Knowledge suggestions mined from 👍 feedback, repeated queries, common aggregates and value mappings, accepted by a person.
|
|
53
|
+
- Open-source groundwork: MIT license, README, contributing guide, security policy, CI.
|
|
33
54
|
|
|
34
|
-
###
|
|
35
|
-
- `token_code`
|
|
36
|
-
-
|
|
55
|
+
### Fixed
|
|
56
|
+
- Business columns such as `token_code` are no longer treated as sensitive.
|
|
57
|
+
- Evaluation recognises the same numbers in pivoted shapes (one row with many columns vs. many rows).
|
|
37
58
|
|
|
38
59
|
## [0.9.0] - 2026-11-12
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
60
|
+
|
|
61
|
+
### Changed
|
|
62
|
+
- Page reorganised into five tabs plus a **Manage** area; grouped settings with descriptions, unsaved-changes bar, reset to defaults and configuration export / import.
|
|
63
|
+
- Onboarding checklist; suggested and recent questions on the Ask page.
|
|
64
|
+
- Dashboard drag-to-reorder, three widths, refresh and cache status; in-page dialogs instead of browser pop-ups; complete English UI.
|
|
65
|
+
- Chunked uploads; streamed truncation of large MySQL / PostgreSQL results; relevant-table selection for large schemas; configurable log retention.
|
|
43
66
|
|
|
44
67
|
## [0.8.0] - 2026-11-12
|
|
45
|
-
|
|
46
|
-
|
|
68
|
+
|
|
69
|
+
### Added
|
|
70
|
+
- Viewer role, row-level rules, scheduler catch-up and status, logs stored in SQLite, `service/` and `client-src/` split, test suite.
|
|
71
|
+
|
|
72
|
+
### Security
|
|
73
|
+
- Per-dialect lexing for read-only admission (fixes writes through PostgreSQL), access-control bypasses, Lark member data source scopes, mismatched Lark answers.
|
|
47
74
|
|
|
48
75
|
## [0.7.0] - 2026-11-11
|
|
49
|
-
- 指标告警、飞书 @机器人问答、下钻与归因、准确率评测、表结构变更检测、指标工具、多看板、Excel 导出、CSV / Excel 上传、结果持久化与缓存、业务知识导入导出、多用户权限与审计。
|
|
50
76
|
|
|
51
|
-
|
|
52
|
-
-
|
|
77
|
+
### Added
|
|
78
|
+
- Metric alerts, Lark @-mention bot, drill-down and attribution, accuracy evaluation, schema change detection, metric tool, multiple dashboards, Excel export, CSV / Excel upload, persisted results and cache, knowledge import / export, members, permissions and audit.
|
|
79
|
+
|
|
80
|
+
## [0.6.0] and earlier
|
|
81
|
+
|
|
82
|
+
- Redesigned UI; Lark push (Markdown and native charts); access control, feedback loop, dashboard global filters; PostgreSQL / Elasticsearch, SSH tunnels, privacy settings, automatic overviews, scheduled reports; semantic layer, ER graph, scan guard, history and audit, dashboards; first version.
|
|
83
|
+
|
|
84
|
+
[Unreleased]: https://github.com/hedeqiang/dsh-nl2sql/compare/v0.12.0...HEAD
|
|
85
|
+
[0.12.0]: https://github.com/hedeqiang/dsh-nl2sql/compare/v0.11.2...v0.12.0
|
|
86
|
+
[0.11.2]: https://github.com/hedeqiang/dsh-nl2sql/compare/v0.11.1...v0.11.2
|
|
87
|
+
[0.11.1]: https://github.com/hedeqiang/dsh-nl2sql/releases/tag/v0.11.1
|
package/README.md
CHANGED
|
@@ -1,89 +1,175 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# dsh-nl2sql
|
|
4
4
|
|
|
5
|
-
[
|
|
5
|
+
**Ask your databases in plain language — inside [DeepSeek Harness](https://github.com/deepseek-ai).**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The agent writes read-only SQL, runs it and charts the answer in the conversation.<br>
|
|
8
|
+
Pin results to dashboards, schedule reports and alerts, and push them to Lark / Feishu, Telegram, WeCom or DingTalk — or let teammates @-mention a bot in their group chat.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
- 自然语言提问:在 Harness 对话中进行,Agent 使用 `nl2sql_*` 工具查询,结果在对话中渲染为 ECharts 图表或表格。
|
|
13
|
-
- 下钻与归因:按维度拆分、查看明细、「为什么变化」——比较两个时段并按维度贡献排序。
|
|
14
|
-
- 指标库与业务知识:词表、指标口径(Agent 用 `nl2sql_metric` 按口径查询)、字段备注、样例问答;支持导入导出。
|
|
15
|
-
- 准确率评测:用样例问答作为评测集,Agent 从零作答后与样例结果比对。
|
|
10
|
+
[](https://www.npmjs.com/package/@hedeqiang/dsh-nl2sql)
|
|
11
|
+
[](https://github.com/hedeqiang/dsh-nl2sql/actions/workflows/check.yml)
|
|
12
|
+
[](LICENSE)
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
- 多看板、全局筛选(时间范围 / 维度)、拖拽排序、三档宽度、快照、Excel 导出。
|
|
19
|
-
- IM 渠道:飞书 / Lark、Telegram、企业微信、钉钉(推送 Markdown 与结果,图表按平台能力用原生图表、图片或表格);架构见 [docs/CHANNELS.md](docs/CHANNELS.md),新增平台只需实现一个适配器。
|
|
20
|
-
- 定时报告(基于 Harness 定时任务)、指标告警(阈值 / 环比 / 异常 / 无数据)、表结构变更检测。
|
|
21
|
-
- 群聊 @机器人提问:飞书长连接、Telegram 长轮询、企业微信智能机器人长连接、钉钉 Stream 模式,都不需要公网地址。
|
|
14
|
+
English · [简体中文](README.zh-CN.md)
|
|
22
15
|
|
|
23
|
-
|
|
24
|
-
- 只读执行:按方言词法检查语句(MySQL / PostgreSQL / SQLite / ES),只读事务,PostgreSQL 使用扩展协议拒绝多语句,服务端超时,大结果流式截断。
|
|
25
|
-
- 访问控制:按表允许 / 排除、隐藏列、脱敏列;大表全表扫描保护。
|
|
26
|
-
- 成员与权限:飞书用户 / 群的数据源范围、只读角色(只能用指标库、已验证样例和看板)、行级权限(自动注入过滤,无法安全改写的查询直接拒绝)。
|
|
27
|
-
- 隐私:可设置发给模型的内容(不发 / 统计摘要 / 前 N 行),敏感字段默认脱敏;审计记录归属到具体的人。
|
|
16
|
+
</div>
|
|
28
17
|
|
|
29
|
-
|
|
18
|
+

|
|
30
19
|
|
|
31
|
-
|
|
20
|
+
## Contents
|
|
21
|
+
|
|
22
|
+
- [Features](#features)
|
|
23
|
+
- [Requirements](#requirements)
|
|
24
|
+
- [Installation](#installation)
|
|
25
|
+
- [Quick start](#quick-start)
|
|
26
|
+
- [IM channels and bots](#im-channels-and-bots)
|
|
27
|
+
- [Security model](#security-model)
|
|
28
|
+
- [Data and privacy](#data-and-privacy)
|
|
29
|
+
- [Limitations](#limitations)
|
|
30
|
+
- [Development](#development)
|
|
31
|
+
- [Contributing](#contributing)
|
|
32
|
+
- [License](#license)
|
|
33
|
+
|
|
34
|
+
## Features
|
|
35
|
+
|
|
36
|
+
**Ask and analyze**
|
|
37
|
+
- Data sources: MySQL 5.7+, PostgreSQL, Elasticsearch (SQL), optionally through an SSH tunnel, and CSV / Excel uploads stored as local SQLite.
|
|
38
|
+
- Schema analysis: table roles, column semantics (time / measure / enum / sensitive), inferred relations and an ER graph.
|
|
39
|
+
- Natural-language questions in any Harness conversation through the `nl2sql_*` agent tools; results render as interactive ECharts charts or tables.
|
|
40
|
+
- Drill-down: split by a dimension, show the rows behind a point, and *why did it change* — rank dimensions by their contribution between two periods.
|
|
41
|
+
- Business knowledge: glossary, governed metrics (queried with `nl2sql_metric`), column notes and verified question → SQL examples, with import / export and suggestions mined from history and feedback.
|
|
42
|
+
- Accuracy evaluation: replay the verified examples, or let the agent answer them from scratch and compare results.
|
|
43
|
+
|
|
44
|
+
**Share and automate**
|
|
45
|
+
- Multiple dashboards with global filters, drag-to-reorder, three widths, snapshots and Excel export. A dashboard may mix data sources; every chart shows where it comes from.
|
|
46
|
+
- Scheduled reports, metric alerts (threshold / change / anomaly / missing data) and schema change detection.
|
|
47
|
+
- Push to Lark / Feishu, Telegram, WeCom and DingTalk; charts are sent as native card charts, images or tables depending on the platform, and large results come with the full data as an Excel attachment where the platform allows files.
|
|
48
|
+
- Chat bots that answer @-mentions in group chats without a public URL (Lark long connection, Telegram long polling, WeCom AI bot long connection, DingTalk Stream mode).
|
|
49
|
+
|
|
50
|
+
**Govern**
|
|
51
|
+
- Read-only by construction, table / column access policies with masking, and a full-scan guard.
|
|
52
|
+
- Members with roles (admin / analyst / viewer), data source scopes and row-level rules for people and group chats on every IM platform.
|
|
53
|
+
- Audit history attributed to people, and a setting for exactly what query data the model may see.
|
|
54
|
+
|
|
55
|
+
<table>
|
|
56
|
+
<tr>
|
|
57
|
+
<td width="50%"><img src="docs/images/schema.png" alt="Schema analysis with column roles"></td>
|
|
58
|
+
<td width="50%"><img src="docs/images/channels.png" alt="IM channels grouped by platform"></td>
|
|
59
|
+
</tr>
|
|
60
|
+
<tr>
|
|
61
|
+
<td align="center"><sub>Schema analysis</sub></td>
|
|
62
|
+
<td align="center"><sub>IM channels</sub></td>
|
|
63
|
+
</tr>
|
|
64
|
+
</table>
|
|
65
|
+
|
|
66
|
+
## Requirements
|
|
67
|
+
|
|
68
|
+
- [DeepSeek Harness](https://github.com/deepseek-ai) 0.2 or later — the desktop app or `dsh web`.
|
|
69
|
+
- Network access from the Harness machine to your databases (directly or through SSH).
|
|
70
|
+
- A **read-only database account** is strongly recommended (see [Security model](#security-model)).
|
|
71
|
+
|
|
72
|
+
## Installation
|
|
73
|
+
|
|
74
|
+
**From the Harness UI (recommended)**
|
|
75
|
+
|
|
76
|
+
1. Open **Plugins** in the sidebar and choose **Add plugin**.
|
|
77
|
+
2. Enter `@hedeqiang/dsh-nl2sql` (optionally pinned, e.g. `@hedeqiang/dsh-nl2sql@0.11.2`), then install and enable it.
|
|
78
|
+
3. **Data Q&A** appears in the sidebar, and a *Data Q&A* agent preset is available for new conversations.
|
|
79
|
+
|
|
80
|
+
You can also simply ask the Harness agent: *"install the plugin @hedeqiang/dsh-nl2sql"*.
|
|
81
|
+
|
|
82
|
+
**From the command line**
|
|
32
83
|
|
|
33
84
|
```bash
|
|
34
|
-
#
|
|
35
|
-
git clone <this repo> dsh-nl2sql && cd dsh-nl2sql
|
|
36
|
-
pnpm install --ignore-scripts # 依赖:mysql2、pg、ssh2、echarts、@larksuiteoapi/node-sdk、@resvg/resvg-js
|
|
85
|
+
dsh plugin --profile desktop add @hedeqiang/dsh-nl2sql # the desktop app uses the "desktop" profile; dsh web uses "web"
|
|
37
86
|
```
|
|
38
87
|
|
|
39
|
-
|
|
88
|
+
Then enable it on the **Plugins** page, or restart Harness.
|
|
40
89
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
90
|
+
**Upgrade and uninstall**
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
dsh plugin --profile desktop update @hedeqiang/dsh-nl2sql
|
|
94
|
+
dsh plugin --profile desktop remove @hedeqiang/dsh-nl2sql
|
|
44
95
|
```
|
|
45
96
|
|
|
46
|
-
|
|
97
|
+
Configuration and data live in `~/.dsh/nl2sql` and survive upgrades and uninstalls; older configuration is migrated automatically on first load. Delete the directory yourself if you no longer need it.
|
|
98
|
+
|
|
99
|
+
All dependencies ship prebuilt binaries, so no install scripts need to run.
|
|
100
|
+
|
|
101
|
+
## Quick start
|
|
102
|
+
|
|
103
|
+
1. **Data Q&A → Manage → Data sources** — add a database, or upload a CSV / Excel file.
|
|
104
|
+
2. **Schema** — run the analysis (it reads metadata and a small sample of enum values, never full tables).
|
|
105
|
+
3. **Ask** — type a question, e.g. *"daily orders and revenue over the last 30 days"*. The agent picks tables, writes SQL for your dialect, runs it and draws a chart. You can also choose the *Data Q&A* preset in any conversation.
|
|
106
|
+
4. **Dashboard** — pin useful charts, add filters, export or send them.
|
|
107
|
+
5. **Knowledge** — add glossary terms, metric definitions and verified examples to make answers consistent; run an evaluation to measure accuracy.
|
|
108
|
+
|
|
109
|
+
## IM channels and bots
|
|
110
|
+
|
|
111
|
+
Every platform is an adapter under [`channels/`](channels); the core only talks to the adapter interface described in [docs/channels.md](docs/channels.md).
|
|
47
112
|
|
|
48
|
-
|
|
113
|
+
| Platform | Push | Charts | Buttons | Bot without public URL |
|
|
114
|
+
|---|---|---|---|---|
|
|
115
|
+
| Lark / Feishu — group webhook | ✓ | native card charts | – | – |
|
|
116
|
+
| Lark / Feishu — app bot | ✓ (+ Excel attachment) | native charts or images | ✓ | ✓ long connection |
|
|
117
|
+
| Telegram | ✓ (+ Excel attachment) | images | ✓ inline keyboard | ✓ long polling |
|
|
118
|
+
| WeCom — group webhook | ✓ | images | – | – |
|
|
119
|
+
| WeCom — AI bot | ✓ (chats that messaged the bot) | tables | – | ✓ long connection |
|
|
120
|
+
| DingTalk — custom robot | ✓ (optional signing) | tables | – | – |
|
|
121
|
+
| DingTalk — internal app robot | ✓ | tables | – | ✓ Stream mode |
|
|
49
122
|
|
|
50
|
-
|
|
51
|
-
2. 「表结构」→ 分析表结构。
|
|
52
|
-
3. 「问答」页提问,或在任意对话中选择「数据问答」预设直接提问。
|
|
53
|
-
4. 把满意的图表固定到「看板」;在「业务知识」补充词表、指标和样例,提高准确率。
|
|
54
|
-
5. 「管理 → 推送渠道」添加飞书机器人;「告警与报告」配置自动任务;「成员与权限」开通飞书群提问。
|
|
123
|
+
Add a channel in **Manage → Channels**: pick the platform and connection type, and the form shows the console steps for that platform. People and groups are granted access in **Manage → Members & access**; anyone who has talked to a bot can be added with one click.
|
|
55
124
|
|
|
56
|
-
|
|
125
|
+
In a group chat, members @-mention the bot and ask. The bot knows which data sources the member may use and picks the matching one. Chat commands: `help`, `数据源` (list sources), `切换 <name>` (pin a source), `自动` (pick automatically again), `新对话` / `reset` (new conversation).
|
|
57
126
|
|
|
58
|
-
|
|
127
|
+
> The Telegram, WeCom and DingTalk adapters are tested against local fakes of their APIs and have not yet been verified with real accounts; Lark has been used with real workspaces. Reports from real deployments are welcome.
|
|
59
128
|
|
|
60
|
-
|
|
129
|
+
## Security model
|
|
130
|
+
|
|
131
|
+
- **Read-only queries.** Every statement passes a per-dialect lexer (MySQL, PostgreSQL, SQLite, Elasticsearch SQL) that admits only `SELECT` / `SHOW` / `DESCRIBE` / `EXPLAIN`; queries run in read-only transactions with server-side timeouts, PostgreSQL uses the extended protocol (no multi-statement strings), and large results are streamed and truncated.
|
|
132
|
+
- **Access policies.** Allow or deny tables, hide or mask columns, and refuse full scans of large tables unless confirmed.
|
|
133
|
+
- **Members.** Data source scopes, a viewer role (metric library, verified examples and dashboards only) and row-level rules that are injected into queries — queries that cannot be rewritten safely are refused.
|
|
134
|
+
- **Bot actions.** Buttons on IM messages carry opaque tokens only; every click is re-authorized for the person who clicked.
|
|
135
|
+
|
|
136
|
+
The lexer is a first line of defence, not a substitute for database permissions: **always connect with a read-only account.** See [SECURITY.md](SECURITY.md) to report a vulnerability.
|
|
137
|
+
|
|
138
|
+
## Data and privacy
|
|
139
|
+
|
|
140
|
+
| What | Where |
|
|
61
141
|
|---|---|
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
|
142
|
+
| Configuration (data sources, dashboards, knowledge, alerts, members, channels, settings) | `~/.dsh/nl2sql/state.json` |
|
|
143
|
+
| Query results, cache, snapshots and logs (history, audit, feedback, deliveries, alerts) | `~/.dsh/nl2sql/results.sqlite` |
|
|
144
|
+
| Uploaded files | `~/.dsh/nl2sql/files/` |
|
|
145
|
+
| Database passwords, SSH keys, bot secrets | the Harness credential store |
|
|
146
|
+
|
|
147
|
+
**Settings → Data shown to the model** controls what query data reaches the LLM: nothing, per-column statistics (default) or the first *N* rows. Sensitive columns are masked by default. Anything you push to an IM platform leaves your machine.
|
|
148
|
+
|
|
149
|
+
## Limitations
|
|
66
150
|
|
|
67
|
-
|
|
151
|
+
- Alerts and the daily schema check run inside the Harness process: nothing is checked while Harness is closed; one catch-up run happens after it starts.
|
|
152
|
+
- The local page has owner rights and no login; do not expose the Harness web port to untrusted networks.
|
|
153
|
+
- Row-level rules apply to IM members; queries with subqueries, CTEs or `UNION` are refused under row-level rules.
|
|
154
|
+
- Legacy `.xls` files are not supported (use `.xlsx` or CSV).
|
|
68
155
|
|
|
69
|
-
##
|
|
156
|
+
## Development
|
|
70
157
|
|
|
71
158
|
```bash
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
159
|
+
git clone https://github.com/hedeqiang/dsh-nl2sql.git
|
|
160
|
+
cd dsh-nl2sql
|
|
161
|
+
pnpm install --ignore-scripts
|
|
162
|
+
npm test # full suite; local MySQL / PostgreSQL are used when available
|
|
163
|
+
npm run test:fast # unit + UI tests only
|
|
164
|
+
node scripts/build-client.mjs # regenerate lib/client.js after editing client-src/
|
|
76
165
|
```
|
|
77
166
|
|
|
78
|
-
|
|
167
|
+
Install your checkout as a linked plugin with **Plugins → Add plugin** and the absolute directory path; re-enable the plugin to load changes. Project layout, conventions and test setup are in [docs/development.md](docs/development.md); an isolated accuracy benchmark lives in [eval/](eval/README.md).
|
|
79
168
|
|
|
80
|
-
##
|
|
169
|
+
## Contributing
|
|
81
170
|
|
|
82
|
-
|
|
83
|
-
- 行级权限只对飞书成员生效;本机页面始终是所有者权限,没有登录机制。
|
|
84
|
-
- 行级权限下不支持子查询、CTE、UNION(会被拒绝)。
|
|
85
|
-
- 不支持旧版 `.xls`。
|
|
171
|
+
Issues and pull requests are welcome — please read [CONTRIBUTING.md](CONTRIBUTING.md) and follow the [Code of Conduct](CODE_OF_CONDUCT.md). Release notes are in [CHANGELOG.md](CHANGELOG.md).
|
|
86
172
|
|
|
87
|
-
##
|
|
173
|
+
## License
|
|
88
174
|
|
|
89
|
-
[MIT](LICENSE)
|
|
175
|
+
[MIT](LICENSE) © hedeqiang
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# dsh-nl2sql
|
|
4
|
+
|
|
5
|
+
**在 [DeepSeek Harness](https://github.com/deepseek-ai) 里用自然语言问数据库。**
|
|
6
|
+
|
|
7
|
+
Agent 编写只读 SQL、执行并在对话中画图。<br>
|
|
8
|
+
结果可以固定到看板、定时报告和告警,推送到飞书、Telegram、企业微信、钉钉,也可以让同事在群里直接 @机器人 提问。
|
|
9
|
+
|
|
10
|
+
[](https://www.npmjs.com/package/@hedeqiang/dsh-nl2sql)
|
|
11
|
+
[](https://github.com/hedeqiang/dsh-nl2sql/actions/workflows/check.yml)
|
|
12
|
+
[](LICENSE)
|
|
13
|
+
|
|
14
|
+
[English](README.md) · 简体中文
|
|
15
|
+
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+

|
|
19
|
+
|
|
20
|
+
## 目录
|
|
21
|
+
|
|
22
|
+
- [功能](#功能)
|
|
23
|
+
- [环境要求](#环境要求)
|
|
24
|
+
- [安装](#安装)
|
|
25
|
+
- [快速开始](#快速开始)
|
|
26
|
+
- [IM 渠道与机器人](#im-渠道与机器人)
|
|
27
|
+
- [安全模型](#安全模型)
|
|
28
|
+
- [数据与隐私](#数据与隐私)
|
|
29
|
+
- [已知限制](#已知限制)
|
|
30
|
+
- [开发](#开发)
|
|
31
|
+
- [参与贡献](#参与贡献)
|
|
32
|
+
- [许可证](#许可证)
|
|
33
|
+
|
|
34
|
+
## 功能
|
|
35
|
+
|
|
36
|
+
**提问与分析**
|
|
37
|
+
- 数据源:MySQL 5.7+、PostgreSQL、Elasticsearch(SQL),可经 SSH 隧道;也可以上传 CSV / Excel,保存为本机 SQLite。
|
|
38
|
+
- 表结构分析:识别表的角色、字段语义(时间 / 度量 / 枚举 / 敏感),推断表间关系,提供关系图。
|
|
39
|
+
- 在任意 Harness 对话中用自然语言提问,Agent 通过 `nl2sql_*` 工具查询,结果渲染为可交互的 ECharts 图表或表格。
|
|
40
|
+
- 下钻:按维度拆分、查看某个点的明细,以及「为什么变化」——比较两个时段并按维度贡献排序。
|
|
41
|
+
- 业务知识:词表、指标口径(`nl2sql_metric` 按口径查询)、字段备注、已验证的问题 → SQL 样例;支持导入导出,并能从历史和反馈中自动生成建议。
|
|
42
|
+
- 准确率评测:回放样例,或让 Agent 从零作答后与样例结果比对。
|
|
43
|
+
|
|
44
|
+
**共享与自动化**
|
|
45
|
+
- 多看板、全局筛选、拖拽排序、三档宽度、快照、Excel 导出;一个看板可以放多个数据源的图表,每个图表标注来源。
|
|
46
|
+
- 定时报告、指标告警(阈值 / 环比 / 异常 / 无数据)、表结构变更检测。
|
|
47
|
+
- 推送到飞书、Telegram、企业微信、钉钉:图表按平台能力用原生卡片图表、图片或表格发送;结果过大时,在能发文件的平台附带完整数据 Excel。
|
|
48
|
+
- 群聊机器人回答 @提问,不需要公网地址(飞书长连接、Telegram 长轮询、企业微信智能机器人长连接、钉钉 Stream 模式)。
|
|
49
|
+
|
|
50
|
+
**治理**
|
|
51
|
+
- 只读执行;表 / 字段级访问控制与脱敏;大表全表扫描保护。
|
|
52
|
+
- 成员:各 IM 平台的个人和群都可以设置角色(管理员 / 分析师 / 只读)、数据源范围和行级权限。
|
|
53
|
+
- 审计记录归属到具体的人;可以精确设置哪些查询数据会发给模型。
|
|
54
|
+
|
|
55
|
+
<table>
|
|
56
|
+
<tr>
|
|
57
|
+
<td width="50%"><img src="docs/images/schema.png" alt="表结构分析"></td>
|
|
58
|
+
<td width="50%"><img src="docs/images/channels.png" alt="按平台分组的 IM 渠道"></td>
|
|
59
|
+
</tr>
|
|
60
|
+
<tr>
|
|
61
|
+
<td align="center"><sub>表结构分析</sub></td>
|
|
62
|
+
<td align="center"><sub>IM 渠道</sub></td>
|
|
63
|
+
</tr>
|
|
64
|
+
</table>
|
|
65
|
+
|
|
66
|
+
## 环境要求
|
|
67
|
+
|
|
68
|
+
- [DeepSeek Harness](https://github.com/deepseek-ai) 0.2 及以上(桌面版或 `dsh web`)。
|
|
69
|
+
- Harness 所在机器能访问数据库(直连或经 SSH)。
|
|
70
|
+
- 强烈建议使用**只读数据库账号**(见[安全模型](#安全模型))。
|
|
71
|
+
|
|
72
|
+
## 安装
|
|
73
|
+
|
|
74
|
+
**在 Harness 界面中安装(推荐)**
|
|
75
|
+
|
|
76
|
+
1. 左侧栏打开 **插件**,选择 **添加插件**。
|
|
77
|
+
2. 输入 `@hedeqiang/dsh-nl2sql`(可指定版本,如 `@hedeqiang/dsh-nl2sql@0.11.2`),安装并启用。
|
|
78
|
+
3. 左侧栏出现 **数据问答**,新建对话时也可以选择「数据问答」预设。
|
|
79
|
+
|
|
80
|
+
也可以直接对 Harness 的 Agent 说:「安装插件 @hedeqiang/dsh-nl2sql」。
|
|
81
|
+
|
|
82
|
+
**命令行**
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
dsh plugin --profile desktop add @hedeqiang/dsh-nl2sql # 桌面版的 profile 是 desktop;dsh web 默认是 web
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
然后在 **插件** 页启用,或重启 Harness。
|
|
89
|
+
|
|
90
|
+
**升级与卸载**
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
dsh plugin --profile desktop update @hedeqiang/dsh-nl2sql
|
|
94
|
+
dsh plugin --profile desktop remove @hedeqiang/dsh-nl2sql
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
配置和数据保存在 `~/.dsh/nl2sql`,升级、卸载都不会删除;旧版本的配置会在首次加载时自动迁移。不再需要时请手动删除该目录。
|
|
98
|
+
|
|
99
|
+
所有依赖都提供预编译包,安装时不需要运行构建脚本。
|
|
100
|
+
|
|
101
|
+
## 快速开始
|
|
102
|
+
|
|
103
|
+
1. **数据问答 → 管理 → 数据源**:添加数据库,或上传 CSV / Excel。
|
|
104
|
+
2. **表结构**:运行分析(只读取元数据和少量枚举取值样本,不会扫描整表)。
|
|
105
|
+
3. **问答**:输入问题,例如「最近 30 天每天的订单量和金额」。Agent 选择表、按方言编写 SQL、执行并画图。也可以在任意对话中选择「数据问答」预设。
|
|
106
|
+
4. **看板**:固定有用的图表,添加筛选,导出或发送。
|
|
107
|
+
5. **业务知识**:补充词表、指标口径和已验证样例,让回答口径一致;运行评测衡量准确率。
|
|
108
|
+
|
|
109
|
+
## IM 渠道与机器人
|
|
110
|
+
|
|
111
|
+
每个平台都是 [`channels/`](channels) 下的一个适配器,核心逻辑只依赖 [docs/channels.md](docs/channels.md) 中定义的接口。
|
|
112
|
+
|
|
113
|
+
| 平台 | 推送 | 图表 | 按钮 | 无需公网地址的机器人 |
|
|
114
|
+
|---|---|---|---|---|
|
|
115
|
+
| 飞书 — 群机器人(Webhook) | ✓ | 原生卡片图表 | – | – |
|
|
116
|
+
| 飞书 — 应用机器人 | ✓(附带 Excel) | 原生图表或图片 | ✓ | ✓ 长连接 |
|
|
117
|
+
| Telegram | ✓(附带 Excel) | 图片 | ✓ 内联按钮 | ✓ 长轮询 |
|
|
118
|
+
| 企业微信 — 群机器人 | ✓ | 图片 | – | – |
|
|
119
|
+
| 企业微信 — 智能机器人 | ✓(仅已给机器人发过消息的会话) | 表格 | – | ✓ 长连接 |
|
|
120
|
+
| 钉钉 — 自定义机器人 | ✓(支持加签) | 表格 | – | – |
|
|
121
|
+
| 钉钉 — 企业内部应用机器人 | ✓ | 表格 | – | ✓ Stream 模式 |
|
|
122
|
+
|
|
123
|
+
在 **管理 → 渠道** 添加渠道:选择平台和接入方式,表单会显示该平台开放平台的配置步骤。在 **管理 → 成员与权限** 给个人和群开通权限,和机器人说过话的人或群可以一键添加。
|
|
124
|
+
|
|
125
|
+
群成员 @机器人 直接提问。机器人知道该成员能用哪些数据源,并自动选择匹配的那个。群内命令:`帮助`、`数据源`(列出可用数据源)、`切换 <名称>`(固定数据源)、`自动`(恢复自动选择)、`新对话`。
|
|
126
|
+
|
|
127
|
+
> Telegram、企业微信、钉钉适配器目前只在本地模拟的平台接口上测试过,尚未在真实账号上验证;飞书已在真实环境中使用。欢迎反馈实际部署情况。
|
|
128
|
+
|
|
129
|
+
## 安全模型
|
|
130
|
+
|
|
131
|
+
- **只读查询。** 每条语句都经过按方言的词法检查(MySQL、PostgreSQL、SQLite、Elasticsearch SQL),只允许 `SELECT` / `SHOW` / `DESCRIBE` / `EXPLAIN`;查询在只读事务中执行并有服务端超时;PostgreSQL 使用扩展协议(不接受多语句);大结果流式读取并截断。
|
|
132
|
+
- **访问控制。** 允许或排除表、隐藏或脱敏字段;大表全表扫描需要确认。
|
|
133
|
+
- **成员。** 数据源范围、只读角色(只能用指标库、已验证样例和看板),以及自动注入查询的行级权限——无法安全改写的查询直接拒绝。
|
|
134
|
+
- **机器人按钮。** IM 消息上的按钮只携带不透明令牌,每次点击都会对点击者重新鉴权。
|
|
135
|
+
|
|
136
|
+
词法检查只是第一道防线,不能替代数据库权限:**请始终使用只读账号连接。** 安全问题的报告方式见 [SECURITY.md](SECURITY.md)。
|
|
137
|
+
|
|
138
|
+
## 数据与隐私
|
|
139
|
+
|
|
140
|
+
| 内容 | 位置 |
|
|
141
|
+
|---|---|
|
|
142
|
+
| 配置(数据源、看板、业务知识、告警、成员、渠道、设置) | `~/.dsh/nl2sql/state.json` |
|
|
143
|
+
| 查询结果、缓存、快照和日志(历史、审计、反馈、推送记录、告警记录) | `~/.dsh/nl2sql/results.sqlite` |
|
|
144
|
+
| 上传的文件 | `~/.dsh/nl2sql/files/` |
|
|
145
|
+
| 数据库密码、SSH 密钥、机器人密钥 | Harness 凭据库 |
|
|
146
|
+
|
|
147
|
+
**设置 → 模型可见数据** 决定哪些查询数据会发给大模型:不发、按列统计摘要(默认)或前 *N* 行。敏感字段默认脱敏。推送到 IM 平台的内容会离开本机。
|
|
148
|
+
|
|
149
|
+
## 已知限制
|
|
150
|
+
|
|
151
|
+
- 告警和每日表结构检查在 Harness 进程内运行:Harness 关闭期间不检查,启动后补查一次。
|
|
152
|
+
- 本机页面拥有所有者权限,没有登录机制;不要把 Harness Web 端口暴露到不可信网络。
|
|
153
|
+
- 行级权限作用于 IM 成员;在行级权限下,含子查询、CTE 或 `UNION` 的查询会被拒绝。
|
|
154
|
+
- 不支持旧版 `.xls`(请使用 `.xlsx` 或 CSV)。
|
|
155
|
+
|
|
156
|
+
## 开发
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
git clone https://github.com/hedeqiang/dsh-nl2sql.git
|
|
160
|
+
cd dsh-nl2sql
|
|
161
|
+
pnpm install --ignore-scripts
|
|
162
|
+
npm test # 全部测试;本机有 MySQL / PostgreSQL 时会用到
|
|
163
|
+
npm run test:fast # 只跑单元测试和界面测试
|
|
164
|
+
node scripts/build-client.mjs # 修改 client-src/ 后重新生成 lib/client.js
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
在 **插件 → 添加插件** 中填入本目录的绝对路径即可以链接方式安装,改代码后重新启用插件生效。目录结构、约定和测试说明见 [docs/development.md](docs/development.md);隔离的准确率评测环境见 [eval/](eval/README.md)。
|
|
168
|
+
|
|
169
|
+
## 参与贡献
|
|
170
|
+
|
|
171
|
+
欢迎提交 Issue 和 Pull Request,请先阅读 [CONTRIBUTING.md](CONTRIBUTING.md) 并遵守[行为准则](CODE_OF_CONDUCT.md)。版本说明见 [CHANGELOG.md](CHANGELOG.md)。
|
|
172
|
+
|
|
173
|
+
## 许可证
|
|
174
|
+
|
|
175
|
+
[MIT](LICENSE) © hedeqiang
|
package/channels/dingtalk.js
CHANGED
|
@@ -159,7 +159,7 @@ export function resultAsDingText(r, maxRows = 10, maxCols = 6) {
|
|
|
159
159
|
const cell = (c, v) => (c.kind === 'number' ? fmtNum(v) : cellText(v, 30)).replace(/\|/g, '|')
|
|
160
160
|
const out = [`**${cols.map(c => c.name).join(' | ')}**`, '', ...rows.map((row, i) => `${i + 1}. ${cols.map((c, j) => cell(c, row[j])).join(' | ')}`)]
|
|
161
161
|
const total = r.rowCount ?? r.rows.length
|
|
162
|
-
if (total > rows.length) out.push('', `> 共 ${total} 行,仅显示前 ${rows.length}
|
|
162
|
+
if (total > rows.length) out.push('', `> 共 ${total} 行,仅显示前 ${rows.length} 行;完整数据可在数据问答页面查看或导出 Excel`)
|
|
163
163
|
return out.join('\n')
|
|
164
164
|
}
|
|
165
165
|
|
|
@@ -508,7 +508,7 @@ const webhookKind = {
|
|
|
508
508
|
{ key: 'webhookUrl', type: 'secret', secret: true, required: true, label: { zh: 'Webhook 地址', en: 'Webhook URL' }, placeholder: 'https://oapi.dingtalk.com/robot/send?access_token=…', pattern: WEBHOOK_RE.source, help: { zh: '群设置 → 机器人 → 添加机器人 → 自定义,完成后复制 Webhook', en: 'Group settings → Bots → Add → Custom, then copy the webhook' } },
|
|
509
509
|
{ key: 'signSecret', type: 'secret', secret: true, required: false, label: { zh: '加签密钥(可选)', en: 'Signing secret (optional)' }, placeholder: 'SEC…', help: { zh: '安全设置选择「加签」时显示的 SEC 开头字符串', en: 'The SEC… string shown when “Sign” is selected in security settings' } },
|
|
510
510
|
],
|
|
511
|
-
capabilities: { push: true, markdown: 'basic', charts: 'none', chartModes: ['table'], tables: 'text', buttons: false, bot: false, listTargets: false, mentionAll: true, maxMessageBytes: MD_LIMIT },
|
|
511
|
+
capabilities: { push: true, markdown: 'basic', charts: 'none', chartModes: ['table'], tables: 'text', tableRows: 10, files: false, buttons: false, bot: false, listTargets: false, mentionAll: true, maxMessageBytes: MD_LIMIT },
|
|
512
512
|
setupSteps: {
|
|
513
513
|
zh: [
|
|
514
514
|
'在钉钉群:群设置 → 机器人 → 添加机器人 → 自定义(通过 Webhook 接入)。',
|
|
@@ -542,7 +542,7 @@ const appKind = {
|
|
|
542
542
|
{ key: 'openConversationId', type: 'text', required: false, label: { zh: '推送目标群(openConversationId,可选)', en: 'Push target group (openConversationId, optional)' }, placeholder: 'cid…', help: { zh: '机器人收到该群消息时的 conversationId(以 cid 开头)', en: 'The conversationId (cid…) seen in a message from that group' } },
|
|
543
543
|
{ key: 'userId', type: 'text', required: false, label: { zh: '推送目标成员 userId(可选)', en: 'Push target member userId (optional)' }, help: { zh: '未填群会话 ID 时,推送到该成员与机器人的单聊', en: 'Used when no group is set: pushes to the member’s chat with the bot' } },
|
|
544
544
|
],
|
|
545
|
-
capabilities: { push: true, markdown: 'basic', charts: 'none', chartModes: ['table'], tables: 'text', buttons: false, bot: true, listTargets: false, mentionAll: false, maxMessageBytes: MD_LIMIT },
|
|
545
|
+
capabilities: { push: true, markdown: 'basic', charts: 'none', chartModes: ['table'], tables: 'text', tableRows: 10, files: false, buttons: false, bot: true, listTargets: false, mentionAll: false, maxMessageBytes: MD_LIMIT },
|
|
546
546
|
setupSteps: {
|
|
547
547
|
zh: [
|
|
548
548
|
'钉钉开发者后台(open-dev.dingtalk.com)→ 应用开发 → 企业内部应用 → 创建应用,记下 Client ID 与 Client Secret。',
|
package/channels/index.js
CHANGED