@yejiming/dsh-data-agent 0.0.2 → 0.0.5
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/README.en.md +12 -12
- package/README.md +12 -12
- package/lib/client.js +313 -257
- package/lib/client.js.map +1 -1
- package/lib/{defaults-Dgu2B2Yq.js → defaults-Bac6QvNt.js} +469 -7
- package/lib/index.js +4 -4
- package/lib/{query-vK9dr7Z6.js → query-CmhTFklw.js} +2 -2
- package/lib/routes.js +3 -2
- package/lib/tool.js +335 -18
- package/lib/types/client/locales.d.ts +4 -2
- package/lib/types/clients.d.ts +22 -2
- package/lib/types/defaults.d.ts +3 -3
- package/lib/types/index.d.ts +6 -6
- package/lib/types/query.d.ts +6 -2
- package/lib/types/sql.d.ts +26 -0
- package/lib/types/structured.d.ts +29 -0
- package/lib/types/tool.d.ts +10 -4
- package/package.json +1 -1
- package/preset/data-agent/agent.cordis.yml +11 -7
- package/preset/data-agent/preset.yml +1 -1
package/README.en.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
This plugin is a Data Agent built on DeepSeek Harness, letting DeepSeek focus on database operations.
|
|
8
8
|
|
|
9
|
-
Leveraging the agent-preset capability of DeepSeek Harness, it adds a Data Agent preset. The preset keeps only the three DSH built-in tools — read, edit, write — and adds
|
|
9
|
+
Leveraging the agent-preset capability of DeepSeek Harness, it adds a Data Agent preset. The preset keeps only the three DSH built-in tools — read, edit, write — and adds custom sql-query / sql-write / sqlcmd database tools in place of the bash tool, free from irrelevant tools and prompts.
|
|
10
10
|
|
|
11
11
|
With this preset, you can configure a database connection right in the conversation UI, grant the AI access to the database, and complete CRUD operations.
|
|
12
12
|
|
|
@@ -17,8 +17,8 @@ With this preset, you can configure a database connection right in the conversat
|
|
|
17
17
|

|
|
18
18
|
|
|
19
19
|
- **Database workbench** (embedded above the session's input bar): connection config card (collapses into a summary row after connecting, expandable for review); schema explorer (a "Tables" button opens a Modal — single-click a database to expand its scrollable table list, click a table to inspect its columns); SQL command box (write and run SQL on the non-agent channel, monospace output). The connection config is persisted to browser localStorage — switching pages or restarting restores the form and auto-reconnects. Once the conversation starts, the workbench becomes the left column and the chat records + input bar sit on the right.
|
|
20
|
-
- **
|
|
21
|
-
- **Data Agent preset**: choose "Data Agent" when creating a session — the tool surface is
|
|
20
|
+
- **Database tools**: `sql-query` runs read-only SQL and returns structured `{ columns, rows, affectedRows, elapsedMs }`; `sql-write` runs one write/management SQL per call with explicit autocommit semantics; `sqlcmd` keeps the original raw terminal output. All three run through the database clients (mysql / psql / sqlite3 / sqlplus / beeline / impala-shell); no shell layer (argv arrays + SQL via stdin), timeouts terminate the process tree, output is bounded and truncated, and one call carries at most one SQL statement.
|
|
21
|
+
- **Data Agent preset**: choose "Data Agent" when creating a session — the tool surface is `sql-query`/`sql-write`/`sqlcmd`/`read`/`write`/`edit`, and every other project tool (bash, grep, skill, todo, goal, web, subagent, …) is simply absent, i.e. disabled; non-Data-Agent sessions render no workbench at all.
|
|
22
22
|
|
|
23
23
|

|
|
24
24
|
|
|
@@ -76,7 +76,7 @@ Browser (apps/web) Host process (dsh --profile web)
|
|
|
76
76
|
│ agent.cordis.yml (preset layer, only 3 rows) │
|
|
77
77
|
│ · persona → data-engineer system prompt │
|
|
78
78
|
│ · dsh-tool-fs → read / write / edit (project built-ins) │
|
|
79
|
-
│ · dsh-data-agent/tool → sqlcmd (
|
|
79
|
+
│ · dsh-data-agent/tool → sql-query / sql-write / sqlcmd (tool half) │
|
|
80
80
|
└──────────────────────────────────────────────────────────────────────────┘
|
|
81
81
|
```
|
|
82
82
|
|
|
@@ -101,12 +101,12 @@ Every field has a loader default; there are no library-level defaults. Host row
|
|
|
101
101
|
| `installPreset` | Whether to self-install the preset on startup (default true; existing directories are skipped, keeping user edits) |
|
|
102
102
|
| `connectTimeoutMs` | End-to-end deadline for one /connect connectivity check (default 10000 ms) |
|
|
103
103
|
| `introspectMaxTables` | Cap on the table list returned by /connect and /status (default 500) |
|
|
104
|
-
| `queryTimeoutMs` | Deadline for one
|
|
105
|
-
| `maxResultChars` | In-memory cap on captured
|
|
104
|
+
| `queryTimeoutMs` | Deadline for one database-tool query (default 30000 ms) |
|
|
105
|
+
| `maxResultChars` | In-memory cap on captured database-tool output, per stream (default 20000 chars) |
|
|
106
106
|
| `clients` | Per-type CLI client overrides: `{ command?, args? }` for keys `mysql` / `postgres` / `sqlite` / `oracle` / `hive` / `impala` (built-in defaults mysql/psql/sqlite3/sqlplus/beeline/impala-shell) |
|
|
107
107
|
| `connections` | Config-seeded connections keyed by session id (`'*'` = wildcard default for any session without its own; headless/keyless runs and deployments pinning one database). **No password field** — passwords only enter memory via the /connect route |
|
|
108
108
|
|
|
109
|
-
The `tool-sqlcmd` row (inside the data-agent preset) additionally has `maxRows` (default 100,
|
|
109
|
+
The `tool-sqlcmd` row (inside the data-agent preset) additionally has `maxRows` (default 100, enforced: an unbounded SELECT gets a top-level LIMIT and structured parsing truncates as a second guard); `queryTimeoutMs` / `maxResultChars` / `clients` share the host row's names and defaults.
|
|
110
110
|
|
|
111
111
|
The `data-agent-routes` row has its own config: `connectTimeoutMs` / `introspectMaxTables` / `maxResultChars` mirror the main row; plus `queryTimeoutMs` (for /query and metadata queries, default 30000) and `maxQueryChars` (single-SQL length cap for /query, default 65536).
|
|
112
112
|
|
|
@@ -128,7 +128,7 @@ The `data-agent-routes` row has its own config: `connectTimeoutMs` / `introspect
|
|
|
128
128
|
|
|
129
129
|
## Headless / One-shot Runs
|
|
130
130
|
|
|
131
|
-
**Important**: `dsh run` (the headless bundle) does not mount the agent-presets roster and never mounts presets for sessions — preset mounting belongs to the web surface (the api-proxy mounts on session creation). Therefore **headless sessions cannot use the sqlcmd/read/write/edit tool surface**;
|
|
131
|
+
**Important**: `dsh run` (the headless bundle) does not mount the agent-presets roster and never mounts presets for sessions — preset mounting belongs to the web surface (the api-proxy mounts on session creation). Therefore **headless sessions cannot use the sql-query/sql-write/sqlcmd/read/write/edit tool surface**; the database tools are verified and used on the web surface. Headless database work is limited to the host base's own tools (e.g. calling clients via bash).
|
|
132
132
|
|
|
133
133
|
(Note: inserting the roster row plus disabling the base tool rows cannot reproduce the preset tool surface headless — the agent ends up with an empty, zero-tool composition. For a headless smoke test, verify "seeded connections + host tools work" only.)
|
|
134
134
|
|
|
@@ -146,16 +146,16 @@ Prefix `/plugins/data-agent` (same-origin calls from the browser half):
|
|
|
146
146
|
| `GET /schemas?sessionId=` | `{ ok, schemas: string[] }`; database list (sqlite returns `['main']`) |
|
|
147
147
|
| `GET /tables?sessionId=&schema=` | `{ ok, tables: string[] }`; tables of one schema (sqlite ignores the schema param) |
|
|
148
148
|
| `GET /describe?sessionId=&schema=&table=` | `{ ok, columns: [{ name, type, nullable? }] }`; table structure (sqlite ignores schema) |
|
|
149
|
-
| `POST /query` | body `{ sessionId, sql }`;
|
|
149
|
+
| `POST /query` | body `{ sessionId, sql }`; runs one SQL statement (the workbench command box, non-agent channel), returns `{ ok, result: { exitCode, stdout, stderr, truncated } }`; `sql` length capped by `maxQueryChars`; multiple statements are rejected; readonly rejects writes |
|
|
150
150
|
|
|
151
|
-
Schema/table identifiers allow only `[A-Za-z0-9_
|
|
151
|
+
Schema/table identifiers allow only `[A-Za-z0-9_$]` (server-side whitelist and per-type quoting; injection-shaped input is rejected).
|
|
152
152
|
|
|
153
153
|
## Security Notes
|
|
154
154
|
|
|
155
155
|
- **Passwords**: server-side, memory only; transport per type — mysql via `MYSQL_PWD`, postgres via `PGPASSWORD` environment variables; oracle via the sqlplus `connect user/pass@...` stdin prefix, hive via the beeline `!connect` stdin prefix (never argv); impala sends no password by default (LDAP/kerberos configured through `clients`). `/status` and the public connection-store reads strip passwords.
|
|
156
|
-
- **Connection-config persistence**: the workbench saves the connection config (
|
|
156
|
+
- **Connection-config persistence**: the workbench saves the connection config (type/host/port/user/database) to browser localStorage (key `dsh-data-agent.connection.v1`) to restore the form and auto-reconnect once on page switches/restarts. **Passwords are not persisted by default**; they are stored only when "remember password" is explicitly checked (plain-text localStorage, opt-in). To clear: run `localStorage.removeItem('dsh-data-agent.connection.v1')` in the browser console.
|
|
157
157
|
- **No shell layer**: `ctx.subprocess.spawn` uses argv arrays, SQL and connect prefixes travel via stdin — no shell concatenation injection surface; metadata route identifiers pass the whitelist.
|
|
158
|
-
- **SQL execution authority**: with the approval policy set to `never`, sqlcmd and `/query` execute DDL/DML directly — connections are session-isolated; assess the data-plane risk yourself
|
|
158
|
+
- **SQL execution authority**: with the approval policy set to `never`, `sql-write`/`sqlcmd` and `/query` execute DDL/DML directly — connections are session-isolated; assess the data-plane risk yourself. `readonly: true` rejects write statements; each database-tool call is an independent client process with autocommit, so transactions do not span calls.
|
|
159
159
|
- **Timeouts & caps**: query timeouts, output truncation, table-list caps, and the /query SQL length are all config items — no hard-coded tunables.
|
|
160
160
|
|
|
161
161
|
## Uninstall & Rollback
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
这个插件就是来填这个坑的。它复用DeepSeek Harness强大的Agent主循环能力,让AI连上数据库并获得实时反馈,同时删掉所有跟数据无关的上下文和工具,让AI专注于SQL生成和业务数据分析。
|
|
10
10
|
|
|
11
|
-
我利用DeepSeek Harness的Agent预设功能,定义了专用的Data Agent预设。仅保留read、edit、write三个DSH自带的 tools,并自定义sqlcmd
|
|
11
|
+
我利用DeepSeek Harness的Agent预设功能,定义了专用的Data Agent预设。仅保留read、edit、write三个DSH自带的 tools,并自定义 sql-query / sql-write / sqlcmd 三个数据库 tools 替代 bash tool。
|
|
12
12
|
|
|
13
13
|
懂行的朋友一眼就能看出,这是借鉴了Pi Agent的设计,只使用最基本的工具。
|
|
14
14
|
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
- **数据库工作台**(内嵌于会话输入框上方):连接配置卡(连接成功后折叠为摘要行,可展开查看);库表浏览(点击「库表」按钮弹出 Modal:单击库展开表列表(可滚动),点击表查看结构);SQL 命令框(编辑并运行 SQL,非 agent 通道,结果等宽展示)。连接配置持久化到浏览器 localStorage,切换页面/重启自动回填并重连。开始对话后工作台自动变为左侧栏,对话记录与输入框在右侧。
|
|
23
23
|
|
|
24
24
|

|
|
25
|
-
-
|
|
26
|
-
- **数据Agent 预设**:新建会话可选「数据Agent
|
|
25
|
+
- **数据库 tools**:`sql-query` 执行只读 SQL 并返回结构化 `{ columns, rows, affectedRows, elapsedMs }`;`sql-write` 执行写/管理 SQL(单条自动提交,写语义明确);`sqlcmd` 保留原始终端输出。三者均在数据库客户端(mysql / psql / sqlite3 / sqlplus / beeline / impala-shell)执行;无 shell 层(argv 数组化 + SQL 走 stdin),超时自动终止进程树,输出有界截断,单次调用只允许一条 SQL。
|
|
26
|
+
- **数据Agent 预设**:新建会话可选「数据Agent」——工具面为 `sql-query`/`sql-write`/`sqlcmd`/`read`/`write`/`edit`,项目其他工具(bash、grep、skill、todo、goal、web、subagent 等)全部缺席即禁用;非数据Agent 会话不渲染工作台,零影响。
|
|
27
27
|
|
|
28
28
|

|
|
29
29
|
- **标准 agent loop**:data-agent 会话就是普通 DSH 会话,走标准 turn/step、流式输出、工具调度与持久化,零宿主改动。
|
|
@@ -80,7 +80,7 @@ dsh --profile web
|
|
|
80
80
|
│ agent.cordis.yml (预设层,仅 3 行) │
|
|
81
81
|
│ · persona → 数据工程师系统提示词 │
|
|
82
82
|
│ · dsh-tool-fs → read / write / edit(项目自带) │
|
|
83
|
-
│ · dsh-data-agent/tool → sqlcmd(本包工具半体)
|
|
83
|
+
│ · dsh-data-agent/tool → sql-query / sql-write / sqlcmd(本包工具半体) │
|
|
84
84
|
└──────────────────────────────────────────────────────────────────────────┘
|
|
85
85
|
```
|
|
86
86
|
|
|
@@ -105,13 +105,13 @@ dsh --profile web
|
|
|
105
105
|
| `installPreset` | 是否在启动时自安装预设(默认 true;已存在则跳过,保留用户编辑) |
|
|
106
106
|
| `connectTimeoutMs` | /connect 连通性检查的端到端超时(默认 10000 毫秒) |
|
|
107
107
|
| `introspectMaxTables` | 表清单上限(默认 500) |
|
|
108
|
-
| `queryTimeoutMs` |
|
|
109
|
-
| `maxResultChars` |
|
|
110
|
-
| `readonly` | 只读护栏(默认 false):true
|
|
108
|
+
| `queryTimeoutMs` | 数据库 tools 单次查询超时(默认 30000 毫秒) |
|
|
109
|
+
| `maxResultChars` | 数据库 tools 捕获输出上限(stdout/stderr 各自,默认 20000 字符) |
|
|
110
|
+
| `readonly` | 只读护栏(默认 false):true 时数据库 tools 与 `/query` 仅放行读语句(SELECT/SHOW/DESCRIBE/EXPLAIN/PRAGMA 等),写语句直接拒绝 |
|
|
111
111
|
| `clients` | 各数据库类型 CLI 客户端覆盖:`{ command?, args? }`,键为 `mysql` / `postgres` / `sqlite` / `oracle` / `hive` / `impala`(内置默认 mysql/psql/sqlite3/sqlplus/beeline/impala-shell) |
|
|
112
112
|
| `connections` | 配置预置连接,键为 sessionId(`'*'` = 通配符默认,任何无自有连接的会话回落它;headless/keyless 运行与部署固定默认库场景)。**不含 password 字段**——密码只允许经 /connect 路由进入内存;可选 `readonly` 字段按连接锁定只读 |
|
|
113
113
|
|
|
114
|
-
工具行 `tool-sqlcmd`(data-agent 预设内)另有 `maxRows`(默认 100
|
|
114
|
+
工具行 `tool-sqlcmd`(data-agent 预设内)另有 `maxRows`(默认 100,强制生效:SELECT 未写 LIMIT 时自动追加,结构化结果解析时二次截断)与 `readonly`,`queryTimeoutMs` / `maxResultChars` / `clients` 与宿主行同名可配。
|
|
115
115
|
|
|
116
116
|
路由行 `data-agent-routes` 独立配置:`connectTimeoutMs` / `introspectMaxTables` / `maxResultChars` / `readonly` 与主行同名同默认;另有 `queryTimeoutMs`(/query 与元数据查询超时,默认 30000)与 `maxQueryChars`(/query 单条 SQL 长度上限,默认 65536)。
|
|
117
117
|
|
|
@@ -132,7 +132,7 @@ dsh --profile web
|
|
|
132
132
|
|
|
133
133
|
## Headless / 一次性运行
|
|
134
134
|
|
|
135
|
-
**重要**:`dsh run`(headless bundle)不装载 agent-presets roster,也不会为会话挂载预设——预设机制属于 web 面(apiproxy 在会话创建时 mount)。因此 **headless 会话无法使用 sqlcmd/read/write/edit
|
|
135
|
+
**重要**:`dsh run`(headless bundle)不装载 agent-presets roster,也不会为会话挂载预设——预设机制属于 web 面(apiproxy 在会话创建时 mount)。因此 **headless 会话无法使用 sql-query/sql-write/sqlcmd/read/write/edit 工具面**,数据库 tools 的验证与使用都在 web 面完成;headless 中如需数据库能力,只能靠宿主 base 自带工具(如 bash 直接调用客户端)。
|
|
136
136
|
|
|
137
137
|
(注:插入 roster 行 + 禁用 base 工具行的 patch 组合无法在 headless 中复现预设工具面——agent 会得到一个零工具的空组合,模型无工具可调。如需 headless 冒烟,仅验证「连接配置预置 + 宿主工具可用」即可。)
|
|
138
138
|
|
|
@@ -150,7 +150,7 @@ dsh --profile web
|
|
|
150
150
|
| `GET /schemas?sessionId=` | `{ ok, schemas: string[] }`;库/数据库列表(sqlite 为 `['main']`) |
|
|
151
151
|
| `GET /tables?sessionId=&schema=` | `{ ok, tables: string[] }`;某库的表列表(sqlite 忽略 schema 参数) |
|
|
152
152
|
| `GET /describe?sessionId=&schema=&table=` | `{ ok, columns: [{ name, type, nullable? }] }`;表结构(sqlite 忽略 schema) |
|
|
153
|
-
| `POST /query` | body `{ sessionId, sql }
|
|
153
|
+
| `POST /query` | body `{ sessionId, sql }`;运行一条 SQL(工作台命令框,非 agent 通道),返回 `{ ok, result: { exitCode, stdout, stderr, truncated } }`;`sql` 长度上限 `maxQueryChars`;单次只允许一条语句;readonly 开启时拒绝写语句 |
|
|
154
154
|
|
|
155
155
|
schema/table 标识符仅允许 `[A-Za-z0-9_$]`(服务端白名单校验并转义引用,拒绝注入形字符)。
|
|
156
156
|
|
|
@@ -159,8 +159,8 @@ schema/table 标识符仅允许 `[A-Za-z0-9_$]`(服务端白名单校验并转
|
|
|
159
159
|
- **密码**:服务端仅存内存,传递通道按类型:mysql 经 `MYSQL_PWD`、postgres 经 `PGPASSWORD` 环境变量;oracle 经 sqlplus `connect user/pass@...` stdin 前缀、hive 经 beeline `!connect` stdin 前缀(均不进 argv);impala 默认不传密码(LDAP/kerberos 由部署侧 `clients` 覆盖)。`/status` 与连接存储的公开读取面均剥离密码。
|
|
160
160
|
- **连接配置持久化**:工作台把连接配置(type/host/port/user/database)保存到浏览器 localStorage(键 `dsh-data-agent.connection.v1`),用于切换页面/重启后回填表单并自动重连一次。**密码默认不落盘**:仅当用户勾选「记住密码」时才持久化密码(明文 localStorage,本机单用户场景的显式 opt-in)。若需清除:浏览器控制台执行 `localStorage.removeItem('dsh-data-agent.connection.v1')`。
|
|
161
161
|
- **无 shell 层**:`ctx.subprocess.spawn` 参数数组化,SQL 与连接前缀经 stdin 传入,不存在 shell 拼接注入面;元数据路由的 schema/table 标识符经收紧白名单 `[A-Za-z0-9_$]` 校验并按类型转义引用(反引号/双引号),拒绝 `#`、`--`、`;`、`'` 等注入形字符。
|
|
162
|
-
- **SQL 执行权**:审批策略为 never
|
|
163
|
-
-
|
|
162
|
+
- **SQL 执行权**:审批策略为 never 时,`sql-write`/`sqlcmd` 与 `/query` 的 DDL/DML 会直接执行——连接按 session 隔离,请自行评估数据面风险。可设 `readonly: true`(宿主/工具/路由三行同名,或 `/connect` 传 `readonly: true` 按连接锁定)强制只放行读语句(SELECT/SHOW/DESCRIBE/EXPLAIN/PRAGMA 等),作为误操作防护;对更强对手防护,仍建议配合数据库侧只读账号。每次数据库工具调用为独立客户端进程并自动提交,不支持跨调用事务。
|
|
163
|
+
- **超时与上限**:查询超时、输出截断、表清单上限、读查询最大行数(`maxRows`)、/query 单条 SQL 长度均为配置项,无硬编码 tunables。
|
|
164
164
|
|
|
165
165
|
## 卸载与回滚
|
|
166
166
|
|