@mantra-ai/core 0.1.2 → 0.1.6
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/dist/analysis/block-filter.d.ts +20 -0
- package/dist/analysis/block-filter.d.ts.map +1 -0
- package/dist/analysis/block-filter.js +59 -0
- package/dist/analysis/block-filter.js.map +1 -0
- package/dist/analysis/extract-findings.d.ts +17 -0
- package/dist/analysis/extract-findings.d.ts.map +1 -0
- package/dist/analysis/extract-findings.js +79 -0
- package/dist/analysis/extract-findings.js.map +1 -0
- package/dist/analysis/generate-hypotheses.d.ts +16 -0
- package/dist/analysis/generate-hypotheses.d.ts.map +1 -0
- package/dist/analysis/generate-hypotheses.js +25 -0
- package/dist/analysis/generate-hypotheses.js.map +1 -0
- package/dist/analysis/index.d.ts +11 -0
- package/dist/analysis/index.d.ts.map +1 -0
- package/dist/analysis/index.js +6 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/analysis/prompts.d.ts +13 -0
- package/dist/analysis/prompts.d.ts.map +1 -0
- package/dist/analysis/prompts.js +140 -0
- package/dist/analysis/prompts.js.map +1 -0
- package/dist/analysis/schemas.d.ts +292 -0
- package/dist/analysis/schemas.d.ts.map +1 -0
- package/dist/analysis/schemas.js +99 -0
- package/dist/analysis/schemas.js.map +1 -0
- package/dist/analysis/types.d.ts +4 -0
- package/dist/analysis/types.d.ts.map +1 -0
- package/dist/analysis/types.js +2 -0
- package/dist/analysis/types.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/normalization/pdf/normalize.d.ts.map +1 -1
- package/dist/normalization/pdf/normalize.js +17 -1
- package/dist/normalization/pdf/normalize.js.map +1 -1
- package/dist/types/work.d.ts +0 -8
- package/dist/types/work.d.ts.map +1 -1
- package/dist/types/work.js +0 -68
- package/dist/types/work.js.map +1 -1
- package/dist/works/export/paper-formats.d.ts +29 -0
- package/dist/works/export/paper-formats.d.ts.map +1 -0
- package/dist/works/export/paper-formats.js +109 -0
- package/dist/works/export/paper-formats.js.map +1 -0
- package/dist/works/util/paper-metadata.d.ts +56 -0
- package/dist/works/util/paper-metadata.d.ts.map +1 -0
- package/dist/works/util/paper-metadata.js +66 -0
- package/dist/works/util/paper-metadata.js.map +1 -0
- package/dist/works/util/retry.d.ts +25 -0
- package/dist/works/util/retry.d.ts.map +1 -0
- package/dist/works/util/retry.js +45 -0
- package/dist/works/util/retry.js.map +1 -0
- package/dist/works/util/zotero-parsers.d.ts +20 -0
- package/dist/works/util/zotero-parsers.d.ts.map +1 -0
- package/dist/works/util/zotero-parsers.js +48 -0
- package/dist/works/util/zotero-parsers.js.map +1 -0
- package/package.json +16 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { NormalizedDoc } from "../normalization/normalized-doc-schema";
|
|
2
|
+
import type { SectionCategory } from "./types";
|
|
3
|
+
export interface FilteredBlock {
|
|
4
|
+
kind: "paragraph" | "figure" | "table";
|
|
5
|
+
plain_text: string;
|
|
6
|
+
label?: string;
|
|
7
|
+
order: number;
|
|
8
|
+
section_title?: string;
|
|
9
|
+
section_category: SectionCategory;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Returns blocks belonging to the given section categories, sorted by `order`.
|
|
13
|
+
*
|
|
14
|
+
* Blocks carry `section_id` / `path_anchor` but not category directly, so we
|
|
15
|
+
* join through the sections array. For each block we:
|
|
16
|
+
* 1. Look up `block.section_id` in the section-ID map
|
|
17
|
+
* 2. If no match, walk `block.path_anchor` ancestors to find a categorised section
|
|
18
|
+
*/
|
|
19
|
+
export declare function getBlocksByCategory(doc: NormalizedDoc, categories: SectionCategory[]): FilteredBlock[];
|
|
20
|
+
//# sourceMappingURL=block-filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-filter.d.ts","sourceRoot":"","sources":["../../src/analysis/block-filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,eAAe,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,aAAa,EAClB,UAAU,EAAE,eAAe,EAAE,GAC5B,aAAa,EAAE,CAqCjB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns blocks belonging to the given section categories, sorted by `order`.
|
|
3
|
+
*
|
|
4
|
+
* Blocks carry `section_id` / `path_anchor` but not category directly, so we
|
|
5
|
+
* join through the sections array. For each block we:
|
|
6
|
+
* 1. Look up `block.section_id` in the section-ID map
|
|
7
|
+
* 2. If no match, walk `block.path_anchor` ancestors to find a categorised section
|
|
8
|
+
*/
|
|
9
|
+
export function getBlocksByCategory(doc, categories) {
|
|
10
|
+
const blocks = doc.blocks ?? [];
|
|
11
|
+
const sections = doc.sections ?? [];
|
|
12
|
+
if (blocks.length === 0)
|
|
13
|
+
return [];
|
|
14
|
+
const catSet = new Set(categories);
|
|
15
|
+
// Map section anchor -> { category, title }
|
|
16
|
+
const byAnchor = new Map();
|
|
17
|
+
// Map section id -> same info (id may differ from anchor for some docs)
|
|
18
|
+
const byId = new Map();
|
|
19
|
+
for (const sec of sections) {
|
|
20
|
+
if (!sec.category)
|
|
21
|
+
continue;
|
|
22
|
+
const info = { category: sec.category, title: sec.title };
|
|
23
|
+
byAnchor.set(sec.anchor, info);
|
|
24
|
+
if (sec.id)
|
|
25
|
+
byId.set(sec.id, info);
|
|
26
|
+
}
|
|
27
|
+
const matched = [];
|
|
28
|
+
for (const block of blocks) {
|
|
29
|
+
const info = resolveCategory(block.section_id, block.path_anchor, byId, byAnchor);
|
|
30
|
+
if (!info || !catSet.has(info.category))
|
|
31
|
+
continue;
|
|
32
|
+
matched.push({
|
|
33
|
+
kind: block.kind,
|
|
34
|
+
plain_text: block.plain_text ?? "",
|
|
35
|
+
label: "label" in block ? (block.label ?? undefined) : undefined,
|
|
36
|
+
order: block.order ?? 0,
|
|
37
|
+
section_title: info.title,
|
|
38
|
+
section_category: info.category,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
matched.sort((a, b) => a.order - b.order);
|
|
42
|
+
return matched;
|
|
43
|
+
}
|
|
44
|
+
function resolveCategory(sectionId, pathAnchor, byId, byAnchor) {
|
|
45
|
+
// Direct ID lookup
|
|
46
|
+
const direct = byId.get(sectionId) ?? byAnchor.get(sectionId);
|
|
47
|
+
if (direct)
|
|
48
|
+
return direct;
|
|
49
|
+
// Walk path_anchor ancestors (e.g. "body/sec-methods/sec-methods-1")
|
|
50
|
+
const parts = pathAnchor.split("/");
|
|
51
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
52
|
+
const ancestor = parts[i];
|
|
53
|
+
const info = byAnchor.get(ancestor) ?? byId.get(ancestor);
|
|
54
|
+
if (info)
|
|
55
|
+
return info;
|
|
56
|
+
}
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=block-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-filter.js","sourceRoot":"","sources":["../../src/analysis/block-filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { NormalizedDoc } from "../normalization/normalized-doc-schema";
|
|
2
|
+
import type { LLMResult } from "../ai/openai/types";
|
|
3
|
+
import { type PaperDigest } from "./schemas";
|
|
4
|
+
export interface ExtractFindingsOptions {
|
|
5
|
+
model?: string;
|
|
6
|
+
temperature?: number;
|
|
7
|
+
maxOutputTokens?: number;
|
|
8
|
+
maxAttempts?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Extract structured findings from a single NormalizedDoc.
|
|
12
|
+
*
|
|
13
|
+
* Filters to methods/results/discussion/limitations/conclusions blocks,
|
|
14
|
+
* falls back to all non-back-matter blocks if too few are found.
|
|
15
|
+
*/
|
|
16
|
+
export declare function extractFindings(doc: NormalizedDoc, opts?: ExtractFindingsOptions): Promise<LLMResult<PaperDigest>>;
|
|
17
|
+
//# sourceMappingURL=extract-findings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-findings.d.ts","sourceRoot":"","sources":["../../src/analysis/extract-findings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGpD,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AA+BhE,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,aAAa,EAClB,IAAI,CAAC,EAAE,sBAAsB,GAC5B,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CA+CjC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { generateWithSchema } from "../ai/openai/generate";
|
|
2
|
+
import { getBlocksByCategory } from "./block-filter";
|
|
3
|
+
import { PaperDigestSchema } from "./schemas";
|
|
4
|
+
import { buildExtractionPrompt } from "./prompts";
|
|
5
|
+
const EXTRACTION_CATEGORIES = [
|
|
6
|
+
"methods",
|
|
7
|
+
"results",
|
|
8
|
+
"results-discussion",
|
|
9
|
+
"discussion",
|
|
10
|
+
"limitations",
|
|
11
|
+
"conclusions",
|
|
12
|
+
];
|
|
13
|
+
const BACK_MATTER_CATEGORIES = [
|
|
14
|
+
"acknowledgements",
|
|
15
|
+
"data_availability",
|
|
16
|
+
"funding",
|
|
17
|
+
"competing_interests",
|
|
18
|
+
"author_contributions",
|
|
19
|
+
"abbreviations",
|
|
20
|
+
"glossary",
|
|
21
|
+
"publisher_note",
|
|
22
|
+
"provenance",
|
|
23
|
+
"trial_registration",
|
|
24
|
+
"code_availability",
|
|
25
|
+
"materials_availability",
|
|
26
|
+
"supplementary",
|
|
27
|
+
"appendices",
|
|
28
|
+
"notes",
|
|
29
|
+
];
|
|
30
|
+
/**
|
|
31
|
+
* Extract structured findings from a single NormalizedDoc.
|
|
32
|
+
*
|
|
33
|
+
* Filters to methods/results/discussion/limitations/conclusions blocks,
|
|
34
|
+
* falls back to all non-back-matter blocks if too few are found.
|
|
35
|
+
*/
|
|
36
|
+
export async function extractFindings(doc, opts) {
|
|
37
|
+
let blocks = getBlocksByCategory(doc, EXTRACTION_CATEGORIES);
|
|
38
|
+
// Fallback: use all blocks except back-matter when section categories are mostly "other"
|
|
39
|
+
if (blocks.length < 3) {
|
|
40
|
+
const allCategories = [
|
|
41
|
+
"abstract",
|
|
42
|
+
"introduction",
|
|
43
|
+
...EXTRACTION_CATEGORIES,
|
|
44
|
+
"ethics",
|
|
45
|
+
"other",
|
|
46
|
+
];
|
|
47
|
+
blocks = getBlocksByCategory(doc, allCategories);
|
|
48
|
+
}
|
|
49
|
+
// If still empty, use whatever blocks exist with a synthetic category
|
|
50
|
+
if (blocks.length === 0 && (doc.blocks?.length ?? 0) > 0) {
|
|
51
|
+
blocks = (doc.blocks ?? []).map((b, i) => ({
|
|
52
|
+
kind: b.kind,
|
|
53
|
+
plain_text: b.plain_text ?? "",
|
|
54
|
+
label: "label" in b ? (b.label ?? undefined) : undefined,
|
|
55
|
+
order: b.order ?? i,
|
|
56
|
+
section_category: "other",
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
59
|
+
const metadata = {
|
|
60
|
+
title: doc.metadata.title,
|
|
61
|
+
doi: doc.metadata.ids?.doi,
|
|
62
|
+
keywords: doc.metadata.keywords,
|
|
63
|
+
abstract: doc.metadata.abstract?.paragraphs?.join(" "),
|
|
64
|
+
};
|
|
65
|
+
const messages = buildExtractionPrompt(metadata, blocks);
|
|
66
|
+
return generateWithSchema({
|
|
67
|
+
messages,
|
|
68
|
+
schema: PaperDigestSchema,
|
|
69
|
+
options: {
|
|
70
|
+
model: opts?.model ?? "gpt-4o",
|
|
71
|
+
temperature: opts?.temperature ?? 0.1,
|
|
72
|
+
maxOutputTokens: opts?.maxOutputTokens ?? 4096,
|
|
73
|
+
},
|
|
74
|
+
retry: {
|
|
75
|
+
maxAttempts: opts?.maxAttempts ?? 3,
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=extract-findings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-findings.js","sourceRoot":"","sources":["../../src/analysis/extract-findings.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAoB,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAGlD,MAAM,qBAAqB,GAAsB;IAC/C,SAAS;IACT,SAAS;IACT,oBAAoB;IACpB,YAAY;IACZ,aAAa;IACb,aAAa;CACd,CAAC;AAEF,MAAM,sBAAsB,GAAsB;IAChD,kBAAkB;IAClB,mBAAmB;IACnB,SAAS;IACT,qBAAqB;IACrB,sBAAsB;IACtB,eAAe;IACf,UAAU;IACV,gBAAgB;IAChB,YAAY;IACZ,oBAAoB;IACpB,mBAAmB;IACnB,wBAAwB;IACxB,eAAe;IACf,YAAY;IACZ,OAAO;CACR,CAAC;AASF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAkB,EAClB,IAA6B;IAE7B,IAAI,MAAM,GAAG,mBAAmB,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;IAE7D,yFAAyF;IACzF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,aAAa,GAAsB;YACvC,UAAU;YACV,cAAc;YACd,GAAG,qBAAqB;YACxB,QAAQ;YACR,OAAO;SACR,CAAC;QACF,MAAM,GAAG,mBAAmB,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IACnD,CAAC;IAED,sEAAsE;IACtE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QACzD,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACzC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,EAAE;YAC9B,KAAK,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;YACxD,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;YACnB,gBAAgB,EAAE,OAA0B;SAC7C,CAAC,CAAC,CAAC;IACN,CAAC;IAED,MAAM,QAAQ,GAAG;QACf,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK;QACzB,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG;QAC1B,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,QAAQ;QAC/B,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC;KACvD,CAAC;IAEF,MAAM,QAAQ,GAAG,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAEzD,OAAO,kBAAkB,CAAc;QACrC,QAAQ;QACR,MAAM,EAAE,iBAAiB;QACzB,OAAO,EAAE;YACP,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,QAAQ;YAC9B,WAAW,EAAE,IAAI,EAAE,WAAW,IAAI,GAAG;YACrC,eAAe,EAAE,IAAI,EAAE,eAAe,IAAI,IAAI;SAC/C;QACD,KAAK,EAAE;YACL,WAAW,EAAE,IAAI,EAAE,WAAW,IAAI,CAAC;SACpC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { LLMResult } from "../ai/openai/types";
|
|
2
|
+
import { type HypothesisSet, type PaperDigest } from "./schemas";
|
|
3
|
+
export interface GenerateHypothesesOptions {
|
|
4
|
+
model?: string;
|
|
5
|
+
temperature?: number;
|
|
6
|
+
maxOutputTokens?: number;
|
|
7
|
+
maxAttempts?: number;
|
|
8
|
+
minPerType?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Synthesise hypotheses across multiple paper digests.
|
|
12
|
+
*
|
|
13
|
+
* Requires at least 2 digests for meaningful cross-paper reasoning.
|
|
14
|
+
*/
|
|
15
|
+
export declare function generateHypotheses(digests: PaperDigest[], opts?: GenerateHypothesesOptions): Promise<LLMResult<HypothesisSet>>;
|
|
16
|
+
//# sourceMappingURL=generate-hypotheses.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-hypotheses.d.ts","sourceRoot":"","sources":["../../src/analysis/generate-hypotheses.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAuB,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAGtF,MAAM,WAAW,yBAAyB;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,WAAW,EAAE,EACtB,IAAI,CAAC,EAAE,yBAAyB,GAC/B,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAgBnC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { generateWithSchema } from "../ai/openai/generate";
|
|
2
|
+
import { HypothesisSetSchema } from "./schemas";
|
|
3
|
+
import { buildHypothesisPrompt } from "./prompts";
|
|
4
|
+
/**
|
|
5
|
+
* Synthesise hypotheses across multiple paper digests.
|
|
6
|
+
*
|
|
7
|
+
* Requires at least 2 digests for meaningful cross-paper reasoning.
|
|
8
|
+
*/
|
|
9
|
+
export async function generateHypotheses(digests, opts) {
|
|
10
|
+
const minPerType = opts?.minPerType ?? 1;
|
|
11
|
+
const messages = buildHypothesisPrompt(digests, minPerType);
|
|
12
|
+
return generateWithSchema({
|
|
13
|
+
messages,
|
|
14
|
+
schema: HypothesisSetSchema,
|
|
15
|
+
options: {
|
|
16
|
+
model: opts?.model ?? "gpt-4o",
|
|
17
|
+
temperature: opts?.temperature ?? 0.4,
|
|
18
|
+
maxOutputTokens: opts?.maxOutputTokens ?? 8192,
|
|
19
|
+
},
|
|
20
|
+
retry: {
|
|
21
|
+
maxAttempts: opts?.maxAttempts ?? 3,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=generate-hypotheses.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-hypotheses.js","sourceRoot":"","sources":["../../src/analysis/generate-hypotheses.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAwC,MAAM,WAAW,CAAC;AACtF,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAUlD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAsB,EACtB,IAAgC;IAEhC,MAAM,UAAU,GAAG,IAAI,EAAE,UAAU,IAAI,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAE5D,OAAO,kBAAkB,CAAgB;QACvC,QAAQ;QACR,MAAM,EAAE,mBAAmB;QAC3B,OAAO,EAAE;YACP,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,QAAQ;YAC9B,WAAW,EAAE,IAAI,EAAE,WAAW,IAAI,GAAG;YACrC,eAAe,EAAE,IAAI,EAAE,eAAe,IAAI,IAAI;SAC/C;QACD,KAAK,EAAE;YACL,WAAW,EAAE,IAAI,EAAE,WAAW,IAAI,CAAC;SACpC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { getBlocksByCategory } from "./block-filter";
|
|
2
|
+
export type { FilteredBlock } from "./block-filter";
|
|
3
|
+
export { PaperDigestSchema, HypothesisSetSchema, } from "./schemas";
|
|
4
|
+
export type { PaperDigest, Hypothesis, HypothesisSet } from "./schemas";
|
|
5
|
+
export { buildExtractionPrompt, buildHypothesisPrompt } from "./prompts";
|
|
6
|
+
export { extractFindings } from "./extract-findings";
|
|
7
|
+
export type { ExtractFindingsOptions } from "./extract-findings";
|
|
8
|
+
export { generateHypotheses } from "./generate-hypotheses";
|
|
9
|
+
export type { GenerateHypothesesOptions } from "./generate-hypotheses";
|
|
10
|
+
export type { SectionCategory } from "./types";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analysis/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EACL,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAExE,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAEzE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,YAAY,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAEvE,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { getBlocksByCategory } from "./block-filter";
|
|
2
|
+
export { PaperDigestSchema, HypothesisSetSchema, } from "./schemas";
|
|
3
|
+
export { buildExtractionPrompt, buildHypothesisPrompt } from "./prompts";
|
|
4
|
+
export { extractFindings } from "./extract-findings";
|
|
5
|
+
export { generateHypotheses } from "./generate-hypotheses";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analysis/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EACL,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAEzE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ChatMessage } from "../ai/openai/types";
|
|
2
|
+
import type { FilteredBlock } from "./block-filter";
|
|
3
|
+
import type { PaperDigest } from "./schemas";
|
|
4
|
+
interface PaperMetadata {
|
|
5
|
+
title?: string;
|
|
6
|
+
doi?: string;
|
|
7
|
+
keywords?: string[];
|
|
8
|
+
abstract?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildExtractionPrompt(metadata: PaperMetadata, blocks: FilteredBlock[]): ChatMessage[];
|
|
11
|
+
export declare function buildHypothesisPrompt(digests: PaperDigest[], minPerType?: number): ChatMessage[];
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/analysis/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAI7C,UAAU,aAAa;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,aAAa,EAAE,GACtB,WAAW,EAAE,CAqEf;AAID,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,WAAW,EAAE,EACtB,UAAU,SAAI,GACb,WAAW,EAAE,CAwEf"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
export function buildExtractionPrompt(metadata, blocks) {
|
|
2
|
+
const system = {
|
|
3
|
+
role: "system",
|
|
4
|
+
content: [
|
|
5
|
+
"You are a domain-agnostic scientific analyst. Your task is to extract structured findings from a research paper.",
|
|
6
|
+
"",
|
|
7
|
+
"Extract the following from the provided paper text:",
|
|
8
|
+
"",
|
|
9
|
+
"TECHNIQUES: Every experimental, computational, or analytical method used. Categorise each as assay, imaging, sequencing, computational, statistical, synthesis, purification, or other. State its purpose in one sentence.",
|
|
10
|
+
"",
|
|
11
|
+
"SYSTEMS: Every biological system, model organism, cell line, protein, pathway, dataset, or software tool studied or used. Categorise each as organism, cell-line, tissue, protein, pathway, dataset, software, or other.",
|
|
12
|
+
"",
|
|
13
|
+
"CONDITIONS: Every experimental condition, treatment, control, comparison group, or key parameter. Assign role: treatment, control, comparison, or parameter.",
|
|
14
|
+
"",
|
|
15
|
+
"FINDINGS: Every distinct claim or result. State each as a single declarative sentence. Classify evidence_type (experimental, computational, statistical, observational, theoretical, review-synthesis), strength (strong, moderate, weak, preliminary), whether it is quantitative, and list related technique names.",
|
|
16
|
+
"",
|
|
17
|
+
"LIMITATIONS: Every stated or clearly implied limitation. Classify as sample-size, generalizability, methodology, scope, temporal, resource, reproducibility, or other.",
|
|
18
|
+
"",
|
|
19
|
+
"OPEN QUESTIONS: Questions the authors raise or that are clearly implied by the text. Mark each as stated or implied.",
|
|
20
|
+
"",
|
|
21
|
+
"Rules:",
|
|
22
|
+
"- Extract faithfully from the text. Never hallucinate data, statistics, or claims not present.",
|
|
23
|
+
"- Each finding must be atomic: one claim per entry.",
|
|
24
|
+
"- Include quantitative details (p-values, effect sizes, percentages) when present in the text.",
|
|
25
|
+
"- The domain field should capture the broad scientific area (e.g. 'molecular biology', 'computational neuroscience', 'organic chemistry').",
|
|
26
|
+
"- For paper_id, use the DOI if available, otherwise use a slug from the title.",
|
|
27
|
+
].join("\n"),
|
|
28
|
+
};
|
|
29
|
+
// Build section-grouped text
|
|
30
|
+
const sectionGroups = new Map();
|
|
31
|
+
for (const block of blocks) {
|
|
32
|
+
const key = block.section_title ?? block.section_category;
|
|
33
|
+
let group = sectionGroups.get(key);
|
|
34
|
+
if (!group) {
|
|
35
|
+
group = [];
|
|
36
|
+
sectionGroups.set(key, group);
|
|
37
|
+
}
|
|
38
|
+
if (block.kind === "figure" || block.kind === "table") {
|
|
39
|
+
const prefix = block.label ? `[${block.label}] ` : `[${block.kind}] `;
|
|
40
|
+
group.push(prefix + (block.plain_text || ""));
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
group.push(block.plain_text);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const bodyParts = [];
|
|
47
|
+
for (const [section, texts] of sectionGroups) {
|
|
48
|
+
bodyParts.push(`## ${section}\n${texts.join("\n\n")}`);
|
|
49
|
+
}
|
|
50
|
+
const metaParts = [];
|
|
51
|
+
if (metadata.title)
|
|
52
|
+
metaParts.push(`Title: ${metadata.title}`);
|
|
53
|
+
if (metadata.doi)
|
|
54
|
+
metaParts.push(`DOI: ${metadata.doi}`);
|
|
55
|
+
if (metadata.keywords?.length)
|
|
56
|
+
metaParts.push(`Keywords: ${metadata.keywords.join(", ")}`);
|
|
57
|
+
if (metadata.abstract)
|
|
58
|
+
metaParts.push(`Abstract: ${metadata.abstract}`);
|
|
59
|
+
const user = {
|
|
60
|
+
role: "user",
|
|
61
|
+
content: [
|
|
62
|
+
"# Paper Metadata",
|
|
63
|
+
metaParts.join("\n"),
|
|
64
|
+
"",
|
|
65
|
+
"# Paper Content",
|
|
66
|
+
bodyParts.join("\n\n"),
|
|
67
|
+
].join("\n"),
|
|
68
|
+
};
|
|
69
|
+
return [system, user];
|
|
70
|
+
}
|
|
71
|
+
// ── Hypothesis prompt (cross-paper) ─────────────────────────────────
|
|
72
|
+
export function buildHypothesisPrompt(digests, minPerType = 1) {
|
|
73
|
+
const system = {
|
|
74
|
+
role: "system",
|
|
75
|
+
content: [
|
|
76
|
+
"You are a scientific hypothesis generator. Given structured digests from multiple research papers, synthesise novel, testable hypotheses.",
|
|
77
|
+
"",
|
|
78
|
+
"Generate hypotheses in three categories:",
|
|
79
|
+
"",
|
|
80
|
+
"MECHANISTIC: Propose causal mechanisms that connect findings across papers. These should explain how observed phenomena relate or predict interactions between systems/pathways studied in different papers.",
|
|
81
|
+
"",
|
|
82
|
+
"METHODOLOGICAL: Propose novel combinations of techniques from different papers that could yield new insights, or identify methodological improvements suggested by comparing approaches across papers.",
|
|
83
|
+
"",
|
|
84
|
+
"GAP: Identify knowledge gaps revealed by contradictions, unexplored intersections, or limitations shared across papers, and formulate hypotheses that address them.",
|
|
85
|
+
"",
|
|
86
|
+
`Generate at least ${minPerType} hypothesis per category (${minPerType * 3} total minimum).`,
|
|
87
|
+
"",
|
|
88
|
+
"Rules:",
|
|
89
|
+
"- Each hypothesis must cite at least 2 papers by their paper_id.",
|
|
90
|
+
"- Each hypothesis must be testable and falsifiable.",
|
|
91
|
+
"- Each hypothesis must be novel: it should go beyond what any single paper concludes.",
|
|
92
|
+
"- Do not propose experiments requiring technology that does not currently exist.",
|
|
93
|
+
"- Provide a concrete testability assessment: the experimental approach, feasibility (straightforward, moderate, challenging), and key techniques needed.",
|
|
94
|
+
"- Assign confidence (high, moderate, low) based on strength of supporting evidence.",
|
|
95
|
+
"- Use H1, H2, H3... as hypothesis IDs.",
|
|
96
|
+
"- The domain_summary should describe the shared scientific landscape across all papers in 1-2 sentences.",
|
|
97
|
+
"- Identify cross_cutting_themes: recurring concepts, methods, or systems that appear in multiple papers.",
|
|
98
|
+
].join("\n"),
|
|
99
|
+
};
|
|
100
|
+
// Serialize digests
|
|
101
|
+
const digestTexts = digests.map((d, i) => {
|
|
102
|
+
const parts = [
|
|
103
|
+
`### Paper ${i + 1}: ${d.title}`,
|
|
104
|
+
`ID: ${d.paper_id}`,
|
|
105
|
+
`Domain: ${d.domain}`,
|
|
106
|
+
];
|
|
107
|
+
if (d.techniques.length > 0) {
|
|
108
|
+
parts.push(`Techniques: ${d.techniques.map((t) => `${t.name} (${t.category}: ${t.purpose})`).join("; ")}`);
|
|
109
|
+
}
|
|
110
|
+
if (d.systems.length > 0) {
|
|
111
|
+
parts.push(`Systems: ${d.systems.map((s) => `${s.name} (${s.type})`).join("; ")}`);
|
|
112
|
+
}
|
|
113
|
+
if (d.conditions.length > 0) {
|
|
114
|
+
parts.push(`Conditions: ${d.conditions.map((c) => `${c.description} [${c.role}]`).join("; ")}`);
|
|
115
|
+
}
|
|
116
|
+
if (d.findings.length > 0) {
|
|
117
|
+
parts.push("Findings:");
|
|
118
|
+
for (const f of d.findings) {
|
|
119
|
+
parts.push(` - ${f.claim} [${f.evidence_type}, ${f.strength}${f.quantitative ? ", quantitative" : ""}]`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (d.limitations.length > 0) {
|
|
123
|
+
parts.push(`Limitations: ${d.limitations.map((l) => `${l.description} (${l.type})`).join("; ")}`);
|
|
124
|
+
}
|
|
125
|
+
if (d.open_questions.length > 0) {
|
|
126
|
+
parts.push(`Open questions: ${d.open_questions.map((q) => `${q.question} [${q.source}]`).join("; ")}`);
|
|
127
|
+
}
|
|
128
|
+
return parts.join("\n");
|
|
129
|
+
});
|
|
130
|
+
const user = {
|
|
131
|
+
role: "user",
|
|
132
|
+
content: [
|
|
133
|
+
`# Paper Digests (${digests.length} papers)`,
|
|
134
|
+
"",
|
|
135
|
+
digestTexts.join("\n\n"),
|
|
136
|
+
].join("\n"),
|
|
137
|
+
};
|
|
138
|
+
return [system, user];
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/analysis/prompts.ts"],"names":[],"mappings":"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"}
|