@restormel/graphrag-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/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/README.md +38 -0
- package/dist/empty-graph.d.ts +4 -0
- package/dist/empty-graph.d.ts.map +1 -0
- package/dist/empty-graph.js +3 -0
- package/dist/hybrid-candidate-generation.d.ts +23 -0
- package/dist/hybrid-candidate-generation.d.ts.map +1 -0
- package/dist/hybrid-candidate-generation.js +147 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/kg-balance.d.ts +21 -0
- package/dist/kg-balance.d.ts.map +1 -0
- package/dist/kg-balance.js +43 -0
- package/dist/ports.d.ts +19 -0
- package/dist/ports.d.ts.map +1 -0
- package/dist/ports.js +1 -0
- package/dist/retrieve-context.d.ts +196 -0
- package/dist/retrieve-context.d.ts.map +1 -0
- package/dist/retrieve-context.js +1401 -0
- package/dist/seed-set-constructor.d.ts +53 -0
- package/dist/seed-set-constructor.d.ts.map +1 -0
- package/dist/seed-set-constructor.js +247 -0
- package/dist/surreal-retrieval-enhancements.d.ts +39 -0
- package/dist/surreal-retrieval-enhancements.d.ts.map +1 -0
- package/dist/surreal-retrieval-enhancements.js +139 -0
- package/package.json +44 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Changelog — @restormel/graphrag-core
|
|
2
|
+
|
|
3
|
+
## 0.1.0 — 2026-06-01
|
|
4
|
+
|
|
5
|
+
- Initial extraction from SOPHIA retrieval pipeline (Phase 4 suite migration).
|
|
6
|
+
- `retrieveContext`, `buildContextBlock`, hybrid/seed/balance helpers, Surreal enhancement fetchers (store-injected).
|
|
7
|
+
- `emptyGraphData` helper retained for consumer smoke tests.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Adam Boon
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# @restormel/graphrag-core
|
|
2
|
+
|
|
3
|
+
Graph-aware **Retrieve** pipeline for Knowledge RAG — hybrid dense/lexical seeding, beam graph traversal, argument closure, and LLM context formatting. Host apps inject **`GraphStore`** and **`EmbeddingPort`** (no Surreal driver in this package).
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @restormel/graphrag-core @restormel/contracts
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import {
|
|
15
|
+
retrieveContext,
|
|
16
|
+
buildContextBlock,
|
|
17
|
+
type GraphRagDeps,
|
|
18
|
+
} from "@restormel/graphrag-core";
|
|
19
|
+
|
|
20
|
+
const deps: GraphRagDeps = {
|
|
21
|
+
store: sophiaGraphStore,
|
|
22
|
+
embedder: { embedQuery: (text) => hostEmbedQuery(text) },
|
|
23
|
+
resolveOriginBucket: (url, sourceType) => hostOriginBucket(url, sourceType),
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const result = await retrieveContext("What is epistemic injustice?", deps, {
|
|
27
|
+
topK: 6,
|
|
28
|
+
maxClaims: 24,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const promptBlock = buildContextBlock(result);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Compose with **`@restormel/context-packs`** for pass-specific analysis/critique/synthesis blocks (host adapter maps `RetrievalResult` → `ContextPackRetrievalInput`).
|
|
35
|
+
|
|
36
|
+
## Publish
|
|
37
|
+
|
|
38
|
+
Tag **`platform-v*`** in the restormel-keys monorepo — see [docs/restormel/SUITE-ARCHITECTURE-MIGRATION.md](../../docs/restormel/SUITE-ARCHITECTURE-MIGRATION.md) Phase 4.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"empty-graph.d.ts","sourceRoot":"","sources":["../src/empty-graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAEjE,wBAAgB,cAAc,IAAI,SAAS,CAE1C;AAED,YAAY,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface HybridCandidate {
|
|
2
|
+
id: string;
|
|
3
|
+
text: string;
|
|
4
|
+
confidence: number;
|
|
5
|
+
source_title: string;
|
|
6
|
+
section_context?: string | null;
|
|
7
|
+
}
|
|
8
|
+
export interface HybridFusionResult<T extends HybridCandidate> {
|
|
9
|
+
ranked: T[];
|
|
10
|
+
denseCount: number;
|
|
11
|
+
lexicalCount: number;
|
|
12
|
+
fusedCount: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function detectCorpusLevelQuery(query: string): boolean;
|
|
15
|
+
export declare function extractLexicalTerms(query: string): string[];
|
|
16
|
+
export declare function fuseHybridCandidates<T extends HybridCandidate>(params: {
|
|
17
|
+
dense: T[];
|
|
18
|
+
lexical: T[];
|
|
19
|
+
lexicalTerms: string[];
|
|
20
|
+
poolSize: number;
|
|
21
|
+
corpusLevelQuery: boolean;
|
|
22
|
+
}): HybridFusionResult<T>;
|
|
23
|
+
//# sourceMappingURL=hybrid-candidate-generation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hybrid-candidate-generation.d.ts","sourceRoot":"","sources":["../src/hybrid-candidate-generation.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,eAAe;IAC3D,MAAM,EAAE,CAAC,EAAE,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAoDD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG7D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAmC3D;AAoCD,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,eAAe,EAAE,MAAM,EAAE;IACtE,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;CAC3B,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAoCxB"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
const STOPWORDS = new Set([
|
|
2
|
+
'a',
|
|
3
|
+
'an',
|
|
4
|
+
'and',
|
|
5
|
+
'are',
|
|
6
|
+
'as',
|
|
7
|
+
'at',
|
|
8
|
+
'be',
|
|
9
|
+
'by',
|
|
10
|
+
'for',
|
|
11
|
+
'from',
|
|
12
|
+
'how',
|
|
13
|
+
'in',
|
|
14
|
+
'is',
|
|
15
|
+
'it',
|
|
16
|
+
'of',
|
|
17
|
+
'on',
|
|
18
|
+
'or',
|
|
19
|
+
'that',
|
|
20
|
+
'the',
|
|
21
|
+
'this',
|
|
22
|
+
'to',
|
|
23
|
+
'what',
|
|
24
|
+
'when',
|
|
25
|
+
'where',
|
|
26
|
+
'which',
|
|
27
|
+
'why',
|
|
28
|
+
'with'
|
|
29
|
+
]);
|
|
30
|
+
const CORPUS_LEVEL_SIGNALS = [
|
|
31
|
+
'across philosophy',
|
|
32
|
+
'across traditions',
|
|
33
|
+
'across thinkers',
|
|
34
|
+
'historical development',
|
|
35
|
+
'main positions',
|
|
36
|
+
'overview',
|
|
37
|
+
'survey',
|
|
38
|
+
'big picture',
|
|
39
|
+
'in general'
|
|
40
|
+
];
|
|
41
|
+
function normalize(text) {
|
|
42
|
+
return text.toLowerCase().replace(/[^\w\s-]/g, ' ').replace(/\s+/g, ' ').trim();
|
|
43
|
+
}
|
|
44
|
+
function uniq(input) {
|
|
45
|
+
return [...new Set(input)];
|
|
46
|
+
}
|
|
47
|
+
export function detectCorpusLevelQuery(query) {
|
|
48
|
+
const q = normalize(query);
|
|
49
|
+
return CORPUS_LEVEL_SIGNALS.some((signal) => q.includes(signal));
|
|
50
|
+
}
|
|
51
|
+
export function extractLexicalTerms(query) {
|
|
52
|
+
const normalized = normalize(query);
|
|
53
|
+
if (!normalized)
|
|
54
|
+
return [];
|
|
55
|
+
const terms = [];
|
|
56
|
+
const quoted = [...query.matchAll(/"([^"]+)"/g)].map((m) => normalize(m[1])).filter(Boolean);
|
|
57
|
+
terms.push(...quoted);
|
|
58
|
+
const hyphenated = normalized.match(/\b[a-z0-9]+(?:-[a-z0-9]+)+\b/g) ?? [];
|
|
59
|
+
terms.push(...hyphenated);
|
|
60
|
+
const tokens = normalized.split(' ').filter(Boolean);
|
|
61
|
+
for (let i = 0; i < tokens.length - 1; i++) {
|
|
62
|
+
const bigram = `${tokens[i]} ${tokens[i + 1]}`;
|
|
63
|
+
if (!STOPWORDS.has(tokens[i]) &&
|
|
64
|
+
!STOPWORDS.has(tokens[i + 1]) &&
|
|
65
|
+
bigram.length >= 10) {
|
|
66
|
+
terms.push(bigram);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
for (const token of tokens) {
|
|
70
|
+
if (token.length >= 8 && !STOPWORDS.has(token)) {
|
|
71
|
+
terms.push(token);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const knownPhrases = ['public reason', 'epistemic injustice', 'non-identity problem'];
|
|
75
|
+
for (const phrase of knownPhrases) {
|
|
76
|
+
if (normalized.includes(phrase))
|
|
77
|
+
terms.push(phrase);
|
|
78
|
+
}
|
|
79
|
+
return uniq(terms).slice(0, 8);
|
|
80
|
+
}
|
|
81
|
+
function rrf(rank, k = 60) {
|
|
82
|
+
return 1 / (k + rank);
|
|
83
|
+
}
|
|
84
|
+
function termCoverage(text, terms) {
|
|
85
|
+
if (terms.length === 0)
|
|
86
|
+
return 0;
|
|
87
|
+
const normalized = normalize(text);
|
|
88
|
+
let hits = 0;
|
|
89
|
+
for (const term of terms) {
|
|
90
|
+
if (normalized.includes(term))
|
|
91
|
+
hits += 1;
|
|
92
|
+
}
|
|
93
|
+
return hits / terms.length;
|
|
94
|
+
}
|
|
95
|
+
function diversifyBySource(ranked, size) {
|
|
96
|
+
const selected = [];
|
|
97
|
+
const seenSources = new Set();
|
|
98
|
+
for (const row of ranked) {
|
|
99
|
+
if (selected.length >= size)
|
|
100
|
+
break;
|
|
101
|
+
if (!seenSources.has(row.source_title)) {
|
|
102
|
+
selected.push(row);
|
|
103
|
+
seenSources.add(row.source_title);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
for (const row of ranked) {
|
|
107
|
+
if (selected.length >= size)
|
|
108
|
+
break;
|
|
109
|
+
if (!selected.includes(row))
|
|
110
|
+
selected.push(row);
|
|
111
|
+
}
|
|
112
|
+
return selected;
|
|
113
|
+
}
|
|
114
|
+
export function fuseHybridCandidates(params) {
|
|
115
|
+
const { dense, lexical, lexicalTerms, poolSize, corpusLevelQuery } = params;
|
|
116
|
+
const denseRanks = new Map();
|
|
117
|
+
const lexicalRanks = new Map();
|
|
118
|
+
const byId = new Map();
|
|
119
|
+
dense.forEach((row, idx) => {
|
|
120
|
+
denseRanks.set(row.id, idx + 1);
|
|
121
|
+
byId.set(row.id, row);
|
|
122
|
+
});
|
|
123
|
+
lexical.forEach((row, idx) => {
|
|
124
|
+
lexicalRanks.set(row.id, idx + 1);
|
|
125
|
+
if (!byId.has(row.id))
|
|
126
|
+
byId.set(row.id, row);
|
|
127
|
+
});
|
|
128
|
+
const scored = Array.from(byId.values()).map((row) => {
|
|
129
|
+
const denseRank = denseRanks.get(row.id);
|
|
130
|
+
const lexicalRank = lexicalRanks.get(row.id);
|
|
131
|
+
const fusionScore = (denseRank ? rrf(denseRank) : 0) + (lexicalRank ? rrf(lexicalRank) : 0);
|
|
132
|
+
const coverage = termCoverage(`${row.text} ${row.section_context ?? ''}`, lexicalTerms);
|
|
133
|
+
const rerankScore = fusionScore + coverage * 0.025 + Math.max(0, row.confidence) * 0.01;
|
|
134
|
+
return { row, rerankScore };
|
|
135
|
+
});
|
|
136
|
+
scored.sort((a, b) => b.rerankScore - a.rerankScore);
|
|
137
|
+
const ordered = scored.map((s) => s.row);
|
|
138
|
+
const ranked = corpusLevelQuery
|
|
139
|
+
? diversifyBySource(ordered, poolSize)
|
|
140
|
+
: ordered.slice(0, poolSize);
|
|
141
|
+
return {
|
|
142
|
+
ranked,
|
|
143
|
+
denseCount: dense.length,
|
|
144
|
+
lexicalCount: lexical.length,
|
|
145
|
+
fusedCount: ranked.length
|
|
146
|
+
};
|
|
147
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type { GraphStore, EmbeddingPort, GraphRagDeps, OriginBucketResolver, RetrievalOriginBalanceKey, } from "./ports.js";
|
|
2
|
+
export { detectCorpusLevelQuery, extractLexicalTerms, fuseHybridCandidates, type HybridCandidate, type HybridFusionResult, } from "./hybrid-candidate-generation.js";
|
|
3
|
+
export { constructSeedSet, type SeedCandidate, type SeedBalanceStats, type SeedRole, type SeedSetConstructionResult, } from "./seed-set-constructor.js";
|
|
4
|
+
export { IDEAL_RETRIEVAL_ORIGIN_FRACTIONS, RETRIEVAL_ORIGIN_BALANCE_STRENGTH, RETRIEVAL_DOMAIN_BALANCE_STRENGTH, isRetrievalKgBalanceEnabled, computeKgBalanceMultiplier, } from "./kg-balance.js";
|
|
5
|
+
export { isRetrievalBm25Enabled, isRetrievalNativeGraphEnabled, isRetrievalPassageGroundedEnabled, isRetrievalTaxonomyRoutingEnabled, isKgEnforcePassageOnAcceptEnabled, fetchBm25ClaimCandidates, fetchNativeGraphNeighbors, fetchPassageGroundedClaimIds, fetchTaxonomySeedClaimIds, ensureClaimSearchIndex, ensurePassageEmbeddingIndex, ensureClaimAcceptPassageEvent, } from "./surreal-retrieval-enhancements.js";
|
|
6
|
+
export { retrieveContext, buildContextBlock, formatThinkerContextBlock, type RetrievedClaim, type RetrievedRelation, type RetrievedArgument, type ThinkerSummary, type ThinkerContext, type RejectedClaimReasonCode, type RejectedRelationReasonCode, type RejectedClaimCandidate, type RejectedRelationCandidate, type ClosureUnitTrace, type RetrievalClosureStats, type RetrievalSeedTrace, type RetrievalQueryDecompositionTrace, type RetrievalPruningSummaryTrace, type RetrievalResult, type RetrievalOptions, } from "./retrieve-context.js";
|
|
7
|
+
export { emptyGraphData, type GraphData } from "./empty-graph.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,aAAa,EACb,YAAY,EACZ,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,gBAAgB,EAChB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,QAAQ,EACb,KAAK,yBAAyB,GAC/B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,gCAAgC,EAChC,iCAAiC,EACjC,iCAAiC,EACjC,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,sBAAsB,EACtB,6BAA6B,EAC7B,iCAAiC,EACjC,iCAAiC,EACjC,iCAAiC,EACjC,wBAAwB,EACxB,yBAAyB,EACzB,4BAA4B,EAC5B,yBAAyB,EACzB,sBAAsB,EACtB,2BAA2B,EAC3B,6BAA6B,GAC9B,MAAM,qCAAqC,CAAC;AAE7C,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,yBAAyB,EACzB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,gCAAgC,EACrC,KAAK,4BAA4B,EACjC,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { detectCorpusLevelQuery, extractLexicalTerms, fuseHybridCandidates, } from "./hybrid-candidate-generation.js";
|
|
2
|
+
export { constructSeedSet, } from "./seed-set-constructor.js";
|
|
3
|
+
export { IDEAL_RETRIEVAL_ORIGIN_FRACTIONS, RETRIEVAL_ORIGIN_BALANCE_STRENGTH, RETRIEVAL_DOMAIN_BALANCE_STRENGTH, isRetrievalKgBalanceEnabled, computeKgBalanceMultiplier, } from "./kg-balance.js";
|
|
4
|
+
export { isRetrievalBm25Enabled, isRetrievalNativeGraphEnabled, isRetrievalPassageGroundedEnabled, isRetrievalTaxonomyRoutingEnabled, isKgEnforcePassageOnAcceptEnabled, fetchBm25ClaimCandidates, fetchNativeGraphNeighbors, fetchPassageGroundedClaimIds, fetchTaxonomySeedClaimIds, ensureClaimSearchIndex, ensurePassageEmbeddingIndex, ensureClaimAcceptPassageEvent, } from "./surreal-retrieval-enhancements.js";
|
|
5
|
+
export { retrieveContext, buildContextBlock, formatThinkerContextBlock, } from "./retrieve-context.js";
|
|
6
|
+
export { emptyGraphData } from "./empty-graph.js";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PhilosophicalDomain } from "@restormel/contracts/domains";
|
|
2
|
+
/** Target mix for inquiry-time retrieval seed selection (not operator dataset metrics). */
|
|
3
|
+
export type RetrievalOriginBalanceKey = "sep" | "gutenberg" | "other";
|
|
4
|
+
/** Default SEP / Gutenberg / other mix for seed claims (sums to 1). */
|
|
5
|
+
export declare const IDEAL_RETRIEVAL_ORIGIN_FRACTIONS: Record<RetrievalOriginBalanceKey, number>;
|
|
6
|
+
export declare const RETRIEVAL_ORIGIN_BALANCE_STRENGTH = 0.95;
|
|
7
|
+
export declare const RETRIEVAL_DOMAIN_BALANCE_STRENGTH = 0.85;
|
|
8
|
+
export declare function isRetrievalKgBalanceEnabled(): boolean;
|
|
9
|
+
/** Multiplicative boost for MMR relevance (1 = neutral). Uses deficit vs ideal fractions. */
|
|
10
|
+
export declare function computeKgBalanceMultiplier(params: {
|
|
11
|
+
origin: RetrievalOriginBalanceKey;
|
|
12
|
+
domain: PhilosophicalDomain | string | null | undefined;
|
|
13
|
+
selectedOriginCounts: Record<RetrievalOriginBalanceKey, number>;
|
|
14
|
+
selectedDomainCounts: Map<string, number>;
|
|
15
|
+
totalSelected: number;
|
|
16
|
+
idealOrigin: Record<RetrievalOriginBalanceKey, number>;
|
|
17
|
+
domainsInPool: Set<string>;
|
|
18
|
+
originStrength?: number;
|
|
19
|
+
domainStrength?: number;
|
|
20
|
+
}): number;
|
|
21
|
+
//# sourceMappingURL=kg-balance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kg-balance.d.ts","sourceRoot":"","sources":["../src/kg-balance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE,2FAA2F;AAC3F,MAAM,MAAM,yBAAyB,GAAG,KAAK,GAAG,WAAW,GAAG,OAAO,CAAC;AAEtE,uEAAuE;AACvE,eAAO,MAAM,gCAAgC,EAAE,MAAM,CAAC,yBAAyB,EAAE,MAAM,CAItF,CAAC;AAEF,eAAO,MAAM,iCAAiC,OAAO,CAAC;AACtD,eAAO,MAAM,iCAAiC,OAAO,CAAC;AAEtD,wBAAgB,2BAA2B,IAAI,OAAO,CAGrD;AAeD,6FAA6F;AAC7F,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,MAAM,EAAE,yBAAyB,CAAC;IAClC,MAAM,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACxD,oBAAoB,EAAE,MAAM,CAAC,yBAAyB,EAAE,MAAM,CAAC,CAAC;IAChE,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC,yBAAyB,EAAE,MAAM,CAAC,CAAC;IACvD,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,MAAM,CAiCT"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** Default SEP / Gutenberg / other mix for seed claims (sums to 1). */
|
|
2
|
+
export const IDEAL_RETRIEVAL_ORIGIN_FRACTIONS = {
|
|
3
|
+
sep: 0.42,
|
|
4
|
+
gutenberg: 0.33,
|
|
5
|
+
other: 0.25,
|
|
6
|
+
};
|
|
7
|
+
export const RETRIEVAL_ORIGIN_BALANCE_STRENGTH = 0.95;
|
|
8
|
+
export const RETRIEVAL_DOMAIN_BALANCE_STRENGTH = 0.85;
|
|
9
|
+
export function isRetrievalKgBalanceEnabled() {
|
|
10
|
+
const v = (process.env.RETRIEVAL_KG_BALANCE ?? "1").trim().toLowerCase();
|
|
11
|
+
return v !== "0" && v !== "false" && v !== "no" && v !== "off";
|
|
12
|
+
}
|
|
13
|
+
function normalizeFractions(w) {
|
|
14
|
+
const sum = Object.values(w).reduce((a, b) => a + (Number.isFinite(b) ? b : 0), 0);
|
|
15
|
+
if (sum <= 0)
|
|
16
|
+
return { ...w };
|
|
17
|
+
const out = {};
|
|
18
|
+
for (const k of Object.keys(w)) {
|
|
19
|
+
out[k] = w[k] / sum;
|
|
20
|
+
}
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
/** Multiplicative boost for MMR relevance (1 = neutral). Uses deficit vs ideal fractions. */
|
|
24
|
+
export function computeKgBalanceMultiplier(params) {
|
|
25
|
+
const { origin, domain, selectedOriginCounts, selectedDomainCounts, totalSelected, idealOrigin, domainsInPool, originStrength = RETRIEVAL_ORIGIN_BALANCE_STRENGTH, domainStrength = RETRIEVAL_DOMAIN_BALANCE_STRENGTH, } = params;
|
|
26
|
+
if (totalSelected === 0)
|
|
27
|
+
return 1;
|
|
28
|
+
const idealO = normalizeFractions(idealOrigin);
|
|
29
|
+
const curO = selectedOriginCounts[origin] / totalSelected;
|
|
30
|
+
const tgtO = idealO[origin] ?? 0;
|
|
31
|
+
const originMult = tgtO > 0 ? 1 + originStrength * Math.max(0, (tgtO - curO) / Math.max(0.08, tgtO)) : 1;
|
|
32
|
+
let domainMult = 1;
|
|
33
|
+
const nDom = domainsInPool.size;
|
|
34
|
+
if (nDom > 1 && domain) {
|
|
35
|
+
const dKey = String(domain);
|
|
36
|
+
if (domainsInPool.has(dKey)) {
|
|
37
|
+
const idealD = 1 / nDom;
|
|
38
|
+
const curD = (selectedDomainCounts.get(dKey) ?? 0) / totalSelected;
|
|
39
|
+
domainMult = 1 + domainStrength * Math.max(0, (idealD - curD) / Math.max(0.06, idealD));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return Math.min(2.4, originMult * domainMult);
|
|
43
|
+
}
|
package/dist/ports.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Injected graph read port — Surreal (or other) implementations live in the host app.
|
|
3
|
+
*/
|
|
4
|
+
export interface GraphStore {
|
|
5
|
+
query<T>(sql: string, vars?: Record<string, unknown>): Promise<T>;
|
|
6
|
+
isDatabaseUnavailable(error: unknown): boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface EmbeddingPort {
|
|
9
|
+
embedQuery(text: string): Promise<number[]>;
|
|
10
|
+
}
|
|
11
|
+
export type RetrievalOriginBalanceKey = "sep" | "gutenberg" | "other";
|
|
12
|
+
/** Host resolves corpus origin bucket (SOPHIA uses ingestRuns URL heuristics). */
|
|
13
|
+
export type OriginBucketResolver = (url: string | null | undefined, storedSourceType?: string | null) => RetrievalOriginBalanceKey;
|
|
14
|
+
export interface GraphRagDeps {
|
|
15
|
+
store: GraphStore;
|
|
16
|
+
embedder: EmbeddingPort;
|
|
17
|
+
resolveOriginBucket: OriginBucketResolver;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=ports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../src/ports.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClE,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;CAChD;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC7C;AAED,MAAM,MAAM,yBAAyB,GAAG,KAAK,GAAG,WAAW,GAAG,OAAO,CAAC;AAEtE,kFAAkF;AAClF,MAAM,MAAM,oBAAoB,GAAG,CACjC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC9B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,KAC7B,yBAAyB,CAAC;AAE/B,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,aAAa,CAAC;IACxB,mBAAmB,EAAE,oBAAoB,CAAC;CAC3C"}
|
package/dist/ports.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SOPHIA — Argument-Aware Retrieval
|
|
3
|
+
*
|
|
4
|
+
* Core differentiator: not just semantic similarity, but graph traversal
|
|
5
|
+
* that assembles complete argumentative chains from the knowledge graph.
|
|
6
|
+
*
|
|
7
|
+
* Retrieval pipeline:
|
|
8
|
+
* 1. Embed query via Voyage AI
|
|
9
|
+
* 2. Vector search for top-K semantically similar claims
|
|
10
|
+
* 3. Graph traversal for each seed claim (depends_on, supports, contradicts, responds_to, defines, qualifies, part_of)
|
|
11
|
+
* 4. Deduplicate claims
|
|
12
|
+
* 5. Resolve inter-claim relations
|
|
13
|
+
* 6. Fetch argument structure (conclusion + key premises)
|
|
14
|
+
* 7. Return assembled RetrievalResult
|
|
15
|
+
*
|
|
16
|
+
* Graceful degradation: never throws — returns empty result on any failure
|
|
17
|
+
* so the three-pass engine can still work without the graph.
|
|
18
|
+
*/
|
|
19
|
+
import type { PhilosophicalDomain } from '@restormel/contracts/domains';
|
|
20
|
+
import type { GraphRagDeps } from './ports.js';
|
|
21
|
+
import { type SeedBalanceStats } from './seed-set-constructor.js';
|
|
22
|
+
export interface RetrievedClaim {
|
|
23
|
+
id: string;
|
|
24
|
+
text: string;
|
|
25
|
+
claim_type: string;
|
|
26
|
+
domain: PhilosophicalDomain;
|
|
27
|
+
source_title: string;
|
|
28
|
+
source_author: string[];
|
|
29
|
+
confidence: number;
|
|
30
|
+
position_in_source: number;
|
|
31
|
+
}
|
|
32
|
+
export interface RetrievedRelation {
|
|
33
|
+
from_index: number;
|
|
34
|
+
to_index: number;
|
|
35
|
+
relation_type: string;
|
|
36
|
+
strength?: string;
|
|
37
|
+
note?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface RetrievedArgument {
|
|
40
|
+
id: string;
|
|
41
|
+
name: string;
|
|
42
|
+
tradition: string | null;
|
|
43
|
+
domain: PhilosophicalDomain;
|
|
44
|
+
summary: string;
|
|
45
|
+
conclusion_text: string | null;
|
|
46
|
+
key_premises: string[];
|
|
47
|
+
}
|
|
48
|
+
export interface ThinkerSummary {
|
|
49
|
+
wikidata_id: string;
|
|
50
|
+
name: string;
|
|
51
|
+
birth_year: number | null;
|
|
52
|
+
death_year: number | null;
|
|
53
|
+
traditions: string[];
|
|
54
|
+
}
|
|
55
|
+
export interface ThinkerContext {
|
|
56
|
+
direct_authors: ThinkerSummary[];
|
|
57
|
+
influences: ThinkerSummary[];
|
|
58
|
+
teachers: ThinkerSummary[];
|
|
59
|
+
}
|
|
60
|
+
export type RejectedClaimReasonCode = 'seed_pool_pruned' | 'duplicate_traversal' | 'confidence_gate' | 'source_integrity_gate';
|
|
61
|
+
export type RejectedRelationReasonCode = 'duplicate_relation' | 'missing_endpoint';
|
|
62
|
+
export interface RejectedClaimCandidate {
|
|
63
|
+
id: string;
|
|
64
|
+
text: string;
|
|
65
|
+
source_title: string;
|
|
66
|
+
confidence?: number;
|
|
67
|
+
reason_code: RejectedClaimReasonCode;
|
|
68
|
+
considered_in: 'seed_pool' | 'traversal';
|
|
69
|
+
anchor_claim_id?: string;
|
|
70
|
+
}
|
|
71
|
+
export interface RejectedRelationCandidate {
|
|
72
|
+
from_claim_id: string;
|
|
73
|
+
to_claim_id: string;
|
|
74
|
+
relation_type: string;
|
|
75
|
+
reason_code: RejectedRelationReasonCode;
|
|
76
|
+
strength?: string;
|
|
77
|
+
note?: string;
|
|
78
|
+
}
|
|
79
|
+
export interface ClosureUnitTrace {
|
|
80
|
+
thesis_claim_id: string;
|
|
81
|
+
objection_claim_id?: string;
|
|
82
|
+
reply_claim_id?: string;
|
|
83
|
+
objection_found: boolean;
|
|
84
|
+
reply_found: boolean;
|
|
85
|
+
unit_complete: boolean;
|
|
86
|
+
}
|
|
87
|
+
export interface RetrievalClosureStats {
|
|
88
|
+
major_thesis_count: number;
|
|
89
|
+
units_attempted: number;
|
|
90
|
+
units_completed: number;
|
|
91
|
+
claims_added_for_closure: number;
|
|
92
|
+
objections_added: number;
|
|
93
|
+
replies_added: number;
|
|
94
|
+
cap_limited_units: number;
|
|
95
|
+
units: ClosureUnitTrace[];
|
|
96
|
+
}
|
|
97
|
+
export interface RetrievalSeedTrace {
|
|
98
|
+
id: string;
|
|
99
|
+
claim_type: string;
|
|
100
|
+
domain: PhilosophicalDomain;
|
|
101
|
+
source_title: string;
|
|
102
|
+
confidence: number;
|
|
103
|
+
}
|
|
104
|
+
export interface RetrievalQueryDecompositionTrace {
|
|
105
|
+
focus_mode: 'corpus_overview' | 'focused';
|
|
106
|
+
domain_filter?: PhilosophicalDomain;
|
|
107
|
+
hybrid_mode: 'auto' | 'dense_only';
|
|
108
|
+
corpus_level_query: boolean;
|
|
109
|
+
lexical_terms: string[];
|
|
110
|
+
lexical_term_count: number;
|
|
111
|
+
}
|
|
112
|
+
export interface RetrievalPruningSummaryTrace {
|
|
113
|
+
claims_by_reason: Record<RejectedClaimReasonCode, number>;
|
|
114
|
+
relations_by_reason: Record<RejectedRelationReasonCode, number>;
|
|
115
|
+
}
|
|
116
|
+
export interface RetrievalResult {
|
|
117
|
+
claims: RetrievedClaim[];
|
|
118
|
+
relations: RetrievedRelation[];
|
|
119
|
+
arguments: RetrievedArgument[];
|
|
120
|
+
seed_claim_ids: string[];
|
|
121
|
+
evidence_passages?: Array<{
|
|
122
|
+
passage_id: string;
|
|
123
|
+
excerpt: string;
|
|
124
|
+
claim_ids: string[];
|
|
125
|
+
}>;
|
|
126
|
+
thinker_context?: ThinkerContext | null;
|
|
127
|
+
trace?: {
|
|
128
|
+
seed_pool_count: number;
|
|
129
|
+
selected_seed_count: number;
|
|
130
|
+
hybrid_mode?: 'auto' | 'dense_only';
|
|
131
|
+
dense_seed_count?: number;
|
|
132
|
+
lexical_seed_count?: number;
|
|
133
|
+
lexical_terms?: string[];
|
|
134
|
+
corpus_level_query?: boolean;
|
|
135
|
+
seed_balance_stats?: SeedBalanceStats;
|
|
136
|
+
traversal_mode?: 'beam_trusted_v1';
|
|
137
|
+
traversal_max_hops?: number;
|
|
138
|
+
traversal_hop_decay?: number;
|
|
139
|
+
traversal_base_confidence_threshold?: number;
|
|
140
|
+
traversal_confidence_thresholds?: number[];
|
|
141
|
+
traversal_domain_aware?: boolean;
|
|
142
|
+
traversal_trusted_edges_only?: boolean;
|
|
143
|
+
traversal_edge_priors?: Partial<Record<string, number>>;
|
|
144
|
+
query_decomposition?: RetrievalQueryDecompositionTrace;
|
|
145
|
+
seed_claims?: RetrievalSeedTrace[];
|
|
146
|
+
pruning_summary?: RetrievalPruningSummaryTrace;
|
|
147
|
+
traversed_claim_count: number;
|
|
148
|
+
relation_candidate_count: number;
|
|
149
|
+
relation_kept_count: number;
|
|
150
|
+
argument_candidate_count: number;
|
|
151
|
+
argument_kept_count: number;
|
|
152
|
+
closure_stats?: RetrievalClosureStats;
|
|
153
|
+
rejected_claims?: RejectedClaimCandidate[];
|
|
154
|
+
rejected_relations?: RejectedRelationCandidate[];
|
|
155
|
+
};
|
|
156
|
+
degraded: boolean;
|
|
157
|
+
degraded_reason?: string;
|
|
158
|
+
}
|
|
159
|
+
export interface RetrievalOptions {
|
|
160
|
+
/** Number of seed claims from vector search (default: 5) */
|
|
161
|
+
topK?: number;
|
|
162
|
+
/** Filter by philosophical domain */
|
|
163
|
+
domain?: PhilosophicalDomain;
|
|
164
|
+
/** Minimum confidence threshold for claims (default: 0) */
|
|
165
|
+
minConfidence?: number;
|
|
166
|
+
/** Optional override for graph traversal depth (hops from seed claims) */
|
|
167
|
+
maxHops?: number;
|
|
168
|
+
/** Optional cap on total claims returned after traversal */
|
|
169
|
+
maxClaims?: number;
|
|
170
|
+
/** Optional retrieval mode override for baseline comparisons */
|
|
171
|
+
hybridMode?: 'auto' | 'dense_only';
|
|
172
|
+
/** Optional viewer context for trace/audit routing */
|
|
173
|
+
viewerUid?: string | null;
|
|
174
|
+
/** Opt-in thinker graph enrichment for retrieved claim context */
|
|
175
|
+
enrichWithThinkerContext?: boolean;
|
|
176
|
+
}
|
|
177
|
+
export declare function formatThinkerContextBlock(context: ThinkerContext | null): string;
|
|
178
|
+
/**
|
|
179
|
+
* Retrieve structured philosophical context from the argument graph.
|
|
180
|
+
*
|
|
181
|
+
* Assembles complete argumentative chains by:
|
|
182
|
+
* 1. Finding semantically similar claims via vector search
|
|
183
|
+
* 2. Traversing the graph for supporting/contradicting/dependent claims
|
|
184
|
+
* 3. Resolving arguments those claims participate in
|
|
185
|
+
*
|
|
186
|
+
* Never throws — returns empty result on any failure.
|
|
187
|
+
*/
|
|
188
|
+
export declare function retrieveContext(userQuery: string, deps: GraphRagDeps, options?: RetrievalOptions): Promise<RetrievalResult>;
|
|
189
|
+
/**
|
|
190
|
+
* Format a RetrievalResult into a structured text block for the LLM prompt.
|
|
191
|
+
*
|
|
192
|
+
* Returns a human-readable representation of the retrieved argument graph
|
|
193
|
+
* that the model can use as grounding context for its three-pass analysis.
|
|
194
|
+
*/
|
|
195
|
+
export declare function buildContextBlock(result: RetrievalResult): string;
|
|
196
|
+
//# sourceMappingURL=retrieve-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retrieve-context.d.ts","sourceRoot":"","sources":["../src/retrieve-context.ts"],"names":[],"mappings":"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"}
|