dsh-data-cleaning-agent 0.6.0 → 0.6.2
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 +29 -0
- package/README.en.md +12 -6
- package/README.md +11 -7
- package/docs/COMPATIBILITY.md +7 -6
- package/docs/G5-HOST-BRIDGE.md +34 -8
- package/docs/QCC-ENRICHMENT-DESIGN.md +4 -2
- package/docs/QCC-PHASES-ROADMAP.md +3 -2
- package/docs/RELEASE-0.6.0.md +14 -3
- package/docs/RELEASE-0.6.1.md +64 -0
- package/docs/RELEASE-0.6.2.md +40 -0
- package/docs/UI-WORKFLOW-V2.md +2 -3
- package/lib/artifacts.js +47 -8
- package/lib/client.js +283 -66
- package/lib/engine.js +1 -1
- package/lib/index.js +9 -4
- package/lib/jobs.js +1 -1
- package/lib/qcc-command.js +280 -0
- package/lib/qcc-runs.js +5 -1
- package/lib/qcc.js +142 -15
- package/lib/skill-enrich.js +7 -2
- package/lib/tools.js +1 -1
- package/lib/web.js +55 -1
- package/lib/workflow-contract.js +9 -0
- package/package.json +4 -2
package/lib/web.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import { parseCsv, parseXlsx, parseJson, detectFormat, toCsv } from './engine.js';
|
|
11
11
|
import { runSync, DataCleaningJobs } from './jobs.js';
|
|
12
12
|
import { QccBridgeError, QccHostBridge } from './qcc.js';
|
|
13
|
+
import { QccCommandStore, registerQccCommandTool, TOOL_QCC_COMMAND } from './qcc-command.js';
|
|
13
14
|
import { fingerprintRequest, G5RunStore } from './qcc-runs.js';
|
|
14
15
|
import { PHASE3_BATCH_LIMITS, Phase3BatchService, Phase3RunStore } from './qcc-phase3-batch.js';
|
|
15
16
|
import { publicWorkflowContract } from './workflow-contract.js';
|
|
@@ -68,7 +69,7 @@ function requirePaidConfirmation(payload) {
|
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
function qccHttpStatus(code) {
|
|
71
|
-
if (code === 'QCC_RUN_NOT_FOUND') return 404;
|
|
72
|
+
if (code === 'QCC_RUN_NOT_FOUND' || code === 'QCC_COMMAND_NOT_FOUND') return 404;
|
|
72
73
|
if (code === 'QCC_AUTH_REQUIRED') return 401;
|
|
73
74
|
if (code === 'QCC_PERMISSION_DENIED') return 403;
|
|
74
75
|
if (code === 'QCC_QUOTA_EXHAUSTED') return 402;
|
|
@@ -79,6 +80,8 @@ function qccHttpStatus(code) {
|
|
|
79
80
|
|| code === 'QCC_TOOL_UNAVAILABLE'
|
|
80
81
|
|| code === 'QCC_UPSTREAM_UNAVAILABLE'
|
|
81
82
|
|| code === 'QCC_IDEMPOTENCY_CAPACITY'
|
|
83
|
+
|| code === 'QCC_COMMAND_CAPACITY'
|
|
84
|
+
|| code === 'QCC_AGENT_COMMAND_UNAVAILABLE'
|
|
82
85
|
) return 503;
|
|
83
86
|
if (
|
|
84
87
|
code === 'QCC_CONFIRM_REQUIRED'
|
|
@@ -89,6 +92,7 @@ function qccHttpStatus(code) {
|
|
|
89
92
|
|| code === 'QCC_OPERATION_IN_PROGRESS'
|
|
90
93
|
|| code === 'QCC_RETRY_NOT_FAILED'
|
|
91
94
|
|| code === 'QCC_RETRY_NOT_ALLOWED'
|
|
95
|
+
|| code === 'QCC_AGENT_EXECUTION_REQUIRED'
|
|
92
96
|
) return 409;
|
|
93
97
|
return 400;
|
|
94
98
|
}
|
|
@@ -282,6 +286,13 @@ export function mountWebRoutes(wctx, { logger, report, TOOL_NAME, SKILL_NAME })
|
|
|
282
286
|
const disposers = [];
|
|
283
287
|
const qccBridge = new QccHostBridge({ tools, logger });
|
|
284
288
|
const g5Runs = new G5RunStore();
|
|
289
|
+
const qccCommands = new QccCommandStore({ bridge: qccBridge, runs: g5Runs });
|
|
290
|
+
if (typeof tools?.register === 'function') {
|
|
291
|
+
disposers.push(registerQccCommandTool(tools, qccCommands));
|
|
292
|
+
report.qccCommandToolRegistered = true;
|
|
293
|
+
} else {
|
|
294
|
+
report.qccCommandToolRegistered = false;
|
|
295
|
+
}
|
|
285
296
|
const phase3Service = new Phase3BatchService(qccBridge);
|
|
286
297
|
const phase3Runs = new Phase3RunStore();
|
|
287
298
|
report.qccBridgeMounted = true;
|
|
@@ -449,6 +460,7 @@ export function mountWebRoutes(wctx, { logger, report, TOOL_NAME, SKILL_NAME })
|
|
|
449
460
|
const artifacts = await artifactStore.createBundle(taskId, {
|
|
450
461
|
rows: payload.rows,
|
|
451
462
|
headers: payload.headers,
|
|
463
|
+
fieldSelection: readyTask.fieldSelection,
|
|
452
464
|
exceptionRows: payload.exceptionRows,
|
|
453
465
|
baseName: payload.baseName || readyTask.title,
|
|
454
466
|
});
|
|
@@ -531,10 +543,52 @@ export function mountWebRoutes(wctx, { logger, report, TOOL_NAME, SKILL_NAME })
|
|
|
531
543
|
idempotencyRequired: true,
|
|
532
544
|
candidateResume: true,
|
|
533
545
|
manualRetry: true,
|
|
546
|
+
agentCommandTool: TOOL_QCC_COMMAND,
|
|
547
|
+
agentCommandToolRegistered: report.qccCommandToolRegistered,
|
|
548
|
+
agentOwnedExecutionRequired: true,
|
|
534
549
|
runPersistence: 'host-memory',
|
|
535
550
|
});
|
|
536
551
|
});
|
|
537
552
|
|
|
553
|
+
register('/data-cleaning/api/g5/commands', async (req, res) => {
|
|
554
|
+
if (!isTrusted(req)) return writeJson(res, 403, { ok: false, error: 'untrusted origin' });
|
|
555
|
+
try {
|
|
556
|
+
const pathname = new URL(req.url ?? '/data-cleaning/api/g5/commands', 'http://127.0.0.1').pathname;
|
|
557
|
+
const segments = pathname.split('/').filter(Boolean);
|
|
558
|
+
const commandsIndex = segments.indexOf('commands');
|
|
559
|
+
const rest = commandsIndex >= 0 ? segments.slice(commandsIndex + 1) : [];
|
|
560
|
+
if (rest.length === 0 && req.method === 'POST') {
|
|
561
|
+
if (!report.qccCommandToolRegistered) {
|
|
562
|
+
throw new QccBridgeError(
|
|
563
|
+
'QCC_AGENT_COMMAND_UNAVAILABLE',
|
|
564
|
+
'The current DSH Host does not expose the Agent command registration API.',
|
|
565
|
+
);
|
|
566
|
+
}
|
|
567
|
+
const payload = JSON.parse((await readBody(req)).toString('utf8'));
|
|
568
|
+
requirePaidConfirmation(payload);
|
|
569
|
+
return writeJson(res, 201, {
|
|
570
|
+
ok: true,
|
|
571
|
+
marker: 'g5-agent-command',
|
|
572
|
+
paidCalls: false,
|
|
573
|
+
command: qccCommands.prepare(payload),
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
if (rest.length === 1 && req.method === 'GET') {
|
|
577
|
+
return writeJson(res, 200, {
|
|
578
|
+
ok: true,
|
|
579
|
+
marker: 'g5-agent-command',
|
|
580
|
+
command: qccCommands.status(decodeURIComponent(rest[0])),
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
return writeJson(res, 405, { ok: false, code: 'DC_METHOD', message: 'POST a command or GET one command id' });
|
|
584
|
+
} catch (error) {
|
|
585
|
+
if (error instanceof SyntaxError) {
|
|
586
|
+
return writeJson(res, 400, { ok: false, code: 'DC_BAD_JSON', message: 'Request body must be valid JSON.' });
|
|
587
|
+
}
|
|
588
|
+
return writeQccError(res, error);
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
|
|
538
592
|
register('/data-cleaning/api/phase2/capabilities', (req, res) => {
|
|
539
593
|
if (!isTrusted(req)) return writeJson(res, 403, { ok: false, error: 'untrusted origin' });
|
|
540
594
|
if (req.method !== 'GET') {
|
package/lib/workflow-contract.js
CHANGED
|
@@ -117,6 +117,15 @@ export const FIELD_CATALOG = Object.freeze([
|
|
|
117
117
|
}),
|
|
118
118
|
]);
|
|
119
119
|
|
|
120
|
+
export const FIELD_LABELS = Object.freeze(Object.fromEntries(
|
|
121
|
+
FIELD_CATALOG.flatMap((group) => group.fields.map((field) => [field.id, field.label])),
|
|
122
|
+
));
|
|
123
|
+
|
|
124
|
+
export function fieldLabel(fieldId) {
|
|
125
|
+
const id = String(fieldId ?? '').trim();
|
|
126
|
+
return FIELD_LABELS[id] ?? id;
|
|
127
|
+
}
|
|
128
|
+
|
|
120
129
|
const FIELD_IDS = new Set(FIELD_CATALOG.flatMap((group) => group.fields.map((field) => field.id)));
|
|
121
130
|
const STAGE_IDS = new Set(WORKFLOW_STAGES.map((stage) => stage.id));
|
|
122
131
|
const STATE_IDS = new Set(WORKFLOW_STATES);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-data-cleaning-agent",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
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",
|
|
@@ -32,6 +32,8 @@
|
|
|
32
32
|
"docs/RELEASE-0.5.2.md",
|
|
33
33
|
"docs/RELEASE-0.5.3.md",
|
|
34
34
|
"docs/RELEASE-0.6.0.md",
|
|
35
|
+
"docs/RELEASE-0.6.1.md",
|
|
36
|
+
"docs/RELEASE-0.6.2.md",
|
|
35
37
|
"docs/UI-WORKFLOW-V2.md",
|
|
36
38
|
"docs/UI-WORKFLOW-V2-MIGRATION.md",
|
|
37
39
|
"docs/UI-WORKFLOW-V2-ACCEPTANCE.md",
|
|
@@ -40,7 +42,7 @@
|
|
|
40
42
|
],
|
|
41
43
|
"scripts": {
|
|
42
44
|
"test": "node --test",
|
|
43
|
-
"lint": "node --check lib/index.js && node --check lib/engine.js && node --check lib/artifacts.js && node --check lib/tools.js && node --check lib/skill.js && node --check lib/qcc-phase2.js && node --check lib/qcc-phase3.js && node --check lib/qcc-phase3-batch.js && node --check lib/qcc-phase2-acceptance.js && node --check lib/skill-enrich.js && node --check lib/jobs.js && node --check lib/workflow-contract.js && node --check lib/workflow.js && node --check lib/qcc-safety.js && node --check lib/qcc.js && node --check lib/qcc-runs.js && node --check lib/web.js && node --check lib/client.js && node --check scripts/check-readme-version.mjs && node --check scripts/check-market-registration.mjs && node --check scripts/g5-e2e.mjs && node --check scripts/phase3-e2e.mjs && node --check scripts/phase2-acceptance.mjs",
|
|
45
|
+
"lint": "node --check lib/index.js && node --check lib/engine.js && node --check lib/artifacts.js && node --check lib/tools.js && node --check lib/skill.js && node --check lib/qcc-phase2.js && node --check lib/qcc-phase3.js && node --check lib/qcc-phase3-batch.js && node --check lib/qcc-phase2-acceptance.js && node --check lib/skill-enrich.js && node --check lib/jobs.js && node --check lib/workflow-contract.js && node --check lib/workflow.js && node --check lib/qcc-safety.js && node --check lib/qcc.js && node --check lib/qcc-command.js && node --check lib/qcc-runs.js && node --check lib/web.js && node --check lib/client.js && node --check scripts/check-readme-version.mjs && node --check scripts/check-market-registration.mjs && node --check scripts/g5-e2e.mjs && node --check scripts/phase3-e2e.mjs && node --check scripts/phase2-acceptance.mjs",
|
|
44
46
|
"docs:check": "node scripts/check-readme-version.mjs",
|
|
45
47
|
"marketing:check": "node scripts/check-marketing.mjs",
|
|
46
48
|
"verify-pack": "node scripts/verify-pack.mjs",
|