mindgraph-core 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/dist/embeddings/embedder-interface.d.ts +15 -0
- package/dist/embeddings/embedder-interface.d.ts.map +1 -0
- package/dist/embeddings/embedder-interface.js +2 -0
- package/dist/embeddings/embedder-interface.js.map +1 -0
- package/dist/embeddings/ollama-embedder.d.ts +21 -0
- package/dist/embeddings/ollama-embedder.d.ts.map +1 -0
- package/dist/embeddings/ollama-embedder.js +78 -0
- package/dist/embeddings/ollama-embedder.js.map +1 -0
- package/dist/embeddings/transformers-embedder.d.ts +20 -0
- package/dist/embeddings/transformers-embedder.d.ts.map +1 -0
- package/dist/embeddings/transformers-embedder.js +61 -0
- package/dist/embeddings/transformers-embedder.js.map +1 -0
- package/dist/extraction/anthropic-extractor.d.ts +17 -0
- package/dist/extraction/anthropic-extractor.d.ts.map +1 -0
- package/dist/extraction/anthropic-extractor.js +43 -0
- package/dist/extraction/anthropic-extractor.js.map +1 -0
- package/dist/extraction/basic-extractor.d.ts +17 -0
- package/dist/extraction/basic-extractor.d.ts.map +1 -0
- package/dist/extraction/basic-extractor.js +135 -0
- package/dist/extraction/basic-extractor.js.map +1 -0
- package/dist/extraction/confidence-gate.d.ts +7 -0
- package/dist/extraction/confidence-gate.d.ts.map +1 -0
- package/dist/extraction/confidence-gate.js +13 -0
- package/dist/extraction/confidence-gate.js.map +1 -0
- package/dist/extraction/contradiction-detector.d.ts +46 -0
- package/dist/extraction/contradiction-detector.d.ts.map +1 -0
- package/dist/extraction/contradiction-detector.js +205 -0
- package/dist/extraction/contradiction-detector.js.map +1 -0
- package/dist/extraction/entity-index.d.ts +31 -0
- package/dist/extraction/entity-index.d.ts.map +1 -0
- package/dist/extraction/entity-index.js +90 -0
- package/dist/extraction/entity-index.js.map +1 -0
- package/dist/extraction/entity-resolver.d.ts +28 -0
- package/dist/extraction/entity-resolver.d.ts.map +1 -0
- package/dist/extraction/entity-resolver.js +111 -0
- package/dist/extraction/entity-resolver.js.map +1 -0
- package/dist/extraction/extractor-interface.d.ts +51 -0
- package/dist/extraction/extractor-interface.d.ts.map +1 -0
- package/dist/extraction/extractor-interface.js +2 -0
- package/dist/extraction/extractor-interface.js.map +1 -0
- package/dist/extraction/llm-extractor.d.ts +21 -0
- package/dist/extraction/llm-extractor.d.ts.map +1 -0
- package/dist/extraction/llm-extractor.js +97 -0
- package/dist/extraction/llm-extractor.js.map +1 -0
- package/dist/extraction/ollama-extractor.d.ts +18 -0
- package/dist/extraction/ollama-extractor.d.ts.map +1 -0
- package/dist/extraction/ollama-extractor.js +50 -0
- package/dist/extraction/ollama-extractor.js.map +1 -0
- package/dist/extraction/open-loop-detector.d.ts +24 -0
- package/dist/extraction/open-loop-detector.d.ts.map +1 -0
- package/dist/extraction/open-loop-detector.js +187 -0
- package/dist/extraction/open-loop-detector.js.map +1 -0
- package/dist/extraction/openai-extractor.d.ts +20 -0
- package/dist/extraction/openai-extractor.d.ts.map +1 -0
- package/dist/extraction/openai-extractor.js +44 -0
- package/dist/extraction/openai-extractor.js.map +1 -0
- package/dist/extraction/prompts/entity-extraction.d.ts +2 -0
- package/dist/extraction/prompts/entity-extraction.d.ts.map +1 -0
- package/dist/extraction/prompts/entity-extraction.js +42 -0
- package/dist/extraction/prompts/entity-extraction.js.map +1 -0
- package/dist/extraction/prompts/proposition-extraction.d.ts +2 -0
- package/dist/extraction/prompts/proposition-extraction.d.ts.map +1 -0
- package/dist/extraction/prompts/proposition-extraction.js +39 -0
- package/dist/extraction/prompts/proposition-extraction.js.map +1 -0
- package/dist/extraction/prompts/thought-extraction.d.ts +2 -0
- package/dist/extraction/prompts/thought-extraction.d.ts.map +1 -0
- package/dist/extraction/prompts/thought-extraction.js +41 -0
- package/dist/extraction/prompts/thought-extraction.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/ingestion/chunk-id.d.ts +27 -0
- package/dist/ingestion/chunk-id.d.ts.map +1 -0
- package/dist/ingestion/chunk-id.js +45 -0
- package/dist/ingestion/chunk-id.js.map +1 -0
- package/dist/ingestion/chunker.d.ts +29 -0
- package/dist/ingestion/chunker.d.ts.map +1 -0
- package/dist/ingestion/chunker.js +182 -0
- package/dist/ingestion/chunker.js.map +1 -0
- package/dist/ingestion/hasher.d.ts +7 -0
- package/dist/ingestion/hasher.d.ts.map +1 -0
- package/dist/ingestion/hasher.js +18 -0
- package/dist/ingestion/hasher.js.map +1 -0
- package/dist/ingestion/pipeline.d.ts +58 -0
- package/dist/ingestion/pipeline.d.ts.map +1 -0
- package/dist/ingestion/pipeline.js +653 -0
- package/dist/ingestion/pipeline.js.map +1 -0
- package/dist/models/citation.d.ts +2 -0
- package/dist/models/citation.d.ts.map +1 -0
- package/dist/models/citation.js +2 -0
- package/dist/models/citation.js.map +1 -0
- package/dist/models/extraction-result.d.ts +2 -0
- package/dist/models/extraction-result.d.ts.map +1 -0
- package/dist/models/extraction-result.js +2 -0
- package/dist/models/extraction-result.js.map +1 -0
- package/dist/models/query-result.d.ts +2 -0
- package/dist/models/query-result.d.ts.map +1 -0
- package/dist/models/query-result.js +2 -0
- package/dist/models/query-result.js.map +1 -0
- package/dist/query/answer-builder.d.ts +15 -0
- package/dist/query/answer-builder.d.ts.map +1 -0
- package/dist/query/answer-builder.js +51 -0
- package/dist/query/answer-builder.js.map +1 -0
- package/dist/query/citation-builder.d.ts +19 -0
- package/dist/query/citation-builder.d.ts.map +1 -0
- package/dist/query/citation-builder.js +54 -0
- package/dist/query/citation-builder.js.map +1 -0
- package/dist/query/graph-data.d.ts +39 -0
- package/dist/query/graph-data.d.ts.map +1 -0
- package/dist/query/graph-data.js +115 -0
- package/dist/query/graph-data.js.map +1 -0
- package/dist/query/graph-search.d.ts +43 -0
- package/dist/query/graph-search.d.ts.map +1 -0
- package/dist/query/graph-search.js +315 -0
- package/dist/query/graph-search.js.map +1 -0
- package/dist/query/query-engine.d.ts +41 -0
- package/dist/query/query-engine.d.ts.map +1 -0
- package/dist/query/query-engine.js +178 -0
- package/dist/query/query-engine.js.map +1 -0
- package/dist/query/semantic-search.d.ts +26 -0
- package/dist/query/semantic-search.d.ts.map +1 -0
- package/dist/query/semantic-search.js +132 -0
- package/dist/query/semantic-search.js.map +1 -0
- package/dist/schema/edge-types.d.ts +95 -0
- package/dist/schema/edge-types.d.ts.map +1 -0
- package/dist/schema/edge-types.js +6 -0
- package/dist/schema/edge-types.js.map +1 -0
- package/dist/schema/node-types.d.ts +100 -0
- package/dist/schema/node-types.d.ts.map +1 -0
- package/dist/schema/node-types.js +6 -0
- package/dist/schema/node-types.js.map +1 -0
- package/dist/schema/types.d.ts +134 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +52 -0
- package/dist/schema/types.js.map +1 -0
- package/dist/schema/validation.d.ts +6 -0
- package/dist/schema/validation.d.ts.map +1 -0
- package/dist/schema/validation.js +140 -0
- package/dist/schema/validation.js.map +1 -0
- package/dist/storage/export-import.d.ts +28 -0
- package/dist/storage/export-import.d.ts.map +1 -0
- package/dist/storage/export-import.js +189 -0
- package/dist/storage/export-import.js.map +1 -0
- package/dist/storage/memory/memory-adapter.d.ts +36 -0
- package/dist/storage/memory/memory-adapter.d.ts.map +1 -0
- package/dist/storage/memory/memory-adapter.js +231 -0
- package/dist/storage/memory/memory-adapter.js.map +1 -0
- package/dist/storage/sqlite/graph-traversal.d.ts +11 -0
- package/dist/storage/sqlite/graph-traversal.d.ts.map +1 -0
- package/dist/storage/sqlite/graph-traversal.js +79 -0
- package/dist/storage/sqlite/graph-traversal.js.map +1 -0
- package/dist/storage/sqlite/query-builder.d.ts +8 -0
- package/dist/storage/sqlite/query-builder.d.ts.map +1 -0
- package/dist/storage/sqlite/query-builder.js +55 -0
- package/dist/storage/sqlite/query-builder.js.map +1 -0
- package/dist/storage/sqlite/sqlite-adapter.d.ts +53 -0
- package/dist/storage/sqlite/sqlite-adapter.d.ts.map +1 -0
- package/dist/storage/sqlite/sqlite-adapter.js +497 -0
- package/dist/storage/sqlite/sqlite-adapter.js.map +1 -0
- package/dist/storage/storage-interface.d.ts +64 -0
- package/dist/storage/storage-interface.d.ts.map +1 -0
- package/dist/storage/storage-interface.js +2 -0
- package/dist/storage/storage-interface.js.map +1 -0
- package/dist/utils/retry-fetch.d.ts +20 -0
- package/dist/utils/retry-fetch.d.ts.map +1 -0
- package/dist/utils/retry-fetch.js +71 -0
- package/dist/utils/retry-fetch.js.map +1 -0
- package/package.json +28 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { ENTITY_EXTRACTION_PROMPT } from './prompts/entity-extraction.js';
|
|
2
|
+
import { PROPOSITION_EXTRACTION_PROMPT } from './prompts/proposition-extraction.js';
|
|
3
|
+
import { THOUGHT_EXTRACTION_PROMPT } from './prompts/thought-extraction.js';
|
|
4
|
+
/**
|
|
5
|
+
* Abstract base class for LLM-based extractors.
|
|
6
|
+
* Contains shared extraction/parsing logic; subclasses implement callLLM() and isAvailable().
|
|
7
|
+
*/
|
|
8
|
+
export class LLMExtractor {
|
|
9
|
+
async extract(chunk, _noteContent) {
|
|
10
|
+
const [entityResult, propResult, thoughtResult] = await Promise.allSettled([
|
|
11
|
+
this.extractEntitiesAndConcepts(chunk),
|
|
12
|
+
this.extractPropositions(chunk),
|
|
13
|
+
this.extractThoughts(chunk),
|
|
14
|
+
]);
|
|
15
|
+
const entities = entityResult.status === 'fulfilled' ? entityResult.value.entities : [];
|
|
16
|
+
const concepts = entityResult.status === 'fulfilled' ? entityResult.value.concepts : [];
|
|
17
|
+
const propositions = propResult.status === 'fulfilled' ? propResult.value : [];
|
|
18
|
+
const thoughts = thoughtResult.status === 'fulfilled' ? thoughtResult.value : [];
|
|
19
|
+
return { entities, concepts, propositions, thoughts };
|
|
20
|
+
}
|
|
21
|
+
async extractEntitiesAndConcepts(chunk) {
|
|
22
|
+
const prompt = ENTITY_EXTRACTION_PROMPT.replace('{{TEXT}}', chunk.text);
|
|
23
|
+
const raw = await this.callLLM(prompt);
|
|
24
|
+
try {
|
|
25
|
+
const parsed = JSON.parse(this.stripCodeFences(raw));
|
|
26
|
+
return {
|
|
27
|
+
entities: (parsed.entities ?? []).map((e) => ({
|
|
28
|
+
name: String(e.name ?? ''),
|
|
29
|
+
entityType: String(e.entityType ?? 'other'),
|
|
30
|
+
aliases: Array.isArray(e.aliases) ? e.aliases.map(String) : [],
|
|
31
|
+
description: String(e.description ?? ''),
|
|
32
|
+
confidence: Number(e.confidence ?? 0.5),
|
|
33
|
+
spans: [],
|
|
34
|
+
})),
|
|
35
|
+
concepts: (parsed.concepts ?? []).map((c) => ({
|
|
36
|
+
name: String(c.name ?? ''),
|
|
37
|
+
domain: String(c.domain ?? ''),
|
|
38
|
+
description: String(c.description ?? ''),
|
|
39
|
+
confidence: Number(c.confidence ?? 0.5),
|
|
40
|
+
})),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return { entities: [], concepts: [] };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async extractPropositions(chunk) {
|
|
48
|
+
const prompt = PROPOSITION_EXTRACTION_PROMPT.replace('{{TEXT}}', chunk.text);
|
|
49
|
+
const raw = await this.callLLM(prompt);
|
|
50
|
+
try {
|
|
51
|
+
const parsed = JSON.parse(this.stripCodeFences(raw));
|
|
52
|
+
return (parsed.propositions ?? []).map((p) => ({
|
|
53
|
+
statement: String(p.statement ?? ''),
|
|
54
|
+
domain: String(p.domain ?? ''),
|
|
55
|
+
confidence: Number(p.confidence ?? 0.5),
|
|
56
|
+
isNegated: Boolean(p.isNegated),
|
|
57
|
+
quoteText: String(p.quoteText ?? ''),
|
|
58
|
+
quoteStart: Number(p.quoteStart ?? chunk.startOffset),
|
|
59
|
+
quoteEnd: Number(p.quoteEnd ?? chunk.endOffset),
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async extractThoughts(chunk) {
|
|
67
|
+
const prompt = THOUGHT_EXTRACTION_PROMPT.replace('{{TEXT}}', chunk.text);
|
|
68
|
+
const raw = await this.callLLM(prompt);
|
|
69
|
+
try {
|
|
70
|
+
const parsed = JSON.parse(this.stripCodeFences(raw));
|
|
71
|
+
return (parsed.thoughts ?? []).map((t) => ({
|
|
72
|
+
statement: String(t.statement ?? ''),
|
|
73
|
+
stance: (['for', 'against', 'neutral'].includes(String(t.stance))
|
|
74
|
+
? t.stance
|
|
75
|
+
: 'neutral'),
|
|
76
|
+
subject: String(t.subject ?? ''),
|
|
77
|
+
confidence: Number(t.confidence ?? 0.5),
|
|
78
|
+
implications: Array.isArray(t.implications) ? t.implications.map(String) : [],
|
|
79
|
+
quoteText: String(t.quoteText ?? ''),
|
|
80
|
+
quoteStart: Number(t.quoteStart ?? chunk.startOffset),
|
|
81
|
+
quoteEnd: Number(t.quoteEnd ?? chunk.endOffset),
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** Strip markdown code fences that some LLMs wrap JSON in. */
|
|
89
|
+
stripCodeFences(text) {
|
|
90
|
+
const trimmed = text.trim();
|
|
91
|
+
if (trimmed.startsWith('```')) {
|
|
92
|
+
return trimmed.replace(/^```(?:json)?\s*\n?/, '').replace(/\n?```\s*$/, '');
|
|
93
|
+
}
|
|
94
|
+
return trimmed;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=llm-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-extractor.js","sourceRoot":"","sources":["../../src/extraction/llm-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { LLMExtractor } from './llm-extractor.js';
|
|
2
|
+
export interface OllamaExtractorOptions {
|
|
3
|
+
baseUrl?: string;
|
|
4
|
+
model?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* LLM-based extractor using Ollama with structured JSON output.
|
|
8
|
+
* Extracts entities, concepts, propositions, and thoughts.
|
|
9
|
+
*/
|
|
10
|
+
export declare class OllamaExtractor extends LLMExtractor {
|
|
11
|
+
readonly name = "ollama";
|
|
12
|
+
private readonly baseUrl;
|
|
13
|
+
private readonly model;
|
|
14
|
+
constructor(options?: OllamaExtractorOptions);
|
|
15
|
+
isAvailable(): Promise<boolean>;
|
|
16
|
+
protected callLLM(prompt: string): Promise<string>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=ollama-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama-extractor.d.ts","sourceRoot":"","sources":["../../src/extraction/ollama-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAOD;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,QAAQ,CAAC,IAAI,YAAY;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,OAAO,GAAE,sBAA2B;IAM1C,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;cAarB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAuBzD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { LLMExtractor } from './llm-extractor.js';
|
|
2
|
+
import { retryFetch } from '../utils/retry-fetch.js';
|
|
3
|
+
/**
|
|
4
|
+
* LLM-based extractor using Ollama with structured JSON output.
|
|
5
|
+
* Extracts entities, concepts, propositions, and thoughts.
|
|
6
|
+
*/
|
|
7
|
+
export class OllamaExtractor extends LLMExtractor {
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
super();
|
|
10
|
+
this.name = 'ollama';
|
|
11
|
+
this.baseUrl = options.baseUrl ?? 'http://localhost:11434';
|
|
12
|
+
this.model = options.model ?? 'llama3.2';
|
|
13
|
+
}
|
|
14
|
+
async isAvailable() {
|
|
15
|
+
try {
|
|
16
|
+
const response = await fetch(`${this.baseUrl}/api/tags`, {
|
|
17
|
+
signal: AbortSignal.timeout(3000),
|
|
18
|
+
});
|
|
19
|
+
if (!response.ok)
|
|
20
|
+
return false;
|
|
21
|
+
const data = (await response.json());
|
|
22
|
+
return data.models.some((m) => m.name.includes(this.model));
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async callLLM(prompt) {
|
|
29
|
+
const response = await retryFetch(`${this.baseUrl}/api/generate`, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: { 'Content-Type': 'application/json' },
|
|
32
|
+
body: JSON.stringify({
|
|
33
|
+
model: this.model,
|
|
34
|
+
prompt,
|
|
35
|
+
format: 'json',
|
|
36
|
+
stream: false,
|
|
37
|
+
options: {
|
|
38
|
+
temperature: 0.1,
|
|
39
|
+
num_predict: 2048,
|
|
40
|
+
},
|
|
41
|
+
}),
|
|
42
|
+
});
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
throw new Error(`Ollama request failed: ${response.status}`);
|
|
45
|
+
}
|
|
46
|
+
const data = (await response.json());
|
|
47
|
+
return data.response ?? data.message?.content ?? '{}';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=ollama-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama-extractor.js","sourceRoot":"","sources":["../../src/extraction/ollama-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAYrD;;;GAGG;AACH,MAAM,OAAO,eAAgB,SAAQ,YAAY;IAK/C,YAAY,UAAkC,EAAE;QAC9C,KAAK,EAAE,CAAC;QALD,SAAI,GAAG,QAAQ,CAAC;QAMvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,wBAAwB,CAAC;QAC3D,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,WAAW,EAAE;gBACvD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;aAClC,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,OAAO,KAAK,CAAC;YAC/B,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwC,CAAC;YAC5E,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAES,KAAK,CAAC,OAAO,CAAC,MAAc;QACpC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,GAAG,IAAI,CAAC,OAAO,eAAe,EAAE;YAChE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,MAAM;gBACN,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE;oBACP,WAAW,EAAE,GAAG;oBAChB,WAAW,EAAE,IAAI;iBAClB;aACF,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/D,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAmB,CAAC;QACvD,OAAO,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC;IACxD,CAAC;CACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { StorageAdapter } from '../storage/storage-interface.js';
|
|
2
|
+
import { type OpenLoop } from '../schema/types.js';
|
|
3
|
+
export type OpenLoopStatus = 'question' | 'todo' | 'uncertain' | 'wonder';
|
|
4
|
+
/**
|
|
5
|
+
* Detects "open loops" — unresolved questions, TODOs, uncertainties, and wonderings.
|
|
6
|
+
* No embeddings required — uses pattern matching on propositions and thoughts.
|
|
7
|
+
*/
|
|
8
|
+
export declare class OpenLoopDetector {
|
|
9
|
+
private storage;
|
|
10
|
+
constructor(storage: StorageAdapter);
|
|
11
|
+
/**
|
|
12
|
+
* Detect the status of a statement based on pattern matching.
|
|
13
|
+
*/
|
|
14
|
+
detectStatus(statement: string): OpenLoopStatus | null;
|
|
15
|
+
/**
|
|
16
|
+
* Find all open loops across the graph.
|
|
17
|
+
* Queries propositions with question/todo status and thoughts with neutral stance.
|
|
18
|
+
* Groups by topic (shared ABOUT targets or text similarity).
|
|
19
|
+
*/
|
|
20
|
+
findOpenLoops(limit?: number): Promise<OpenLoop[]>;
|
|
21
|
+
private getCitations;
|
|
22
|
+
private groupByTopic;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=open-loop-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-loop-detector.d.ts","sourceRoot":"","sources":["../../src/extraction/open-loop-detector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAqC,KAAK,QAAQ,EAAiB,MAAM,oBAAoB,CAAC;AAIrG,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;AAwC1E;;;GAGG;AACH,qBAAa,gBAAgB;IACf,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,cAAc;IAE3C;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAgBtD;;;;OAIG;IACG,aAAa,CAAC,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;YAyD9C,YAAY;YAsBZ,YAAY;CA4D3B"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { NodeType, RelType } from '../schema/types.js';
|
|
2
|
+
// ─── Pattern matchers ─────────────────────────────────────────────
|
|
3
|
+
const WONDER_PATTERNS = [
|
|
4
|
+
/\bi wonder\b/i,
|
|
5
|
+
/\bwhat if\b/i,
|
|
6
|
+
/\bcould it be\b/i,
|
|
7
|
+
/\bi'm curious\b/i,
|
|
8
|
+
];
|
|
9
|
+
const TODO_PATTERNS = [
|
|
10
|
+
/\btodo\b/i,
|
|
11
|
+
/\bfixme\b/i,
|
|
12
|
+
/\bhack\b/i,
|
|
13
|
+
/\bneed to\b/i,
|
|
14
|
+
/\bshould (look into|investigate|explore|figure out)\b/i,
|
|
15
|
+
];
|
|
16
|
+
const UNCERTAIN_PATTERNS = [
|
|
17
|
+
/\bunclear\b/i,
|
|
18
|
+
/\bnot sure\b/i,
|
|
19
|
+
/\bi('m| am) unsure\b/i,
|
|
20
|
+
/\bperhaps\b/i,
|
|
21
|
+
/\bmaybe\b/i,
|
|
22
|
+
/\bmight be\b/i,
|
|
23
|
+
];
|
|
24
|
+
const QUESTION_PATTERNS = [
|
|
25
|
+
/\?\s*$/,
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* Detects "open loops" — unresolved questions, TODOs, uncertainties, and wonderings.
|
|
29
|
+
* No embeddings required — uses pattern matching on propositions and thoughts.
|
|
30
|
+
*/
|
|
31
|
+
export class OpenLoopDetector {
|
|
32
|
+
constructor(storage) {
|
|
33
|
+
this.storage = storage;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Detect the status of a statement based on pattern matching.
|
|
37
|
+
*/
|
|
38
|
+
detectStatus(statement) {
|
|
39
|
+
for (const pattern of WONDER_PATTERNS) {
|
|
40
|
+
if (pattern.test(statement))
|
|
41
|
+
return 'wonder';
|
|
42
|
+
}
|
|
43
|
+
for (const pattern of TODO_PATTERNS) {
|
|
44
|
+
if (pattern.test(statement))
|
|
45
|
+
return 'todo';
|
|
46
|
+
}
|
|
47
|
+
for (const pattern of UNCERTAIN_PATTERNS) {
|
|
48
|
+
if (pattern.test(statement))
|
|
49
|
+
return 'uncertain';
|
|
50
|
+
}
|
|
51
|
+
for (const pattern of QUESTION_PATTERNS) {
|
|
52
|
+
if (pattern.test(statement))
|
|
53
|
+
return 'question';
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Find all open loops across the graph.
|
|
59
|
+
* Queries propositions with question/todo status and thoughts with neutral stance.
|
|
60
|
+
* Groups by topic (shared ABOUT targets or text similarity).
|
|
61
|
+
*/
|
|
62
|
+
async findOpenLoops(limit = 20) {
|
|
63
|
+
const loops = [];
|
|
64
|
+
// Search propositions for open loop patterns
|
|
65
|
+
const propositions = await this.storage.queryNodes({
|
|
66
|
+
nodeType: NodeType.Proposition,
|
|
67
|
+
limit: 500,
|
|
68
|
+
});
|
|
69
|
+
for (const prop of propositions) {
|
|
70
|
+
const data = prop.data;
|
|
71
|
+
const status = data.status ?? this.detectStatus(data.statement);
|
|
72
|
+
if (status && status !== 'assertion') {
|
|
73
|
+
const citations = await this.getCitations(prop.id);
|
|
74
|
+
loops.push({
|
|
75
|
+
nodeId: prop.id,
|
|
76
|
+
statement: data.statement,
|
|
77
|
+
status: status,
|
|
78
|
+
date: prop.updatedAt ?? prop.createdAt,
|
|
79
|
+
citations,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Search thoughts with neutral stance
|
|
84
|
+
const thoughts = await this.storage.queryNodes({
|
|
85
|
+
nodeType: NodeType.Thought,
|
|
86
|
+
limit: 500,
|
|
87
|
+
});
|
|
88
|
+
for (const thought of thoughts) {
|
|
89
|
+
const data = thought.data;
|
|
90
|
+
if (data.stance === 'neutral') {
|
|
91
|
+
const status = this.detectStatus(data.statement) ?? 'uncertain';
|
|
92
|
+
const citations = await this.getCitations(thought.id);
|
|
93
|
+
loops.push({
|
|
94
|
+
nodeId: thought.id,
|
|
95
|
+
statement: data.statement,
|
|
96
|
+
status,
|
|
97
|
+
date: thought.updatedAt ?? thought.createdAt,
|
|
98
|
+
citations,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Group by topic using ABOUT edges
|
|
103
|
+
const grouped = await this.groupByTopic(loops);
|
|
104
|
+
// Sort by occurrence count + recency
|
|
105
|
+
grouped.sort((a, b) => {
|
|
106
|
+
if (b.occurrences !== a.occurrences)
|
|
107
|
+
return b.occurrences - a.occurrences;
|
|
108
|
+
return b.mostRecentDate.localeCompare(a.mostRecentDate);
|
|
109
|
+
});
|
|
110
|
+
return grouped.slice(0, limit);
|
|
111
|
+
}
|
|
112
|
+
async getCitations(nodeId) {
|
|
113
|
+
const derivedEdges = await this.storage.queryEdges({
|
|
114
|
+
sourceId: nodeId,
|
|
115
|
+
relType: RelType.DERIVED_FROM,
|
|
116
|
+
});
|
|
117
|
+
const citations = [];
|
|
118
|
+
for (const edge of derivedEdges) {
|
|
119
|
+
const data = edge.data;
|
|
120
|
+
if (data.provenance) {
|
|
121
|
+
citations.push({
|
|
122
|
+
notePath: data.provenance.notePath,
|
|
123
|
+
startOffset: data.provenance.startOffset,
|
|
124
|
+
endOffset: data.provenance.endOffset,
|
|
125
|
+
quoteText: data.provenance.quoteText,
|
|
126
|
+
chunkId: data.provenance.chunkId,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return citations;
|
|
131
|
+
}
|
|
132
|
+
async groupByTopic(loops) {
|
|
133
|
+
// Group loops that share ABOUT targets
|
|
134
|
+
const topicMap = new Map();
|
|
135
|
+
const ungrouped = [];
|
|
136
|
+
for (const loop of loops) {
|
|
137
|
+
const aboutEdges = await this.storage.queryEdges({
|
|
138
|
+
sourceId: loop.nodeId,
|
|
139
|
+
relType: RelType.ABOUT,
|
|
140
|
+
});
|
|
141
|
+
if (aboutEdges.length > 0) {
|
|
142
|
+
// Use first ABOUT target as group key
|
|
143
|
+
const topicId = aboutEdges[0].targetId;
|
|
144
|
+
const topicNode = await this.storage.getNode(topicId);
|
|
145
|
+
const topicName = topicNode
|
|
146
|
+
? topicNode.data.name ?? topicId
|
|
147
|
+
: topicId;
|
|
148
|
+
const key = topicName.toLowerCase();
|
|
149
|
+
if (!topicMap.has(key))
|
|
150
|
+
topicMap.set(key, []);
|
|
151
|
+
topicMap.get(key).push(loop);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
ungrouped.push(loop);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const result = [];
|
|
158
|
+
// Convert grouped loops
|
|
159
|
+
for (const [topic, group] of topicMap) {
|
|
160
|
+
// Pick the most recent loop as representative
|
|
161
|
+
group.sort((a, b) => b.date.localeCompare(a.date));
|
|
162
|
+
const representative = group[0];
|
|
163
|
+
result.push({
|
|
164
|
+
id: representative.nodeId,
|
|
165
|
+
statement: representative.statement,
|
|
166
|
+
status: representative.status,
|
|
167
|
+
topic,
|
|
168
|
+
occurrences: group.length,
|
|
169
|
+
mostRecentDate: representative.date,
|
|
170
|
+
citations: group.flatMap((l) => l.citations).slice(0, 3),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
// Add ungrouped loops individually
|
|
174
|
+
for (const loop of ungrouped) {
|
|
175
|
+
result.push({
|
|
176
|
+
id: loop.nodeId,
|
|
177
|
+
statement: loop.statement,
|
|
178
|
+
status: loop.status,
|
|
179
|
+
occurrences: 1,
|
|
180
|
+
mostRecentDate: loop.date,
|
|
181
|
+
citations: loop.citations.slice(0, 3),
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=open-loop-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-loop-detector.js","sourceRoot":"","sources":["../../src/extraction/open-loop-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { LLMExtractor } from './llm-extractor.js';
|
|
2
|
+
export interface OpenAIExtractorOptions {
|
|
3
|
+
apiKey: string;
|
|
4
|
+
model?: string;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* LLM-based extractor using OpenAI-compatible chat completions API.
|
|
9
|
+
* Works with OpenAI, Azure OpenAI, and any compatible endpoint.
|
|
10
|
+
*/
|
|
11
|
+
export declare class OpenAIExtractor extends LLMExtractor {
|
|
12
|
+
readonly name = "openai";
|
|
13
|
+
private readonly apiKey;
|
|
14
|
+
private readonly model;
|
|
15
|
+
private readonly baseUrl;
|
|
16
|
+
constructor(options: OpenAIExtractorOptions);
|
|
17
|
+
isAvailable(): Promise<boolean>;
|
|
18
|
+
protected callLLM(prompt: string): Promise<string>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=openai-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-extractor.d.ts","sourceRoot":"","sources":["../../src/extraction/openai-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,QAAQ,CAAC,IAAI,YAAY;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,EAAE,sBAAsB;IAOrC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;cAIrB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA2BzD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { LLMExtractor } from './llm-extractor.js';
|
|
2
|
+
import { retryFetch } from '../utils/retry-fetch.js';
|
|
3
|
+
/**
|
|
4
|
+
* LLM-based extractor using OpenAI-compatible chat completions API.
|
|
5
|
+
* Works with OpenAI, Azure OpenAI, and any compatible endpoint.
|
|
6
|
+
*/
|
|
7
|
+
export class OpenAIExtractor extends LLMExtractor {
|
|
8
|
+
constructor(options) {
|
|
9
|
+
super();
|
|
10
|
+
this.name = 'openai';
|
|
11
|
+
this.apiKey = options.apiKey;
|
|
12
|
+
this.model = options.model ?? 'gpt-4o-mini';
|
|
13
|
+
this.baseUrl = (options.baseUrl ?? 'https://api.openai.com').replace(/\/+$/, '');
|
|
14
|
+
}
|
|
15
|
+
async isAvailable() {
|
|
16
|
+
return this.apiKey.trim().length > 0;
|
|
17
|
+
}
|
|
18
|
+
async callLLM(prompt) {
|
|
19
|
+
const response = await retryFetch(`${this.baseUrl}/v1/chat/completions`, {
|
|
20
|
+
method: 'POST',
|
|
21
|
+
headers: {
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
24
|
+
},
|
|
25
|
+
body: JSON.stringify({
|
|
26
|
+
model: this.model,
|
|
27
|
+
messages: [
|
|
28
|
+
{ role: 'system', content: 'You are a structured data extraction system. Always respond with valid JSON only, no extra text.' },
|
|
29
|
+
{ role: 'user', content: prompt },
|
|
30
|
+
],
|
|
31
|
+
response_format: { type: 'json_object' },
|
|
32
|
+
temperature: 0.1,
|
|
33
|
+
max_tokens: 2048,
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
const text = await response.text().catch(() => '');
|
|
38
|
+
throw new Error(`OpenAI request failed: ${response.status} ${text}`);
|
|
39
|
+
}
|
|
40
|
+
const data = (await response.json());
|
|
41
|
+
return data.choices[0]?.message?.content ?? '{}';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=openai-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-extractor.js","sourceRoot":"","sources":["../../src/extraction/openai-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAYrD;;;GAGG;AACH,MAAM,OAAO,eAAgB,SAAQ,YAAY;IAM/C,YAAY,OAA+B;QACzC,KAAK,EAAE,CAAC;QAND,SAAI,GAAG,QAAQ,CAAC;QAOvB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,aAAa,CAAC;QAC5C,IAAI,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,wBAAwB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACnF,CAAC;IAED,KAAK,CAAC,WAAW;QACf,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IACvC,CAAC;IAES,KAAK,CAAC,OAAO,CAAC,MAAc;QACpC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,GAAG,IAAI,CAAC,OAAO,sBAAsB,EAAE;YACvE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,eAAe,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;aACzC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE;oBACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,kGAAkG,EAAE;oBAC/H,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE;iBAClC;gBACD,eAAe,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE;gBACxC,WAAW,EAAE,GAAG;gBAChB,UAAU,EAAE,IAAI;aACjB,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;QACvE,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAmB,CAAC;QACvD,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC;IACnD,CAAC;CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const ENTITY_EXTRACTION_PROMPT = "You are an entity and concept extraction system. Analyze the following text and extract all named entities and abstract concepts.\n\nFor entities, identify:\n- People (person)\n- Organizations (organization)\n- Products or tools (product)\n- Works like books, papers, projects (work)\n- Other named entities (other)\n\nFor concepts, identify abstract ideas, topics, methodologies, theories, or domains of knowledge.\n\nTEXT:\n{{TEXT}}\n\nRespond with ONLY valid JSON in this exact format:\n{\n \"entities\": [\n {\n \"name\": \"Entity Name\",\n \"entityType\": \"person|organization|product|work|other\",\n \"aliases\": [\"Alternative Name\"],\n \"description\": \"Brief description based on context\",\n \"confidence\": 0.9\n }\n ],\n \"concepts\": [\n {\n \"name\": \"Concept Name\",\n \"domain\": \"Domain or field\",\n \"description\": \"Brief description\",\n \"confidence\": 0.8\n }\n ]\n}\n\nRules:\n- confidence is 0.0 to 1.0\n- Only extract what is clearly present in the text\n- Prefer specific names over generic terms\n- Merge duplicates and list aliases\n- Keep descriptions concise (under 20 words)";
|
|
2
|
+
//# sourceMappingURL=entity-extraction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-extraction.d.ts","sourceRoot":"","sources":["../../../src/extraction/prompts/entity-extraction.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,wBAAwB,0pCAwCQ,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export const ENTITY_EXTRACTION_PROMPT = `You are an entity and concept extraction system. Analyze the following text and extract all named entities and abstract concepts.
|
|
2
|
+
|
|
3
|
+
For entities, identify:
|
|
4
|
+
- People (person)
|
|
5
|
+
- Organizations (organization)
|
|
6
|
+
- Products or tools (product)
|
|
7
|
+
- Works like books, papers, projects (work)
|
|
8
|
+
- Other named entities (other)
|
|
9
|
+
|
|
10
|
+
For concepts, identify abstract ideas, topics, methodologies, theories, or domains of knowledge.
|
|
11
|
+
|
|
12
|
+
TEXT:
|
|
13
|
+
{{TEXT}}
|
|
14
|
+
|
|
15
|
+
Respond with ONLY valid JSON in this exact format:
|
|
16
|
+
{
|
|
17
|
+
"entities": [
|
|
18
|
+
{
|
|
19
|
+
"name": "Entity Name",
|
|
20
|
+
"entityType": "person|organization|product|work|other",
|
|
21
|
+
"aliases": ["Alternative Name"],
|
|
22
|
+
"description": "Brief description based on context",
|
|
23
|
+
"confidence": 0.9
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"concepts": [
|
|
27
|
+
{
|
|
28
|
+
"name": "Concept Name",
|
|
29
|
+
"domain": "Domain or field",
|
|
30
|
+
"description": "Brief description",
|
|
31
|
+
"confidence": 0.8
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
Rules:
|
|
37
|
+
- confidence is 0.0 to 1.0
|
|
38
|
+
- Only extract what is clearly present in the text
|
|
39
|
+
- Prefer specific names over generic terms
|
|
40
|
+
- Merge duplicates and list aliases
|
|
41
|
+
- Keep descriptions concise (under 20 words)`;
|
|
42
|
+
//# sourceMappingURL=entity-extraction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-extraction.js","sourceRoot":"","sources":["../../../src/extraction/prompts/entity-extraction.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6CAwCK,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const PROPOSITION_EXTRACTION_PROMPT = "You are a proposition extraction system. Analyze the following text and extract objective claims, facts, and statements that can be verified or debated.\n\nA proposition is an objective claim about the world \u2014 a statement that could be true or false. Focus on:\n- Factual claims (\"X causes Y\", \"X is true\")\n- Definitions and classifications\n- Quantitative claims\n- Causal relationships\n- Temporal facts\n\nDo NOT include:\n- Pure opinions (those are \"thoughts\")\n- Questions\n- Imperatives/commands\n\nTEXT:\n{{TEXT}}\n\nRespond with ONLY valid JSON in this exact format:\n{\n \"propositions\": [\n {\n \"statement\": \"Clear, standalone restatement of the claim\",\n \"domain\": \"Science|Technology|Philosophy|Politics|Health|Economics|History|Other\",\n \"confidence\": 0.8,\n \"isNegated\": false,\n \"quoteText\": \"exact text span from the source that contains this claim\",\n \"quoteStart\": 0,\n \"quoteEnd\": 50\n }\n ]\n}\n\nRules:\n- confidence is 0.0 to 1.0 \u2014 how certain the text is about this claim\n- quoteText must be the EXACT substring from the source text\n- quoteStart/quoteEnd are character offsets within the provided text\n- statement should be self-contained (understandable without the original text)\n- isNegated is true if the claim denies something (\"X is NOT Y\")";
|
|
2
|
+
//# sourceMappingURL=proposition-extraction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proposition-extraction.d.ts","sourceRoot":"","sources":["../../../src/extraction/prompts/proposition-extraction.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,6BAA6B,i1CAqCuB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export const PROPOSITION_EXTRACTION_PROMPT = `You are a proposition extraction system. Analyze the following text and extract objective claims, facts, and statements that can be verified or debated.
|
|
2
|
+
|
|
3
|
+
A proposition is an objective claim about the world — a statement that could be true or false. Focus on:
|
|
4
|
+
- Factual claims ("X causes Y", "X is true")
|
|
5
|
+
- Definitions and classifications
|
|
6
|
+
- Quantitative claims
|
|
7
|
+
- Causal relationships
|
|
8
|
+
- Temporal facts
|
|
9
|
+
|
|
10
|
+
Do NOT include:
|
|
11
|
+
- Pure opinions (those are "thoughts")
|
|
12
|
+
- Questions
|
|
13
|
+
- Imperatives/commands
|
|
14
|
+
|
|
15
|
+
TEXT:
|
|
16
|
+
{{TEXT}}
|
|
17
|
+
|
|
18
|
+
Respond with ONLY valid JSON in this exact format:
|
|
19
|
+
{
|
|
20
|
+
"propositions": [
|
|
21
|
+
{
|
|
22
|
+
"statement": "Clear, standalone restatement of the claim",
|
|
23
|
+
"domain": "Science|Technology|Philosophy|Politics|Health|Economics|History|Other",
|
|
24
|
+
"confidence": 0.8,
|
|
25
|
+
"isNegated": false,
|
|
26
|
+
"quoteText": "exact text span from the source that contains this claim",
|
|
27
|
+
"quoteStart": 0,
|
|
28
|
+
"quoteEnd": 50
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
Rules:
|
|
34
|
+
- confidence is 0.0 to 1.0 — how certain the text is about this claim
|
|
35
|
+
- quoteText must be the EXACT substring from the source text
|
|
36
|
+
- quoteStart/quoteEnd are character offsets within the provided text
|
|
37
|
+
- statement should be self-contained (understandable without the original text)
|
|
38
|
+
- isNegated is true if the claim denies something ("X is NOT Y")`;
|
|
39
|
+
//# sourceMappingURL=proposition-extraction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proposition-extraction.js","sourceRoot":"","sources":["../../../src/extraction/prompts/proposition-extraction.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,6BAA6B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iEAqCoB,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const THOUGHT_EXTRACTION_PROMPT = "You are a thought and opinion extraction system. Analyze the following text and extract subjective interpretations, opinions, stances, and personal judgments.\n\nA thought is a subjective statement \u2014 an opinion, belief, interpretation, or personal stance. Focus on:\n- Opinions (\"I think X is better than Y\")\n- Value judgments (\"This approach is flawed\")\n- Interpretations (\"This suggests that...\")\n- Preferences (\"I prefer X over Y\")\n- Predictions based on judgment (\"This will likely lead to...\")\n\nDo NOT include:\n- Objective facts (those are \"propositions\")\n- Questions\n- Direct quotes from others (unless the author endorses them)\n\nTEXT:\n{{TEXT}}\n\nRespond with ONLY valid JSON in this exact format:\n{\n \"thoughts\": [\n {\n \"statement\": \"Clear restatement of the opinion/thought\",\n \"stance\": \"for|against|neutral\",\n \"subject\": \"What entity or concept this thought is about\",\n \"confidence\": 0.7,\n \"implications\": [\"What this thought implies\"],\n \"quoteText\": \"exact text span from the source\",\n \"quoteStart\": 0,\n \"quoteEnd\": 50\n }\n ]\n}\n\nRules:\n- stance is the author's position: \"for\" (positive/supportive), \"against\" (negative/critical), or \"neutral\" (ambivalent/observational)\n- subject should name a specific entity or concept the thought is about\n- confidence is 0.0 to 1.0 \u2014 how strongly the thought is expressed\n- quoteText must be the EXACT substring from the source text\n- implications are downstream consequences of holding this view\n- statement should be self-contained";
|
|
2
|
+
//# sourceMappingURL=thought-extraction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thought-extraction.d.ts","sourceRoot":"","sources":["../../../src/extraction/prompts/thought-extraction.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,slDAuCD,CAAC"}
|