dsh-data-quality 0.1.0
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 +16 -0
- package/LICENSE +201 -0
- package/README.es.md +181 -0
- package/README.hi.md +181 -0
- package/README.md +181 -0
- package/README.pt.md +181 -0
- package/README.zh.md +181 -0
- package/THIRD_PARTY_NOTICES.md +20 -0
- package/cordis.patch.yml +46 -0
- package/lib/index.js +2458 -0
- package/lib/types/clean.d.ts +82 -0
- package/lib/types/clean.d.ts.map +1 -0
- package/lib/types/clean.js +351 -0
- package/lib/types/clean.js.map +1 -0
- package/lib/types/config.d.ts +47 -0
- package/lib/types/config.d.ts.map +1 -0
- package/lib/types/config.js +66 -0
- package/lib/types/config.js.map +1 -0
- package/lib/types/dataset.d.ts +133 -0
- package/lib/types/dataset.d.ts.map +1 -0
- package/lib/types/dataset.js +404 -0
- package/lib/types/dataset.js.map +1 -0
- package/lib/types/events.d.ts +73 -0
- package/lib/types/events.d.ts.map +1 -0
- package/lib/types/events.js +41 -0
- package/lib/types/events.js.map +1 -0
- package/lib/types/index.d.ts +45 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +78 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/present.d.ts +24 -0
- package/lib/types/present.d.ts.map +1 -0
- package/lib/types/present.js +34 -0
- package/lib/types/present.js.map +1 -0
- package/lib/types/profile.d.ts +79 -0
- package/lib/types/profile.d.ts.map +1 -0
- package/lib/types/profile.js +196 -0
- package/lib/types/profile.js.map +1 -0
- package/lib/types/provider-local.d.ts +56 -0
- package/lib/types/provider-local.d.ts.map +1 -0
- package/lib/types/provider-local.js +163 -0
- package/lib/types/provider-local.js.map +1 -0
- package/lib/types/service.d.ts +160 -0
- package/lib/types/service.d.ts.map +1 -0
- package/lib/types/service.js +25 -0
- package/lib/types/service.js.map +1 -0
- package/lib/types/store.d.ts +61 -0
- package/lib/types/store.d.ts.map +1 -0
- package/lib/types/store.js +42 -0
- package/lib/types/store.js.map +1 -0
- package/lib/types/tools/clean.d.ts +14 -0
- package/lib/types/tools/clean.d.ts.map +1 -0
- package/lib/types/tools/clean.js +146 -0
- package/lib/types/tools/clean.js.map +1 -0
- package/lib/types/tools/profile.d.ts +13 -0
- package/lib/types/tools/profile.d.ts.map +1 -0
- package/lib/types/tools/profile.js +91 -0
- package/lib/types/tools/profile.js.map +1 -0
- package/lib/types/tools/shared.d.ts +19 -0
- package/lib/types/tools/shared.d.ts.map +1 -0
- package/lib/types/tools/shared.js +44 -0
- package/lib/types/tools/shared.js.map +1 -0
- package/lib/types/tools/verify.d.ts +14 -0
- package/lib/types/tools/verify.d.ts.map +1 -0
- package/lib/types/tools/verify.js +160 -0
- package/lib/types/tools/verify.js.map +1 -0
- package/lib/types/verify.d.ts +124 -0
- package/lib/types/verify.d.ts.map +1 -0
- package/lib/types/verify.js +391 -0
- package/lib/types/verify.js.map +1 -0
- package/lib/types/version.d.ts +8 -0
- package/lib/types/version.d.ts.map +1 -0
- package/lib/types/version.js +8 -0
- package/lib/types/version.js.map +1 -0
- package/package.json +137 -0
- package/src/clean.ts +382 -0
- package/src/config.ts +104 -0
- package/src/dataset.ts +445 -0
- package/src/events.ts +90 -0
- package/src/index.ts +115 -0
- package/src/present.ts +38 -0
- package/src/profile.ts +250 -0
- package/src/provider-local.ts +194 -0
- package/src/service.ts +172 -0
- package/src/store.ts +74 -0
- package/src/tools/clean.ts +150 -0
- package/src/tools/profile.ts +94 -0
- package/src/tools/shared.ts +47 -0
- package/src/tools/verify.ts +163 -0
- package/src/verify.ts +496 -0
- package/src/version.ts +8 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `data-quality/*` session-event vocabulary and its adaptive append gate.
|
|
3
|
+
* The vocabulary is declared on `SessionEventMap` for type-checked payloads;
|
|
4
|
+
* the runtime gate decides per host whether appending is safe:
|
|
5
|
+
*
|
|
6
|
+
* - Hosts whose known-type set already covers the vocabulary (a future harness
|
|
7
|
+
* that adopts these events) append plainly.
|
|
8
|
+
* - Hosts with an `ignorable` append option (the master-build
|
|
9
|
+
* `Session.append(type, data, { ignorable: true })` contract) append with the
|
|
10
|
+
* marker, so builds that do not know the type skip the event on restore.
|
|
11
|
+
* - 0.1.0-rc.6 hosts have neither a registration surface nor the `ignorable`
|
|
12
|
+
* append flag; appending an unknown type there would make the persistence
|
|
13
|
+
* coordinator refuse the session log on restore, so the append is skipped
|
|
14
|
+
* and the storage-domain report remains the durable copy.
|
|
15
|
+
* @module dsh-data-quality/events
|
|
16
|
+
*/
|
|
17
|
+
import { KNOWN_SESSION_EVENT_TYPES } from '@deepseek-ai/dsh-session';
|
|
18
|
+
/** The event type vocabulary this plugin appends. */
|
|
19
|
+
export const DATA_QUALITY_EVENT_TYPES = ['data-quality/profile', 'data-quality/clean', 'data-quality/verify'];
|
|
20
|
+
/**
|
|
21
|
+
* Append one `data-quality/*` event when the host can carry it safely; skip
|
|
22
|
+
* silently otherwise (the storage-domain report is always the durable copy).
|
|
23
|
+
* The `ignorable` probe reads the UNBOUND method's source (a `.bind()` result
|
|
24
|
+
* reports `[native code]`): the rc.6 build contains no `ignorable` handling
|
|
25
|
+
* while the master build references the flag by name; property names survive
|
|
26
|
+
* minification, so the probe fails safe (skips) rather than corrupting a log.
|
|
27
|
+
* @param session - the calling session.
|
|
28
|
+
* @param type - the event type.
|
|
29
|
+
* @param data - the payload.
|
|
30
|
+
*/
|
|
31
|
+
export function appendDataQualityEvent(session, type, data) {
|
|
32
|
+
if (KNOWN_SESSION_EVENT_TYPES.has(type)) {
|
|
33
|
+
session.append(type, data);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const append = session.append;
|
|
37
|
+
if (Function.prototype.toString.call(append).includes('ignorable')) {
|
|
38
|
+
append.call(session, type, data, { ignorable: true });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,yBAAyB,EAAgB,MAAM,0BAA0B,CAAA;AA2ClF,qDAAqD;AACrD,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,sBAAsB,EAAE,oBAAoB,EAAE,qBAAqB,CAAU,CAAA;AAQtH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAgB,EAAE,IAA0B,EAAE,IAA0B;IAC7G,IAAI,yBAAyB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAC1B,OAAM;IACR,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAqB,CAAA;IAC5C,IAAI,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QACnE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACvD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dsh-data-quality` — deterministic data profiling, cleaning, and
|
|
3
|
+
* verification for DeepSeek Harness. Mounts the `ctx.dataQuality` capability
|
|
4
|
+
* seam (Service Definition in `service.ts`, local Provider in
|
|
5
|
+
* `provider-local.ts`), registers the `data_profile` / `data_clean` /
|
|
6
|
+
* `data_verify` model tools (Consumers — all computation goes through the
|
|
7
|
+
* service layer), persists run reports to the `data_quality` storage domain,
|
|
8
|
+
* and appends adaptive `data-quality/*` session events on hosts that can
|
|
9
|
+
* carry them.
|
|
10
|
+
*
|
|
11
|
+
* Function plugin — no default export (the Loader unwraps
|
|
12
|
+
* `exports.default ?? exports`, and a stray default would discard
|
|
13
|
+
* `name`/`inject`/`Config`/`apply`).
|
|
14
|
+
* @module dsh-data-quality
|
|
15
|
+
*/
|
|
16
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
17
|
+
import { Config } from './config.js';
|
|
18
|
+
export declare const name = "data-quality";
|
|
19
|
+
/** The three model tools and the durable report domain. */
|
|
20
|
+
export declare const inject: string[];
|
|
21
|
+
export { Config, resolveConfig } from './config.js';
|
|
22
|
+
export type { Config as DataQualityConfig, ResolvedConfig } from './config.js';
|
|
23
|
+
export { VERSION } from './version.js';
|
|
24
|
+
export { DataQualityService, type CitationCheckRequest, type CitationCheckResult, type ProfileRequest, type CleanRequest, type CleanRunReport, type VerifyRequest, } from './service.js';
|
|
25
|
+
export { LocalDataQualityService, type ProviderDeps } from './provider-local.js';
|
|
26
|
+
export type { CleanRule, CleanRuleLog, CleanResult } from './clean.js';
|
|
27
|
+
export type { ProfileReport, ColumnProfile, NumericProfile } from './profile.js';
|
|
28
|
+
export type { VerifyRule, VerifyReport, VerifyRuleResult, VerifyEvidenceRow } from './verify.js';
|
|
29
|
+
export { parseLocator, checkCitations } from './verify.js';
|
|
30
|
+
export { profileTable, renderProfileText } from './profile.js';
|
|
31
|
+
export { applyCleanRules, serializeDelimited } from './clean.js';
|
|
32
|
+
export { verifyTable, renderVerifyText } from './verify.js';
|
|
33
|
+
export { DatasetError, loadTable, loadDocument, parseDelimited, parseJsonTable, resolveWorkspacePath, sampleRows, isMissing, parseNumeric, parseDate, parseBoolean, type Table, type Row, type Cell, type DocumentRoot, } from './dataset.js';
|
|
34
|
+
export { dataQualityDomainSpec, reportKeyOf, reportRecordSchema, type ReportRecord, type ReportStore } from './store.js';
|
|
35
|
+
export { DATA_QUALITY_EVENT_TYPES, appendDataQualityEvent, type DataQualityEventData, type DataQualityEventType } from './events.js';
|
|
36
|
+
export { MAX_CELL_TEXT, truncateCell, truncateRow } from './present.js';
|
|
37
|
+
/**
|
|
38
|
+
* Mount the seam: resolve config (fail loud), open the report domain, publish
|
|
39
|
+
* `ctx.dataQuality`, and register the three tools. With `enabled: false` the
|
|
40
|
+
* plugin registers nothing and stays inert.
|
|
41
|
+
* @param ctx - the plugin context (host).
|
|
42
|
+
* @param config - raw plugin config.
|
|
43
|
+
*/
|
|
44
|
+
export declare function apply(ctx: Context, config?: Config): Promise<void>;
|
|
45
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,EAAE,MAAM,EAAiB,MAAM,aAAa,CAAA;AAQnD,eAAO,MAAM,IAAI,iBAAiB,CAAA;AAClC,2DAA2D;AAC3D,eAAO,MAAM,MAAM,UAA6B,CAAA;AAEhD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACnD,YAAY,EAAE,MAAM,IAAI,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC9E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EACL,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,aAAa,GACnB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,uBAAuB,EAAE,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAChF,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACtE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAChF,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAChG,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAChE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,EACL,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,UAAU,EACV,SAAS,EACT,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,KAAK,KAAK,EACV,KAAK,GAAG,EACR,KAAK,IAAI,EACT,KAAK,YAAY,GAClB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AACxH,OAAO,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,KAAK,oBAAoB,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACpI,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAEvE;;;;;;GAMG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,MAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAmC5E"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dsh-data-quality` — deterministic data profiling, cleaning, and
|
|
3
|
+
* verification for DeepSeek Harness. Mounts the `ctx.dataQuality` capability
|
|
4
|
+
* seam (Service Definition in `service.ts`, local Provider in
|
|
5
|
+
* `provider-local.ts`), registers the `data_profile` / `data_clean` /
|
|
6
|
+
* `data_verify` model tools (Consumers — all computation goes through the
|
|
7
|
+
* service layer), persists run reports to the `data_quality` storage domain,
|
|
8
|
+
* and appends adaptive `data-quality/*` session events on hosts that can
|
|
9
|
+
* carry them.
|
|
10
|
+
*
|
|
11
|
+
* Function plugin — no default export (the Loader unwraps
|
|
12
|
+
* `exports.default ?? exports`, and a stray default would discard
|
|
13
|
+
* `name`/`inject`/`Config`/`apply`).
|
|
14
|
+
* @module dsh-data-quality
|
|
15
|
+
*/
|
|
16
|
+
import { resolveConfig } from "./config.js";
|
|
17
|
+
import { dataQualityDomainSpec, reportKeyOf } from "./store.js";
|
|
18
|
+
import { LocalDataQualityService } from "./provider-local.js";
|
|
19
|
+
import { defineProfileTool } from "./tools/profile.js";
|
|
20
|
+
import { defineCleanTool } from "./tools/clean.js";
|
|
21
|
+
import { defineVerifyTool } from "./tools/verify.js";
|
|
22
|
+
import { VERSION } from "./version.js";
|
|
23
|
+
export const name = 'data-quality';
|
|
24
|
+
/** The three model tools and the durable report domain. */
|
|
25
|
+
export const inject = ['tools', 'storageDomain'];
|
|
26
|
+
export { Config, resolveConfig } from "./config.js";
|
|
27
|
+
export { VERSION } from "./version.js";
|
|
28
|
+
export { DataQualityService, } from "./service.js";
|
|
29
|
+
export { LocalDataQualityService } from "./provider-local.js";
|
|
30
|
+
export { parseLocator, checkCitations } from "./verify.js";
|
|
31
|
+
export { profileTable, renderProfileText } from "./profile.js";
|
|
32
|
+
export { applyCleanRules, serializeDelimited } from "./clean.js";
|
|
33
|
+
export { verifyTable, renderVerifyText } from "./verify.js";
|
|
34
|
+
export { DatasetError, loadTable, loadDocument, parseDelimited, parseJsonTable, resolveWorkspacePath, sampleRows, isMissing, parseNumeric, parseDate, parseBoolean, } from "./dataset.js";
|
|
35
|
+
export { dataQualityDomainSpec, reportKeyOf, reportRecordSchema } from "./store.js";
|
|
36
|
+
export { DATA_QUALITY_EVENT_TYPES, appendDataQualityEvent } from "./events.js";
|
|
37
|
+
export { MAX_CELL_TEXT, truncateCell, truncateRow } from "./present.js";
|
|
38
|
+
/**
|
|
39
|
+
* Mount the seam: resolve config (fail loud), open the report domain, publish
|
|
40
|
+
* `ctx.dataQuality`, and register the three tools. With `enabled: false` the
|
|
41
|
+
* plugin registers nothing and stays inert.
|
|
42
|
+
* @param ctx - the plugin context (host).
|
|
43
|
+
* @param config - raw plugin config.
|
|
44
|
+
*/
|
|
45
|
+
export async function apply(ctx, config = {}) {
|
|
46
|
+
const resolved = resolveConfig(config);
|
|
47
|
+
const logger = ctx.logger('data-quality');
|
|
48
|
+
if (!resolved.enabled) {
|
|
49
|
+
logger.info('disabled: enabled is false — no service or tools are mounted');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
let store;
|
|
53
|
+
let domain;
|
|
54
|
+
if (resolved.storeReports) {
|
|
55
|
+
domain = await ctx.storageDomain.open(dataQualityDomainSpec);
|
|
56
|
+
const reports = domain.table('reports');
|
|
57
|
+
store = {
|
|
58
|
+
put: async (record) => {
|
|
59
|
+
const key = reportKeyOf(record);
|
|
60
|
+
await reports.put(key, record);
|
|
61
|
+
return key;
|
|
62
|
+
},
|
|
63
|
+
get: (key) => reports.get(key),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const service = new LocalDataQualityService(ctx, resolved, { store, now: Date.now });
|
|
67
|
+
ctx.tools.register(defineProfileTool(service));
|
|
68
|
+
ctx.tools.register(defineCleanTool(service));
|
|
69
|
+
ctx.tools.register(defineVerifyTool(service));
|
|
70
|
+
logger.info(`dsh-data-quality ${VERSION} mounted: ctx.dataQuality + data_profile/data_clean/data_verify`);
|
|
71
|
+
if (domain !== undefined) {
|
|
72
|
+
const handle = domain;
|
|
73
|
+
ctx.effect(() => async () => {
|
|
74
|
+
await handle.close();
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presentation bounds for tool-facing canonical values: cell text is truncated
|
|
3
|
+
* so one oversized cell cannot flood the model context. This is a display
|
|
4
|
+
* safety invariant, not a deployment tunable — the durable storage-domain
|
|
5
|
+
* report always keeps full fidelity.
|
|
6
|
+
* @module dsh-data-quality/present
|
|
7
|
+
*/
|
|
8
|
+
import type { JsonValue } from '@deepseek-ai/dsh-session';
|
|
9
|
+
/** Maximum characters one cell contributes to a tool-facing row payload. */
|
|
10
|
+
export declare const MAX_CELL_TEXT = 120;
|
|
11
|
+
/**
|
|
12
|
+
* Truncate one cell for display: long strings are cut with an ellipsis
|
|
13
|
+
* marker; non-strings pass through.
|
|
14
|
+
* @param cell - the cell to bound.
|
|
15
|
+
* @returns the display-safe cell.
|
|
16
|
+
*/
|
|
17
|
+
export declare function truncateCell(cell: JsonValue): JsonValue;
|
|
18
|
+
/**
|
|
19
|
+
* Truncate every string cell of one row.
|
|
20
|
+
* @param row - the row to bound.
|
|
21
|
+
* @returns a display-safe copy.
|
|
22
|
+
*/
|
|
23
|
+
export declare function truncateRow(row: Record<string, JsonValue>): Record<string, JsonValue>;
|
|
24
|
+
//# sourceMappingURL=present.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"present.d.ts","sourceRoot":"","sources":["../../src/present.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAEzD,4EAA4E;AAC5E,eAAO,MAAM,aAAa,MAAM,CAAA;AAEhC;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAKvD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAMrF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presentation bounds for tool-facing canonical values: cell text is truncated
|
|
3
|
+
* so one oversized cell cannot flood the model context. This is a display
|
|
4
|
+
* safety invariant, not a deployment tunable — the durable storage-domain
|
|
5
|
+
* report always keeps full fidelity.
|
|
6
|
+
* @module dsh-data-quality/present
|
|
7
|
+
*/
|
|
8
|
+
/** Maximum characters one cell contributes to a tool-facing row payload. */
|
|
9
|
+
export const MAX_CELL_TEXT = 120;
|
|
10
|
+
/**
|
|
11
|
+
* Truncate one cell for display: long strings are cut with an ellipsis
|
|
12
|
+
* marker; non-strings pass through.
|
|
13
|
+
* @param cell - the cell to bound.
|
|
14
|
+
* @returns the display-safe cell.
|
|
15
|
+
*/
|
|
16
|
+
export function truncateCell(cell) {
|
|
17
|
+
if (typeof cell === 'string' && cell.length > MAX_CELL_TEXT) {
|
|
18
|
+
return `${cell.slice(0, MAX_CELL_TEXT)}…`;
|
|
19
|
+
}
|
|
20
|
+
return cell;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Truncate every string cell of one row.
|
|
24
|
+
* @param row - the row to bound.
|
|
25
|
+
* @returns a display-safe copy.
|
|
26
|
+
*/
|
|
27
|
+
export function truncateRow(row) {
|
|
28
|
+
const out = {};
|
|
29
|
+
for (const [key, value] of Object.entries(row)) {
|
|
30
|
+
out[key] = truncateCell(value);
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=present.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"present.js","sourceRoot":"","sources":["../../src/present.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,4EAA4E;AAC5E,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAA;AAEhC;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,IAAe;IAC1C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,aAAa,EAAE,CAAC;QAC5D,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,GAAG,CAAA;IAC3C,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,GAA8B;IACxD,MAAM,GAAG,GAA8B,EAAE,CAAA;IACzC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,GAAG,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;IAChC,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic dataset profiling: per-column type inference, missingness,
|
|
3
|
+
* cardinality, numeric distribution, IQR outlier counts, and duplicate-row
|
|
4
|
+
* detection. Pure functions over a parsed {@link Table} — no clock, no RNG,
|
|
5
|
+
* no I/O; `generatedAt` is injected by the caller.
|
|
6
|
+
* @module dsh-data-quality/profile
|
|
7
|
+
*/
|
|
8
|
+
import { type Table } from './dataset.js';
|
|
9
|
+
/** Inferred column type from parsed cell classes. */
|
|
10
|
+
export type InferredType = 'number' | 'date' | 'boolean' | 'string' | 'empty' | 'mixed';
|
|
11
|
+
/** Numeric distribution of one numeric column. */
|
|
12
|
+
export interface NumericProfile {
|
|
13
|
+
readonly min: number;
|
|
14
|
+
readonly max: number;
|
|
15
|
+
readonly mean: number;
|
|
16
|
+
readonly median: number;
|
|
17
|
+
readonly p25: number;
|
|
18
|
+
readonly p75: number;
|
|
19
|
+
/** Values outside `[p25 - 1.5*IQR, p75 + 1.5*IQR]`. */
|
|
20
|
+
readonly outliers: number;
|
|
21
|
+
}
|
|
22
|
+
/** One column's profile card. */
|
|
23
|
+
export interface ColumnProfile {
|
|
24
|
+
readonly name: string;
|
|
25
|
+
readonly inferredType: InferredType;
|
|
26
|
+
/** Missing cells over the profiled rows. */
|
|
27
|
+
readonly missing: number;
|
|
28
|
+
/** `missing / profiledRows` (0 when the column has no rows). */
|
|
29
|
+
readonly missingRate: number;
|
|
30
|
+
/** Distinct non-missing values over the profiled rows. */
|
|
31
|
+
readonly unique: number;
|
|
32
|
+
/** Numeric distribution; present only for `number` columns with values. */
|
|
33
|
+
readonly numeric?: NumericProfile;
|
|
34
|
+
/** Up to 5 most frequent values for low-cardinality (<= 10 distinct) string/boolean columns. */
|
|
35
|
+
topValues?: Array<{
|
|
36
|
+
readonly value: string;
|
|
37
|
+
readonly count: number;
|
|
38
|
+
}>;
|
|
39
|
+
/** Suspicion notes, e.g. mixed-type composition. */
|
|
40
|
+
notes: string[];
|
|
41
|
+
}
|
|
42
|
+
/** The full profile report (also the persisted and tool-returned value). */
|
|
43
|
+
export interface ProfileReport {
|
|
44
|
+
readonly dataset: string;
|
|
45
|
+
readonly rowCount: number;
|
|
46
|
+
/** Whether column cards describe a systematic sample rather than every row. */
|
|
47
|
+
readonly sampled: boolean;
|
|
48
|
+
/** Rows the column cards were computed over. */
|
|
49
|
+
readonly profiledRows: number;
|
|
50
|
+
readonly columnCount: number;
|
|
51
|
+
/** Rows whose full content duplicates an earlier row (over ALL rows). */
|
|
52
|
+
readonly duplicateRows: number;
|
|
53
|
+
columns: ColumnProfile[];
|
|
54
|
+
/** Storage-domain key of the persisted report, when persistence is on (set by the provider). */
|
|
55
|
+
readonly reportKey?: string;
|
|
56
|
+
/** Injected generation timestamp (epoch ms). */
|
|
57
|
+
readonly generatedAt: number;
|
|
58
|
+
}
|
|
59
|
+
/** Compute the numeric distribution of already-parsed values. */
|
|
60
|
+
export declare function numericProfile(values: readonly number[]): NumericProfile | undefined;
|
|
61
|
+
/** Count rows whose full content duplicates an earlier row (first occurrence is not counted). */
|
|
62
|
+
export declare function countDuplicateRows(table: Table, signal?: AbortSignal): number;
|
|
63
|
+
/**
|
|
64
|
+
* Profile a parsed table. Column cards are computed over a deterministic
|
|
65
|
+
* systematic sample when `sample` is given; row counts and duplicate counts
|
|
66
|
+
* always cover the full table.
|
|
67
|
+
* @param table - the parsed dataset.
|
|
68
|
+
* @param options - dataset label, optional sample size, injected timestamp, abort signal.
|
|
69
|
+
* @returns the profile report.
|
|
70
|
+
*/
|
|
71
|
+
export declare function profileTable(table: Table, options: {
|
|
72
|
+
dataset: string;
|
|
73
|
+
sample?: number | undefined;
|
|
74
|
+
generatedAt: number;
|
|
75
|
+
signal?: AbortSignal | undefined;
|
|
76
|
+
}): ProfileReport;
|
|
77
|
+
/** Human-readable profile summary for the tool's Native render. */
|
|
78
|
+
export declare function renderProfileText(report: ProfileReport): string;
|
|
79
|
+
//# sourceMappingURL=profile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/profile.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAA0F,KAAK,KAAK,EAAE,MAAM,cAAc,CAAA;AAEjI,qDAAqD;AACrD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAA;AAEvF,kDAAkD;AAClD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,uDAAuD;IACvD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,iCAAiC;AACjC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAA;IACnC,4CAA4C;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,gEAAgE;IAChE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAA;IACjC,gGAAgG;IAChG,SAAS,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACrE,oDAAoD;IACpD,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,4EAA4E;AAC5E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,gDAAgD;IAChD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,yEAAyE;IACzE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB,gGAAgG;IAChG,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,gDAAgD;IAChD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAiBD,iEAAiE;AACjE,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,cAAc,GAAG,SAAS,CAmBpF;AAED,iGAAiG;AACjG,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAa7E;AAsFD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;CAAE,GAC/G,aAAa,CAef;AAED,mEAAmE;AACnE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAsB/D"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic dataset profiling: per-column type inference, missingness,
|
|
3
|
+
* cardinality, numeric distribution, IQR outlier counts, and duplicate-row
|
|
4
|
+
* detection. Pure functions over a parsed {@link Table} — no clock, no RNG,
|
|
5
|
+
* no I/O; `generatedAt` is injected by the caller.
|
|
6
|
+
* @module dsh-data-quality/profile
|
|
7
|
+
*/
|
|
8
|
+
import { isMissing, parseBoolean, parseDate, parseNumeric, sampleRows, throwIfAborted } from "./dataset.js";
|
|
9
|
+
/** Round to 6 significant digits for stable, readable report numbers. */
|
|
10
|
+
function round6(value) {
|
|
11
|
+
return Number(value.toPrecision(6));
|
|
12
|
+
}
|
|
13
|
+
/** Linear-interpolation quantile over an ascending-sorted array. */
|
|
14
|
+
function quantile(sorted, q) {
|
|
15
|
+
const index = (sorted.length - 1) * q;
|
|
16
|
+
const low = Math.floor(index);
|
|
17
|
+
const high = Math.ceil(index);
|
|
18
|
+
const lower = sorted[low];
|
|
19
|
+
const upper = sorted[high];
|
|
20
|
+
return lower + (upper - lower) * (index - low);
|
|
21
|
+
}
|
|
22
|
+
/** Compute the numeric distribution of already-parsed values. */
|
|
23
|
+
export function numericProfile(values) {
|
|
24
|
+
if (values.length === 0)
|
|
25
|
+
return undefined;
|
|
26
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
27
|
+
const sum = sorted.reduce((acc, value) => acc + value, 0);
|
|
28
|
+
const p25 = quantile(sorted, 0.25);
|
|
29
|
+
const p75 = quantile(sorted, 0.75);
|
|
30
|
+
const iqr = p75 - p25;
|
|
31
|
+
const lowFence = p25 - 1.5 * iqr;
|
|
32
|
+
const highFence = p75 + 1.5 * iqr;
|
|
33
|
+
const outliers = iqr === 0 ? 0 : sorted.filter((value) => value < lowFence || value > highFence).length;
|
|
34
|
+
return {
|
|
35
|
+
min: round6(sorted[0]),
|
|
36
|
+
max: round6(sorted[sorted.length - 1]),
|
|
37
|
+
mean: round6(sum / sorted.length),
|
|
38
|
+
median: round6(quantile(sorted, 0.5)),
|
|
39
|
+
p25: round6(p25),
|
|
40
|
+
p75: round6(p75),
|
|
41
|
+
outliers,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** Count rows whose full content duplicates an earlier row (first occurrence is not counted). */
|
|
45
|
+
export function countDuplicateRows(table, signal) {
|
|
46
|
+
const seen = new Set();
|
|
47
|
+
let duplicates = 0;
|
|
48
|
+
for (const [index, row] of table.rows.entries()) {
|
|
49
|
+
if (index % 1024 === 0)
|
|
50
|
+
throwIfAborted(signal);
|
|
51
|
+
const key = JSON.stringify(table.columns.map((column) => row[column] ?? null));
|
|
52
|
+
if (seen.has(key)) {
|
|
53
|
+
duplicates += 1;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
seen.add(key);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return duplicates;
|
|
60
|
+
}
|
|
61
|
+
/** Profile one column over the given rows. */
|
|
62
|
+
function profileColumn(rows, column, signal) {
|
|
63
|
+
let missing = 0;
|
|
64
|
+
let numbers = 0;
|
|
65
|
+
let dates = 0;
|
|
66
|
+
let booleans = 0;
|
|
67
|
+
let strings = 0;
|
|
68
|
+
const numericValues = [];
|
|
69
|
+
const distinct = new Set();
|
|
70
|
+
const frequencies = new Map();
|
|
71
|
+
for (const [index, row] of rows.entries()) {
|
|
72
|
+
if (index % 1024 === 0)
|
|
73
|
+
throwIfAborted(signal);
|
|
74
|
+
const cell = row[column];
|
|
75
|
+
if (isMissing(cell)) {
|
|
76
|
+
missing += 1;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const text = typeof cell === 'string' ? cell : JSON.stringify(cell);
|
|
80
|
+
distinct.add(text);
|
|
81
|
+
frequencies.set(text, (frequencies.get(text) ?? 0) + 1);
|
|
82
|
+
const numeric = parseNumeric(cell);
|
|
83
|
+
if (numeric !== undefined) {
|
|
84
|
+
numbers += 1;
|
|
85
|
+
numericValues.push(numeric);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (parseDate(cell) !== undefined) {
|
|
89
|
+
dates += 1;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (parseBoolean(cell) !== undefined) {
|
|
93
|
+
booleans += 1;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
strings += 1;
|
|
97
|
+
}
|
|
98
|
+
const present = rows.length - missing;
|
|
99
|
+
const notes = [];
|
|
100
|
+
let inferredType;
|
|
101
|
+
if (present === 0) {
|
|
102
|
+
inferredType = 'empty';
|
|
103
|
+
}
|
|
104
|
+
else if (numbers === present) {
|
|
105
|
+
inferredType = 'number';
|
|
106
|
+
}
|
|
107
|
+
else if (dates === present) {
|
|
108
|
+
inferredType = 'date';
|
|
109
|
+
}
|
|
110
|
+
else if (booleans === present) {
|
|
111
|
+
inferredType = 'boolean';
|
|
112
|
+
}
|
|
113
|
+
else if (strings === present) {
|
|
114
|
+
inferredType = 'string';
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
inferredType = 'mixed';
|
|
118
|
+
const parts = [
|
|
119
|
+
numbers > 0 ? `${numbers} numeric` : undefined,
|
|
120
|
+
dates > 0 ? `${dates} date` : undefined,
|
|
121
|
+
booleans > 0 ? `${booleans} boolean` : undefined,
|
|
122
|
+
strings > 0 ? `${strings} string` : undefined,
|
|
123
|
+
].filter((part) => part !== undefined);
|
|
124
|
+
notes.push(`mixed types among ${present} present values: ${parts.join(', ')}`);
|
|
125
|
+
}
|
|
126
|
+
const profile = {
|
|
127
|
+
name: column,
|
|
128
|
+
inferredType,
|
|
129
|
+
missing,
|
|
130
|
+
missingRate: rows.length === 0 ? 0 : round6(missing / rows.length),
|
|
131
|
+
unique: distinct.size,
|
|
132
|
+
notes,
|
|
133
|
+
};
|
|
134
|
+
const numeric = inferredType === 'number' ? numericProfile(numericValues) : undefined;
|
|
135
|
+
const topValues = (inferredType === 'string' || inferredType === 'boolean') && distinct.size > 0 && distinct.size <= 10
|
|
136
|
+
? [...frequencies.entries()]
|
|
137
|
+
.sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))
|
|
138
|
+
.slice(0, 5)
|
|
139
|
+
.map(([value, count]) => ({ value, count }))
|
|
140
|
+
: undefined;
|
|
141
|
+
return {
|
|
142
|
+
...profile,
|
|
143
|
+
...(numeric !== undefined ? { numeric } : {}),
|
|
144
|
+
...(topValues !== undefined ? { topValues } : {}),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Profile a parsed table. Column cards are computed over a deterministic
|
|
149
|
+
* systematic sample when `sample` is given; row counts and duplicate counts
|
|
150
|
+
* always cover the full table.
|
|
151
|
+
* @param table - the parsed dataset.
|
|
152
|
+
* @param options - dataset label, optional sample size, injected timestamp, abort signal.
|
|
153
|
+
* @returns the profile report.
|
|
154
|
+
*/
|
|
155
|
+
export function profileTable(table, options) {
|
|
156
|
+
throwIfAborted(options.signal);
|
|
157
|
+
const profiled = options.sample === undefined ? table.rows : sampleRows(table.rows, options.sample);
|
|
158
|
+
const columns = table.columns.map((column) => profileColumn(profiled, column, options.signal));
|
|
159
|
+
const duplicateRows = countDuplicateRows(table, options.signal);
|
|
160
|
+
return {
|
|
161
|
+
dataset: options.dataset,
|
|
162
|
+
rowCount: table.rows.length,
|
|
163
|
+
sampled: profiled.length !== table.rows.length,
|
|
164
|
+
profiledRows: profiled.length,
|
|
165
|
+
columnCount: table.columns.length,
|
|
166
|
+
duplicateRows,
|
|
167
|
+
columns,
|
|
168
|
+
generatedAt: options.generatedAt,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/** Human-readable profile summary for the tool's Native render. */
|
|
172
|
+
export function renderProfileText(report) {
|
|
173
|
+
const lines = [];
|
|
174
|
+
lines.push(`Profile of ${report.dataset}: ${report.rowCount} rows x ${report.columnCount} columns` +
|
|
175
|
+
(report.sampled ? ` (column cards over a systematic sample of ${report.profiledRows} rows)` : ''));
|
|
176
|
+
if (report.duplicateRows > 0)
|
|
177
|
+
lines.push(`Duplicate rows: ${report.duplicateRows}`);
|
|
178
|
+
for (const column of report.columns) {
|
|
179
|
+
const parts = [`${column.name}: ${column.inferredType}`];
|
|
180
|
+
if (column.missing > 0)
|
|
181
|
+
parts.push(`missing ${column.missing} (${(column.missingRate * 100).toFixed(1)}%)`);
|
|
182
|
+
parts.push(`unique ${column.unique}`);
|
|
183
|
+
if (column.numeric !== undefined) {
|
|
184
|
+
parts.push(`min ${column.numeric.min}, p25 ${column.numeric.p25}, median ${column.numeric.median}, p75 ${column.numeric.p75}, max ${column.numeric.max}, mean ${column.numeric.mean}` +
|
|
185
|
+
(column.numeric.outliers > 0 ? `, ${column.numeric.outliers} IQR outliers` : ''));
|
|
186
|
+
}
|
|
187
|
+
if (column.topValues !== undefined) {
|
|
188
|
+
parts.push(`top: ${column.topValues.map((entry) => `${JSON.stringify(entry.value)} x${entry.count}`).join(', ')}`);
|
|
189
|
+
}
|
|
190
|
+
for (const note of column.notes)
|
|
191
|
+
parts.push(`note: ${note}`);
|
|
192
|
+
lines.push(`- ${parts.join('; ')}`);
|
|
193
|
+
}
|
|
194
|
+
return lines.join('\n');
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.js","sourceRoot":"","sources":["../../src/profile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The local deterministic Provider of the `ctx.dataQuality` seam: orchestrates
|
|
3
|
+
* dataset loading, the pure engines, durable report persistence, and the
|
|
4
|
+
* adaptive `data-quality/*` session events. All computation is TypeScript in
|
|
5
|
+
* this process — no model arithmetic, no external processes.
|
|
6
|
+
* @module dsh-data-quality/provider-local
|
|
7
|
+
*/
|
|
8
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
9
|
+
import type { ResolvedConfig } from './config.js';
|
|
10
|
+
import { type ReportStore } from './store.js';
|
|
11
|
+
import { DataQualityService, type CitationCheckRequest, type CitationCheckResult, type CleanRequest, type CleanRunReport, type ProfileRequest, type VerifyRequest } from './service.js';
|
|
12
|
+
import type { ProfileReport } from './profile.js';
|
|
13
|
+
import type { VerifyReport } from './verify.js';
|
|
14
|
+
import type { Session } from '@deepseek-ai/dsh-session';
|
|
15
|
+
/** Provider construction dependencies. */
|
|
16
|
+
export interface ProviderDeps {
|
|
17
|
+
/** Report persistence; absent when `storeReports` is off. */
|
|
18
|
+
readonly store?: ReportStore | undefined;
|
|
19
|
+
/** Injected clock — the single time source for reports and freshness defaults. */
|
|
20
|
+
readonly now: () => number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The local deterministic `dataQuality` implementation. Mounted by the plugin
|
|
24
|
+
* entry; third-party plugins consume it through `ctx.dataQuality`.
|
|
25
|
+
*/
|
|
26
|
+
export declare class LocalDataQualityService extends DataQualityService {
|
|
27
|
+
private readonly config;
|
|
28
|
+
private readonly deps;
|
|
29
|
+
/**
|
|
30
|
+
* @param ctx - the plugin context.
|
|
31
|
+
* @param config - the resolved plugin config.
|
|
32
|
+
* @param deps - store handle plus the injected clock.
|
|
33
|
+
*/
|
|
34
|
+
constructor(ctx: Context, config: ResolvedConfig, deps: ProviderDeps);
|
|
35
|
+
/** The absolute root for service-level calls without a session workspace. */
|
|
36
|
+
serviceRoot(): string;
|
|
37
|
+
/** Persist one report when persistence is on; returns the storage key. */
|
|
38
|
+
private persist;
|
|
39
|
+
/** Emit the adaptive session event when the call carries a session. */
|
|
40
|
+
emitEvent(session: Session | undefined, kind: 'profile' | 'clean' | 'verify', dataset: string, reportKey: string | undefined, summary: {
|
|
41
|
+
rows: number;
|
|
42
|
+
columns?: number;
|
|
43
|
+
rules?: number;
|
|
44
|
+
failedRules?: number;
|
|
45
|
+
passed?: boolean;
|
|
46
|
+
}): void;
|
|
47
|
+
/** @inheritdoc DataQualityService.profileDataset */
|
|
48
|
+
profileDataset(request: ProfileRequest): Promise<ProfileReport>;
|
|
49
|
+
/** @inheritdoc DataQualityService.cleanDataset */
|
|
50
|
+
cleanDataset(request: CleanRequest): Promise<CleanRunReport>;
|
|
51
|
+
/** @inheritdoc DataQualityService.verifyDataset */
|
|
52
|
+
verifyDataset(request: VerifyRequest): Promise<VerifyReport>;
|
|
53
|
+
/** @inheritdoc DataQualityService.verifyCitations */
|
|
54
|
+
verifyCitations(request: CitationCheckRequest): Promise<CitationCheckResult>;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=provider-local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-local.d.ts","sourceRoot":"","sources":["../../src/provider-local.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAMjD,OAAO,EAAkC,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7E,OAAO,EACL,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAEvD,0CAA0C;AAC1C,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;IACxC,kFAAkF;IAClF,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAA;CAC3B;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,kBAAkB;IAC7D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAc;IAEnC;;;;OAIG;gBACS,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,YAAY;IAMpE,6EAA6E;IAC7E,WAAW,IAAI,MAAM;IAIrB,0EAA0E;YAC5D,OAAO;IASrB,uEAAuE;IACvE,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAUxO,oDAAoD;IACrC,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAe9E,kDAAkD;IACnC,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC;IAgD3E,mDAAmD;IACpC,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAqB3E,qDAAqD;IACtC,eAAe,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAoB5F"}
|