dsh-data-cleaning-agent 0.8.11 → 0.8.12
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 +6 -0
- package/README.en.md +2 -2
- package/README.md +2 -2
- package/lib/client.js +44 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.8.12] - 2026-09-07
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- 导入页以已解析数据集显示当前来源、文件名与行数,不再依赖可能重建的原生文件选择框。文件选择后自动解析;文本按钮仅处理新粘贴内容,避免成功上传后误报「请粘贴或上传数据」。
|
|
11
|
+
- 支持重新选择同一文件,失败替换保留现有数据;新粘贴内容需先解析或清空,避免带着未生效输入进入下一步。仅有历史摘要而无明细时明确要求重新导入。
|
|
12
|
+
|
|
7
13
|
## [0.8.11] - 2026-09-07
|
|
8
14
|
|
|
9
15
|
### Fixed
|
package/README.en.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
> 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.
|
|
4
4
|
>
|
|
5
|
-
> Current source version / 当前源码版本: **0.8.
|
|
5
|
+
> Current source version / 当前源码版本: **0.8.12** (stable release)
|
|
6
6
|
|
|
7
|
-
This release
|
|
7
|
+
This release fixes misleading import errors after a successful upload. Files are parsed automatically, with persistent source, filename, and row-count status; text parsing handles only newly pasted content. The same file can be selected again, failed parsing preserves existing data, and pending pasted content must be parsed or cleared before continuing. Automatic mapping for 128 fields, blank-cell enrichment in original columns, QCC-blue menus, the resizable workbench, and native DSH sending remain unchanged. Existing download artifacts are not rewritten.
|
|
8
8
|
|
|
9
9
|
[](https://github.com/duhu2000/dsh-data-cleaning-agent/actions/workflows/ci.yml)
|
|
10
10
|
[](https://www.npmjs.com/package/dsh-data-cleaning-agent)
|
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
> 在 DeepSeek Harness 中清洗、补全、画像企业名单数据的智能体插件:本地 CSV/XLSX/JSON 引擎 + 可选企查查(Qichacha/QCC)MCP 企业数据补全,由企查查(Qichacha/QCC)团队发起并维护。
|
|
4
4
|
>
|
|
5
|
-
> 当前源码版本 / Current source version: **0.8.
|
|
5
|
+
> 当前源码版本 / Current source version: **0.8.12**(正式版本)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
本版修复文件上传成功后的导入状态误报:文件选择后自动解析,当前来源、文件名和行数持续显示;文本解析仅处理新粘贴内容。支持重新选择同一文件,解析失败保留现有数据,新粘贴内容解析或清空后再进入下一步。保留 128 字段智能映射、原列补空、企查查蓝菜单、可调宽工作台及 DSH 原生发送机制。历史下载文件不自动改写。
|
|
8
8
|
|
|
9
9
|
[](https://github.com/duhu2000/dsh-data-cleaning-agent/actions/workflows/ci.yml)
|
|
10
10
|
[](https://www.npmjs.com/package/dsh-data-cleaning-agent)
|
package/lib/client.js
CHANGED
|
@@ -3054,6 +3054,17 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3054
3054
|
}
|
|
3055
3055
|
|
|
3056
3056
|
/** 文本/JSON 直通 parse(与 web.js 内联页同构,含 JSON 数组直通)。 */
|
|
3057
|
+
function intakeState(dataset, sourceRows, input, source) {
|
|
3058
|
+
const count = Number(dataset?.rowCount || 0);
|
|
3059
|
+
const available = count > 0 && Array.isArray(sourceRows) && sourceRows.length === count;
|
|
3060
|
+
return {
|
|
3061
|
+
available,
|
|
3062
|
+
pendingText: Boolean(String(input ?? '').trim()),
|
|
3063
|
+
fileName: source?.fileName || (source?.type === 'image' ? '图片识别名单' : '粘贴 / 向导导入名单'),
|
|
3064
|
+
count,
|
|
3065
|
+
};
|
|
3066
|
+
}
|
|
3067
|
+
|
|
3057
3068
|
async function parseText(text, actions) {
|
|
3058
3069
|
const trimmed = (text ?? '').trim();
|
|
3059
3070
|
if (!trimmed) {
|
|
@@ -3361,6 +3372,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3361
3372
|
const runtime = runtimeFor(runtimeKey);
|
|
3362
3373
|
const stagedSource = runtimeFor(`session:${activeSessionId || 'unassigned'}`, false);
|
|
3363
3374
|
const sourceRows = stagedSource?.sourceRows ?? runtime.sourceRows ?? runtime.rows;
|
|
3375
|
+
const intake = intakeState(dataset, sourceRows, input, runtime.source || stagedSource?.source || cachedTask?.source);
|
|
3364
3376
|
const lastCsv = runtime.lastCsv;
|
|
3365
3377
|
const fieldByPattern = (pattern) => runtime.headers.find((field) => pattern.test(field)) ?? null;
|
|
3366
3378
|
const phoneField = fieldByPattern(/^(phone|mobile|tel|telephone|联系电话|手机号码|手机号)$/i);
|
|
@@ -3380,13 +3392,20 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3380
3392
|
|
|
3381
3393
|
const handleParse = async () => {
|
|
3382
3394
|
if (busy) return;
|
|
3395
|
+
if (!intake.pendingText) {
|
|
3396
|
+
if (intake.available) actions.setError(null);
|
|
3397
|
+
return;
|
|
3398
|
+
}
|
|
3383
3399
|
actions.setBusy(true);
|
|
3384
3400
|
actions.setError(null);
|
|
3385
3401
|
try {
|
|
3386
3402
|
const result = await parseText(input, actions);
|
|
3387
|
-
if (result) {
|
|
3403
|
+
if (result && result.ok !== false) {
|
|
3388
3404
|
applyParsed(result, actions, runtimeKey, { type: result.fmt || 'csv' });
|
|
3389
3405
|
await persistParsedWorkflow(actions, activeSessionId, result, { type: result.fmt || 'csv' }, cachedTask);
|
|
3406
|
+
actions.setInput('');
|
|
3407
|
+
} else if (result) {
|
|
3408
|
+
actions.setError(result.message || result.error || '解析失败,已导入的数据保持不变。');
|
|
3390
3409
|
}
|
|
3391
3410
|
} catch (err) {
|
|
3392
3411
|
actions.setError(err instanceof Error ? err.message : String(err));
|
|
@@ -3404,6 +3423,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3404
3423
|
return true;
|
|
3405
3424
|
};
|
|
3406
3425
|
const handleFile = async (event) => {
|
|
3426
|
+
if (busy) return;
|
|
3407
3427
|
const file = event.target && event.target.files && event.target.files[0];
|
|
3408
3428
|
if (!file) return;
|
|
3409
3429
|
if (String(file.type ?? '').startsWith('image/')) {
|
|
@@ -3418,11 +3438,13 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3418
3438
|
if (result && result.ok !== false) {
|
|
3419
3439
|
applyParsed(result, actions, runtimeKey, { type: result.fmt || 'csv', fileName: file.name, sizeBytes: file.size || 0 });
|
|
3420
3440
|
await persistParsedWorkflow(actions, activeSessionId, result, { type: result.fmt || 'csv', fileName: file.name, sizeBytes: file.size || 0 }, cachedTask);
|
|
3441
|
+
actions.setInput('');
|
|
3421
3442
|
}
|
|
3422
3443
|
else actions.setError((result && (result.message || result.error)) || '解析失败');
|
|
3423
3444
|
} catch (err) {
|
|
3424
3445
|
actions.setError(err instanceof Error ? err.message : String(err));
|
|
3425
3446
|
} finally {
|
|
3447
|
+
event.target.value = '';
|
|
3426
3448
|
actions.setBusy(false);
|
|
3427
3449
|
}
|
|
3428
3450
|
};
|
|
@@ -4159,13 +4181,26 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
4159
4181
|
} else {
|
|
4160
4182
|
pane = h('div', { className: 'dcAgentPane' },
|
|
4161
4183
|
h('p', { className: 'dcAgentHint' }, '上传 CSV / XLSX / XLS / JSON,或粘贴数据。也可选择图片,通过企查查智能文档解析提取名单后继续清洗补全。'),
|
|
4162
|
-
h('
|
|
4184
|
+
dataset ? h('section', { className: 'dcAgentSection', 'aria-label': '当前导入数据', role: 'status' },
|
|
4185
|
+
h('h3', null, intake.available ? `已解析 ${intake.count} 条数据` : '已保存导入摘要'),
|
|
4186
|
+
h('p', { className: 'dcAgentHint', style: { overflowWrap: 'anywhere' } }, `当前来源:${intake.fileName}`),
|
|
4187
|
+
h('p', { className: 'dcAgentHint' }, intake.available
|
|
4188
|
+
? '文件选择后已自动解析,无需再次点击解析。核对下方名单后可直接进入规则与体检;重新选择文件会替换当前导入数据。'
|
|
4189
|
+
: '当前页面没有完整原始数据。请重新导入原文件;历史下载制品仍可从任务历史获取。'),
|
|
4190
|
+
) : null,
|
|
4191
|
+
h('div', { className: 'dcAgentRow' },
|
|
4192
|
+
h('button', { type: 'button', className: 'dcAgentButton', disabled: busy,
|
|
4193
|
+
onClick: (event) => event.currentTarget.nextElementSibling?.click() },
|
|
4194
|
+
dataset ? '重新选择文件(自动解析)' : '选择文件(自动解析)'),
|
|
4195
|
+
h('input', {
|
|
4163
4196
|
type: 'file',
|
|
4164
4197
|
accept: '.csv,.json,.xlsx,.xls,image/png,image/jpeg,image/webp',
|
|
4165
4198
|
className: 'dcAgentField',
|
|
4199
|
+
style: { display: 'none' },
|
|
4200
|
+
disabled: busy,
|
|
4166
4201
|
'aria-label': '选择数据文件',
|
|
4167
4202
|
onChange: handleFile,
|
|
4168
|
-
}),
|
|
4203
|
+
})),
|
|
4169
4204
|
h('button', { type: 'button', className: 'dcAgentButton', disabled: busy,
|
|
4170
4205
|
onClick: () => openImageIntake() }, '图片识别(粘贴 / 选择)'),
|
|
4171
4206
|
h('textarea', {
|
|
@@ -4173,6 +4208,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
4173
4208
|
placeholder: '粘贴 CSV 文本,或 JSON 数组(例如 [{"name":"某公司","amount":"100"}])…',
|
|
4174
4209
|
'aria-label': '粘贴数据',
|
|
4175
4210
|
value: input,
|
|
4211
|
+
disabled: busy,
|
|
4176
4212
|
onPaste: (event) => {
|
|
4177
4213
|
const files = imageFilesFromTransfer(event.clipboardData);
|
|
4178
4214
|
if (files.length && openImageIntake(files[0])) {
|
|
@@ -4180,7 +4216,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
4180
4216
|
event.stopPropagation?.();
|
|
4181
4217
|
}
|
|
4182
4218
|
},
|
|
4183
|
-
onInput: (event) => actions.setInput(event.target.value),
|
|
4219
|
+
onInput: (event) => { actions.setInput(event.target.value); actions.setError(null); },
|
|
4184
4220
|
}),
|
|
4185
4221
|
dataset ? h('div', { className: 'dcAgentChips' },
|
|
4186
4222
|
h('span', { className: 'dcAgentChip' }, `格式 ${dataset.fmt}`),
|
|
@@ -4196,8 +4232,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
4196
4232
|
}) : null,
|
|
4197
4233
|
hasData ? h('p', { className: 'dcAgentHint' }, '请核对完整名单。识别清单不代表已完成企查查匹配。核对后进入「规则与体检」,确认规则生成质量体检;再进入「主体匹配」估算调用量并确认账号额度,点击「生成可编辑任务说明」自动回填中央对话框,无需手工复制任务凭证。') : null,
|
|
4198
4234
|
h('div', { className: 'dcAgentRow' },
|
|
4199
|
-
h('button', { type: 'button', className: 'dcAgentButton is-primary', disabled: busy, 'aria-label': '解析数据', onClick: handleParse }, busy ? '解析中…' : '
|
|
4200
|
-
hasData ? h('
|
|
4235
|
+
h('button', { type: 'button', className: 'dcAgentButton is-primary', disabled: busy || !intake.pendingText, 'aria-label': '解析数据', onClick: handleParse }, busy ? '解析中…' : '解析粘贴内容'),
|
|
4236
|
+
intake.pendingText && hasData ? h('p', { className: 'dcAgentHint', role: 'status' }, '有尚未解析的新粘贴内容,请先解析或清空后再继续。') : null,
|
|
4237
|
+
hasData ? h('button', { type: 'button', className: 'dcAgentButton', disabled: busy || !intake.available || intake.pendingText, onClick: () => { actions.setError(null); actions.setStep('rules'); } }, '已核对清单,下一步:字段映射与规则') : null,
|
|
4201
4238
|
),
|
|
4202
4239
|
);
|
|
4203
4240
|
}
|
|
@@ -4414,6 +4451,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
4414
4451
|
isImagePathEntry,
|
|
4415
4452
|
requestPromptImage,
|
|
4416
4453
|
guessMappings,
|
|
4454
|
+
intakeState,
|
|
4417
4455
|
projectCompletionResult,
|
|
4418
4456
|
mappingRecommendations,
|
|
4419
4457
|
mergeRecommendedMappings,
|
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.12",
|
|
4
4
|
"description": "Clean, complete, and profile enterprise name lists in DeepSeek Harness — a data cleaning & completion agent plugin with local CSV/XLSX/JSON engine and optional Qichacha (QCC) MCP enrichment. Maintained by Qichacha/QCC.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|