dsh-research-report 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 +18 -0
- package/LICENSE +201 -0
- package/README.es.md +155 -0
- package/README.hi.md +155 -0
- package/README.md +155 -0
- package/README.pt.md +155 -0
- package/README.zh.md +155 -0
- package/THIRD_PARTY_NOTICES.md +21 -0
- package/cordis.patch.yml +24 -0
- package/lib/index.js +2143 -0
- package/lib/types/assemble.d.ts +123 -0
- package/lib/types/assemble.d.ts.map +1 -0
- package/lib/types/assemble.js +239 -0
- package/lib/types/assemble.js.map +1 -0
- package/lib/types/config.d.ts +48 -0
- package/lib/types/config.d.ts.map +1 -0
- package/lib/types/config.js +60 -0
- package/lib/types/config.js.map +1 -0
- package/lib/types/gather.d.ts +119 -0
- package/lib/types/gather.d.ts.map +1 -0
- package/lib/types/gather.js +165 -0
- package/lib/types/gather.js.map +1 -0
- package/lib/types/index.d.ts +51 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +71 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/ledger.d.ts +159 -0
- package/lib/types/ledger.d.ts.map +1 -0
- package/lib/types/ledger.js +276 -0
- package/lib/types/ledger.js.map +1 -0
- package/lib/types/provider-local.d.ts +137 -0
- package/lib/types/provider-local.d.ts.map +1 -0
- package/lib/types/provider-local.js +418 -0
- package/lib/types/provider-local.js.map +1 -0
- package/lib/types/service.d.ts +302 -0
- package/lib/types/service.d.ts.map +1 -0
- package/lib/types/service.js +31 -0
- package/lib/types/service.js.map +1 -0
- package/lib/types/tools/evidence-add.d.ts +36 -0
- package/lib/types/tools/evidence-add.d.ts.map +1 -0
- package/lib/types/tools/evidence-add.js +107 -0
- package/lib/types/tools/evidence-add.js.map +1 -0
- package/lib/types/tools/ledger-query.d.ts +42 -0
- package/lib/types/tools/ledger-query.d.ts.map +1 -0
- package/lib/types/tools/ledger-query.js +154 -0
- package/lib/types/tools/ledger-query.js.map +1 -0
- package/lib/types/tools/research-report.d.ts +67 -0
- package/lib/types/tools/research-report.d.ts.map +1 -0
- package/lib/types/tools/research-report.js +345 -0
- package/lib/types/tools/research-report.js.map +1 -0
- package/lib/types/verify.d.ts +128 -0
- package/lib/types/verify.d.ts.map +1 -0
- package/lib/types/verify.js +208 -0
- package/lib/types/verify.js.map +1 -0
- package/lib/types/version.d.ts +7 -0
- package/lib/types/version.d.ts.map +1 -0
- package/lib/types/version.js +7 -0
- package/lib/types/version.js.map +1 -0
- package/package.json +147 -0
- package/src/assemble.ts +302 -0
- package/src/config.ts +97 -0
- package/src/gather.ts +239 -0
- package/src/index.ts +139 -0
- package/src/ledger.ts +344 -0
- package/src/provider-local.ts +489 -0
- package/src/service.ts +322 -0
- package/src/tools/evidence-add.ts +132 -0
- package/src/tools/ledger-query.ts +191 -0
- package/src/tools/research-report.ts +424 -0
- package/src/verify.ts +285 -0
- package/src/version.ts +7 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evidence capture: URL snapshots via the `ctx.web` seam, workspace file
|
|
3
|
+
* snapshots via `node:fs` — never a direct `fetch` (provider selection and the
|
|
4
|
+
* WebError taxonomy stay with the seam), never a path outside the workspace.
|
|
5
|
+
* @module dsh-research-report/gather
|
|
6
|
+
*/
|
|
7
|
+
import { readFile } from 'node:fs/promises';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
/** A loud capture failure with a machine-routable code (also in the message). */
|
|
10
|
+
export class CaptureError extends Error {
|
|
11
|
+
/** The machine-routable failure code. */
|
|
12
|
+
code;
|
|
13
|
+
constructor(code, message) {
|
|
14
|
+
super(`[${code}] ${message}`);
|
|
15
|
+
this.name = 'CaptureError';
|
|
16
|
+
this.code = code;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** Whether the origin is an HTTP(S) URL (vs a workspace path). */
|
|
20
|
+
export function isUrlOrigin(origin) {
|
|
21
|
+
return /^https?:\/\//iu.test(origin);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolve a workspace-relative origin to an absolute path inside the
|
|
25
|
+
* workspace. Both sides are resolved before comparison (Windows backslash
|
|
26
|
+
* trap) and the prefix check is segment-aware.
|
|
27
|
+
* @param workspaceRoot - absolute workspace root.
|
|
28
|
+
* @param origin - the workspace-relative (or absolute) origin.
|
|
29
|
+
* @returns the absolute in-workspace path.
|
|
30
|
+
*/
|
|
31
|
+
export function resolveWorkspacePath(workspaceRoot, origin) {
|
|
32
|
+
const root = path.resolve(workspaceRoot);
|
|
33
|
+
const resolved = path.resolve(root, origin);
|
|
34
|
+
if (resolved !== root && !resolved.startsWith(`${root}${path.sep}`)) {
|
|
35
|
+
throw new CaptureError('ORIGIN_OUTSIDE_WORKSPACE', `origin ${JSON.stringify(origin)} resolves outside the workspace`);
|
|
36
|
+
}
|
|
37
|
+
return resolved;
|
|
38
|
+
}
|
|
39
|
+
/** Relativize an absolute in-workspace path for display/durable records. */
|
|
40
|
+
export function toWorkspaceRelative(workspaceRoot, absolute) {
|
|
41
|
+
const relative = path.relative(path.resolve(workspaceRoot), path.resolve(absolute));
|
|
42
|
+
return relative.split(path.sep).join('/');
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Capture one URL snapshot through the web seam.
|
|
46
|
+
* @param deps - web seam, deadline, workspace root.
|
|
47
|
+
* @param url - the URL to fetch.
|
|
48
|
+
* @param signal - caller cancellation.
|
|
49
|
+
* @returns the snapshot (throws {@link CaptureError} on every failure).
|
|
50
|
+
*/
|
|
51
|
+
export async function captureFromWeb(deps, url, signal) {
|
|
52
|
+
if (deps.web === undefined) {
|
|
53
|
+
throw new CaptureError('WEB_UNAVAILABLE', 'the web capability (ctx.web) is not mounted in this composition; pass `content` explicitly or load @deepseek-ai/dsh-web with a fetch provider');
|
|
54
|
+
}
|
|
55
|
+
const timeout = AbortSignal.timeout(deps.fetchTimeoutMs);
|
|
56
|
+
const linked = signal === undefined ? timeout : AbortSignal.any([signal, timeout]);
|
|
57
|
+
let result;
|
|
58
|
+
try {
|
|
59
|
+
result = await deps.web.fetch({ url }, linked);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (timeout.aborted && (signal === undefined || !signal.aborted)) {
|
|
63
|
+
throw new CaptureError('FETCH_TIMEOUT', `fetch of ${url} exceeded the configured fetchTimeoutMs ${deps.fetchTimeoutMs}`);
|
|
64
|
+
}
|
|
65
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
66
|
+
throw new CaptureError('FETCH_FAILED', `fetch of ${url} failed: ${message}`);
|
|
67
|
+
}
|
|
68
|
+
if (result.statusCode < 200 || result.statusCode >= 300) {
|
|
69
|
+
throw new CaptureError('FETCH_STATUS', `fetch of ${url} returned HTTP ${result.statusCode}; no snapshot captured`);
|
|
70
|
+
}
|
|
71
|
+
return { content: result.body.content, origin: result.url };
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Capture one workspace file snapshot.
|
|
75
|
+
* @param deps - workspace root (the web fields are unused here).
|
|
76
|
+
* @param origin - the workspace-relative path.
|
|
77
|
+
* @returns the snapshot (throws {@link CaptureError} when unreadable).
|
|
78
|
+
*/
|
|
79
|
+
export async function captureFromFile(deps, origin) {
|
|
80
|
+
const absolute = resolveWorkspacePath(deps.workspaceRoot, origin);
|
|
81
|
+
let content;
|
|
82
|
+
try {
|
|
83
|
+
content = await readFile(absolute, 'utf8');
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
throw new CaptureError('ORIGIN_UNREADABLE', `cannot read ${JSON.stringify(origin)}: ${error.message}`);
|
|
87
|
+
}
|
|
88
|
+
return { content, origin: toWorkspaceRelative(deps.workspaceRoot, absolute) };
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Capture one snapshot from any supported origin.
|
|
92
|
+
* @param deps - web seam, deadline, workspace root.
|
|
93
|
+
* @param origin - URL or workspace path.
|
|
94
|
+
* @param signal - caller cancellation.
|
|
95
|
+
* @returns the snapshot.
|
|
96
|
+
*/
|
|
97
|
+
export async function captureSnapshot(deps, origin, signal) {
|
|
98
|
+
return isUrlOrigin(origin) ? captureFromWeb(deps, origin, signal) : captureFromFile(deps, origin);
|
|
99
|
+
}
|
|
100
|
+
// ── Topic gathering (the optional `gather: true` convenience) ───────────────
|
|
101
|
+
/** Search depth → how many sources are fetched for snapshot capture. */
|
|
102
|
+
export const GATHER_DEPTH_RESULTS = { quick: 3, standard: 5, deep: 8 };
|
|
103
|
+
/**
|
|
104
|
+
* Run one search over the topic and capture snapshots for the top sources.
|
|
105
|
+
* Captured snapshots are registered through `register`; uncaptured sources
|
|
106
|
+
* land in the gap list with their reason — gathering never fabricates
|
|
107
|
+
* evidence and never auto-assembles.
|
|
108
|
+
* @param deps - web seam, deadline, workspace root.
|
|
109
|
+
* @param topic - the research topic.
|
|
110
|
+
* @param depth - quick | standard | deep.
|
|
111
|
+
* @param signal - caller cancellation.
|
|
112
|
+
* @param register - ledger registration callback for captured snapshots.
|
|
113
|
+
* @returns candidates plus gaps.
|
|
114
|
+
*/
|
|
115
|
+
export async function gatherCandidates(deps, topic, depth, signal, register) {
|
|
116
|
+
if (deps.web === undefined) {
|
|
117
|
+
throw new CaptureError('WEB_UNAVAILABLE', 'the web capability (ctx.web) is not mounted in this composition; gather needs @deepseek-ai/dsh-web with a search provider');
|
|
118
|
+
}
|
|
119
|
+
const maxResults = GATHER_DEPTH_RESULTS[depth];
|
|
120
|
+
let search;
|
|
121
|
+
try {
|
|
122
|
+
search = await deps.web.search({ query: topic, maxResults }, signal);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
126
|
+
throw new CaptureError('FETCH_FAILED', `search for ${JSON.stringify(topic)} failed: ${message}`);
|
|
127
|
+
}
|
|
128
|
+
const candidates = [];
|
|
129
|
+
const gaps = [];
|
|
130
|
+
for (const source of search.sources) {
|
|
131
|
+
try {
|
|
132
|
+
const snapshot = await captureFromWeb(deps, source.url, signal);
|
|
133
|
+
const record = await register({
|
|
134
|
+
title: source.title ?? source.url,
|
|
135
|
+
origin: snapshot.origin,
|
|
136
|
+
content: snapshot.content,
|
|
137
|
+
});
|
|
138
|
+
candidates.push({
|
|
139
|
+
url: source.url,
|
|
140
|
+
...(source.title === undefined ? {} : { title: source.title }),
|
|
141
|
+
...(source.snippet === undefined ? {} : { snippet: source.snippet }),
|
|
142
|
+
status: 'captured',
|
|
143
|
+
evidenceId: record.id,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
const reason = error instanceof CaptureError ? `${error.code}: ${error.message}` : String(error);
|
|
148
|
+
candidates.push({
|
|
149
|
+
url: source.url,
|
|
150
|
+
...(source.title === undefined ? {} : { title: source.title }),
|
|
151
|
+
...(source.snippet === undefined ? {} : { snippet: source.snippet }),
|
|
152
|
+
status: 'uncaptured',
|
|
153
|
+
reason,
|
|
154
|
+
});
|
|
155
|
+
gaps.push(`no snapshot for ${source.url} (${reason}) — add it with evidence_add once content is available`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (search.truncated)
|
|
159
|
+
gaps.push(`search returned more than ${maxResults} sources; only the top ${maxResults} were considered`);
|
|
160
|
+
if (candidates.every(candidate => candidate.status === 'uncaptured')) {
|
|
161
|
+
gaps.push('no evidence was captured; the report cannot be assembled until at least one snapshot lands in the ledger');
|
|
162
|
+
}
|
|
163
|
+
return { topic, candidates, gaps };
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=gather.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gather.js","sourceRoot":"","sources":["../../src/gather.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dsh-research-report` — a domain-agnostic verifiable research-report engine
|
|
3
|
+
* for DeepSeek Harness. A content-addressed evidence ledger (claim ↔ snapshot
|
|
4
|
+
* binding, tamper-evident) plus versioned sealed reports: every claim carries
|
|
5
|
+
* a verification verdict, and the manifest hash seals the report directory.
|
|
6
|
+
* Retrieval orchestration is deliberately NOT re-implemented here — evidence
|
|
7
|
+
* gathering reuses the official `ctx.web` seam and long runs ride `ctx.jobs`.
|
|
8
|
+
*
|
|
9
|
+
* One package carries the complete capability seam: `service.ts` is the
|
|
10
|
+
* Service Definition (`ctx.researchReport`, with the byte-frozen assemble
|
|
11
|
+
* contract), `provider-local.ts` is the local Provider, and `tools/` the
|
|
12
|
+
* model-facing Consumers.
|
|
13
|
+
*
|
|
14
|
+
* Function plugin — no default export (the Loader unwraps
|
|
15
|
+
* `exports.default ?? exports`, and a stray default would discard
|
|
16
|
+
* `name`/`inject`/`Config`/`apply`).
|
|
17
|
+
* @module dsh-research-report
|
|
18
|
+
*/
|
|
19
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
20
|
+
import { Config } from './config.js';
|
|
21
|
+
export declare const name = "research-report";
|
|
22
|
+
/**
|
|
23
|
+
* Public services only. `web` (evidence capture) and `jobs` (background
|
|
24
|
+
* assembly) are deliberately OPTIONAL and resolved with `ctx.get` at call
|
|
25
|
+
* time: a composition without them still mounts, and the affected paths fail
|
|
26
|
+
* loud with an explicit reason.
|
|
27
|
+
*/
|
|
28
|
+
export declare const inject: string[];
|
|
29
|
+
export { Config, resolveConfig } from './config.js';
|
|
30
|
+
export type { ResolvedConfig } from './config.js';
|
|
31
|
+
export { VERSION } from './version.js';
|
|
32
|
+
export { ResearchReportService } from './service.js';
|
|
33
|
+
export type { AddEvidenceInput, AssembleContext, AssembleReportRequest, AssembleReportResult, ClaimRegistration, ClaimVerdict, ClaimView, EvidenceInput, EvidenceIntegrity, EvidenceRecord, EvidenceView, LedgerSummary, ReportSectionInput, StoredVerdict, VerdictStatus, } from './service.js';
|
|
34
|
+
export { EvidenceLedger, LedgerError, sha256Of } from './ledger.js';
|
|
35
|
+
export type { LedgerClaimLine, LedgerIndexLine, LedgerVerdictLine } from './ledger.js';
|
|
36
|
+
export { combineOutcomes, contextLabelOf, extractCitations, mapBridgeResults, normalizeNumber, verifyClaimText, } from './verify.js';
|
|
37
|
+
export type { ByteCheckOutcome, Citation, CitationCheckRequest, CitationCheckResult, DataQualityBridge, } from './verify.js';
|
|
38
|
+
export { CONTRADICTED_MARK, MANIFEST_SCHEMA, RequestValidationError, UNVERIFIED_MARK, buildManifest, configFingerprint, renderReportMarkdown, serializeManifest, slugify, validateAssembleRequest, versionIdOf, } from './assemble.js';
|
|
39
|
+
export type { ReportManifest, ReportPlan } from './assemble.js';
|
|
40
|
+
export { CaptureError, GATHER_DEPTH_RESULTS, captureFromFile, captureFromWeb, captureSnapshot, gatherCandidates, isUrlOrigin, resolveWorkspacePath, toWorkspaceRelative, } from './gather.js';
|
|
41
|
+
export type { CaptureDeps, GatherCandidate, GatherOutcome } from './gather.js';
|
|
42
|
+
export { LocalResearchReportService, ResearchReportError } from './provider-local.js';
|
|
43
|
+
/**
|
|
44
|
+
* Mount the engine: resolve config (fail loud), construct the local provider
|
|
45
|
+
* (registering `ctx.researchReport` on this fiber), register the three tools,
|
|
46
|
+
* and contribute the short prompt section.
|
|
47
|
+
* @param ctx - the plugin context (host).
|
|
48
|
+
* @param config - raw plugin config.
|
|
49
|
+
*/
|
|
50
|
+
export declare function apply(ctx: Context, config: Config): void;
|
|
51
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,EAAE,MAAM,EAAiB,MAAM,aAAa,CAAA;AAMnD,eAAO,MAAM,IAAI,oBAAoB,CAAA;AAErC;;;;;GAKG;AACH,eAAO,MAAM,MAAM,UAA4B,CAAA;AAE/C,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACnD,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AACpD,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,aAAa,GACd,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACnE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACtF,OAAO,EACL,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAA;AACpB,YAAY,EACV,gBAAgB,EAChB,QAAQ,EACR,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,OAAO,EACP,uBAAuB,EACvB,WAAW,GACZ,MAAM,eAAe,CAAA;AACtB,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC/D,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,eAAe,EACf,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC9E,OAAO,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAQrF;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAqBxD"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dsh-research-report` — a domain-agnostic verifiable research-report engine
|
|
3
|
+
* for DeepSeek Harness. A content-addressed evidence ledger (claim ↔ snapshot
|
|
4
|
+
* binding, tamper-evident) plus versioned sealed reports: every claim carries
|
|
5
|
+
* a verification verdict, and the manifest hash seals the report directory.
|
|
6
|
+
* Retrieval orchestration is deliberately NOT re-implemented here — evidence
|
|
7
|
+
* gathering reuses the official `ctx.web` seam and long runs ride `ctx.jobs`.
|
|
8
|
+
*
|
|
9
|
+
* One package carries the complete capability seam: `service.ts` is the
|
|
10
|
+
* Service Definition (`ctx.researchReport`, with the byte-frozen assemble
|
|
11
|
+
* contract), `provider-local.ts` is the local Provider, and `tools/` the
|
|
12
|
+
* model-facing Consumers.
|
|
13
|
+
*
|
|
14
|
+
* Function plugin — no default export (the Loader unwraps
|
|
15
|
+
* `exports.default ?? exports`, and a stray default would discard
|
|
16
|
+
* `name`/`inject`/`Config`/`apply`).
|
|
17
|
+
* @module dsh-research-report
|
|
18
|
+
*/
|
|
19
|
+
import { resolveConfig } from "./config.js";
|
|
20
|
+
import { LocalResearchReportService } from "./provider-local.js";
|
|
21
|
+
import { makeEvidenceAddTool } from "./tools/evidence-add.js";
|
|
22
|
+
import { makeLedgerQueryTool } from "./tools/ledger-query.js";
|
|
23
|
+
import { makeResearchReportTool } from "./tools/research-report.js";
|
|
24
|
+
export const name = 'research-report';
|
|
25
|
+
/**
|
|
26
|
+
* Public services only. `web` (evidence capture) and `jobs` (background
|
|
27
|
+
* assembly) are deliberately OPTIONAL and resolved with `ctx.get` at call
|
|
28
|
+
* time: a composition without them still mounts, and the affected paths fail
|
|
29
|
+
* loud with an explicit reason.
|
|
30
|
+
*/
|
|
31
|
+
export const inject = ['tools', 'systemPrompt'];
|
|
32
|
+
export { Config, resolveConfig } from "./config.js";
|
|
33
|
+
export { VERSION } from "./version.js";
|
|
34
|
+
export { ResearchReportService } from "./service.js";
|
|
35
|
+
export { EvidenceLedger, LedgerError, sha256Of } from "./ledger.js";
|
|
36
|
+
export { combineOutcomes, contextLabelOf, extractCitations, mapBridgeResults, normalizeNumber, verifyClaimText, } from "./verify.js";
|
|
37
|
+
export { CONTRADICTED_MARK, MANIFEST_SCHEMA, RequestValidationError, UNVERIFIED_MARK, buildManifest, configFingerprint, renderReportMarkdown, serializeManifest, slugify, validateAssembleRequest, versionIdOf, } from "./assemble.js";
|
|
38
|
+
export { CaptureError, GATHER_DEPTH_RESULTS, captureFromFile, captureFromWeb, captureSnapshot, gatherCandidates, isUrlOrigin, resolveWorkspacePath, toWorkspaceRelative, } from "./gather.js";
|
|
39
|
+
export { LocalResearchReportService, ResearchReportError } from "./provider-local.js";
|
|
40
|
+
/** The short prompt section: one role statement plus the workflow. */
|
|
41
|
+
const PROMPT_SECTION = [
|
|
42
|
+
'You have a verifiable research-report engine (dsh-research-report) whose reports prove every claim against stored evidence bytes.',
|
|
43
|
+
'When asked for a research deliverable: register evidence snapshots with evidence_add (URL or workspace path), then call research_report with sections whose paragraphs cite claim ids bound to those evidence ids. Every claim is verified against the stored snapshot bytes; unverified or contradicted claims stay visibly marked in the sealed report — never paper over them. ledger_query reads bindings and verdicts back.',
|
|
44
|
+
].join('\n');
|
|
45
|
+
/**
|
|
46
|
+
* Mount the engine: resolve config (fail loud), construct the local provider
|
|
47
|
+
* (registering `ctx.researchReport` on this fiber), register the three tools,
|
|
48
|
+
* and contribute the short prompt section.
|
|
49
|
+
* @param ctx - the plugin context (host).
|
|
50
|
+
* @param config - raw plugin config.
|
|
51
|
+
*/
|
|
52
|
+
export function apply(ctx, config) {
|
|
53
|
+
const resolved = resolveConfig(config);
|
|
54
|
+
const logger = ctx.logger('research-report');
|
|
55
|
+
if (!resolved.enabled) {
|
|
56
|
+
logger.info('disabled: enabled is false — no service, tools, or prompt section are mounted');
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
// The provider registers itself as ctx.researchReport on construction and
|
|
60
|
+
// is unregistered with this fiber (Service base semantics).
|
|
61
|
+
const service = new LocalResearchReportService(ctx, resolved, process.cwd());
|
|
62
|
+
ctx.effect(() => ctx.tools.register(makeEvidenceAddTool(service)), 'research-report: evidence_add tool');
|
|
63
|
+
ctx.effect(() => ctx.tools.register(makeResearchReportTool({ ctx, service })), 'research-report: research_report tool');
|
|
64
|
+
ctx.effect(() => ctx.tools.register(makeLedgerQueryTool(service)), 'research-report: ledger_query tool');
|
|
65
|
+
ctx.systemPrompt.section({
|
|
66
|
+
name: 'dsh-research-report:workflow',
|
|
67
|
+
order: 10,
|
|
68
|
+
text: PROMPT_SECTION,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,EAAU,aAAa,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAEnE,MAAM,CAAC,MAAM,IAAI,GAAG,iBAAiB,CAAA;AAErC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,cAAc,CAAC,CAAA;AAE/C,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAkBpD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEnE,OAAO,EACL,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAA;AAQpB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,OAAO,EACP,uBAAuB,EACvB,WAAW,GACZ,MAAM,eAAe,CAAA;AAEtB,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,eAAe,EACf,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAErF,sEAAsE;AACtE,MAAM,cAAc,GAAG;IACrB,mIAAmI;IACnI,kaAAka;CACna,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAEZ;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAC,GAAY,EAAE,MAAc;IAChD,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;IACtC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAA;IAC5C,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC,+EAA+E,CAAC,CAAA;QAC5F,OAAM;IACR,CAAC;IAED,0EAA0E;IAC1E,4DAA4D;IAC5D,MAAM,OAAO,GAAG,IAAI,0BAA0B,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;IAE5E,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,EAAE,oCAAoC,CAAC,CAAA;IACxG,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,uCAAuC,CAAC,CAAA;IACvH,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,EAAE,oCAAoC,CAAC,CAAA;IAExG,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC;QACvB,IAAI,EAAE,8BAA8B;QACpC,KAAK,EAAE,EAAE;QACT,IAAI,EAAE,cAAc;KACrB,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The evidence ledger: a content-addressed snapshot store with JSONL journals.
|
|
3
|
+
*
|
|
4
|
+
* Layout under the configured `ledgerRoot`:
|
|
5
|
+
* - `objects/<sha256>` — one immutable snapshot per content hash (same content
|
|
6
|
+
* is stored exactly once; an "update" is a new object, history is never
|
|
7
|
+
* rewritten).
|
|
8
|
+
* - `index.jsonl` — evidence registrations: id → hash, origin, capturedAt,
|
|
9
|
+
* title, bytes. Append-only.
|
|
10
|
+
* - `claims.jsonl` — claim registrations: id → text, evidenceIds, optional
|
|
11
|
+
* dataset bridge fields. Append-only.
|
|
12
|
+
* - `verdicts.jsonl` — verification verdicts; the latest line per claim wins.
|
|
13
|
+
*
|
|
14
|
+
* Tamper detection is the point of the design: every content read recomputes
|
|
15
|
+
* the SHA-256 of the object file and compares it against the indexed hash —
|
|
16
|
+
* a mismatch surfaces as `tampered`, a deleted object as `missing`.
|
|
17
|
+
*
|
|
18
|
+
* This module is pure Node (zero DSH imports) so it stays testable in
|
|
19
|
+
* isolation; policy (size caps, fetch) lives in the provider.
|
|
20
|
+
*
|
|
21
|
+
* @module dsh-research-report/ledger
|
|
22
|
+
*/
|
|
23
|
+
/** SHA-256 hex of one UTF-8 string. */
|
|
24
|
+
export declare function sha256Of(content: string): string;
|
|
25
|
+
/** Error codes the ledger reports. */
|
|
26
|
+
export type LedgerErrorCode = 'ID_CONFLICT' | 'JOURNAL_CORRUPT' | 'IO';
|
|
27
|
+
/** A loud ledger failure (audit state must never degrade silently). */
|
|
28
|
+
export declare class LedgerError extends Error {
|
|
29
|
+
/** The machine-routable failure code. */
|
|
30
|
+
readonly code: LedgerErrorCode;
|
|
31
|
+
constructor(code: LedgerErrorCode, message: string);
|
|
32
|
+
}
|
|
33
|
+
/** One line of `index.jsonl` — the durable evidence record. */
|
|
34
|
+
export interface LedgerIndexLine {
|
|
35
|
+
id: string;
|
|
36
|
+
hash: string;
|
|
37
|
+
title: string;
|
|
38
|
+
origin: string;
|
|
39
|
+
capturedAt: string;
|
|
40
|
+
bytes: number;
|
|
41
|
+
}
|
|
42
|
+
/** One line of `claims.jsonl` — the durable claim registration. */
|
|
43
|
+
export interface LedgerClaimLine {
|
|
44
|
+
id: string;
|
|
45
|
+
text: string;
|
|
46
|
+
evidenceIds: string[];
|
|
47
|
+
dataset?: string;
|
|
48
|
+
citations?: Array<{
|
|
49
|
+
id: string;
|
|
50
|
+
path: string;
|
|
51
|
+
value: number | string;
|
|
52
|
+
tolerance?: number;
|
|
53
|
+
}>;
|
|
54
|
+
registeredAt: string;
|
|
55
|
+
}
|
|
56
|
+
/** One line of `verdicts.jsonl` — the durable verdict record. */
|
|
57
|
+
export interface LedgerVerdictLine {
|
|
58
|
+
claimId: string;
|
|
59
|
+
status: 'verified' | 'unverified' | 'contradicted';
|
|
60
|
+
note?: string;
|
|
61
|
+
at: string;
|
|
62
|
+
}
|
|
63
|
+
/** Outcome of one {@link EvidenceLedger.putEvidence}. */
|
|
64
|
+
export interface PutOutcome {
|
|
65
|
+
/** The durable record (the existing one when deduplicated). */
|
|
66
|
+
record: LedgerIndexLine;
|
|
67
|
+
/** True when this call appended a new registration. */
|
|
68
|
+
created: boolean;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The content-addressed evidence ledger. Writes are serialized through an
|
|
72
|
+
* internal promise queue so concurrent tool calls cannot interleave journals.
|
|
73
|
+
*/
|
|
74
|
+
export declare class EvidenceLedger {
|
|
75
|
+
/** Absolute ledger root directory. */
|
|
76
|
+
readonly root: string;
|
|
77
|
+
/** Write serialization chain (never rejects — each link absorbs the previous error). */
|
|
78
|
+
private queue;
|
|
79
|
+
/**
|
|
80
|
+
* @param root - absolute ledger root directory.
|
|
81
|
+
*/
|
|
82
|
+
constructor(root: string);
|
|
83
|
+
private get objectsDir();
|
|
84
|
+
private get indexFile();
|
|
85
|
+
private get claimsFile();
|
|
86
|
+
private get verdictsFile();
|
|
87
|
+
/** Run `work` after all previously queued writes settle. */
|
|
88
|
+
private enqueue;
|
|
89
|
+
/** Ensure the directory layout exists. */
|
|
90
|
+
private ensureLayout;
|
|
91
|
+
/** Write one snapshot object atomically (tmp + rename); no-op when present. */
|
|
92
|
+
private writeObject;
|
|
93
|
+
/**
|
|
94
|
+
* Register one evidence snapshot. Same content dedupes to the stored object;
|
|
95
|
+
* a caller-chosen id that already exists with DIFFERENT content is refused
|
|
96
|
+
* loudly (history is never rewritten).
|
|
97
|
+
* @param input - id (optional), title, origin, content, capturedAt.
|
|
98
|
+
* @returns the record plus whether this call created it.
|
|
99
|
+
*/
|
|
100
|
+
putEvidence(input: {
|
|
101
|
+
id?: string;
|
|
102
|
+
title: string;
|
|
103
|
+
origin: string;
|
|
104
|
+
content: string;
|
|
105
|
+
capturedAt: string;
|
|
106
|
+
}): Promise<PutOutcome>;
|
|
107
|
+
/**
|
|
108
|
+
* Register claims (id → text, evidenceIds). Re-registering a claim id with
|
|
109
|
+
* a different text or different bindings is refused loudly.
|
|
110
|
+
* @param claims - the registrations to append.
|
|
111
|
+
* @param registeredAt - ISO-8601 registration time.
|
|
112
|
+
* @returns the durable claim lines (existing lines for idempotent repeats).
|
|
113
|
+
*/
|
|
114
|
+
registerClaims(claims: Array<Omit<LedgerClaimLine, 'registeredAt'>>, registeredAt: string): Promise<LedgerClaimLine[]>;
|
|
115
|
+
/**
|
|
116
|
+
* Append one verdict (latest per claim wins on read).
|
|
117
|
+
* @param verdict - claimId, status, optional note.
|
|
118
|
+
* @param at - ISO-8601 write time.
|
|
119
|
+
*/
|
|
120
|
+
recordVerdict(verdict: Omit<LedgerVerdictLine, 'at'>, at: string): Promise<void>;
|
|
121
|
+
/**
|
|
122
|
+
* Read the evidence index.
|
|
123
|
+
* @returns every registration in append order.
|
|
124
|
+
*/
|
|
125
|
+
listEvidence(): Promise<LedgerIndexLine[]>;
|
|
126
|
+
/**
|
|
127
|
+
* Read one evidence registration.
|
|
128
|
+
* @param id - the ledger id.
|
|
129
|
+
* @returns the record, or undefined when unknown.
|
|
130
|
+
*/
|
|
131
|
+
getEvidence(id: string): Promise<LedgerIndexLine | undefined>;
|
|
132
|
+
/**
|
|
133
|
+
* Read every claim registration.
|
|
134
|
+
* @returns every claim in append order.
|
|
135
|
+
*/
|
|
136
|
+
listClaims(): Promise<LedgerClaimLine[]>;
|
|
137
|
+
/**
|
|
138
|
+
* Read one claim registration.
|
|
139
|
+
* @param id - the claim id.
|
|
140
|
+
* @returns the claim line, or undefined when unknown.
|
|
141
|
+
*/
|
|
142
|
+
getClaim(id: string): Promise<LedgerClaimLine | undefined>;
|
|
143
|
+
/**
|
|
144
|
+
* Fold the verdict journal to the latest verdict per claim.
|
|
145
|
+
* @returns claimId → latest stored verdict.
|
|
146
|
+
*/
|
|
147
|
+
latestVerdicts(): Promise<Map<string, LedgerVerdictLine>>;
|
|
148
|
+
/**
|
|
149
|
+
* Read one snapshot and recompute its hash — the tamper-detection path.
|
|
150
|
+
* @param id - the ledger id.
|
|
151
|
+
* @returns content plus integrity (`ok` | `tampered` | `missing`), or
|
|
152
|
+
* undefined when the id is unknown.
|
|
153
|
+
*/
|
|
154
|
+
readContent(id: string): Promise<{
|
|
155
|
+
content: string;
|
|
156
|
+
integrity: 'ok' | 'tampered' | 'missing';
|
|
157
|
+
} | undefined>;
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=ledger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../../src/ledger.ts"],"names":[],"mappings":"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"}
|