@anvia/neo4j 1.0.2 → 1.0.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 CHANGED
@@ -2,10 +2,14 @@
2
2
 
3
3
  Schema-first local GraphRAG for Neo4j 2026.01 and newer.
4
4
 
5
+ Provider-neutral schemas from `@anvia/graph` are accepted alongside the compatibility
6
+ `defineNeo4jGraphSchema()` API. Registered graphs expose `graph.retrieve()`, and the shared
7
+ `createGraphSearchTool()` factory gives Neo4j and Memgraph the same Agent tool API.
8
+
5
9
  ## Installation
6
10
 
7
11
  ```sh
8
- pnpm add @anvia/neo4j @anvia/core
12
+ pnpm add @anvia/graph @anvia/neo4j @anvia/core
9
13
  ```
10
14
 
11
15
  ## Managed knowledge graph
@@ -13,12 +17,8 @@ pnpm add @anvia/neo4j @anvia/core
13
17
  ```ts
14
18
  import { Agent } from "@anvia/core/agent";
15
19
  import { embedDocuments } from "@anvia/core/embeddings";
16
- import {
17
- Neo4jClient,
18
- createNeo4jGraphSearchTool,
19
- defineNeo4jGraphSchema,
20
- extractGraphFacts,
21
- } from "@anvia/neo4j";
20
+ import { createGraphSearchTool } from "@anvia/graph";
21
+ import { Neo4jClient, defineNeo4jGraphSchema, extractGraphFacts } from "@anvia/neo4j";
22
22
  import { z } from "zod";
23
23
 
24
24
  const schema = defineNeo4jGraphSchema({
@@ -98,7 +98,7 @@ const write = await graph.replaceDocuments({
98
98
  });
99
99
  console.log(write);
100
100
 
101
- const searchGraph = createNeo4jGraphSearchTool({
101
+ const searchGraph = createGraphSearchTool({
102
102
  name: "search_support_graph",
103
103
  description: "Search connected support incidents and products.",
104
104
  graph,
@@ -181,6 +181,23 @@ const graph = client.knowledgeGraph({
181
181
  await graph.validate();
182
182
  ```
183
183
 
184
+ ## Graph explorer
185
+
186
+ Managed and existing graph registrations implement the shared `GraphExplorer` contract:
187
+
188
+ ```ts
189
+ const overview = await graph.explore({ mode: "overview", maxNodes: 100 });
190
+ const neighborhood = await graph.explore({
191
+ mode: "expand",
192
+ nodeIds: [overview.nodes[0]!.id],
193
+ maxDepth: 1,
194
+ });
195
+ ```
196
+
197
+ The explorer returns Neo4j element IDs as opaque strings, limits every query, and omits embeddings
198
+ and other `__anvia_*` properties. Use stable graph identity properties for application logic; use the
199
+ opaque IDs only to expand the current view.
200
+
184
201
  Existing registrations are read-only and expose no provisioning or write methods. Use
185
202
  `client.nativeDriver()` for application-owned Cypher.
186
203
 
@@ -0,0 +1,176 @@
1
+ import {
2
+ Neo4jKnowledgeGraphBase,
3
+ parseNeo4jProperties
4
+ } from "./chunk-QNHOT7P2.js";
5
+
6
+ // src/explore.ts
7
+ import {
8
+ resolveGraphExploreOptions
9
+ } from "@anvia/graph";
10
+ import { int } from "neo4j-driver";
11
+ async function exploreGraph(graph, options) {
12
+ if (!(graph instanceof Neo4jKnowledgeGraphBase)) {
13
+ throw new TypeError("exploreGraph requires a Neo4j knowledge graph registration.");
14
+ }
15
+ const resolved = resolveGraphExploreOptions(graph.schema, options);
16
+ const records = resolved.mode === "overview" ? await overviewNodes(graph, resolved) : await expandedNodes(graph, resolved);
17
+ const nodes = uniqueNodes(records.map((record) => nodeFromRecord(record, graph.schema)));
18
+ const visibleNodes = nodes.slice(0, resolved.maxNodes);
19
+ const relationships = await relationshipsBetween(
20
+ graph,
21
+ visibleNodes.map((node) => node.id),
22
+ resolved.relationships,
23
+ resolved.maxRelationships,
24
+ resolved.abortSignal
25
+ );
26
+ return {
27
+ nodes: visibleNodes,
28
+ relationships: relationships.slice(0, resolved.maxRelationships),
29
+ truncated: {
30
+ nodes: records.length > resolved.maxNodes || nodes.length > resolved.maxNodes,
31
+ relationships: relationships.length > resolved.maxRelationships
32
+ }
33
+ };
34
+ }
35
+ async function overviewNodes(graph, options) {
36
+ const result = await graph.query(
37
+ `MATCH (node)
38
+ WHERE any(type IN labels(node) WHERE type IN $nodeTypes)
39
+ RETURN elementId(node) AS id, labels(node) AS labels, properties(node) AS properties
40
+ ORDER BY elementId(node)
41
+ LIMIT $nodeLimit`,
42
+ { nodeTypes: options.nodeTypes, nodeLimit: int(options.maxNodes + 1) },
43
+ options.abortSignal
44
+ );
45
+ return result.records;
46
+ }
47
+ async function expandedNodes(graph, options) {
48
+ const roots = await graph.query(
49
+ `MATCH (node)
50
+ WHERE elementId(node) IN $nodeIds
51
+ AND any(type IN labels(node) WHERE type IN $nodeTypes)
52
+ RETURN elementId(node) AS id, labels(node) AS labels, properties(node) AS properties`,
53
+ { nodeIds: options.nodeIds, nodeTypes: options.nodeTypes },
54
+ options.abortSignal
55
+ );
56
+ if (options.relationships.length === 0) return roots.records;
57
+ const remainingNodeLimit = options.maxNodes + 1 - roots.records.length;
58
+ if (remainingNodeLimit <= 0) return roots.records;
59
+ const pattern = traversalPattern(options.direction, options.maxDepth);
60
+ const neighbors = await graph.query(
61
+ `MATCH (root) WHERE elementId(root) IN $nodeIds
62
+ MATCH path = ${pattern}
63
+ WHERE all(rel IN relationships(path) WHERE type(rel) IN $relationshipTypes)
64
+ AND any(type IN labels(node) WHERE type IN $nodeTypes)
65
+ RETURN elementId(node) AS id, labels(node) AS labels, properties(node) AS properties
66
+ LIMIT $nodeLimit`,
67
+ {
68
+ nodeIds: options.nodeIds,
69
+ nodeTypes: options.nodeTypes,
70
+ relationshipTypes: options.relationships,
71
+ nodeLimit: int(remainingNodeLimit)
72
+ },
73
+ options.abortSignal
74
+ );
75
+ return [...roots.records, ...neighbors.records];
76
+ }
77
+ async function relationshipsBetween(graph, nodeIds, relationshipTypes, maxRelationships, abortSignal) {
78
+ if (nodeIds.length === 0 || relationshipTypes.length === 0) return [];
79
+ const result = await graph.query(
80
+ `MATCH (from)-[relationship]->(to)
81
+ WHERE elementId(from) IN $nodeIds
82
+ AND elementId(to) IN $nodeIds
83
+ AND type(relationship) IN $relationshipTypes
84
+ RETURN elementId(relationship) AS id,
85
+ type(relationship) AS type,
86
+ elementId(from) AS source,
87
+ elementId(to) AS target,
88
+ properties(relationship) AS properties
89
+ ORDER BY elementId(relationship)
90
+ LIMIT $relationshipLimit`,
91
+ {
92
+ nodeIds,
93
+ relationshipTypes,
94
+ relationshipLimit: int(maxRelationships + 1)
95
+ },
96
+ abortSignal
97
+ );
98
+ return result.records.map(relationshipFromRecord);
99
+ }
100
+ function nodeFromRecord(record, schema) {
101
+ const id = stringValue(record.get("id"), "Neo4j explorer node id");
102
+ const labels = stringArray(record.get("labels"), "Neo4j explorer node labels");
103
+ const raw = objectValue(record.get("properties"), "Neo4j explorer node properties");
104
+ const type = labels.find((label) => label in schema.nodes);
105
+ if (type === void 0) throw new TypeError("Neo4j explorer node has no registered type.");
106
+ const properties = applicationProperties(raw, "Neo4j explorer node properties");
107
+ const node = {
108
+ id,
109
+ type,
110
+ identity: identityProperties(schema, type, properties),
111
+ properties
112
+ };
113
+ const key = raw.__anvia_key;
114
+ if (typeof key === "string") node.key = key;
115
+ return node;
116
+ }
117
+ function relationshipFromRecord(record) {
118
+ const raw = objectValue(record.get("properties"), "Neo4j explorer relationship properties");
119
+ const relationship = {
120
+ id: stringValue(record.get("id"), "Neo4j explorer relationship id"),
121
+ type: stringValue(record.get("type"), "Neo4j explorer relationship type"),
122
+ from: stringValue(record.get("source"), "Neo4j explorer relationship source"),
123
+ to: stringValue(record.get("target"), "Neo4j explorer relationship target"),
124
+ properties: applicationProperties(raw, "Neo4j explorer relationship properties")
125
+ };
126
+ const key = raw.__anvia_key;
127
+ if (typeof key === "string") relationship.key = key;
128
+ return relationship;
129
+ }
130
+ function identityProperties(schema, type, properties) {
131
+ const identity = {};
132
+ const definition = schema.nodes[type];
133
+ if (definition === void 0) return identity;
134
+ for (const property of definition.identity) {
135
+ const value = properties[property];
136
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
137
+ identity[property] = value;
138
+ }
139
+ }
140
+ return identity;
141
+ }
142
+ function applicationProperties(value, label) {
143
+ return parseNeo4jProperties(
144
+ Object.fromEntries(Object.entries(value).filter(([key]) => !key.startsWith("__anvia_"))),
145
+ label
146
+ );
147
+ }
148
+ function uniqueNodes(nodes) {
149
+ return [...new Map(nodes.map((node) => [node.id, node])).values()];
150
+ }
151
+ function traversalPattern(direction, maxDepth) {
152
+ if (direction === "outgoing") return `(root)-[*1..${maxDepth}]->(node)`;
153
+ if (direction === "incoming") return `(root)<-[*1..${maxDepth}]-(node)`;
154
+ return `(root)-[*1..${maxDepth}]-(node)`;
155
+ }
156
+ function stringValue(value, label) {
157
+ if (typeof value !== "string") throw new TypeError(`${label} must be a string.`);
158
+ return value;
159
+ }
160
+ function stringArray(value, label) {
161
+ if (!Array.isArray(value) || !value.every((item) => typeof item === "string")) {
162
+ throw new TypeError(`${label} must be a string array.`);
163
+ }
164
+ return value;
165
+ }
166
+ function objectValue(value, label) {
167
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
168
+ throw new TypeError(`${label} must be an object.`);
169
+ }
170
+ return value;
171
+ }
172
+
173
+ export {
174
+ exploreGraph
175
+ };
176
+ //# sourceMappingURL=chunk-PWE3ETSF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/explore.ts"],"sourcesContent":["import {\n resolveGraphExploreOptions,\n type GraphExploreNode,\n type GraphExploreOptions,\n type GraphExploreRelationship,\n type GraphExploreResult,\n type ResolvedGraphExploreExpandOptions,\n} from \"@anvia/graph\";\nimport { int, type Record as Neo4jRecord } from \"neo4j-driver\";\nimport { Neo4jKnowledgeGraphBase } from \"./graph.js\";\nimport { parseNeo4jProperties } from \"./schema.js\";\nimport type { Neo4jGraphSchema, Neo4jNodeIdentity } from \"./types.js\";\n\nexport async function exploreGraph<Schema extends Neo4jGraphSchema>(\n graph: Neo4jKnowledgeGraphBase<Schema>,\n options: GraphExploreOptions<Schema>,\n): Promise<GraphExploreResult> {\n if (!(graph instanceof Neo4jKnowledgeGraphBase)) {\n throw new TypeError(\"exploreGraph requires a Neo4j knowledge graph registration.\");\n }\n const resolved = resolveGraphExploreOptions(graph.schema, options);\n const records =\n resolved.mode === \"overview\"\n ? await overviewNodes(graph, resolved)\n : await expandedNodes(graph, resolved);\n const nodes = uniqueNodes(records.map((record) => nodeFromRecord(record, graph.schema)));\n const visibleNodes = nodes.slice(0, resolved.maxNodes);\n const relationships = await relationshipsBetween(\n graph,\n visibleNodes.map((node) => node.id),\n resolved.relationships,\n resolved.maxRelationships,\n resolved.abortSignal,\n );\n return {\n nodes: visibleNodes,\n relationships: relationships.slice(0, resolved.maxRelationships),\n truncated: {\n nodes: records.length > resolved.maxNodes || nodes.length > resolved.maxNodes,\n relationships: relationships.length > resolved.maxRelationships,\n },\n };\n}\n\nasync function overviewNodes(\n graph: Neo4jKnowledgeGraphBase,\n options: ReturnType<typeof resolveGraphExploreOptions> & { mode: \"overview\" },\n): Promise<readonly Neo4jRecord[]> {\n const result = await graph.query(\n `MATCH (node)\nWHERE any(type IN labels(node) WHERE type IN $nodeTypes)\nRETURN elementId(node) AS id, labels(node) AS labels, properties(node) AS properties\nORDER BY elementId(node)\nLIMIT $nodeLimit`,\n { nodeTypes: options.nodeTypes, nodeLimit: int(options.maxNodes + 1) },\n options.abortSignal,\n );\n return result.records;\n}\n\nasync function expandedNodes(\n graph: Neo4jKnowledgeGraphBase,\n options: ResolvedGraphExploreExpandOptions,\n): Promise<readonly Neo4jRecord[]> {\n const roots = await graph.query(\n `MATCH (node)\nWHERE elementId(node) IN $nodeIds\n AND any(type IN labels(node) WHERE type IN $nodeTypes)\nRETURN elementId(node) AS id, labels(node) AS labels, properties(node) AS properties`,\n { nodeIds: options.nodeIds, nodeTypes: options.nodeTypes },\n options.abortSignal,\n );\n if (options.relationships.length === 0) return roots.records;\n const remainingNodeLimit = options.maxNodes + 1 - roots.records.length;\n if (remainingNodeLimit <= 0) return roots.records;\n const pattern = traversalPattern(options.direction, options.maxDepth);\n const neighbors = await graph.query(\n `MATCH (root) WHERE elementId(root) IN $nodeIds\nMATCH path = ${pattern}\nWHERE all(rel IN relationships(path) WHERE type(rel) IN $relationshipTypes)\n AND any(type IN labels(node) WHERE type IN $nodeTypes)\nRETURN elementId(node) AS id, labels(node) AS labels, properties(node) AS properties\nLIMIT $nodeLimit`,\n {\n nodeIds: options.nodeIds,\n nodeTypes: options.nodeTypes,\n relationshipTypes: options.relationships,\n nodeLimit: int(remainingNodeLimit),\n },\n options.abortSignal,\n );\n return [...roots.records, ...neighbors.records];\n}\n\nasync function relationshipsBetween(\n graph: Neo4jKnowledgeGraphBase,\n nodeIds: readonly string[],\n relationshipTypes: readonly string[],\n maxRelationships: number,\n abortSignal?: AbortSignal,\n): Promise<GraphExploreRelationship[]> {\n if (nodeIds.length === 0 || relationshipTypes.length === 0) return [];\n const result = await graph.query(\n `MATCH (from)-[relationship]->(to)\nWHERE elementId(from) IN $nodeIds\n AND elementId(to) IN $nodeIds\n AND type(relationship) IN $relationshipTypes\nRETURN elementId(relationship) AS id,\n type(relationship) AS type,\n elementId(from) AS source,\n elementId(to) AS target,\n properties(relationship) AS properties\nORDER BY elementId(relationship)\nLIMIT $relationshipLimit`,\n {\n nodeIds,\n relationshipTypes,\n relationshipLimit: int(maxRelationships + 1),\n },\n abortSignal,\n );\n return result.records.map(relationshipFromRecord);\n}\n\nfunction nodeFromRecord(record: Neo4jRecord, schema: Neo4jGraphSchema): GraphExploreNode {\n const id = stringValue(record.get(\"id\"), \"Neo4j explorer node id\");\n const labels = stringArray(record.get(\"labels\"), \"Neo4j explorer node labels\");\n const raw = objectValue(record.get(\"properties\"), \"Neo4j explorer node properties\");\n const type = labels.find((label) => label in schema.nodes);\n if (type === undefined) throw new TypeError(\"Neo4j explorer node has no registered type.\");\n const properties = applicationProperties(raw, \"Neo4j explorer node properties\");\n const node: {\n id: string;\n key?: string | undefined;\n type: string;\n identity: Neo4jNodeIdentity;\n properties: typeof properties;\n } = {\n id,\n type,\n identity: identityProperties(schema, type, properties),\n properties,\n };\n const key = raw.__anvia_key;\n if (typeof key === \"string\") node.key = key;\n return node;\n}\n\nfunction relationshipFromRecord(record: Neo4jRecord): GraphExploreRelationship {\n const raw = objectValue(record.get(\"properties\"), \"Neo4j explorer relationship properties\");\n const relationship: {\n id: string;\n key?: string | undefined;\n type: string;\n from: string;\n to: string;\n properties: ReturnType<typeof applicationProperties>;\n } = {\n id: stringValue(record.get(\"id\"), \"Neo4j explorer relationship id\"),\n type: stringValue(record.get(\"type\"), \"Neo4j explorer relationship type\"),\n from: stringValue(record.get(\"source\"), \"Neo4j explorer relationship source\"),\n to: stringValue(record.get(\"target\"), \"Neo4j explorer relationship target\"),\n properties: applicationProperties(raw, \"Neo4j explorer relationship properties\"),\n };\n const key = raw.__anvia_key;\n if (typeof key === \"string\") relationship.key = key;\n return relationship;\n}\n\nfunction identityProperties(\n schema: Neo4jGraphSchema,\n type: string,\n properties: ReturnType<typeof applicationProperties>,\n): Neo4jNodeIdentity {\n const identity: Record<string, string | number | boolean> = {};\n const definition = schema.nodes[type];\n if (definition === undefined) return identity;\n for (const property of definition.identity) {\n const value = properties[property];\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n identity[property] = value;\n }\n }\n return identity;\n}\n\nfunction applicationProperties(value: Record<string, unknown>, label: string) {\n return parseNeo4jProperties(\n Object.fromEntries(Object.entries(value).filter(([key]) => !key.startsWith(\"__anvia_\"))),\n label,\n );\n}\n\nfunction uniqueNodes(nodes: readonly GraphExploreNode[]): GraphExploreNode[] {\n return [...new Map(nodes.map((node) => [node.id, node])).values()];\n}\n\nfunction traversalPattern(direction: \"outgoing\" | \"incoming\" | \"both\", maxDepth: number): string {\n if (direction === \"outgoing\") return `(root)-[*1..${maxDepth}]->(node)`;\n if (direction === \"incoming\") return `(root)<-[*1..${maxDepth}]-(node)`;\n return `(root)-[*1..${maxDepth}]-(node)`;\n}\n\nfunction stringValue(value: unknown, label: string): string {\n if (typeof value !== \"string\") throw new TypeError(`${label} must be a string.`);\n return value;\n}\n\nfunction stringArray(value: unknown, label: string): string[] {\n if (!Array.isArray(value) || !value.every((item) => typeof item === \"string\")) {\n throw new TypeError(`${label} must be a string array.`);\n }\n return value;\n}\n\nfunction objectValue(value: unknown, label: string): Record<string, unknown> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new TypeError(`${label} must be an object.`);\n }\n return value as Record<string, unknown>;\n}\n"],"mappings":"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","names":[]}