hana-kgvector 0.1.1 → 0.1.3
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/README.md +2 -3
- package/dist/index.d.ts +1 -3
- package/dist/index.js +0 -7
- package/dist/index.js.map +1 -1
- package/package.json +2 -4
package/README.md
CHANGED
|
@@ -46,7 +46,6 @@ DEFAULT_EMBEDDING_MODEL=text-embedding-3-small
|
|
|
46
46
|
|
|
47
47
|
```typescript
|
|
48
48
|
import {
|
|
49
|
-
loadEnv,
|
|
50
49
|
createHanaConnection,
|
|
51
50
|
HanaPropertyGraphStore,
|
|
52
51
|
PropertyGraphIndex,
|
|
@@ -55,8 +54,8 @@ import {
|
|
|
55
54
|
} from "hana-kgvector";
|
|
56
55
|
import OpenAI from "openai";
|
|
57
56
|
|
|
58
|
-
// Load environment
|
|
59
|
-
|
|
57
|
+
// Load environment variables (user should handle this in their application)
|
|
58
|
+
// Example: dotenv.config({ path: ".env.local" });
|
|
60
59
|
|
|
61
60
|
// Connect to HANA
|
|
62
61
|
const conn = await createHanaConnection({
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
-
declare function loadEnv(): void;
|
|
4
|
-
|
|
5
3
|
type HanaConnectionConfig = {
|
|
6
4
|
host: string;
|
|
7
5
|
port?: number;
|
|
@@ -379,4 +377,4 @@ declare class ImplicitPathExtractor implements TransformComponent {
|
|
|
379
377
|
}): Promise<TextNode[]>;
|
|
380
378
|
}
|
|
381
379
|
|
|
382
|
-
export { BasePGRetriever, type BasePGRetrieverOptions, DEFAULT_PREAMBLE, type EmbedModel, type EntityNode, EntityNodeSchema, type EntityType, type ExtractedKG, type HanaConnection, type HanaConnectionConfig, HanaPropertyGraphStore, type HanaPropertyGraphStoreOptions, HanaSparqlStore, ImplicitPathExtractor, KG_NODES_KEY, KG_RELATIONS_KEY, KG_SOURCE_REL, type LLMClient, type LabelledNode, type NodeWithScore, PGRetriever, type PGRetrieverOptions, PropertyGraphIndex, type PropertyGraphIndexOptions, type PropertyGraphStore, type QueryBundle, type Relation, RelationSchema, type RelationType, type SchemaDefinition, SchemaLLMPathExtractor, type SchemaLLMPathExtractorOptions, TRIPLET_SOURCE_KEY, type TextNode, type TransformComponent, type Triplet, VECTOR_SOURCE_KEY, VectorContextRetriever, type VectorContextRetrieverOptions, type VectorStoreQuery, createEntityNode, createHanaConnection, createRelation, hanaExec,
|
|
380
|
+
export { BasePGRetriever, type BasePGRetrieverOptions, DEFAULT_PREAMBLE, type EmbedModel, type EntityNode, EntityNodeSchema, type EntityType, type ExtractedKG, type HanaConnection, type HanaConnectionConfig, HanaPropertyGraphStore, type HanaPropertyGraphStoreOptions, HanaSparqlStore, ImplicitPathExtractor, KG_NODES_KEY, KG_RELATIONS_KEY, KG_SOURCE_REL, type LLMClient, type LabelledNode, type NodeWithScore, PGRetriever, type PGRetrieverOptions, PropertyGraphIndex, type PropertyGraphIndexOptions, type PropertyGraphStore, type QueryBundle, type Relation, RelationSchema, type RelationType, type SchemaDefinition, SchemaLLMPathExtractor, type SchemaLLMPathExtractorOptions, TRIPLET_SOURCE_KEY, type TextNode, type TransformComponent, type Triplet, VECTOR_SOURCE_KEY, VectorContextRetriever, type VectorContextRetrieverOptions, type VectorStoreQuery, createEntityNode, createHanaConnection, createRelation, hanaExec, tripletToString };
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import "./chunk-VUNV25KB.js";
|
|
2
2
|
|
|
3
|
-
// src/env.ts
|
|
4
|
-
import dotenv from "dotenv";
|
|
5
|
-
function loadEnv() {
|
|
6
|
-
dotenv.config({ path: ".env.local" });
|
|
7
|
-
}
|
|
8
|
-
|
|
9
3
|
// src/hana/parse-host-port.ts
|
|
10
4
|
function parseHostPort(host, fallbackPort) {
|
|
11
5
|
const idx = host.lastIndexOf(":");
|
|
@@ -1030,7 +1024,6 @@ export {
|
|
|
1030
1024
|
createHanaConnection,
|
|
1031
1025
|
createRelation,
|
|
1032
1026
|
hanaExec,
|
|
1033
|
-
loadEnv,
|
|
1034
1027
|
tripletToString
|
|
1035
1028
|
};
|
|
1036
1029
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/env.ts","../src/hana/parse-host-port.ts","../src/hana/connection.ts","../src/hana/sparql-store.ts","../src/graph/types.ts","../src/graph/hana-property-graph-store.ts","../src/graph/pg-retriever.ts","../src/graph/retrievers/base.ts","../src/graph/retrievers/vector-context.ts","../src/graph/extractors/implicit.ts","../src/graph/property-graph-index.ts","../src/graph/extractors/schema-llm.ts"],"sourcesContent":["import dotenv from \"dotenv\";\n\nexport function loadEnv(): void {\n dotenv.config({ path: \".env.local\" });\n}\n","export function parseHostPort(\n host: string,\n fallbackPort: number\n): { host: string; port: number } {\n const idx = host.lastIndexOf(\":\");\n if (idx > -1 && idx < host.length - 1) {\n const maybePort = Number(host.slice(idx + 1));\n if (!Number.isNaN(maybePort) && maybePort > 0) {\n return { host: host.slice(0, idx), port: maybePort };\n }\n }\n\n return { host, port: fallbackPort };\n}\n","import { parseHostPort } from \"./parse-host-port\";\nimport type { HanaConnection, HanaConnectionConfig } from \"./types\";\n\nexport async function createHanaConnection(\n config: HanaConnectionConfig\n): Promise<HanaConnection> {\n let hana: any;\n try {\n const hanaModule = await import(\"@sap/hana-client\");\n hana = (hanaModule as any).default || hanaModule;\n } catch {\n throw new Error(\n \"@sap/hana-client is not available. Ensure it is installed and pnpm build scripts are approved (pnpm approve-builds).\"\n );\n }\n\n const fallbackPort = config.port ?? 443;\n const { host, port } = parseHostPort(config.host, fallbackPort);\n\n const conn: HanaConnection = hana.createConnection();\n\n await new Promise<void>((resolve, reject) => {\n conn.connect(\n {\n serverNode: `${host}:${port}`,\n uid: config.user,\n pwd: config.password,\n encrypt: config.encrypt ?? true,\n sslValidateCertificate: config.sslValidateCertificate ?? true\n },\n (err?: unknown) => (err ? reject(err) : resolve())\n );\n });\n\n return conn;\n}\n\nexport async function hanaExec<T = unknown>(\n conn: HanaConnection,\n sql: string\n): Promise<T> {\n return await new Promise<T>((resolve, reject) => {\n conn.exec(sql, (err: unknown, result: unknown) => {\n if (err) return reject(err);\n resolve(result as T);\n });\n });\n}\n","import type { HanaConnection } from \"./types\";\n\nexport type SparqlExecuteResult = unknown;\n\nexport class HanaSparqlStore {\n private readonly conn: HanaConnection;\n\n constructor(conn: HanaConnection) {\n this.conn = conn;\n }\n\n async execute(options: {\n sparql: string;\n headers?: string;\n defaultGraphUri?: string;\n }): Promise<SparqlExecuteResult> {\n const headerLines: string[] = [];\n\n if (options.defaultGraphUri) {\n headerLines.push(`rqx-default-graph-uri: ${options.defaultGraphUri}`);\n }\n\n if (options.headers) {\n headerLines.push(options.headers.trim());\n }\n\n const hdrs = headerLines.length ? `${headerLines.join(\"\\r\\n\")}\\r\\n` : \"\";\n\n const sql = \"CALL SPARQL_EXECUTE(?, ?, ?, ?)\";\n\n return await new Promise((resolve, reject) => {\n // @sap/hana-client supports conn.exec with parameter arrays.\n // We intentionally keep the result as unknown; callers can parse the XML/JSON depending on HANA return mode.\n (this.conn as any).exec(sql, [options.sparql, hdrs, \"\", null], (err: unknown, result: unknown) => {\n if (err) return reject(err);\n resolve(result);\n });\n });\n }\n\n async loadTurtle(options: {\n turtle: string;\n graphName: string;\n filename?: string;\n }): Promise<SparqlExecuteResult> {\n const requestHdrs = [\n \"rqx-load-protocol: true\",\n options.filename ? `rqx-load-filename: ${options.filename}` : undefined,\n `rqx-load-graphname: ${options.graphName}`\n ]\n .filter(Boolean)\n .join(\"\\r\\n\");\n\n return await this.execute({ sparql: options.turtle, headers: requestHdrs });\n }\n}\n","import { z } from \"zod\";\n\nexport const TRIPLET_SOURCE_KEY = \"triplet_source_id\";\nexport const KG_NODES_KEY = \"kg_nodes\";\nexport const KG_RELATIONS_KEY = \"kg_relations\";\nexport const VECTOR_SOURCE_KEY = \"vector_source_id\";\nexport const KG_SOURCE_REL = \"HAS_SOURCE\";\n\nexport const EntityNodeSchema = z.object({\n id: z.string(),\n label: z.string(),\n name: z.string(),\n properties: z.record(z.unknown()).default({}),\n embedding: z.array(z.number()).optional(),\n});\n\nexport type EntityNode = z.infer<typeof EntityNodeSchema>;\n\nexport const RelationSchema = z.object({\n id: z.string().optional(),\n label: z.string(),\n sourceId: z.string(),\n targetId: z.string(),\n properties: z.record(z.unknown()).default({}),\n});\n\nexport type Relation = z.infer<typeof RelationSchema>;\n\nexport type Triplet = [EntityNode, Relation, EntityNode];\n\nexport type LabelledNode = EntityNode;\n\nexport interface NodeWithScore {\n node: {\n id: string;\n text: string;\n metadata: Record<string, unknown>;\n refDocId?: string;\n };\n score: number;\n}\n\nexport interface QueryBundle {\n queryStr: string;\n embedding?: number[];\n embeddingStrs?: string[];\n}\n\nexport function createEntityNode(opts: {\n label: string;\n name: string;\n properties?: Record<string, unknown>;\n embedding?: number[];\n}): EntityNode {\n const id = `${opts.label.toUpperCase()}_${opts.name.replace(/\\s+/g, \"_\").toUpperCase()}`;\n return {\n id,\n label: opts.label,\n name: opts.name,\n properties: opts.properties ?? {},\n embedding: opts.embedding,\n };\n}\n\nexport function createRelation(opts: {\n label: string;\n sourceId: string;\n targetId: string;\n properties?: Record<string, unknown>;\n}): Relation {\n return {\n id: `${opts.sourceId}_${opts.label}_${opts.targetId}`,\n label: opts.label,\n sourceId: opts.sourceId,\n targetId: opts.targetId,\n properties: opts.properties ?? {},\n };\n}\n\nexport function tripletToString(triplet: Triplet, includeProperties = false): string {\n const [subj, rel, obj] = triplet;\n if (includeProperties) {\n return `${subj.name} (${subj.label}) -[${rel.label}]-> ${obj.name} (${obj.label})`;\n }\n return `${subj.id} -> ${rel.label} -> ${obj.id}`;\n}\n","import type { HanaConnection } from \"../hana/types\";\nimport type { PropertyGraphStore, VectorStoreQuery } from \"./property-graph-store\";\nimport type { EntityNode, Relation, Triplet, LabelledNode } from \"./types\";\nimport { TRIPLET_SOURCE_KEY, KG_SOURCE_REL } from \"./types\";\n\ntype LlamaNode = {\n id: string;\n text: string;\n metadata: Record<string, unknown>;\n embedding?: number[];\n hash?: string;\n};\n\nexport interface HanaPropertyGraphStoreOptions {\n graphName: string;\n vectorTableName?: string;\n llamaNodesTableName?: string;\n /** Optional, unused for dimensionless REAL_VECTOR columns (kept for backward compat logging). */\n vectorDimension?: number;\n /** If true, will DROP and recreate tables on init (intended for tests/dev only). */\n resetTables?: boolean;\n}\n\nexport class HanaPropertyGraphStore implements PropertyGraphStore {\n private readonly conn: HanaConnection;\n private readonly graphName: string;\n private readonly vectorTableName: string;\n private readonly llamaNodesTableName: string;\n private readonly resetTables: boolean;\n private initialized = false;\n\n readonly supportsVectorQueries = true;\n readonly supportsStructuredQueries = true;\n\n constructor(conn: HanaConnection, options: HanaPropertyGraphStoreOptions) {\n this.conn = conn;\n this.graphName = options.graphName;\n this.vectorTableName = options.vectorTableName ?? `${options.graphName.replace(/[^a-zA-Z0-9]/g, \"_\")}_VECTORS`;\n this.llamaNodesTableName = options.llamaNodesTableName ?? `${options.graphName.replace(/[^a-zA-Z0-9]/g, \"_\")}_NODES`;\n this.resetTables = options.resetTables ?? false;\n }\n\n private async ensureInitialized(): Promise<void> {\n if (this.initialized) return;\n\n // Optional destructive reset intended for tests/dev. This is OFF by default.\n if (this.resetTables) {\n await this.exec(`DROP TABLE ${this.vectorTableName}`).catch(() => {});\n await this.exec(`DROP TABLE ${this.llamaNodesTableName}`).catch(() => {});\n\n // Also clear the RDF named graph to avoid accumulating triples across test runs.\n // (Tables are recreated, but the KG graph would otherwise persist.)\n await this.sparqlExecute(`CLEAR GRAPH <${this.graphName}>`).catch(() => {});\n }\n\n // HANA does not support \"IF NOT EXISTS\" for CREATE TABLE. We try to create and ignore the\n // \"name exists\" error, but surface any other errors.\n const createVectorTable = `\n CREATE COLUMN TABLE ${this.vectorTableName} (\n id NVARCHAR(512) PRIMARY KEY,\n node_type NVARCHAR(64),\n label NVARCHAR(128),\n name NVARCHAR(512),\n properties NCLOB,\n embedding REAL_VECTOR\n )\n `;\n await this.exec(createVectorTable).catch((err: any) => {\n const message = String(err?.message ?? \"\");\n // Handle \"duplicate table name\" or \"already exists\"\n if (!/exists|duplicate table name/i.test(message)) {\n throw err;\n }\n });\n\n const createLlamaTable = `\n CREATE COLUMN TABLE ${this.llamaNodesTableName} (\n id NVARCHAR(512) PRIMARY KEY,\n text NCLOB,\n metadata NCLOB,\n hash NVARCHAR(64),\n embedding REAL_VECTOR\n )\n `;\n await this.exec(createLlamaTable).catch((err: any) => {\n const message = String(err?.message ?? \"\");\n if (!/exists|duplicate table name/i.test(message)) {\n throw err;\n }\n });\n\n this.initialized = true;\n }\n\n private async exec(sql: string, params?: unknown[]): Promise<unknown[]> {\n return new Promise((resolve, reject) => {\n if (params && params.length > 0) {\n (this.conn as any).exec(sql, params, (err: unknown, result: unknown) => {\n if (err) reject(err);\n else resolve(result as unknown[]);\n });\n } else {\n this.conn.exec(sql, (err: unknown, result: unknown) => {\n if (err) reject(err);\n else resolve(result as unknown[]);\n });\n }\n });\n }\n\n private async sparqlExecute(sparql: string, headers = \"\"): Promise<unknown> {\n // Some HANA environments require OUT parameters (e.g. RESPONSE) to be bound.\n // The @sap/hana-client driver provides a proc statement helper which correctly\n // handles OUT params *without* requiring you to pass them in the params array.\n try {\n const streamMod = await import(\"@sap/hana-client/extension/Stream\");\n const Stream = (streamMod as any).default ?? streamMod;\n\n return await new Promise<unknown>((resolve, reject) => {\n Stream.createProcStatement(this.conn as any, \"CALL SPARQL_EXECUTE(?, ?, ?, ?)\", (err: any, stmt: any) => {\n if (err) return reject(err);\n stmt.exec([sparql, headers], (err2: any, scalarParams: any) => {\n // scalarParams contains OUT params by name (e.g. RESPONSE)\n if (err2) return reject(err2);\n resolve(scalarParams);\n });\n });\n });\n } catch {\n // Fallback (may fail on systems requiring bound OUT params)\n return await new Promise<unknown>((resolve, reject) => {\n (this.conn as any).exec(\n \"CALL SPARQL_EXECUTE(?, ?, ?, ?)\",\n // Important: only pass IN params; OUT params are placeholders in SQL.\n [sparql, headers],\n (err: unknown, result: unknown) => {\n if (err) reject(err);\n else resolve(result);\n }\n );\n });\n }\n }\n\n private entityToUri(node: EntityNode): string {\n return `<urn:hkv:${this.graphName}:${node.label}:${encodeURIComponent(node.id)}>`;\n }\n\n private relationToTriples(rel: Relation, subj: EntityNode, obj: EntityNode): string {\n const subjUri = this.entityToUri(subj);\n const objUri = this.entityToUri(obj);\n const predUri = `<urn:hkv:rel:${rel.label}>`;\n return `${subjUri} ${predUri} ${objUri} .`;\n }\n\n private entityToTriples(node: EntityNode): string {\n const uri = this.entityToUri(node);\n const lines: string[] = [];\n lines.push(`${uri} a <urn:hkv:type:${node.label}> .`);\n lines.push(`${uri} <urn:hkv:prop:name> \"${this.escapeLiteral(node.name)}\" .`);\n\n for (const [key, value] of Object.entries(node.properties)) {\n if (value !== undefined && value !== null) {\n const escaped = typeof value === \"string\" ? this.escapeLiteral(value) : String(value);\n lines.push(`${uri} <urn:hkv:prop:${key}> \"${escaped}\" .`);\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n private escapeLiteral(s: string): string {\n return s.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\");\n }\n\n async upsertNodes(nodes: EntityNode[]): Promise<void> {\n await this.ensureInitialized();\n if (nodes.length === 0) return;\n\n const triples = nodes.map((n) => this.entityToTriples(n)).join(\"\\n\");\n const sparql = `INSERT DATA { GRAPH <${this.graphName}> { ${triples} } }`;\n await this.sparqlExecute(sparql);\n\n for (const node of nodes) {\n if (node.embedding) {\n // Defensive: prevent circular references from being serialized into NCLOB\n const safeProps: Record<string, unknown> = { ...(node.properties ?? {}) };\n delete (safeProps as any).kg_nodes;\n delete (safeProps as any).kg_relations;\n\n const sql = `\n UPSERT ${this.vectorTableName} (id, node_type, label, name, properties, embedding)\n VALUES (?, 'entity', ?, ?, ?, TO_REAL_VECTOR(?))\n WITH PRIMARY KEY\n `;\n await this.exec(sql, [\n node.id,\n node.label,\n node.name,\n JSON.stringify(safeProps),\n JSON.stringify(node.embedding),\n ]);\n }\n }\n }\n\n async upsertRelations(relations: Relation[]): Promise<void> {\n await this.ensureInitialized();\n if (relations.length === 0) return;\n\n const nodeIds = new Set<string>();\n for (const rel of relations) {\n nodeIds.add(rel.sourceId);\n nodeIds.add(rel.targetId);\n }\n\n const existingNodes = await this.get({ ids: Array.from(nodeIds) });\n const nodeMap = new Map(existingNodes.map((n) => [n.id, n]));\n\n const lines: string[] = [];\n for (const rel of relations) {\n const subj = nodeMap.get(rel.sourceId);\n const obj = nodeMap.get(rel.targetId);\n if (subj && obj) {\n lines.push(this.relationToTriples(rel, subj, obj));\n }\n }\n\n if (lines.length > 0) {\n const sparql = `INSERT DATA { GRAPH <${this.graphName}> { ${lines.join(\"\\n\")} } }`;\n await this.sparqlExecute(sparql);\n }\n }\n\n async get(opts: { ids: string[] }): Promise<LabelledNode[]> {\n await this.ensureInitialized();\n if (opts.ids.length === 0) return [];\n\n const rows = (await this.exec(\n `SELECT id, label, name, properties FROM ${this.vectorTableName} WHERE id IN (${opts.ids.map(() => \"?\").join(\",\")})`,\n opts.ids\n )) as any[];\n\n return (rows ?? []).map((r) => ({\n id: r.ID ?? r.id,\n label: r.LABEL ?? r.label,\n name: r.NAME ?? r.name,\n properties: JSON.parse(r.PROPERTIES ?? r.properties ?? \"{}\"),\n }));\n }\n\n async getRelMap(opts: {\n nodes: LabelledNode[];\n depth?: number;\n limit?: number;\n ignoreRels?: string[];\n }): Promise<Triplet[]> {\n await this.ensureInitialized();\n if (opts.nodes.length === 0) return [];\n\n const nodeIds = opts.nodes.map((n) => n.id);\n const depth = opts.depth ?? 1;\n const limit = opts.limit ?? 100;\n const ignoreRels = opts.ignoreRels ?? [KG_SOURCE_REL];\n\n const filterClause = nodeIds\n .map((id) => `CONTAINS(STR(?s), \"${encodeURIComponent(id)}\") || CONTAINS(STR(?o), \"${encodeURIComponent(id)}\")`)\n .join(\" || \");\n\n const ignoreFilter = ignoreRels.length > 0\n ? `FILTER(${ignoreRels.map((r) => `!CONTAINS(STR(?p), \"${r}\")`).join(\" && \")})`\n : \"\";\n\n const sparql = `\n SELECT ?s ?p ?o\n FROM <${this.graphName}>\n WHERE {\n ?s ?p ?o .\n FILTER(${filterClause})\n ${ignoreFilter}\n }\n LIMIT ${limit}\n `;\n\n const result = await this.exec(\n `SELECT * FROM SPARQL_TABLE('${sparql.replace(/'/g, \"''\")}')`\n ) as any[];\n\n const triplets: Triplet[] = [];\n const nodeMap = new Map(opts.nodes.map((n) => [n.id, n]));\n\n for (const row of result ?? []) {\n const sUri = row.S ?? row.s;\n const pUri = row.P ?? row.p;\n const oUri = row.O ?? row.o;\n\n const sId = this.extractIdFromUri(sUri);\n const oId = this.extractIdFromUri(oUri);\n const relLabel = this.extractRelLabelFromUri(pUri);\n\n let subj = nodeMap.get(sId);\n let obj = nodeMap.get(oId);\n\n if (!subj) {\n subj = { id: sId, label: \"UNKNOWN\", name: sId, properties: {} };\n }\n if (!obj) {\n obj = { id: oId, label: \"UNKNOWN\", name: oId, properties: {} };\n }\n\n const rel: Relation = {\n label: relLabel,\n sourceId: sId,\n targetId: oId,\n properties: {},\n };\n\n triplets.push([subj, rel, obj]);\n }\n\n return triplets;\n }\n\n private extractIdFromUri(uri: string): string {\n // URI format: <urn:hkv:graphName:label:id> or just the content without angle brackets\n // The ID is the last segment after the label (second-to-last segment)\n const cleanUri = uri.replace(/^<|>$/g, \"\");\n const parts = cleanUri.split(\":\");\n // ID is the last part, decode it\n if (parts.length >= 2) {\n return decodeURIComponent(parts[parts.length - 1]);\n }\n return uri;\n }\n\n private extractRelLabelFromUri(uri: string): string {\n const match = uri.match(/urn:hkv:rel:(.+)>?$/);\n return match ? match[1].replace(/>$/, \"\") : uri;\n }\n\n async delete(opts: { ids: string[] }): Promise<void> {\n await this.ensureInitialized();\n if (opts.ids.length === 0) return;\n\n for (const id of opts.ids) {\n await this.exec(`DELETE FROM ${this.vectorTableName} WHERE id = ?`, [id]);\n }\n }\n\n async vectorQuery(query: VectorStoreQuery): Promise<[LabelledNode[], number[]]> {\n await this.ensureInitialized();\n\n const sql = `\n SELECT id, label, name, properties,\n COSINE_SIMILARITY(embedding, TO_REAL_VECTOR(?)) AS score\n FROM ${this.vectorTableName}\n WHERE embedding IS NOT NULL\n ORDER BY score DESC\n LIMIT ?\n `;\n\n const rows = (await this.exec(sql, [\n JSON.stringify(query.queryEmbedding),\n query.similarityTopK,\n ])) as any[];\n\n const nodes: LabelledNode[] = [];\n const scores: number[] = [];\n\n for (const row of rows ?? []) {\n nodes.push({\n id: row.ID ?? row.id,\n label: row.LABEL ?? row.label,\n name: row.NAME ?? row.name,\n properties: JSON.parse(row.PROPERTIES ?? row.properties ?? \"{}\"),\n });\n scores.push(row.SCORE ?? row.score ?? 0);\n }\n\n return [nodes, scores];\n }\n\n async upsertLlamaNodes(nodes: LlamaNode[]): Promise<void> {\n await this.ensureInitialized();\n for (const node of nodes) {\n // Remove circular references from metadata before serialization\n const { metadata, ...rest } = node;\n const safeMetadata = { ...metadata };\n delete (safeMetadata as any).kg_nodes;\n delete (safeMetadata as any).kg_relations;\n\n const sql = `\n UPSERT ${this.llamaNodesTableName} (id, text, metadata, hash, embedding)\n VALUES (?, ?, ?, ?, ${node.embedding ? \"TO_REAL_VECTOR(?)\" : \"NULL\"})\n WITH PRIMARY KEY\n `;\n const params: unknown[] = [\n node.id,\n node.text,\n JSON.stringify(safeMetadata ?? {}),\n node.hash ?? null,\n ];\n if (node.embedding) {\n params.push(JSON.stringify(node.embedding));\n }\n await this.exec(sql, params);\n }\n }\n\n async getLlamaNodes(ids: string[]): Promise<LlamaNode[]> {\n await this.ensureInitialized();\n if (ids.length === 0) return [];\n\n const rows = (await this.exec(\n `SELECT id, text, metadata, hash FROM ${this.llamaNodesTableName} WHERE id IN (${ids.map(() => \"?\").join(\",\")})`,\n ids\n )) as any[];\n\n return (rows ?? []).map((r) => ({\n id: r.ID ?? r.id,\n text: r.TEXT ?? r.text,\n metadata: JSON.parse(r.METADATA ?? r.metadata ?? \"{}\"),\n hash: r.HASH ?? r.hash,\n }));\n }\n}\n","import type { QueryBundle, NodeWithScore } from \"./types\";\nimport type { BasePGRetriever } from \"./retrievers/base\";\n\nexport interface PGRetrieverOptions {\n subRetrievers: BasePGRetriever[];\n showProgress?: boolean;\n}\n\nexport class PGRetriever {\n private readonly subRetrievers: BasePGRetriever[];\n private readonly showProgress: boolean;\n\n constructor(options: PGRetrieverOptions) {\n this.subRetrievers = options.subRetrievers;\n this.showProgress = options.showProgress ?? false;\n }\n\n private deduplicate(nodes: NodeWithScore[]): NodeWithScore[] {\n const seen = new Set<string>();\n const deduped: NodeWithScore[] = [];\n\n for (const node of nodes) {\n if (!seen.has(node.node.text)) {\n deduped.push(node);\n seen.add(node.node.text);\n }\n }\n\n return deduped;\n }\n\n async retrieve(queryBundle: QueryBundle): Promise<NodeWithScore[]> {\n const allResults: NodeWithScore[] = [];\n\n const promises = this.subRetrievers.map((r) => r.retrieve(queryBundle));\n const results = await Promise.all(promises);\n\n for (const result of results) {\n allResults.push(...result);\n }\n\n return this.deduplicate(allResults);\n }\n}\n","import type { PropertyGraphStore } from \"../property-graph-store\";\nimport type { Triplet, NodeWithScore, QueryBundle, LabelledNode } from \"../types\";\nimport { TRIPLET_SOURCE_KEY, tripletToString } from \"../types\";\n\nexport const DEFAULT_PREAMBLE = \"Here are some facts extracted from the provided text:\\n\\n\";\n\nexport interface BasePGRetrieverOptions {\n graphStore: PropertyGraphStore;\n includeText?: boolean;\n includeTextPreamble?: string;\n includeProperties?: boolean;\n}\n\nexport abstract class BasePGRetriever {\n protected readonly graphStore: PropertyGraphStore;\n protected readonly includeText: boolean;\n protected readonly includeTextPreamble: string;\n protected readonly includeProperties: boolean;\n\n constructor(options: BasePGRetrieverOptions) {\n this.graphStore = options.graphStore;\n this.includeText = options.includeText ?? true;\n this.includeTextPreamble = options.includeTextPreamble ?? DEFAULT_PREAMBLE;\n this.includeProperties = options.includeProperties ?? false;\n }\n\n protected getNodesWithScore(triplets: Triplet[], scores?: number[]): NodeWithScore[] {\n const results: NodeWithScore[] = [];\n\n for (let i = 0; i < triplets.length; i++) {\n const triplet = triplets[i];\n const sourceId = triplet[0].properties[TRIPLET_SOURCE_KEY] as string | undefined;\n\n const text = tripletToString(triplet, this.includeProperties);\n\n results.push({\n node: {\n id: `triplet_${i}`,\n text,\n metadata: {},\n refDocId: sourceId,\n },\n score: scores?.[i] ?? 1.0,\n });\n }\n\n return results;\n }\n\n protected async addSourceText(nodes: NodeWithScore[]): Promise<NodeWithScore[]> {\n if (!this.graphStore.getLlamaNodes) {\n return nodes;\n }\n\n const refDocIds = nodes\n .map((n) => n.node.refDocId)\n .filter((id): id is string => id !== undefined);\n\n if (refDocIds.length === 0) return nodes;\n\n const ogNodes = await this.graphStore.getLlamaNodes(refDocIds);\n const nodeMap = new Map(ogNodes.map((n) => [n.id, n]));\n\n const graphNodeMap = new Map<string, string[]>();\n for (const node of nodes) {\n const refDocId = node.node.refDocId ?? \"\";\n if (!graphNodeMap.has(refDocId)) {\n graphNodeMap.set(refDocId, []);\n }\n graphNodeMap.get(refDocId)!.push(node.node.text);\n }\n\n const resultNodes: NodeWithScore[] = [];\n for (const nodeWithScore of nodes) {\n const mappedNode = nodeMap.get(nodeWithScore.node.refDocId ?? \"\");\n\n if (mappedNode) {\n const graphContent = graphNodeMap.get(mappedNode.id) ?? [];\n if (graphContent.length > 0) {\n const graphContentStr = graphContent.join(\"\\n\");\n const newContent = this.includeTextPreamble + graphContentStr + \"\\n\\n\" + mappedNode.text;\n resultNodes.push({\n node: {\n id: mappedNode.id,\n text: newContent,\n metadata: mappedNode.metadata,\n refDocId: nodeWithScore.node.refDocId,\n },\n score: nodeWithScore.score,\n });\n } else {\n resultNodes.push({\n node: {\n id: mappedNode.id,\n text: mappedNode.text,\n metadata: mappedNode.metadata,\n refDocId: nodeWithScore.node.refDocId,\n },\n score: nodeWithScore.score,\n });\n }\n } else {\n resultNodes.push(nodeWithScore);\n }\n }\n\n return resultNodes;\n }\n\n async retrieve(queryBundle: QueryBundle): Promise<NodeWithScore[]> {\n let nodes = await this.retrieveFromGraph(queryBundle);\n if (this.includeText && nodes.length > 0) {\n nodes = await this.addSourceText(nodes);\n }\n return nodes;\n }\n\n abstract retrieveFromGraph(queryBundle: QueryBundle): Promise<NodeWithScore[]>;\n}\n","import type { PropertyGraphStore, VectorStoreQuery } from \"../property-graph-store\";\nimport type { QueryBundle, NodeWithScore, LabelledNode } from \"../types\";\nimport { KG_SOURCE_REL } from \"../types\";\nimport { BasePGRetriever, type BasePGRetrieverOptions } from \"./base\";\n\nexport interface EmbedModel {\n getTextEmbedding(text: string): Promise<number[]>;\n getTextEmbeddingBatch(texts: string[]): Promise<number[][]>;\n}\n\nexport interface VectorContextRetrieverOptions extends BasePGRetrieverOptions {\n embedModel: EmbedModel;\n similarityTopK?: number;\n pathDepth?: number;\n limit?: number;\n similarityScore?: number;\n /** Enable cross-check boosting: boost scores when vector-matched entities link to graph facts (default: true) */\n crossCheckBoost?: boolean;\n /** Multiplier for cross-check boost (default: 1.25 = 25% boost) */\n crossCheckBoostFactor?: number;\n}\n\nexport class VectorContextRetriever extends BasePGRetriever {\n private readonly embedModel: EmbedModel;\n private readonly similarityTopK: number;\n private readonly pathDepth: number;\n private readonly limit: number;\n private readonly similarityScore?: number;\n private readonly crossCheckBoost: boolean;\n private readonly crossCheckBoostFactor: number;\n\n constructor(options: VectorContextRetrieverOptions) {\n super(options);\n this.embedModel = options.embedModel;\n this.similarityTopK = options.similarityTopK ?? 4;\n this.pathDepth = options.pathDepth ?? 1;\n this.limit = options.limit ?? 30;\n this.similarityScore = options.similarityScore;\n this.crossCheckBoost = options.crossCheckBoost ?? true;\n this.crossCheckBoostFactor = options.crossCheckBoostFactor ?? 1.25;\n }\n\n async retrieveFromGraph(queryBundle: QueryBundle): Promise<NodeWithScore[]> {\n let embedding = queryBundle.embedding;\n\n if (!embedding) {\n embedding = await this.embedModel.getTextEmbedding(queryBundle.queryStr);\n }\n\n const vectorQuery: VectorStoreQuery = {\n queryEmbedding: embedding,\n similarityTopK: this.similarityTopK,\n };\n\n if (!this.graphStore.supportsVectorQueries || !this.graphStore.vectorQuery) {\n throw new Error(\"Graph store does not support vector queries\");\n }\n\n const [kgNodes, scores] = await this.graphStore.vectorQuery(vectorQuery);\n\n if (kgNodes.length === 0) {\n return [];\n }\n\n const kgIds = kgNodes.map((n) => n.id);\n\n // Build provenance set from vector-matched nodes for cross-check boosting\n // This includes document IDs, chunk IDs, and other source identifiers\n const provenanceSet = new Set<string>();\n if (this.crossCheckBoost) {\n for (const node of kgNodes) {\n // Add node ID itself (for CHUNK nodes)\n provenanceSet.add(node.id.toLowerCase());\n provenanceSet.add(node.name.toLowerCase());\n \n // Add documentId from properties if present\n const props = node.properties ?? {};\n if (props.documentId) {\n provenanceSet.add(String(props.documentId).toLowerCase());\n }\n if (props.sourceChunk) {\n provenanceSet.add(String(props.sourceChunk).toLowerCase());\n }\n }\n }\n\n const triplets = await this.graphStore.getRelMap({\n nodes: kgNodes,\n depth: this.pathDepth,\n limit: this.limit,\n ignoreRels: [KG_SOURCE_REL],\n });\n\n const newScores: number[] = [];\n for (const triplet of triplets) {\n const idx1 = kgIds.indexOf(triplet[0].id);\n const idx2 = kgIds.indexOf(triplet[2].id);\n const score1 = idx1 >= 0 ? scores[idx1] : 0;\n const score2 = idx2 >= 0 ? scores[idx2] : 0;\n let baseScore = Math.max(score1, score2);\n\n // Cross-check boosting: if triplet entities have provenance linking back to\n // vector-matched nodes, boost the score. This rewards facts that are both\n // semantically similar AND have explicit graph connections.\n if (this.crossCheckBoost && baseScore > 0) {\n const shouldBoost = this.checkProvenance(triplet[0], provenanceSet) ||\n this.checkProvenance(triplet[2], provenanceSet);\n if (shouldBoost) {\n baseScore = Math.min(1.0, baseScore * this.crossCheckBoostFactor);\n }\n }\n\n newScores.push(baseScore);\n }\n\n let results = triplets.map((t, i) => ({ triplet: t, score: newScores[i] }));\n\n if (this.similarityScore !== undefined) {\n results = results.filter((r) => r.score >= this.similarityScore!);\n }\n\n results.sort((a, b) => b.score - a.score);\n\n return this.getNodesWithScore(\n results.map((r) => r.triplet),\n results.map((r) => r.score)\n );\n }\n\n /**\n * Check if a node has provenance linking to the vector-matched nodes.\n * Returns true if the node's properties contain a documentId or sourceChunk\n * that matches something in the provenance set.\n */\n private checkProvenance(node: LabelledNode, provenanceSet: Set<string>): boolean {\n if (provenanceSet.size === 0) return false;\n\n const props = node.properties ?? {};\n \n // Check documentId property\n if (props.documentId && provenanceSet.has(String(props.documentId).toLowerCase())) {\n return true;\n }\n \n // Check sourceChunk property\n if (props.sourceChunk && provenanceSet.has(String(props.sourceChunk).toLowerCase())) {\n return true;\n }\n \n // Check if this node itself is in the provenance set (e.g., a CHUNK node)\n if (provenanceSet.has(node.id.toLowerCase()) || provenanceSet.has(node.name.toLowerCase())) {\n return true;\n }\n\n return false;\n }\n}\n","import type { TransformComponent, TextNode } from \"./types\";\nimport type { EntityNode, Relation } from \"../types\";\nimport { KG_NODES_KEY, KG_RELATIONS_KEY, createEntityNode, createRelation } from \"../types\";\n\nexport class ImplicitPathExtractor implements TransformComponent {\n async transform(nodes: TextNode[], options?: { showProgress?: boolean }): Promise<TextNode[]> {\n const results: TextNode[] = [];\n\n for (const node of nodes) {\n const existingNodes = (node.metadata[KG_NODES_KEY] as EntityNode[]) ?? [];\n const existingRelations = (node.metadata[KG_RELATIONS_KEY] as Relation[]) ?? [];\n\n const safeMetadata: Record<string, unknown> = { ...node.metadata };\n delete safeMetadata[KG_NODES_KEY];\n delete safeMetadata[KG_RELATIONS_KEY];\n\n const chunkNode = createEntityNode({\n label: \"CHUNK\",\n name: node.id,\n properties: {\n text: node.text.slice(0, 500),\n ...safeMetadata,\n },\n });\n\n if (node.metadata.documentId) {\n const docNode = createEntityNode({\n label: \"DOCUMENT\",\n name: String(node.metadata.documentId),\n properties: {},\n });\n\n const rel = createRelation({\n label: \"FROM_DOCUMENT\",\n sourceId: chunkNode.id,\n targetId: docNode.id,\n });\n\n existingNodes.push(docNode);\n existingRelations.push(rel);\n }\n\n existingNodes.push(chunkNode);\n\n results.push({\n ...node,\n metadata: {\n ...node.metadata,\n [KG_NODES_KEY]: existingNodes,\n [KG_RELATIONS_KEY]: existingRelations,\n },\n });\n }\n\n return results;\n }\n}\n","import type { PropertyGraphStore } from \"./property-graph-store\";\nimport type { TransformComponent, TextNode } from \"./extractors/types\";\nimport type { EntityNode, Relation, NodeWithScore, QueryBundle } from \"./types\";\nimport { KG_NODES_KEY, KG_RELATIONS_KEY, TRIPLET_SOURCE_KEY } from \"./types\";\nimport { PGRetriever } from \"./pg-retriever\";\nimport { VectorContextRetriever, type EmbedModel } from \"./retrievers/vector-context\";\nimport { ImplicitPathExtractor } from \"./extractors/implicit\";\nimport { createHash } from \"crypto\";\n\nexport interface PropertyGraphIndexOptions {\n propertyGraphStore: PropertyGraphStore;\n kgExtractors?: TransformComponent[];\n embedModel?: EmbedModel;\n embedKgNodes?: boolean;\n showProgress?: boolean;\n}\n\nexport class PropertyGraphIndex {\n private readonly propertyGraphStore: PropertyGraphStore;\n private readonly kgExtractors: TransformComponent[];\n private readonly embedModel?: EmbedModel;\n private readonly embedKgNodes: boolean;\n private readonly showProgress: boolean;\n\n constructor(options: PropertyGraphIndexOptions) {\n this.propertyGraphStore = options.propertyGraphStore;\n this.kgExtractors = options.kgExtractors ?? [new ImplicitPathExtractor()];\n this.embedModel = options.embedModel;\n this.embedKgNodes = options.embedKgNodes ?? true;\n this.showProgress = options.showProgress ?? false;\n }\n\n get graphStore(): PropertyGraphStore {\n return this.propertyGraphStore;\n }\n\n static fromExisting(options: PropertyGraphIndexOptions): PropertyGraphIndex {\n return new PropertyGraphIndex(options);\n }\n\n private computeHash(text: string): string {\n return createHash(\"md5\").update(text).digest(\"hex\");\n }\n\n async insert(nodes: TextNode[]): Promise<TextNode[]> {\n if (nodes.length === 0) return [];\n\n let processedNodes = nodes;\n for (const extractor of this.kgExtractors) {\n processedNodes = await extractor.transform(processedNodes, {\n showProgress: this.showProgress,\n });\n }\n\n for (const node of processedNodes) {\n if (!node.metadata[KG_NODES_KEY] && !node.metadata[KG_RELATIONS_KEY]) {\n throw new Error(`Node ${node.id} has no KG_NODES_KEY or KG_RELATIONS_KEY after extraction`);\n }\n }\n\n const kgNodesToInsert: EntityNode[] = [];\n const kgRelsToInsert: Relation[] = [];\n\n for (const node of processedNodes) {\n const kgNodes = (node.metadata[KG_NODES_KEY] as EntityNode[]) ?? [];\n const kgRels = (node.metadata[KG_RELATIONS_KEY] as Relation[]) ?? [];\n\n for (const kgNode of kgNodes) {\n kgNode.properties[TRIPLET_SOURCE_KEY] = node.id;\n }\n for (const kgRel of kgRels) {\n kgRel.properties[TRIPLET_SOURCE_KEY] = node.id;\n }\n\n kgNodesToInsert.push(...kgNodes);\n kgRelsToInsert.push(...kgRels);\n }\n\n const kgNodeIds = [...new Set(kgNodesToInsert.map((n) => n.id))];\n const existingKgNodes = await this.propertyGraphStore.get({ ids: kgNodeIds });\n const existingKgNodeIds = new Set(existingKgNodes.map((n) => n.id));\n const newKgNodes = kgNodesToInsert.filter((n) => !existingKgNodeIds.has(n.id));\n\n if (this.propertyGraphStore.getLlamaNodes) {\n const existingLlamaNodes = await this.propertyGraphStore.getLlamaNodes(\n processedNodes.map((n) => n.id)\n );\n const existingHashes = new Set(existingLlamaNodes.map((n) => n.hash));\n processedNodes = processedNodes.filter((n) => {\n const hash = this.computeHash(n.text);\n n.hash = hash;\n return !existingHashes.has(hash);\n });\n }\n\n if (this.embedKgNodes && this.embedModel && newKgNodes.length > 0) {\n const nodeTexts = processedNodes.map((n) => n.text);\n const embeddings = await this.embedModel.getTextEmbeddingBatch(nodeTexts);\n for (let i = 0; i < processedNodes.length; i++) {\n processedNodes[i].embedding = embeddings[i];\n }\n\n const kgNodeTexts = newKgNodes.map((n) => `${n.label}: ${n.name}`);\n const kgEmbeddings = await this.embedModel.getTextEmbeddingBatch(kgNodeTexts);\n for (let i = 0; i < newKgNodes.length; i++) {\n newKgNodes[i].embedding = kgEmbeddings[i];\n }\n }\n\n if (this.propertyGraphStore.upsertLlamaNodes && processedNodes.length > 0) {\n await this.propertyGraphStore.upsertLlamaNodes(\n processedNodes.map((n) => ({\n id: n.id,\n text: n.text,\n metadata: n.metadata,\n embedding: n.embedding,\n hash: n.hash,\n }))\n );\n }\n\n if (newKgNodes.length > 0) {\n await this.propertyGraphStore.upsertNodes(newKgNodes);\n }\n\n if (kgRelsToInsert.length > 0) {\n await this.propertyGraphStore.upsertRelations(kgRelsToInsert);\n }\n\n return processedNodes;\n }\n\n async delete(nodeIds: string[]): Promise<void> {\n await this.propertyGraphStore.delete({ ids: nodeIds });\n }\n\n asRetriever(options?: {\n subRetrievers?: Array<{ retrieve(query: QueryBundle): Promise<NodeWithScore[]> }>;\n includeText?: boolean;\n /** Number of top similar nodes to retrieve via vector search (default: 4) */\n similarityTopK?: number;\n /** Graph traversal depth from matched nodes (default: 1) */\n pathDepth?: number;\n /** Maximum number of triplets to return after expansion (default: 30) */\n limit?: number;\n /** Minimum similarity score threshold to include results (default: no threshold) */\n similarityScore?: number;\n /** Enable cross-check boosting: boost scores when vector-matched entities link to graph facts (default: true) */\n crossCheckBoost?: boolean;\n /** Multiplier for cross-check boost (default: 1.25 = 25% boost) */\n crossCheckBoostFactor?: number;\n }): PGRetriever {\n let subRetrievers = options?.subRetrievers as any[];\n\n if (!subRetrievers && this.embedModel && this.propertyGraphStore.supportsVectorQueries) {\n subRetrievers = [\n new VectorContextRetriever({\n graphStore: this.propertyGraphStore,\n embedModel: this.embedModel,\n includeText: options?.includeText ?? true,\n similarityTopK: options?.similarityTopK,\n pathDepth: options?.pathDepth,\n limit: options?.limit,\n similarityScore: options?.similarityScore,\n crossCheckBoost: options?.crossCheckBoost,\n crossCheckBoostFactor: options?.crossCheckBoostFactor,\n }),\n ];\n }\n\n if (!subRetrievers) {\n subRetrievers = [];\n }\n\n return new PGRetriever({ subRetrievers });\n }\n\n async query(queryStr: string, options?: {\n /** Number of top similar nodes to retrieve via vector search (default: 4) */\n similarityTopK?: number;\n /** Graph traversal depth from matched nodes (default: 1) */\n pathDepth?: number;\n /** Maximum number of triplets to return after expansion (default: 30) */\n limit?: number;\n /** Minimum similarity score threshold to include results (default: no threshold) */\n similarityScore?: number;\n /** Enable cross-check boosting: boost scores when vector-matched entities link to graph facts (default: true) */\n crossCheckBoost?: boolean;\n /** Multiplier for cross-check boost (default: 1.25 = 25% boost) */\n crossCheckBoostFactor?: number;\n }): Promise<NodeWithScore[]> {\n const retriever = this.asRetriever(options);\n return retriever.retrieve({ queryStr });\n }\n}\n","import { z } from \"zod\";\nimport type { TransformComponent, TextNode, SchemaDefinition } from \"./types\";\nimport type { EntityNode, Relation, Triplet } from \"../types\";\nimport { KG_NODES_KEY, KG_RELATIONS_KEY, createEntityNode, createRelation } from \"../types\";\n\nexport interface LLMClient {\n structuredPredict<T>(schema: z.ZodType<T>, prompt: string): Promise<T>;\n}\n\nexport interface SchemaLLMPathExtractorOptions {\n llm: LLMClient;\n schema: SchemaDefinition;\n maxTripletsPerChunk?: number;\n strict?: boolean;\n extractPromptTemplate?: string;\n}\n\nconst DEFAULT_EXTRACT_PROMPT = `Given the following text, extract a knowledge graph according to the provided schema.\nTry to limit to {maxTriplets} extracted paths.\n\nSchema:\n- Entity types: {entityTypes}\n- Relation types: {relationTypes}\n- Valid relationships: {validationSchema}\n\nText:\n-------\n{text}\n-------\n\nExtract entities and relationships from the text above.\nReturn your answer as a JSON object with a \"triplets\" array. Each triplet should have:\n- \"subject\": { \"name\": string, \"type\": one of [{entityTypes}] }\n- \"relation\": { \"type\": one of [{relationTypes}] }\n- \"object\": { \"name\": string, \"type\": one of [{entityTypes}] }\n\nExample output format:\n{\n \"triplets\": [\n {\n \"subject\": { \"name\": \"John\", \"type\": \"PERSON\" },\n \"relation\": { \"type\": \"WORKS_AT\" },\n \"object\": { \"name\": \"Acme Corp\", \"type\": \"ORGANIZATION\" }\n }\n ]\n}`;\n\nexport class SchemaLLMPathExtractor implements TransformComponent {\n private readonly llm: LLMClient;\n private readonly schema: SchemaDefinition;\n private readonly maxTripletsPerChunk: number;\n private readonly strict: boolean;\n private readonly extractPromptTemplate: string;\n private readonly tripletSchema: z.ZodType<any>;\n\n constructor(options: SchemaLLMPathExtractorOptions) {\n this.llm = options.llm;\n this.schema = options.schema;\n this.maxTripletsPerChunk = options.maxTripletsPerChunk ?? 10;\n this.strict = options.strict ?? true;\n this.extractPromptTemplate = options.extractPromptTemplate ?? DEFAULT_EXTRACT_PROMPT;\n\n const entityTypeEnum = z.enum(this.schema.entityTypes as [string, ...string[]]);\n const relationTypeEnum = z.enum(this.schema.relationTypes as [string, ...string[]]);\n\n const entitySchema = z.object({\n name: z.string(),\n type: entityTypeEnum,\n properties: z.record(z.unknown()).optional(),\n });\n\n const relationSchema = z.object({\n type: relationTypeEnum,\n properties: z.record(z.unknown()).optional(),\n });\n\n const tripletSchema = z.object({\n subject: entitySchema,\n relation: relationSchema,\n object: entitySchema,\n });\n\n this.tripletSchema = z.object({\n triplets: z.array(tripletSchema),\n });\n }\n\n private buildPrompt(text: string): string {\n const validationSchemaStr = this.schema.validationSchema\n ?.map(([s, r, o]) => `(${s})-[${r}]->(${o})`)\n .join(\", \") ?? \"Any valid combination\";\n\n return this.extractPromptTemplate\n .replace(\"{maxTriplets}\", String(this.maxTripletsPerChunk))\n .replace(\"{entityTypes}\", this.schema.entityTypes.join(\", \"))\n .replace(\"{relationTypes}\", this.schema.relationTypes.join(\", \"))\n .replace(\"{validationSchema}\", validationSchemaStr)\n .replace(\"{text}\", text);\n }\n\n private isValidTriplet(subjectType: string, relationType: string, objectType: string): boolean {\n if (!this.strict || !this.schema.validationSchema) {\n return true;\n }\n\n return this.schema.validationSchema.some(\n ([s, r, o]) =>\n s.toUpperCase() === subjectType.toUpperCase() &&\n r.toUpperCase() === relationType.toUpperCase() &&\n o.toUpperCase() === objectType.toUpperCase()\n );\n }\n\n private pruneInvalidTriplets(\n extracted: { triplets: Array<{ subject: any; relation: any; object: any }> }\n ): Triplet[] {\n const validTriplets: Triplet[] = [];\n\n for (const triplet of extracted.triplets) {\n const subjectType = String(triplet.subject.type).toUpperCase().replace(/\\s+/g, \"_\");\n const relationType = String(triplet.relation.type).toUpperCase().replace(/\\s+/g, \"_\");\n const objectType = String(triplet.object.type).toUpperCase().replace(/\\s+/g, \"_\");\n\n if (!this.isValidTriplet(subjectType, relationType, objectType)) {\n continue;\n }\n\n const subjectName = String(triplet.subject.name).trim();\n const objectName = String(triplet.object.name).trim();\n\n if (subjectName.toLowerCase() === objectName.toLowerCase()) {\n continue;\n }\n\n const subj = createEntityNode({\n label: subjectType,\n name: subjectName,\n properties: triplet.subject.properties ?? {},\n });\n\n const obj = createEntityNode({\n label: objectType,\n name: objectName,\n properties: triplet.object.properties ?? {},\n });\n\n const rel = createRelation({\n label: relationType,\n sourceId: subj.id,\n targetId: obj.id,\n properties: triplet.relation.properties ?? {},\n });\n\n validTriplets.push([subj, rel, obj]);\n }\n\n return validTriplets;\n }\n\n private async extractFromNode(node: TextNode): Promise<TextNode> {\n const prompt = this.buildPrompt(node.text);\n\n let triplets: Triplet[] = [];\n\n try {\n const result = await this.llm.structuredPredict(this.tripletSchema, prompt);\n triplets = this.pruneInvalidTriplets(result);\n } catch (err) {\n // Log extraction errors for debugging\n console.warn(`[SchemaLLMPathExtractor] Failed to extract from node ${node.id}:`, err);\n triplets = [];\n }\n\n const existingNodes = (node.metadata[KG_NODES_KEY] as EntityNode[]) ?? [];\n const existingRelations = (node.metadata[KG_RELATIONS_KEY] as Relation[]) ?? [];\n\n // Avoid copying kg_nodes/kg_relations into node properties (can create circular refs)\n const safeMetadata: Record<string, unknown> = { ...node.metadata };\n delete safeMetadata[KG_NODES_KEY];\n delete safeMetadata[KG_RELATIONS_KEY];\n\n for (const [subj, rel, obj] of triplets) {\n subj.properties = { ...subj.properties, ...safeMetadata };\n obj.properties = { ...obj.properties, ...safeMetadata };\n rel.properties = { ...rel.properties, ...safeMetadata };\n\n existingNodes.push(subj);\n existingNodes.push(obj);\n existingRelations.push(rel);\n }\n\n return {\n ...node,\n metadata: {\n ...node.metadata,\n [KG_NODES_KEY]: existingNodes,\n [KG_RELATIONS_KEY]: existingRelations,\n },\n };\n }\n\n async transform(nodes: TextNode[], options?: { showProgress?: boolean }): Promise<TextNode[]> {\n const results: TextNode[] = [];\n\n for (const node of nodes) {\n const processed = await this.extractFromNode(node);\n results.push(processed);\n }\n\n return results;\n }\n}\n"],"mappings":"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","names":["z","z"]}
|
|
1
|
+
{"version":3,"sources":["../src/hana/parse-host-port.ts","../src/hana/connection.ts","../src/hana/sparql-store.ts","../src/graph/types.ts","../src/graph/hana-property-graph-store.ts","../src/graph/pg-retriever.ts","../src/graph/retrievers/base.ts","../src/graph/retrievers/vector-context.ts","../src/graph/extractors/implicit.ts","../src/graph/property-graph-index.ts","../src/graph/extractors/schema-llm.ts"],"sourcesContent":["export function parseHostPort(\n host: string,\n fallbackPort: number\n): { host: string; port: number } {\n const idx = host.lastIndexOf(\":\");\n if (idx > -1 && idx < host.length - 1) {\n const maybePort = Number(host.slice(idx + 1));\n if (!Number.isNaN(maybePort) && maybePort > 0) {\n return { host: host.slice(0, idx), port: maybePort };\n }\n }\n\n return { host, port: fallbackPort };\n}\n","import { parseHostPort } from \"./parse-host-port\";\nimport type { HanaConnection, HanaConnectionConfig } from \"./types\";\n\nexport async function createHanaConnection(\n config: HanaConnectionConfig\n): Promise<HanaConnection> {\n let hana: any;\n try {\n const hanaModule = await import(\"@sap/hana-client\");\n hana = (hanaModule as any).default || hanaModule;\n } catch {\n throw new Error(\n \"@sap/hana-client is not available. Ensure it is installed and pnpm build scripts are approved (pnpm approve-builds).\"\n );\n }\n\n const fallbackPort = config.port ?? 443;\n const { host, port } = parseHostPort(config.host, fallbackPort);\n\n const conn: HanaConnection = hana.createConnection();\n\n await new Promise<void>((resolve, reject) => {\n conn.connect(\n {\n serverNode: `${host}:${port}`,\n uid: config.user,\n pwd: config.password,\n encrypt: config.encrypt ?? true,\n sslValidateCertificate: config.sslValidateCertificate ?? true\n },\n (err?: unknown) => (err ? reject(err) : resolve())\n );\n });\n\n return conn;\n}\n\nexport async function hanaExec<T = unknown>(\n conn: HanaConnection,\n sql: string\n): Promise<T> {\n return await new Promise<T>((resolve, reject) => {\n conn.exec(sql, (err: unknown, result: unknown) => {\n if (err) return reject(err);\n resolve(result as T);\n });\n });\n}\n","import type { HanaConnection } from \"./types\";\n\nexport type SparqlExecuteResult = unknown;\n\nexport class HanaSparqlStore {\n private readonly conn: HanaConnection;\n\n constructor(conn: HanaConnection) {\n this.conn = conn;\n }\n\n async execute(options: {\n sparql: string;\n headers?: string;\n defaultGraphUri?: string;\n }): Promise<SparqlExecuteResult> {\n const headerLines: string[] = [];\n\n if (options.defaultGraphUri) {\n headerLines.push(`rqx-default-graph-uri: ${options.defaultGraphUri}`);\n }\n\n if (options.headers) {\n headerLines.push(options.headers.trim());\n }\n\n const hdrs = headerLines.length ? `${headerLines.join(\"\\r\\n\")}\\r\\n` : \"\";\n\n const sql = \"CALL SPARQL_EXECUTE(?, ?, ?, ?)\";\n\n return await new Promise((resolve, reject) => {\n // @sap/hana-client supports conn.exec with parameter arrays.\n // We intentionally keep the result as unknown; callers can parse the XML/JSON depending on HANA return mode.\n (this.conn as any).exec(sql, [options.sparql, hdrs, \"\", null], (err: unknown, result: unknown) => {\n if (err) return reject(err);\n resolve(result);\n });\n });\n }\n\n async loadTurtle(options: {\n turtle: string;\n graphName: string;\n filename?: string;\n }): Promise<SparqlExecuteResult> {\n const requestHdrs = [\n \"rqx-load-protocol: true\",\n options.filename ? `rqx-load-filename: ${options.filename}` : undefined,\n `rqx-load-graphname: ${options.graphName}`\n ]\n .filter(Boolean)\n .join(\"\\r\\n\");\n\n return await this.execute({ sparql: options.turtle, headers: requestHdrs });\n }\n}\n","import { z } from \"zod\";\n\nexport const TRIPLET_SOURCE_KEY = \"triplet_source_id\";\nexport const KG_NODES_KEY = \"kg_nodes\";\nexport const KG_RELATIONS_KEY = \"kg_relations\";\nexport const VECTOR_SOURCE_KEY = \"vector_source_id\";\nexport const KG_SOURCE_REL = \"HAS_SOURCE\";\n\nexport const EntityNodeSchema = z.object({\n id: z.string(),\n label: z.string(),\n name: z.string(),\n properties: z.record(z.unknown()).default({}),\n embedding: z.array(z.number()).optional(),\n});\n\nexport type EntityNode = z.infer<typeof EntityNodeSchema>;\n\nexport const RelationSchema = z.object({\n id: z.string().optional(),\n label: z.string(),\n sourceId: z.string(),\n targetId: z.string(),\n properties: z.record(z.unknown()).default({}),\n});\n\nexport type Relation = z.infer<typeof RelationSchema>;\n\nexport type Triplet = [EntityNode, Relation, EntityNode];\n\nexport type LabelledNode = EntityNode;\n\nexport interface NodeWithScore {\n node: {\n id: string;\n text: string;\n metadata: Record<string, unknown>;\n refDocId?: string;\n };\n score: number;\n}\n\nexport interface QueryBundle {\n queryStr: string;\n embedding?: number[];\n embeddingStrs?: string[];\n}\n\nexport function createEntityNode(opts: {\n label: string;\n name: string;\n properties?: Record<string, unknown>;\n embedding?: number[];\n}): EntityNode {\n const id = `${opts.label.toUpperCase()}_${opts.name.replace(/\\s+/g, \"_\").toUpperCase()}`;\n return {\n id,\n label: opts.label,\n name: opts.name,\n properties: opts.properties ?? {},\n embedding: opts.embedding,\n };\n}\n\nexport function createRelation(opts: {\n label: string;\n sourceId: string;\n targetId: string;\n properties?: Record<string, unknown>;\n}): Relation {\n return {\n id: `${opts.sourceId}_${opts.label}_${opts.targetId}`,\n label: opts.label,\n sourceId: opts.sourceId,\n targetId: opts.targetId,\n properties: opts.properties ?? {},\n };\n}\n\nexport function tripletToString(triplet: Triplet, includeProperties = false): string {\n const [subj, rel, obj] = triplet;\n if (includeProperties) {\n return `${subj.name} (${subj.label}) -[${rel.label}]-> ${obj.name} (${obj.label})`;\n }\n return `${subj.id} -> ${rel.label} -> ${obj.id}`;\n}\n","import type { HanaConnection } from \"../hana/types\";\nimport type { PropertyGraphStore, VectorStoreQuery } from \"./property-graph-store\";\nimport type { EntityNode, Relation, Triplet, LabelledNode } from \"./types\";\nimport { TRIPLET_SOURCE_KEY, KG_SOURCE_REL } from \"./types\";\n\ntype LlamaNode = {\n id: string;\n text: string;\n metadata: Record<string, unknown>;\n embedding?: number[];\n hash?: string;\n};\n\nexport interface HanaPropertyGraphStoreOptions {\n graphName: string;\n vectorTableName?: string;\n llamaNodesTableName?: string;\n /** Optional, unused for dimensionless REAL_VECTOR columns (kept for backward compat logging). */\n vectorDimension?: number;\n /** If true, will DROP and recreate tables on init (intended for tests/dev only). */\n resetTables?: boolean;\n}\n\nexport class HanaPropertyGraphStore implements PropertyGraphStore {\n private readonly conn: HanaConnection;\n private readonly graphName: string;\n private readonly vectorTableName: string;\n private readonly llamaNodesTableName: string;\n private readonly resetTables: boolean;\n private initialized = false;\n\n readonly supportsVectorQueries = true;\n readonly supportsStructuredQueries = true;\n\n constructor(conn: HanaConnection, options: HanaPropertyGraphStoreOptions) {\n this.conn = conn;\n this.graphName = options.graphName;\n this.vectorTableName = options.vectorTableName ?? `${options.graphName.replace(/[^a-zA-Z0-9]/g, \"_\")}_VECTORS`;\n this.llamaNodesTableName = options.llamaNodesTableName ?? `${options.graphName.replace(/[^a-zA-Z0-9]/g, \"_\")}_NODES`;\n this.resetTables = options.resetTables ?? false;\n }\n\n private async ensureInitialized(): Promise<void> {\n if (this.initialized) return;\n\n // Optional destructive reset intended for tests/dev. This is OFF by default.\n if (this.resetTables) {\n await this.exec(`DROP TABLE ${this.vectorTableName}`).catch(() => {});\n await this.exec(`DROP TABLE ${this.llamaNodesTableName}`).catch(() => {});\n\n // Also clear the RDF named graph to avoid accumulating triples across test runs.\n // (Tables are recreated, but the KG graph would otherwise persist.)\n await this.sparqlExecute(`CLEAR GRAPH <${this.graphName}>`).catch(() => {});\n }\n\n // HANA does not support \"IF NOT EXISTS\" for CREATE TABLE. We try to create and ignore the\n // \"name exists\" error, but surface any other errors.\n const createVectorTable = `\n CREATE COLUMN TABLE ${this.vectorTableName} (\n id NVARCHAR(512) PRIMARY KEY,\n node_type NVARCHAR(64),\n label NVARCHAR(128),\n name NVARCHAR(512),\n properties NCLOB,\n embedding REAL_VECTOR\n )\n `;\n await this.exec(createVectorTable).catch((err: any) => {\n const message = String(err?.message ?? \"\");\n // Handle \"duplicate table name\" or \"already exists\"\n if (!/exists|duplicate table name/i.test(message)) {\n throw err;\n }\n });\n\n const createLlamaTable = `\n CREATE COLUMN TABLE ${this.llamaNodesTableName} (\n id NVARCHAR(512) PRIMARY KEY,\n text NCLOB,\n metadata NCLOB,\n hash NVARCHAR(64),\n embedding REAL_VECTOR\n )\n `;\n await this.exec(createLlamaTable).catch((err: any) => {\n const message = String(err?.message ?? \"\");\n if (!/exists|duplicate table name/i.test(message)) {\n throw err;\n }\n });\n\n this.initialized = true;\n }\n\n private async exec(sql: string, params?: unknown[]): Promise<unknown[]> {\n return new Promise((resolve, reject) => {\n if (params && params.length > 0) {\n (this.conn as any).exec(sql, params, (err: unknown, result: unknown) => {\n if (err) reject(err);\n else resolve(result as unknown[]);\n });\n } else {\n this.conn.exec(sql, (err: unknown, result: unknown) => {\n if (err) reject(err);\n else resolve(result as unknown[]);\n });\n }\n });\n }\n\n private async sparqlExecute(sparql: string, headers = \"\"): Promise<unknown> {\n // Some HANA environments require OUT parameters (e.g. RESPONSE) to be bound.\n // The @sap/hana-client driver provides a proc statement helper which correctly\n // handles OUT params *without* requiring you to pass them in the params array.\n try {\n const streamMod = await import(\"@sap/hana-client/extension/Stream\");\n const Stream = (streamMod as any).default ?? streamMod;\n\n return await new Promise<unknown>((resolve, reject) => {\n Stream.createProcStatement(this.conn as any, \"CALL SPARQL_EXECUTE(?, ?, ?, ?)\", (err: any, stmt: any) => {\n if (err) return reject(err);\n stmt.exec([sparql, headers], (err2: any, scalarParams: any) => {\n // scalarParams contains OUT params by name (e.g. RESPONSE)\n if (err2) return reject(err2);\n resolve(scalarParams);\n });\n });\n });\n } catch {\n // Fallback (may fail on systems requiring bound OUT params)\n return await new Promise<unknown>((resolve, reject) => {\n (this.conn as any).exec(\n \"CALL SPARQL_EXECUTE(?, ?, ?, ?)\",\n // Important: only pass IN params; OUT params are placeholders in SQL.\n [sparql, headers],\n (err: unknown, result: unknown) => {\n if (err) reject(err);\n else resolve(result);\n }\n );\n });\n }\n }\n\n private entityToUri(node: EntityNode): string {\n return `<urn:hkv:${this.graphName}:${node.label}:${encodeURIComponent(node.id)}>`;\n }\n\n private relationToTriples(rel: Relation, subj: EntityNode, obj: EntityNode): string {\n const subjUri = this.entityToUri(subj);\n const objUri = this.entityToUri(obj);\n const predUri = `<urn:hkv:rel:${rel.label}>`;\n return `${subjUri} ${predUri} ${objUri} .`;\n }\n\n private entityToTriples(node: EntityNode): string {\n const uri = this.entityToUri(node);\n const lines: string[] = [];\n lines.push(`${uri} a <urn:hkv:type:${node.label}> .`);\n lines.push(`${uri} <urn:hkv:prop:name> \"${this.escapeLiteral(node.name)}\" .`);\n\n for (const [key, value] of Object.entries(node.properties)) {\n if (value !== undefined && value !== null) {\n const escaped = typeof value === \"string\" ? this.escapeLiteral(value) : String(value);\n lines.push(`${uri} <urn:hkv:prop:${key}> \"${escaped}\" .`);\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n private escapeLiteral(s: string): string {\n return s.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\");\n }\n\n async upsertNodes(nodes: EntityNode[]): Promise<void> {\n await this.ensureInitialized();\n if (nodes.length === 0) return;\n\n const triples = nodes.map((n) => this.entityToTriples(n)).join(\"\\n\");\n const sparql = `INSERT DATA { GRAPH <${this.graphName}> { ${triples} } }`;\n await this.sparqlExecute(sparql);\n\n for (const node of nodes) {\n if (node.embedding) {\n // Defensive: prevent circular references from being serialized into NCLOB\n const safeProps: Record<string, unknown> = { ...(node.properties ?? {}) };\n delete (safeProps as any).kg_nodes;\n delete (safeProps as any).kg_relations;\n\n const sql = `\n UPSERT ${this.vectorTableName} (id, node_type, label, name, properties, embedding)\n VALUES (?, 'entity', ?, ?, ?, TO_REAL_VECTOR(?))\n WITH PRIMARY KEY\n `;\n await this.exec(sql, [\n node.id,\n node.label,\n node.name,\n JSON.stringify(safeProps),\n JSON.stringify(node.embedding),\n ]);\n }\n }\n }\n\n async upsertRelations(relations: Relation[]): Promise<void> {\n await this.ensureInitialized();\n if (relations.length === 0) return;\n\n const nodeIds = new Set<string>();\n for (const rel of relations) {\n nodeIds.add(rel.sourceId);\n nodeIds.add(rel.targetId);\n }\n\n const existingNodes = await this.get({ ids: Array.from(nodeIds) });\n const nodeMap = new Map(existingNodes.map((n) => [n.id, n]));\n\n const lines: string[] = [];\n for (const rel of relations) {\n const subj = nodeMap.get(rel.sourceId);\n const obj = nodeMap.get(rel.targetId);\n if (subj && obj) {\n lines.push(this.relationToTriples(rel, subj, obj));\n }\n }\n\n if (lines.length > 0) {\n const sparql = `INSERT DATA { GRAPH <${this.graphName}> { ${lines.join(\"\\n\")} } }`;\n await this.sparqlExecute(sparql);\n }\n }\n\n async get(opts: { ids: string[] }): Promise<LabelledNode[]> {\n await this.ensureInitialized();\n if (opts.ids.length === 0) return [];\n\n const rows = (await this.exec(\n `SELECT id, label, name, properties FROM ${this.vectorTableName} WHERE id IN (${opts.ids.map(() => \"?\").join(\",\")})`,\n opts.ids\n )) as any[];\n\n return (rows ?? []).map((r) => ({\n id: r.ID ?? r.id,\n label: r.LABEL ?? r.label,\n name: r.NAME ?? r.name,\n properties: JSON.parse(r.PROPERTIES ?? r.properties ?? \"{}\"),\n }));\n }\n\n async getRelMap(opts: {\n nodes: LabelledNode[];\n depth?: number;\n limit?: number;\n ignoreRels?: string[];\n }): Promise<Triplet[]> {\n await this.ensureInitialized();\n if (opts.nodes.length === 0) return [];\n\n const nodeIds = opts.nodes.map((n) => n.id);\n const depth = opts.depth ?? 1;\n const limit = opts.limit ?? 100;\n const ignoreRels = opts.ignoreRels ?? [KG_SOURCE_REL];\n\n const filterClause = nodeIds\n .map((id) => `CONTAINS(STR(?s), \"${encodeURIComponent(id)}\") || CONTAINS(STR(?o), \"${encodeURIComponent(id)}\")`)\n .join(\" || \");\n\n const ignoreFilter = ignoreRels.length > 0\n ? `FILTER(${ignoreRels.map((r) => `!CONTAINS(STR(?p), \"${r}\")`).join(\" && \")})`\n : \"\";\n\n const sparql = `\n SELECT ?s ?p ?o\n FROM <${this.graphName}>\n WHERE {\n ?s ?p ?o .\n FILTER(${filterClause})\n ${ignoreFilter}\n }\n LIMIT ${limit}\n `;\n\n const result = await this.exec(\n `SELECT * FROM SPARQL_TABLE('${sparql.replace(/'/g, \"''\")}')`\n ) as any[];\n\n const triplets: Triplet[] = [];\n const nodeMap = new Map(opts.nodes.map((n) => [n.id, n]));\n\n for (const row of result ?? []) {\n const sUri = row.S ?? row.s;\n const pUri = row.P ?? row.p;\n const oUri = row.O ?? row.o;\n\n const sId = this.extractIdFromUri(sUri);\n const oId = this.extractIdFromUri(oUri);\n const relLabel = this.extractRelLabelFromUri(pUri);\n\n let subj = nodeMap.get(sId);\n let obj = nodeMap.get(oId);\n\n if (!subj) {\n subj = { id: sId, label: \"UNKNOWN\", name: sId, properties: {} };\n }\n if (!obj) {\n obj = { id: oId, label: \"UNKNOWN\", name: oId, properties: {} };\n }\n\n const rel: Relation = {\n label: relLabel,\n sourceId: sId,\n targetId: oId,\n properties: {},\n };\n\n triplets.push([subj, rel, obj]);\n }\n\n return triplets;\n }\n\n private extractIdFromUri(uri: string): string {\n // URI format: <urn:hkv:graphName:label:id> or just the content without angle brackets\n // The ID is the last segment after the label (second-to-last segment)\n const cleanUri = uri.replace(/^<|>$/g, \"\");\n const parts = cleanUri.split(\":\");\n // ID is the last part, decode it\n if (parts.length >= 2) {\n return decodeURIComponent(parts[parts.length - 1]);\n }\n return uri;\n }\n\n private extractRelLabelFromUri(uri: string): string {\n const match = uri.match(/urn:hkv:rel:(.+)>?$/);\n return match ? match[1].replace(/>$/, \"\") : uri;\n }\n\n async delete(opts: { ids: string[] }): Promise<void> {\n await this.ensureInitialized();\n if (opts.ids.length === 0) return;\n\n for (const id of opts.ids) {\n await this.exec(`DELETE FROM ${this.vectorTableName} WHERE id = ?`, [id]);\n }\n }\n\n async vectorQuery(query: VectorStoreQuery): Promise<[LabelledNode[], number[]]> {\n await this.ensureInitialized();\n\n const sql = `\n SELECT id, label, name, properties,\n COSINE_SIMILARITY(embedding, TO_REAL_VECTOR(?)) AS score\n FROM ${this.vectorTableName}\n WHERE embedding IS NOT NULL\n ORDER BY score DESC\n LIMIT ?\n `;\n\n const rows = (await this.exec(sql, [\n JSON.stringify(query.queryEmbedding),\n query.similarityTopK,\n ])) as any[];\n\n const nodes: LabelledNode[] = [];\n const scores: number[] = [];\n\n for (const row of rows ?? []) {\n nodes.push({\n id: row.ID ?? row.id,\n label: row.LABEL ?? row.label,\n name: row.NAME ?? row.name,\n properties: JSON.parse(row.PROPERTIES ?? row.properties ?? \"{}\"),\n });\n scores.push(row.SCORE ?? row.score ?? 0);\n }\n\n return [nodes, scores];\n }\n\n async upsertLlamaNodes(nodes: LlamaNode[]): Promise<void> {\n await this.ensureInitialized();\n for (const node of nodes) {\n // Remove circular references from metadata before serialization\n const { metadata, ...rest } = node;\n const safeMetadata = { ...metadata };\n delete (safeMetadata as any).kg_nodes;\n delete (safeMetadata as any).kg_relations;\n\n const sql = `\n UPSERT ${this.llamaNodesTableName} (id, text, metadata, hash, embedding)\n VALUES (?, ?, ?, ?, ${node.embedding ? \"TO_REAL_VECTOR(?)\" : \"NULL\"})\n WITH PRIMARY KEY\n `;\n const params: unknown[] = [\n node.id,\n node.text,\n JSON.stringify(safeMetadata ?? {}),\n node.hash ?? null,\n ];\n if (node.embedding) {\n params.push(JSON.stringify(node.embedding));\n }\n await this.exec(sql, params);\n }\n }\n\n async getLlamaNodes(ids: string[]): Promise<LlamaNode[]> {\n await this.ensureInitialized();\n if (ids.length === 0) return [];\n\n const rows = (await this.exec(\n `SELECT id, text, metadata, hash FROM ${this.llamaNodesTableName} WHERE id IN (${ids.map(() => \"?\").join(\",\")})`,\n ids\n )) as any[];\n\n return (rows ?? []).map((r) => ({\n id: r.ID ?? r.id,\n text: r.TEXT ?? r.text,\n metadata: JSON.parse(r.METADATA ?? r.metadata ?? \"{}\"),\n hash: r.HASH ?? r.hash,\n }));\n }\n}\n","import type { QueryBundle, NodeWithScore } from \"./types\";\nimport type { BasePGRetriever } from \"./retrievers/base\";\n\nexport interface PGRetrieverOptions {\n subRetrievers: BasePGRetriever[];\n showProgress?: boolean;\n}\n\nexport class PGRetriever {\n private readonly subRetrievers: BasePGRetriever[];\n private readonly showProgress: boolean;\n\n constructor(options: PGRetrieverOptions) {\n this.subRetrievers = options.subRetrievers;\n this.showProgress = options.showProgress ?? false;\n }\n\n private deduplicate(nodes: NodeWithScore[]): NodeWithScore[] {\n const seen = new Set<string>();\n const deduped: NodeWithScore[] = [];\n\n for (const node of nodes) {\n if (!seen.has(node.node.text)) {\n deduped.push(node);\n seen.add(node.node.text);\n }\n }\n\n return deduped;\n }\n\n async retrieve(queryBundle: QueryBundle): Promise<NodeWithScore[]> {\n const allResults: NodeWithScore[] = [];\n\n const promises = this.subRetrievers.map((r) => r.retrieve(queryBundle));\n const results = await Promise.all(promises);\n\n for (const result of results) {\n allResults.push(...result);\n }\n\n return this.deduplicate(allResults);\n }\n}\n","import type { PropertyGraphStore } from \"../property-graph-store\";\nimport type { Triplet, NodeWithScore, QueryBundle, LabelledNode } from \"../types\";\nimport { TRIPLET_SOURCE_KEY, tripletToString } from \"../types\";\n\nexport const DEFAULT_PREAMBLE = \"Here are some facts extracted from the provided text:\\n\\n\";\n\nexport interface BasePGRetrieverOptions {\n graphStore: PropertyGraphStore;\n includeText?: boolean;\n includeTextPreamble?: string;\n includeProperties?: boolean;\n}\n\nexport abstract class BasePGRetriever {\n protected readonly graphStore: PropertyGraphStore;\n protected readonly includeText: boolean;\n protected readonly includeTextPreamble: string;\n protected readonly includeProperties: boolean;\n\n constructor(options: BasePGRetrieverOptions) {\n this.graphStore = options.graphStore;\n this.includeText = options.includeText ?? true;\n this.includeTextPreamble = options.includeTextPreamble ?? DEFAULT_PREAMBLE;\n this.includeProperties = options.includeProperties ?? false;\n }\n\n protected getNodesWithScore(triplets: Triplet[], scores?: number[]): NodeWithScore[] {\n const results: NodeWithScore[] = [];\n\n for (let i = 0; i < triplets.length; i++) {\n const triplet = triplets[i];\n const sourceId = triplet[0].properties[TRIPLET_SOURCE_KEY] as string | undefined;\n\n const text = tripletToString(triplet, this.includeProperties);\n\n results.push({\n node: {\n id: `triplet_${i}`,\n text,\n metadata: {},\n refDocId: sourceId,\n },\n score: scores?.[i] ?? 1.0,\n });\n }\n\n return results;\n }\n\n protected async addSourceText(nodes: NodeWithScore[]): Promise<NodeWithScore[]> {\n if (!this.graphStore.getLlamaNodes) {\n return nodes;\n }\n\n const refDocIds = nodes\n .map((n) => n.node.refDocId)\n .filter((id): id is string => id !== undefined);\n\n if (refDocIds.length === 0) return nodes;\n\n const ogNodes = await this.graphStore.getLlamaNodes(refDocIds);\n const nodeMap = new Map(ogNodes.map((n) => [n.id, n]));\n\n const graphNodeMap = new Map<string, string[]>();\n for (const node of nodes) {\n const refDocId = node.node.refDocId ?? \"\";\n if (!graphNodeMap.has(refDocId)) {\n graphNodeMap.set(refDocId, []);\n }\n graphNodeMap.get(refDocId)!.push(node.node.text);\n }\n\n const resultNodes: NodeWithScore[] = [];\n for (const nodeWithScore of nodes) {\n const mappedNode = nodeMap.get(nodeWithScore.node.refDocId ?? \"\");\n\n if (mappedNode) {\n const graphContent = graphNodeMap.get(mappedNode.id) ?? [];\n if (graphContent.length > 0) {\n const graphContentStr = graphContent.join(\"\\n\");\n const newContent = this.includeTextPreamble + graphContentStr + \"\\n\\n\" + mappedNode.text;\n resultNodes.push({\n node: {\n id: mappedNode.id,\n text: newContent,\n metadata: mappedNode.metadata,\n refDocId: nodeWithScore.node.refDocId,\n },\n score: nodeWithScore.score,\n });\n } else {\n resultNodes.push({\n node: {\n id: mappedNode.id,\n text: mappedNode.text,\n metadata: mappedNode.metadata,\n refDocId: nodeWithScore.node.refDocId,\n },\n score: nodeWithScore.score,\n });\n }\n } else {\n resultNodes.push(nodeWithScore);\n }\n }\n\n return resultNodes;\n }\n\n async retrieve(queryBundle: QueryBundle): Promise<NodeWithScore[]> {\n let nodes = await this.retrieveFromGraph(queryBundle);\n if (this.includeText && nodes.length > 0) {\n nodes = await this.addSourceText(nodes);\n }\n return nodes;\n }\n\n abstract retrieveFromGraph(queryBundle: QueryBundle): Promise<NodeWithScore[]>;\n}\n","import type { PropertyGraphStore, VectorStoreQuery } from \"../property-graph-store\";\nimport type { QueryBundle, NodeWithScore, LabelledNode } from \"../types\";\nimport { KG_SOURCE_REL } from \"../types\";\nimport { BasePGRetriever, type BasePGRetrieverOptions } from \"./base\";\n\nexport interface EmbedModel {\n getTextEmbedding(text: string): Promise<number[]>;\n getTextEmbeddingBatch(texts: string[]): Promise<number[][]>;\n}\n\nexport interface VectorContextRetrieverOptions extends BasePGRetrieverOptions {\n embedModel: EmbedModel;\n similarityTopK?: number;\n pathDepth?: number;\n limit?: number;\n similarityScore?: number;\n /** Enable cross-check boosting: boost scores when vector-matched entities link to graph facts (default: true) */\n crossCheckBoost?: boolean;\n /** Multiplier for cross-check boost (default: 1.25 = 25% boost) */\n crossCheckBoostFactor?: number;\n}\n\nexport class VectorContextRetriever extends BasePGRetriever {\n private readonly embedModel: EmbedModel;\n private readonly similarityTopK: number;\n private readonly pathDepth: number;\n private readonly limit: number;\n private readonly similarityScore?: number;\n private readonly crossCheckBoost: boolean;\n private readonly crossCheckBoostFactor: number;\n\n constructor(options: VectorContextRetrieverOptions) {\n super(options);\n this.embedModel = options.embedModel;\n this.similarityTopK = options.similarityTopK ?? 4;\n this.pathDepth = options.pathDepth ?? 1;\n this.limit = options.limit ?? 30;\n this.similarityScore = options.similarityScore;\n this.crossCheckBoost = options.crossCheckBoost ?? true;\n this.crossCheckBoostFactor = options.crossCheckBoostFactor ?? 1.25;\n }\n\n async retrieveFromGraph(queryBundle: QueryBundle): Promise<NodeWithScore[]> {\n let embedding = queryBundle.embedding;\n\n if (!embedding) {\n embedding = await this.embedModel.getTextEmbedding(queryBundle.queryStr);\n }\n\n const vectorQuery: VectorStoreQuery = {\n queryEmbedding: embedding,\n similarityTopK: this.similarityTopK,\n };\n\n if (!this.graphStore.supportsVectorQueries || !this.graphStore.vectorQuery) {\n throw new Error(\"Graph store does not support vector queries\");\n }\n\n const [kgNodes, scores] = await this.graphStore.vectorQuery(vectorQuery);\n\n if (kgNodes.length === 0) {\n return [];\n }\n\n const kgIds = kgNodes.map((n) => n.id);\n\n // Build provenance set from vector-matched nodes for cross-check boosting\n // This includes document IDs, chunk IDs, and other source identifiers\n const provenanceSet = new Set<string>();\n if (this.crossCheckBoost) {\n for (const node of kgNodes) {\n // Add node ID itself (for CHUNK nodes)\n provenanceSet.add(node.id.toLowerCase());\n provenanceSet.add(node.name.toLowerCase());\n \n // Add documentId from properties if present\n const props = node.properties ?? {};\n if (props.documentId) {\n provenanceSet.add(String(props.documentId).toLowerCase());\n }\n if (props.sourceChunk) {\n provenanceSet.add(String(props.sourceChunk).toLowerCase());\n }\n }\n }\n\n const triplets = await this.graphStore.getRelMap({\n nodes: kgNodes,\n depth: this.pathDepth,\n limit: this.limit,\n ignoreRels: [KG_SOURCE_REL],\n });\n\n const newScores: number[] = [];\n for (const triplet of triplets) {\n const idx1 = kgIds.indexOf(triplet[0].id);\n const idx2 = kgIds.indexOf(triplet[2].id);\n const score1 = idx1 >= 0 ? scores[idx1] : 0;\n const score2 = idx2 >= 0 ? scores[idx2] : 0;\n let baseScore = Math.max(score1, score2);\n\n // Cross-check boosting: if triplet entities have provenance linking back to\n // vector-matched nodes, boost the score. This rewards facts that are both\n // semantically similar AND have explicit graph connections.\n if (this.crossCheckBoost && baseScore > 0) {\n const shouldBoost = this.checkProvenance(triplet[0], provenanceSet) ||\n this.checkProvenance(triplet[2], provenanceSet);\n if (shouldBoost) {\n baseScore = Math.min(1.0, baseScore * this.crossCheckBoostFactor);\n }\n }\n\n newScores.push(baseScore);\n }\n\n let results = triplets.map((t, i) => ({ triplet: t, score: newScores[i] }));\n\n if (this.similarityScore !== undefined) {\n results = results.filter((r) => r.score >= this.similarityScore!);\n }\n\n results.sort((a, b) => b.score - a.score);\n\n return this.getNodesWithScore(\n results.map((r) => r.triplet),\n results.map((r) => r.score)\n );\n }\n\n /**\n * Check if a node has provenance linking to the vector-matched nodes.\n * Returns true if the node's properties contain a documentId or sourceChunk\n * that matches something in the provenance set.\n */\n private checkProvenance(node: LabelledNode, provenanceSet: Set<string>): boolean {\n if (provenanceSet.size === 0) return false;\n\n const props = node.properties ?? {};\n \n // Check documentId property\n if (props.documentId && provenanceSet.has(String(props.documentId).toLowerCase())) {\n return true;\n }\n \n // Check sourceChunk property\n if (props.sourceChunk && provenanceSet.has(String(props.sourceChunk).toLowerCase())) {\n return true;\n }\n \n // Check if this node itself is in the provenance set (e.g., a CHUNK node)\n if (provenanceSet.has(node.id.toLowerCase()) || provenanceSet.has(node.name.toLowerCase())) {\n return true;\n }\n\n return false;\n }\n}\n","import type { TransformComponent, TextNode } from \"./types\";\nimport type { EntityNode, Relation } from \"../types\";\nimport { KG_NODES_KEY, KG_RELATIONS_KEY, createEntityNode, createRelation } from \"../types\";\n\nexport class ImplicitPathExtractor implements TransformComponent {\n async transform(nodes: TextNode[], options?: { showProgress?: boolean }): Promise<TextNode[]> {\n const results: TextNode[] = [];\n\n for (const node of nodes) {\n const existingNodes = (node.metadata[KG_NODES_KEY] as EntityNode[]) ?? [];\n const existingRelations = (node.metadata[KG_RELATIONS_KEY] as Relation[]) ?? [];\n\n const safeMetadata: Record<string, unknown> = { ...node.metadata };\n delete safeMetadata[KG_NODES_KEY];\n delete safeMetadata[KG_RELATIONS_KEY];\n\n const chunkNode = createEntityNode({\n label: \"CHUNK\",\n name: node.id,\n properties: {\n text: node.text.slice(0, 500),\n ...safeMetadata,\n },\n });\n\n if (node.metadata.documentId) {\n const docNode = createEntityNode({\n label: \"DOCUMENT\",\n name: String(node.metadata.documentId),\n properties: {},\n });\n\n const rel = createRelation({\n label: \"FROM_DOCUMENT\",\n sourceId: chunkNode.id,\n targetId: docNode.id,\n });\n\n existingNodes.push(docNode);\n existingRelations.push(rel);\n }\n\n existingNodes.push(chunkNode);\n\n results.push({\n ...node,\n metadata: {\n ...node.metadata,\n [KG_NODES_KEY]: existingNodes,\n [KG_RELATIONS_KEY]: existingRelations,\n },\n });\n }\n\n return results;\n }\n}\n","import type { PropertyGraphStore } from \"./property-graph-store\";\nimport type { TransformComponent, TextNode } from \"./extractors/types\";\nimport type { EntityNode, Relation, NodeWithScore, QueryBundle } from \"./types\";\nimport { KG_NODES_KEY, KG_RELATIONS_KEY, TRIPLET_SOURCE_KEY } from \"./types\";\nimport { PGRetriever } from \"./pg-retriever\";\nimport { VectorContextRetriever, type EmbedModel } from \"./retrievers/vector-context\";\nimport { ImplicitPathExtractor } from \"./extractors/implicit\";\nimport { createHash } from \"crypto\";\n\nexport interface PropertyGraphIndexOptions {\n propertyGraphStore: PropertyGraphStore;\n kgExtractors?: TransformComponent[];\n embedModel?: EmbedModel;\n embedKgNodes?: boolean;\n showProgress?: boolean;\n}\n\nexport class PropertyGraphIndex {\n private readonly propertyGraphStore: PropertyGraphStore;\n private readonly kgExtractors: TransformComponent[];\n private readonly embedModel?: EmbedModel;\n private readonly embedKgNodes: boolean;\n private readonly showProgress: boolean;\n\n constructor(options: PropertyGraphIndexOptions) {\n this.propertyGraphStore = options.propertyGraphStore;\n this.kgExtractors = options.kgExtractors ?? [new ImplicitPathExtractor()];\n this.embedModel = options.embedModel;\n this.embedKgNodes = options.embedKgNodes ?? true;\n this.showProgress = options.showProgress ?? false;\n }\n\n get graphStore(): PropertyGraphStore {\n return this.propertyGraphStore;\n }\n\n static fromExisting(options: PropertyGraphIndexOptions): PropertyGraphIndex {\n return new PropertyGraphIndex(options);\n }\n\n private computeHash(text: string): string {\n return createHash(\"md5\").update(text).digest(\"hex\");\n }\n\n async insert(nodes: TextNode[]): Promise<TextNode[]> {\n if (nodes.length === 0) return [];\n\n let processedNodes = nodes;\n for (const extractor of this.kgExtractors) {\n processedNodes = await extractor.transform(processedNodes, {\n showProgress: this.showProgress,\n });\n }\n\n for (const node of processedNodes) {\n if (!node.metadata[KG_NODES_KEY] && !node.metadata[KG_RELATIONS_KEY]) {\n throw new Error(`Node ${node.id} has no KG_NODES_KEY or KG_RELATIONS_KEY after extraction`);\n }\n }\n\n const kgNodesToInsert: EntityNode[] = [];\n const kgRelsToInsert: Relation[] = [];\n\n for (const node of processedNodes) {\n const kgNodes = (node.metadata[KG_NODES_KEY] as EntityNode[]) ?? [];\n const kgRels = (node.metadata[KG_RELATIONS_KEY] as Relation[]) ?? [];\n\n for (const kgNode of kgNodes) {\n kgNode.properties[TRIPLET_SOURCE_KEY] = node.id;\n }\n for (const kgRel of kgRels) {\n kgRel.properties[TRIPLET_SOURCE_KEY] = node.id;\n }\n\n kgNodesToInsert.push(...kgNodes);\n kgRelsToInsert.push(...kgRels);\n }\n\n const kgNodeIds = [...new Set(kgNodesToInsert.map((n) => n.id))];\n const existingKgNodes = await this.propertyGraphStore.get({ ids: kgNodeIds });\n const existingKgNodeIds = new Set(existingKgNodes.map((n) => n.id));\n const newKgNodes = kgNodesToInsert.filter((n) => !existingKgNodeIds.has(n.id));\n\n if (this.propertyGraphStore.getLlamaNodes) {\n const existingLlamaNodes = await this.propertyGraphStore.getLlamaNodes(\n processedNodes.map((n) => n.id)\n );\n const existingHashes = new Set(existingLlamaNodes.map((n) => n.hash));\n processedNodes = processedNodes.filter((n) => {\n const hash = this.computeHash(n.text);\n n.hash = hash;\n return !existingHashes.has(hash);\n });\n }\n\n if (this.embedKgNodes && this.embedModel && newKgNodes.length > 0) {\n const nodeTexts = processedNodes.map((n) => n.text);\n const embeddings = await this.embedModel.getTextEmbeddingBatch(nodeTexts);\n for (let i = 0; i < processedNodes.length; i++) {\n processedNodes[i].embedding = embeddings[i];\n }\n\n const kgNodeTexts = newKgNodes.map((n) => `${n.label}: ${n.name}`);\n const kgEmbeddings = await this.embedModel.getTextEmbeddingBatch(kgNodeTexts);\n for (let i = 0; i < newKgNodes.length; i++) {\n newKgNodes[i].embedding = kgEmbeddings[i];\n }\n }\n\n if (this.propertyGraphStore.upsertLlamaNodes && processedNodes.length > 0) {\n await this.propertyGraphStore.upsertLlamaNodes(\n processedNodes.map((n) => ({\n id: n.id,\n text: n.text,\n metadata: n.metadata,\n embedding: n.embedding,\n hash: n.hash,\n }))\n );\n }\n\n if (newKgNodes.length > 0) {\n await this.propertyGraphStore.upsertNodes(newKgNodes);\n }\n\n if (kgRelsToInsert.length > 0) {\n await this.propertyGraphStore.upsertRelations(kgRelsToInsert);\n }\n\n return processedNodes;\n }\n\n async delete(nodeIds: string[]): Promise<void> {\n await this.propertyGraphStore.delete({ ids: nodeIds });\n }\n\n asRetriever(options?: {\n subRetrievers?: Array<{ retrieve(query: QueryBundle): Promise<NodeWithScore[]> }>;\n includeText?: boolean;\n /** Number of top similar nodes to retrieve via vector search (default: 4) */\n similarityTopK?: number;\n /** Graph traversal depth from matched nodes (default: 1) */\n pathDepth?: number;\n /** Maximum number of triplets to return after expansion (default: 30) */\n limit?: number;\n /** Minimum similarity score threshold to include results (default: no threshold) */\n similarityScore?: number;\n /** Enable cross-check boosting: boost scores when vector-matched entities link to graph facts (default: true) */\n crossCheckBoost?: boolean;\n /** Multiplier for cross-check boost (default: 1.25 = 25% boost) */\n crossCheckBoostFactor?: number;\n }): PGRetriever {\n let subRetrievers = options?.subRetrievers as any[];\n\n if (!subRetrievers && this.embedModel && this.propertyGraphStore.supportsVectorQueries) {\n subRetrievers = [\n new VectorContextRetriever({\n graphStore: this.propertyGraphStore,\n embedModel: this.embedModel,\n includeText: options?.includeText ?? true,\n similarityTopK: options?.similarityTopK,\n pathDepth: options?.pathDepth,\n limit: options?.limit,\n similarityScore: options?.similarityScore,\n crossCheckBoost: options?.crossCheckBoost,\n crossCheckBoostFactor: options?.crossCheckBoostFactor,\n }),\n ];\n }\n\n if (!subRetrievers) {\n subRetrievers = [];\n }\n\n return new PGRetriever({ subRetrievers });\n }\n\n async query(queryStr: string, options?: {\n /** Number of top similar nodes to retrieve via vector search (default: 4) */\n similarityTopK?: number;\n /** Graph traversal depth from matched nodes (default: 1) */\n pathDepth?: number;\n /** Maximum number of triplets to return after expansion (default: 30) */\n limit?: number;\n /** Minimum similarity score threshold to include results (default: no threshold) */\n similarityScore?: number;\n /** Enable cross-check boosting: boost scores when vector-matched entities link to graph facts (default: true) */\n crossCheckBoost?: boolean;\n /** Multiplier for cross-check boost (default: 1.25 = 25% boost) */\n crossCheckBoostFactor?: number;\n }): Promise<NodeWithScore[]> {\n const retriever = this.asRetriever(options);\n return retriever.retrieve({ queryStr });\n }\n}\n","import { z } from \"zod\";\nimport type { TransformComponent, TextNode, SchemaDefinition } from \"./types\";\nimport type { EntityNode, Relation, Triplet } from \"../types\";\nimport { KG_NODES_KEY, KG_RELATIONS_KEY, createEntityNode, createRelation } from \"../types\";\n\nexport interface LLMClient {\n structuredPredict<T>(schema: z.ZodType<T>, prompt: string): Promise<T>;\n}\n\nexport interface SchemaLLMPathExtractorOptions {\n llm: LLMClient;\n schema: SchemaDefinition;\n maxTripletsPerChunk?: number;\n strict?: boolean;\n extractPromptTemplate?: string;\n}\n\nconst DEFAULT_EXTRACT_PROMPT = `Given the following text, extract a knowledge graph according to the provided schema.\nTry to limit to {maxTriplets} extracted paths.\n\nSchema:\n- Entity types: {entityTypes}\n- Relation types: {relationTypes}\n- Valid relationships: {validationSchema}\n\nText:\n-------\n{text}\n-------\n\nExtract entities and relationships from the text above.\nReturn your answer as a JSON object with a \"triplets\" array. Each triplet should have:\n- \"subject\": { \"name\": string, \"type\": one of [{entityTypes}] }\n- \"relation\": { \"type\": one of [{relationTypes}] }\n- \"object\": { \"name\": string, \"type\": one of [{entityTypes}] }\n\nExample output format:\n{\n \"triplets\": [\n {\n \"subject\": { \"name\": \"John\", \"type\": \"PERSON\" },\n \"relation\": { \"type\": \"WORKS_AT\" },\n \"object\": { \"name\": \"Acme Corp\", \"type\": \"ORGANIZATION\" }\n }\n ]\n}`;\n\nexport class SchemaLLMPathExtractor implements TransformComponent {\n private readonly llm: LLMClient;\n private readonly schema: SchemaDefinition;\n private readonly maxTripletsPerChunk: number;\n private readonly strict: boolean;\n private readonly extractPromptTemplate: string;\n private readonly tripletSchema: z.ZodType<any>;\n\n constructor(options: SchemaLLMPathExtractorOptions) {\n this.llm = options.llm;\n this.schema = options.schema;\n this.maxTripletsPerChunk = options.maxTripletsPerChunk ?? 10;\n this.strict = options.strict ?? true;\n this.extractPromptTemplate = options.extractPromptTemplate ?? DEFAULT_EXTRACT_PROMPT;\n\n const entityTypeEnum = z.enum(this.schema.entityTypes as [string, ...string[]]);\n const relationTypeEnum = z.enum(this.schema.relationTypes as [string, ...string[]]);\n\n const entitySchema = z.object({\n name: z.string(),\n type: entityTypeEnum,\n properties: z.record(z.unknown()).optional(),\n });\n\n const relationSchema = z.object({\n type: relationTypeEnum,\n properties: z.record(z.unknown()).optional(),\n });\n\n const tripletSchema = z.object({\n subject: entitySchema,\n relation: relationSchema,\n object: entitySchema,\n });\n\n this.tripletSchema = z.object({\n triplets: z.array(tripletSchema),\n });\n }\n\n private buildPrompt(text: string): string {\n const validationSchemaStr = this.schema.validationSchema\n ?.map(([s, r, o]) => `(${s})-[${r}]->(${o})`)\n .join(\", \") ?? \"Any valid combination\";\n\n return this.extractPromptTemplate\n .replace(\"{maxTriplets}\", String(this.maxTripletsPerChunk))\n .replace(\"{entityTypes}\", this.schema.entityTypes.join(\", \"))\n .replace(\"{relationTypes}\", this.schema.relationTypes.join(\", \"))\n .replace(\"{validationSchema}\", validationSchemaStr)\n .replace(\"{text}\", text);\n }\n\n private isValidTriplet(subjectType: string, relationType: string, objectType: string): boolean {\n if (!this.strict || !this.schema.validationSchema) {\n return true;\n }\n\n return this.schema.validationSchema.some(\n ([s, r, o]) =>\n s.toUpperCase() === subjectType.toUpperCase() &&\n r.toUpperCase() === relationType.toUpperCase() &&\n o.toUpperCase() === objectType.toUpperCase()\n );\n }\n\n private pruneInvalidTriplets(\n extracted: { triplets: Array<{ subject: any; relation: any; object: any }> }\n ): Triplet[] {\n const validTriplets: Triplet[] = [];\n\n for (const triplet of extracted.triplets) {\n const subjectType = String(triplet.subject.type).toUpperCase().replace(/\\s+/g, \"_\");\n const relationType = String(triplet.relation.type).toUpperCase().replace(/\\s+/g, \"_\");\n const objectType = String(triplet.object.type).toUpperCase().replace(/\\s+/g, \"_\");\n\n if (!this.isValidTriplet(subjectType, relationType, objectType)) {\n continue;\n }\n\n const subjectName = String(triplet.subject.name).trim();\n const objectName = String(triplet.object.name).trim();\n\n if (subjectName.toLowerCase() === objectName.toLowerCase()) {\n continue;\n }\n\n const subj = createEntityNode({\n label: subjectType,\n name: subjectName,\n properties: triplet.subject.properties ?? {},\n });\n\n const obj = createEntityNode({\n label: objectType,\n name: objectName,\n properties: triplet.object.properties ?? {},\n });\n\n const rel = createRelation({\n label: relationType,\n sourceId: subj.id,\n targetId: obj.id,\n properties: triplet.relation.properties ?? {},\n });\n\n validTriplets.push([subj, rel, obj]);\n }\n\n return validTriplets;\n }\n\n private async extractFromNode(node: TextNode): Promise<TextNode> {\n const prompt = this.buildPrompt(node.text);\n\n let triplets: Triplet[] = [];\n\n try {\n const result = await this.llm.structuredPredict(this.tripletSchema, prompt);\n triplets = this.pruneInvalidTriplets(result);\n } catch (err) {\n // Log extraction errors for debugging\n console.warn(`[SchemaLLMPathExtractor] Failed to extract from node ${node.id}:`, err);\n triplets = [];\n }\n\n const existingNodes = (node.metadata[KG_NODES_KEY] as EntityNode[]) ?? [];\n const existingRelations = (node.metadata[KG_RELATIONS_KEY] as Relation[]) ?? [];\n\n // Avoid copying kg_nodes/kg_relations into node properties (can create circular refs)\n const safeMetadata: Record<string, unknown> = { ...node.metadata };\n delete safeMetadata[KG_NODES_KEY];\n delete safeMetadata[KG_RELATIONS_KEY];\n\n for (const [subj, rel, obj] of triplets) {\n subj.properties = { ...subj.properties, ...safeMetadata };\n obj.properties = { ...obj.properties, ...safeMetadata };\n rel.properties = { ...rel.properties, ...safeMetadata };\n\n existingNodes.push(subj);\n existingNodes.push(obj);\n existingRelations.push(rel);\n }\n\n return {\n ...node,\n metadata: {\n ...node.metadata,\n [KG_NODES_KEY]: existingNodes,\n [KG_RELATIONS_KEY]: existingRelations,\n },\n };\n }\n\n async transform(nodes: TextNode[], options?: { showProgress?: boolean }): Promise<TextNode[]> {\n const results: TextNode[] = [];\n\n for (const node of nodes) {\n const processed = await this.extractFromNode(node);\n results.push(processed);\n }\n\n return results;\n }\n}\n"],"mappings":"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","names":["z","z"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hana-kgvector",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "A TypeScript framework for building hybrid GraphRAG applications using SAP HANA Cloud as the unified backend for knowledge graphs (RDF) and vector embeddings",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -33,14 +33,12 @@
|
|
|
33
33
|
"homepage": "https://github.com/skye0402/hana-kgvector#readme",
|
|
34
34
|
"scripts": {
|
|
35
35
|
"build": "tsup",
|
|
36
|
-
"test": "vitest",
|
|
37
36
|
"dev": "tsx src/index.ts",
|
|
38
37
|
"phase0:litellm": "tsx scripts/validate-litellm.ts",
|
|
39
38
|
"phase0:hana": "tsx scripts/validate-hana.ts",
|
|
40
39
|
"smoke:pg": "tsx scripts/smoke-property-graph.ts"
|
|
41
40
|
},
|
|
42
41
|
"dependencies": {
|
|
43
|
-
"dotenv": "^16.4.5",
|
|
44
42
|
"openai": "^4.0.0",
|
|
45
43
|
"zod": "^3.23.8"
|
|
46
44
|
},
|
|
@@ -52,6 +50,6 @@
|
|
|
52
50
|
"tsup": "^8.0.0",
|
|
53
51
|
"tsx": "^4.0.0",
|
|
54
52
|
"typescript": "^5.0.0",
|
|
55
|
-
"
|
|
53
|
+
"dotenv": "^16.4.5"
|
|
56
54
|
}
|
|
57
55
|
}
|