dsh-data-cleaning-agent 0.8.20 → 0.8.21
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 +7 -0
- package/README.en.md +1 -1
- package/README.md +3 -3
- package/docs/RELEASE-0.8.21.md +9 -0
- package/lib/client.js +6 -1
- package/lib/qcc-command.js +3 -2
- package/lib/web.js +10 -1
- package/package.json +2 -2
- package/docs/RELEASE-0.8.20.md +0 -11
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.8.21] - 2026-09-09
|
|
8
|
+
|
|
9
|
+
- 从实际 Host 请求获取文件地址的协议和主机;修复本地 HTTP 链接被补成 HTTPS 的问题。
|
|
10
|
+
- 工具卡片支持同源完整文件地址,继续拒绝非同源链接。
|
|
11
|
+
- 已确认任务开始执行时自动展开工作台一次并跟随处理步骤;生成说明不触发,关闭后不反复弹出。
|
|
12
|
+
- 246 项测试及 10 组浏览器回归通过,无付费查询。
|
|
13
|
+
|
|
7
14
|
## [0.8.20] - 2026-09-09
|
|
8
15
|
|
|
9
16
|
- 普通无记录/未披露字段保留为无数据说明,尊重共享契约 reviewRequired=false,不再误计为待核验。
|
package/README.en.md
CHANGED
|
@@ -8,7 +8,7 @@ Related agents: [数据清洗补全](https://github.com/duhu2000/dsh-data-cleani
|
|
|
8
8
|
|
|
9
9
|
> A data cleaning & completion agent plugin for DeepSeek Harness: local CSV/XLSX/JSON engine plus optional Qichacha (QCC) MCP enterprise-data enrichment. Initiated and maintained by the Qichacha (QCC) team.
|
|
10
10
|
>
|
|
11
|
-
> Current source version / 当前源码版本: **0.8.
|
|
11
|
+
> Current source version / 当前源码版本: **0.8.21** (stable release)
|
|
12
12
|
|
|
13
13
|
This release unifies spreadsheet previews, column mapping, and enrichment scope across the prompt wizard and workbench. Mapping statuses use color and text; mapped fields automatically enter the scope, with optional extra fields collapsed. Multiple confirmed output columns may share a non-identity field while preserving non-empty values. It fixes saved drafts resetting the scope to five defaults and detects stale Host versions. Preparing a draft does not query QCC; sending starts execution. Fully restart DSH after upgrading. Existing download artifacts are not rewritten.
|
|
14
14
|
|
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# dsh-data-cleaning-agent
|
|
2
2
|
|
|
3
|
-
本版统一向导与工作台的 Host 执行闭环:发送后自动生成新 Excel,原文件不修改,工作台入口可恢复;发布记录见 [发布说明](docs/RELEASE-0.8.
|
|
3
|
+
本版统一向导与工作台的 Host 执行闭环:发送后自动生成新 Excel,原文件不修改,工作台入口可恢复;发布记录见 [发布说明](docs/RELEASE-0.8.21.md)。
|
|
4
4
|
|
|
5
5
|
## 安装与三分钟上手
|
|
6
6
|
|
|
7
7
|
数据清洗补全智能体:面向 Excel/CSV/JSON 企业名单,提供数据清洗、表格清洗、清洗补全、去重、企业数据补全与字段补全,支持企查查 MCP 和结果导出。
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
|
-
dsh plugin --profile web add dsh-data-cleaning-agent@0.8.
|
|
10
|
+
dsh plugin --profile web add dsh-data-cleaning-agent@0.8.21
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
请先满足下文的 DSH、连接器及侧边栏依赖要求;安装后完整停止并重启对应 Profile。
|
|
@@ -25,7 +25,7 @@ dsh plugin --profile web add dsh-data-cleaning-agent@0.8.20
|
|
|
25
25
|
|
|
26
26
|
> 在 DeepSeek Harness 中清洗、补全、画像企业名单数据的智能体插件:本地 CSV/XLSX/JSON 引擎 + 可选企查查(Qichacha/QCC)MCP 企业数据补全,由企查查(Qichacha/QCC)团队发起并维护。
|
|
27
27
|
>
|
|
28
|
-
> 当前源码版本 / Current source version: **0.8.
|
|
28
|
+
> 当前源码版本 / Current source version: **0.8.21**(正式版本)
|
|
29
29
|
|
|
30
30
|
本版上传表格后展示完整清单及空白数量,用绿色、琥珀色、红色及文字区分已通过、待确认和未匹配映射。已映射字段自动纳入补全范围,额外字段默认折叠;多个原列可经确认使用同一非主体字段,分别补空并保留非空原值。修复 Host 草稿重置为默认五字段的问题,增加前后端版本错配提示。生成说明不查询,发送才执行;升级后需完整重启 DSH,历史下载文件不自动改写。
|
|
31
31
|
|
package/lib/client.js
CHANGED
|
@@ -1862,9 +1862,14 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1862
1862
|
return response.task;
|
|
1863
1863
|
}
|
|
1864
1864
|
function watchHostedCommand(actions, sessionId, command) {
|
|
1865
|
+
let openedForExecution = false;
|
|
1865
1866
|
void waitForQccCommand(command.commandId, 1800, async (status) => {
|
|
1866
1867
|
if (!status || status.state === 'prepared') return;
|
|
1867
1868
|
await refreshHostedTask(actions, sessionId, command.taskId, null, true).catch(() => {});
|
|
1869
|
+
if (!openedForExecution && isCleaningSession(sessionId) && workflowTaskBySession.get(String(sessionId))?.id === command.taskId) {
|
|
1870
|
+
openedForExecution = true;
|
|
1871
|
+
openWorkbench(actions, workflowTaskBySession.get(String(sessionId))?.stage || 'match', sessionId);
|
|
1872
|
+
}
|
|
1868
1873
|
if (isCleaningSession(sessionId) && workflowTaskBySession.get(String(sessionId))?.id === command.taskId) actions.setCommandProgress?.({ taskId: command.taskId, ...status.progress });
|
|
1869
1874
|
}).then(async (completed) => {
|
|
1870
1875
|
await refreshHostedTask(actions, sessionId, command.taskId, completed.run);
|
|
@@ -3228,7 +3233,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3228
3233
|
meta.hint ? h('div', { className: 'dcAgentToolCardHint' }, meta.hint) : null,
|
|
3229
3234
|
summary ? h('div', { className: 'dcAgentToolCardBody' }, summary) : null,
|
|
3230
3235
|
toolName === 'data_cleaning_qcc_run' ? h('div', { className: 'dcAgentArtifactList' },
|
|
3231
|
-
[...summary.matchAll(/\[([^\]]+)\]\((
|
|
3236
|
+
[...summary.matchAll(/\[([^\]]+)\]\(((?:https?:\/\/[a-zA-Z0-9.:[\]-]+)?\/data-cleaning\/api\/workflow\/tasks\/[a-zA-Z0-9%_-]+\/artifacts\/[a-zA-Z0-9%_-]+(?:\?preview=1)?)\)/g)].filter(match => match[2].startsWith('/') || (typeof location !== 'undefined' && new URL(match[2]).origin === location.origin)).map((match, index) =>
|
|
3232
3237
|
h('a', { key: index, className: 'dcAgentButton', href: match[2], target: '_blank', rel: 'noopener noreferrer' }, match[1]))) : null,
|
|
3233
3238
|
);
|
|
3234
3239
|
}
|
package/lib/qcc-command.js
CHANGED
|
@@ -138,7 +138,7 @@ export class QccCommandStore {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
prepare(input) {
|
|
141
|
+
prepare(input, { artifactOrigin = '' } = {}) {
|
|
142
142
|
this.cleanup(true);
|
|
143
143
|
const normalized = normalizedInput(input);
|
|
144
144
|
const estimate = normalized.kind === 'enrich'
|
|
@@ -148,6 +148,7 @@ export class QccCommandStore {
|
|
|
148
148
|
const at = new Date(this.clock()).toISOString();
|
|
149
149
|
const record = {
|
|
150
150
|
commandId,
|
|
151
|
+
artifactOrigin,
|
|
151
152
|
taskId: normalized.taskId,
|
|
152
153
|
kind: normalized.kind,
|
|
153
154
|
state: 'prepared',
|
|
@@ -265,7 +266,7 @@ export class QccCommandStore {
|
|
|
265
266
|
state: run.state,
|
|
266
267
|
summary: run.summary,
|
|
267
268
|
...(record.delivery ? { deliveryState: record.delivery.state, artifactCount: record.delivery.artifacts.length,
|
|
268
|
-
artifacts: record.delivery.artifacts.filter(a => a.format === 'xlsx' && (a.kind !== 'review' || a.rowCount > 0)).map(a => ({ fileName: a.fileName, url:
|
|
269
|
+
artifacts: record.delivery.artifacts.filter(a => a.format === 'xlsx' && (a.kind !== 'review' || a.rowCount > 0)).map(a => ({ fileName: a.fileName, url: `${record.artifactOrigin || ''}/data-cleaning/api/workflow/tasks/${encodeURIComponent(record.taskId)}/artifacts/${encodeURIComponent(a.id)}` })) } : {}),
|
|
269
270
|
});
|
|
270
271
|
}
|
|
271
272
|
}
|
package/lib/web.js
CHANGED
|
@@ -659,11 +659,20 @@ export function mountWebRoutes(wctx, { logger, report, TOOL_NAME, SKILL_NAME })
|
|
|
659
659
|
}
|
|
660
660
|
const payload = JSON.parse((await readBody(req)).toString('utf8'));
|
|
661
661
|
if (payload.kind && payload.kind !== 'enrich') requirePaidConfirmation(payload);
|
|
662
|
+
// Resolve from the actual browser request, never from model/task input.
|
|
663
|
+
let artifactOrigin = '';
|
|
664
|
+
const requestHost = req.headers?.host;
|
|
665
|
+
if (typeof requestHost === 'string' && /^[a-zA-Z0-9.:[\]-]+$/.test(requestHost)) {
|
|
666
|
+
try {
|
|
667
|
+
const origin = new URL(req.headers.origin || `${req.socket?.encrypted ? 'https' : 'http'}://${requestHost}`);
|
|
668
|
+
if (['http:', 'https:'].includes(origin.protocol) && origin.host === requestHost) artifactOrigin = origin.origin;
|
|
669
|
+
} catch { /* Relative links remain available for hosts without an origin. */ }
|
|
670
|
+
}
|
|
662
671
|
return writeJson(res, 201, {
|
|
663
672
|
ok: true,
|
|
664
673
|
marker: 'g5-agent-command',
|
|
665
674
|
paidCalls: false,
|
|
666
|
-
command: qccCommands.prepare(payload.workflowOwned ? await execution.prepare(payload) : payload),
|
|
675
|
+
command: qccCommands.prepare(payload.workflowOwned ? await execution.prepare(payload) : payload, { artifactOrigin }),
|
|
667
676
|
});
|
|
668
677
|
}
|
|
669
678
|
if (rest.length === 1 && req.method === 'GET') {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-data-cleaning-agent",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.21",
|
|
4
4
|
"description": "Data cleaning and data enrichment for CSV/XLSX/JSON enterprise lists in DeepSeek Harness, including spreadsheet cleaning, deduplication, profiling, optional Qichacha MCP and exports.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"docs/RELEASE-0.8.1.md",
|
|
41
41
|
"docs/RELEASE-0.8.16.md",
|
|
42
42
|
"docs/RELEASE-0.8.17.md",
|
|
43
|
-
"docs/RELEASE-0.8.
|
|
43
|
+
"docs/RELEASE-0.8.21.md",
|
|
44
44
|
"docs/TEMPLATE-MAPPING-ACCEPTANCE.md",
|
|
45
45
|
"docs/UI-WORKFLOW-V2.md",
|
|
46
46
|
"docs/UI-WORKFLOW-V2-MIGRATION.md",
|
package/docs/RELEASE-0.8.20.md
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# 0.8.20 发布说明
|
|
2
|
-
|
|
3
|
-
修复未披露数据被误判为人工核验;保留未披露说明和空白值,不伪造数据。真正的多候选或无法判定的问题继续进入待核验。
|
|
4
|
-
|
|
5
|
-
当前页和历史列表同步最新任务状态。处理进度条区分处理中、完成、需核验和失败;100% 仅表示主体处理结束。摘要尚未生成时显示“结果统计中”。
|
|
6
|
-
|
|
7
|
-
任务展示名优先尊重自定义名称,否则由源文件名、行数和创建时间生成;当前页与历史一致。
|
|
8
|
-
|
|
9
|
-
验证:246 项自动测试、10 组浏览器回归。无付费查询,源文件未修改。
|
|
10
|
-
|
|
11
|
-
升级并完整重启 DSH 后生效;历史任务的旧异常文件和统计不会自动重算,不应仅为更新展示而重复查询。
|