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/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') {
@@ -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.0",
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",