@langchain/neo4j 0.0.1

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.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +281 -0
  3. package/dist/_virtual/_rolldown/runtime.cjs +23 -0
  4. package/dist/chains/graph_qa/cypher.cjs +117 -0
  5. package/dist/chains/graph_qa/cypher.cjs.map +1 -0
  6. package/dist/chains/graph_qa/cypher.d.cts +73 -0
  7. package/dist/chains/graph_qa/cypher.d.cts.map +1 -0
  8. package/dist/chains/graph_qa/cypher.d.ts +73 -0
  9. package/dist/chains/graph_qa/cypher.d.ts.map +1 -0
  10. package/dist/chains/graph_qa/cypher.js +115 -0
  11. package/dist/chains/graph_qa/cypher.js.map +1 -0
  12. package/dist/chains/graph_qa/index.cjs +2 -0
  13. package/dist/chains/graph_qa/index.d.ts +2 -0
  14. package/dist/chains/graph_qa/index.js +3 -0
  15. package/dist/chains/graph_qa/prompts.cjs +42 -0
  16. package/dist/chains/graph_qa/prompts.cjs.map +1 -0
  17. package/dist/chains/graph_qa/prompts.d.cts +14 -0
  18. package/dist/chains/graph_qa/prompts.d.cts.map +1 -0
  19. package/dist/chains/graph_qa/prompts.d.ts +14 -0
  20. package/dist/chains/graph_qa/prompts.d.ts.map +1 -0
  21. package/dist/chains/graph_qa/prompts.js +40 -0
  22. package/dist/chains/graph_qa/prompts.js.map +1 -0
  23. package/dist/graphs/document.cjs +63 -0
  24. package/dist/graphs/document.cjs.map +1 -0
  25. package/dist/graphs/document.d.cts +56 -0
  26. package/dist/graphs/document.d.cts.map +1 -0
  27. package/dist/graphs/document.d.ts +56 -0
  28. package/dist/graphs/document.d.ts.map +1 -0
  29. package/dist/graphs/document.js +60 -0
  30. package/dist/graphs/document.js.map +1 -0
  31. package/dist/graphs/index.cjs +3 -0
  32. package/dist/graphs/index.d.ts +3 -0
  33. package/dist/graphs/index.js +4 -0
  34. package/dist/graphs/memgraph_graph.cjs +74 -0
  35. package/dist/graphs/memgraph_graph.cjs.map +1 -0
  36. package/dist/graphs/memgraph_graph.d.cts +36 -0
  37. package/dist/graphs/memgraph_graph.d.cts.map +1 -0
  38. package/dist/graphs/memgraph_graph.d.ts +36 -0
  39. package/dist/graphs/memgraph_graph.d.ts.map +1 -0
  40. package/dist/graphs/memgraph_graph.js +74 -0
  41. package/dist/graphs/memgraph_graph.js.map +1 -0
  42. package/dist/graphs/neo4j_graph.cjs +429 -0
  43. package/dist/graphs/neo4j_graph.cjs.map +1 -0
  44. package/dist/graphs/neo4j_graph.d.cts +96 -0
  45. package/dist/graphs/neo4j_graph.d.cts.map +1 -0
  46. package/dist/graphs/neo4j_graph.d.ts +96 -0
  47. package/dist/graphs/neo4j_graph.d.ts.map +1 -0
  48. package/dist/graphs/neo4j_graph.js +425 -0
  49. package/dist/graphs/neo4j_graph.js.map +1 -0
  50. package/dist/index.cjs +28 -0
  51. package/dist/index.d.cts +8 -0
  52. package/dist/index.d.ts +8 -0
  53. package/dist/index.js +12 -0
  54. package/dist/stores/message/index.cjs +1 -0
  55. package/dist/stores/message/index.d.ts +1 -0
  56. package/dist/stores/message/index.js +2 -0
  57. package/dist/stores/message/neo4j.cjs +114 -0
  58. package/dist/stores/message/neo4j.cjs.map +1 -0
  59. package/dist/stores/message/neo4j.d.cts +40 -0
  60. package/dist/stores/message/neo4j.d.cts.map +1 -0
  61. package/dist/stores/message/neo4j.d.ts +40 -0
  62. package/dist/stores/message/neo4j.d.ts.map +1 -0
  63. package/dist/stores/message/neo4j.js +112 -0
  64. package/dist/stores/message/neo4j.js.map +1 -0
  65. package/dist/vectorstores/index.cjs +1 -0
  66. package/dist/vectorstores/index.d.ts +1 -0
  67. package/dist/vectorstores/index.js +2 -0
  68. package/dist/vectorstores/neo4j_vector.cjs +622 -0
  69. package/dist/vectorstores/neo4j_vector.cjs.map +1 -0
  70. package/dist/vectorstores/neo4j_vector.d.cts +96 -0
  71. package/dist/vectorstores/neo4j_vector.d.cts.map +1 -0
  72. package/dist/vectorstores/neo4j_vector.d.ts +96 -0
  73. package/dist/vectorstores/neo4j_vector.d.ts.map +1 -0
  74. package/dist/vectorstores/neo4j_vector.js +616 -0
  75. package/dist/vectorstores/neo4j_vector.js.map +1 -0
  76. package/package.json +98 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) LangChain, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,281 @@
1
+ # @langchain/neo4j
2
+
3
+ This package contains the [LangChain.js](https://github.com/langchain-ai/langchainjs) integrations for [Neo4j](https://neo4j.com/) graph database, including support for [Memgraph](https://memgraph.com/) (which uses the Bolt protocol).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @langchain/neo4j @langchain/core
9
+ ```
10
+
11
+ You also need to have `neo4j-driver` installed (it is included as a dependency of this package).
12
+
13
+ ## Components
14
+
15
+ ### Neo4jGraph
16
+
17
+ A wrapper around the Neo4j database that provides schema introspection and query execution.
18
+
19
+ ```typescript
20
+ import { Neo4jGraph } from "@langchain/neo4j";
21
+
22
+ const graph = await Neo4jGraph.initialize({
23
+ url: "bolt://localhost:7687",
24
+ username: "neo4j",
25
+ password: "password",
26
+ database: "neo4j", // optional, defaults to "neo4j"
27
+ });
28
+
29
+ // Get the database schema
30
+ console.log(graph.getSchema());
31
+
32
+ // Run a Cypher query
33
+ const results = await graph.query("MATCH (n:Person) RETURN n.name LIMIT 10");
34
+
35
+ // Clean up
36
+ await graph.close();
37
+ ```
38
+
39
+ #### Enhanced Schema
40
+
41
+ You can enable enhanced schema introspection to get more detailed information about node and relationship properties, including value distributions, min/max ranges, and distinct counts:
42
+
43
+ ```typescript
44
+ const graph = await Neo4jGraph.initialize({
45
+ url: "bolt://localhost:7687",
46
+ username: "neo4j",
47
+ password: "password",
48
+ enhancedSchema: true,
49
+ });
50
+ ```
51
+
52
+ #### Graph Documents
53
+
54
+ You can add structured graph documents (nodes and relationships extracted from text) to the database:
55
+
56
+ ```typescript
57
+ import { Neo4jGraph, Node, Relationship, GraphDocument } from "@langchain/neo4j";
58
+ import { Document } from "@langchain/core/documents";
59
+
60
+ const source = new Document({
61
+ pageContent: "Alice works at Acme Corp.",
62
+ metadata: { id: "doc1" },
63
+ });
64
+
65
+ const alice = new Node({ id: "alice", type: "Person", properties: { name: "Alice" } });
66
+ const acme = new Node({ id: "acme", type: "Company", properties: { name: "Acme Corp" } });
67
+ const worksAt = new Relationship({
68
+ source: alice,
69
+ target: acme,
70
+ type: "WORKS_AT",
71
+ });
72
+
73
+ const graphDoc = new GraphDocument({
74
+ nodes: [alice, acme],
75
+ relationships: [worksAt],
76
+ source,
77
+ });
78
+
79
+ await graph.addGraphDocuments([graphDoc]);
80
+ ```
81
+
82
+ ### Neo4jVectorStore
83
+
84
+ A vector store implementation backed by Neo4j's vector index capabilities. Supports vector search, hybrid search (vector + full-text), and metadata filtering.
85
+
86
+ ```typescript
87
+ import { Neo4jVectorStore } from "@langchain/neo4j";
88
+ import { OpenAIEmbeddings } from "@langchain/openai";
89
+
90
+ const embeddings = new OpenAIEmbeddings();
91
+
92
+ // Create from documents
93
+ const vectorStore = await Neo4jVectorStore.fromDocuments(docs, embeddings, {
94
+ url: "bolt://localhost:7687",
95
+ username: "neo4j",
96
+ password: "password",
97
+ indexName: "vector",
98
+ nodeLabel: "Chunk",
99
+ textNodeProperty: "text",
100
+ embeddingNodeProperty: "embedding",
101
+ });
102
+
103
+ // Similarity search
104
+ const results = await vectorStore.similaritySearch("What is Neo4j?", 4);
105
+
106
+ // Similarity search with score
107
+ const resultsWithScore = await vectorStore.similaritySearchWithScore(
108
+ "What is Neo4j?",
109
+ 4
110
+ );
111
+
112
+ // Clean up
113
+ await vectorStore.close();
114
+ ```
115
+
116
+ #### Hybrid Search
117
+
118
+ Combine vector search with full-text search for improved retrieval:
119
+
120
+ ```typescript
121
+ const vectorStore = await Neo4jVectorStore.fromDocuments(docs, embeddings, {
122
+ url: "bolt://localhost:7687",
123
+ username: "neo4j",
124
+ password: "password",
125
+ searchType: "hybrid",
126
+ indexName: "vector",
127
+ keywordIndexName: "keyword",
128
+ nodeLabel: "Chunk",
129
+ });
130
+ ```
131
+
132
+ #### Using an Existing Index
133
+
134
+ Connect to a pre-existing vector index:
135
+
136
+ ```typescript
137
+ const vectorStore = await Neo4jVectorStore.fromExistingIndex(embeddings, {
138
+ url: "bolt://localhost:7687",
139
+ username: "neo4j",
140
+ password: "password",
141
+ indexName: "my_existing_index",
142
+ });
143
+ ```
144
+
145
+ #### Metadata Filtering
146
+
147
+ Filter search results by node properties (requires Neo4j 5.18+):
148
+
149
+ ```typescript
150
+ const results = await vectorStore.similaritySearch("query", 4, {
151
+ filter: {
152
+ category: "science",
153
+ year: { $gte: 2020 },
154
+ },
155
+ });
156
+ ```
157
+
158
+ Supported filter operators: `$eq`, `$ne`, `$lt`, `$lte`, `$gt`, `$gte`, `$in`, `$nin`, `$like`, `$ilike`, `$between`, `$and`, `$or`.
159
+
160
+ ### Neo4jChatMessageHistory
161
+
162
+ Persist chat message history in a Neo4j database:
163
+
164
+ ```typescript
165
+ import { Neo4jChatMessageHistory } from "@langchain/neo4j";
166
+ import { HumanMessage, AIMessage } from "@langchain/core/messages";
167
+
168
+ const history = await Neo4jChatMessageHistory.initialize({
169
+ url: "bolt://localhost:7687",
170
+ username: "neo4j",
171
+ password: "password",
172
+ sessionId: "my-session-id", // optional, auto-generated if not provided
173
+ windowSize: 5, // optional, defaults to 3
174
+ });
175
+
176
+ // Add messages
177
+ await history.addMessage(new HumanMessage("Hello!"));
178
+ await history.addMessage(new AIMessage("Hi there! How can I help you?"));
179
+
180
+ // Retrieve messages
181
+ const messages = await history.getMessages();
182
+
183
+ // Clear history
184
+ await history.clear();
185
+
186
+ // Clean up
187
+ await history.close();
188
+ ```
189
+
190
+ ### GraphCypherQAChain
191
+
192
+ A chain for question-answering against a Neo4j graph database by generating Cypher statements. Requires `@langchain/classic` as an optional dependency.
193
+
194
+ ```typescript
195
+ import { Neo4jGraph, GraphCypherQAChain } from "@langchain/neo4j";
196
+ import { ChatOpenAI } from "@langchain/openai";
197
+
198
+ const graph = await Neo4jGraph.initialize({
199
+ url: "bolt://localhost:7687",
200
+ username: "neo4j",
201
+ password: "password",
202
+ });
203
+
204
+ const llm = new ChatOpenAI({ model: "gpt-4o-mini", temperature: 0 });
205
+
206
+ const chain = GraphCypherQAChain.fromLLM({
207
+ graph,
208
+ llm,
209
+ returnIntermediateSteps: true,
210
+ });
211
+
212
+ const result = await chain.invoke({ query: "Who played in Pulp Fiction?" });
213
+ console.log(result.result);
214
+ ```
215
+
216
+ You can also use separate LLMs for Cypher generation and answer synthesis:
217
+
218
+ ```typescript
219
+ const chain = GraphCypherQAChain.fromLLM({
220
+ graph,
221
+ cypherLLM: new ChatOpenAI({ model: "gpt-4o", temperature: 0 }),
222
+ qaLLM: new ChatOpenAI({ model: "gpt-4o-mini", temperature: 0 }),
223
+ });
224
+ ```
225
+
226
+ ### MemgraphGraph
227
+
228
+ A subclass of `Neo4jGraph` for use with [Memgraph](https://memgraph.com/), which is compatible with the Bolt protocol:
229
+
230
+ ```typescript
231
+ import { MemgraphGraph } from "@langchain/neo4j";
232
+
233
+ const graph = await MemgraphGraph.initialize({
234
+ url: "bolt://localhost:7687",
235
+ username: "memgraph",
236
+ password: "password",
237
+ });
238
+
239
+ console.log(graph.getSchema());
240
+ await graph.close();
241
+ ```
242
+
243
+ ## Security
244
+
245
+ All database components in this package accept connection credentials. Make sure that the database connection uses credentials that are narrowly-scoped to only include necessary permissions. See the [LangChain security documentation](https://js.langchain.com/docs/security) for more information.
246
+
247
+ ## Migration from `@langchain/community`
248
+
249
+ If you were previously using Neo4j integrations from `@langchain/community`, update your imports:
250
+
251
+ ```typescript
252
+ // Before
253
+ import { Neo4jGraph } from "@langchain/community/graphs/neo4j_graph";
254
+ import { Neo4jVectorStore } from "@langchain/community/vectorstores/neo4j_vector";
255
+ import { Neo4jChatMessageHistory } from "@langchain/community/stores/message/neo4j";
256
+ import { GraphCypherQAChain } from "@langchain/community/chains/graph_qa/cypher";
257
+
258
+ // After
259
+ import {
260
+ Neo4jGraph,
261
+ Neo4jVectorStore,
262
+ Neo4jChatMessageHistory,
263
+ GraphCypherQAChain,
264
+ } from "@langchain/neo4j";
265
+ ```
266
+
267
+ ## Development
268
+
269
+ ```bash
270
+ # Install dependencies
271
+ pnpm install
272
+
273
+ # Build
274
+ pnpm --filter @langchain/neo4j build
275
+
276
+ # Run tests
277
+ pnpm --filter @langchain/neo4j test
278
+
279
+ # Lint
280
+ pnpm --filter @langchain/neo4j lint
281
+ ```
@@ -0,0 +1,23 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+ //#endregion
23
+ exports.__toESM = __toESM;
@@ -0,0 +1,117 @@
1
+ require("../../_virtual/_rolldown/runtime.cjs");
2
+ const require_prompts = require("./prompts.cjs");
3
+ let _langchain_classic_chains = require("@langchain/classic/chains");
4
+ //#region src/chains/graph_qa/cypher.ts
5
+ const INTERMEDIATE_STEPS_KEY = "intermediateSteps";
6
+ /**
7
+ * Chain for question-answering against a graph by generating Cypher statements.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const chain = new GraphCypherQAChain({
12
+ * llm: new ChatOpenAI({ model: "gpt-4o-mini", temperature: 0 }),
13
+ * graph: new Neo4jGraph(),
14
+ * });
15
+ * const res = await chain.invoke("Who played in Pulp Fiction?");
16
+ * ```
17
+ *
18
+ * @security
19
+ * This chain will execute Cypher statements against the provided database.
20
+ * Make sure that the database connection uses credentials
21
+ * that are narrowly-scoped to only include necessary permissions.
22
+ * Failure to do so may result in data corruption or loss, since the calling code
23
+ * may attempt commands that would result in deletion, mutation of data
24
+ * if appropriately prompted or reading sensitive data if such data is present in the database.
25
+ * The best way to guard against such negative outcomes is to (as appropriate) limit the
26
+ * permissions granted to the credentials used with this tool.
27
+ *
28
+ * See https://js.langchain.com/docs/security for more information.
29
+ */
30
+ var GraphCypherQAChain = class GraphCypherQAChain extends _langchain_classic_chains.BaseChain {
31
+ graph;
32
+ cypherGenerationChain;
33
+ qaChain;
34
+ inputKey = "query";
35
+ outputKey = "result";
36
+ topK = 10;
37
+ returnDirect = false;
38
+ returnIntermediateSteps = false;
39
+ constructor(props) {
40
+ super(props);
41
+ const { graph, cypherGenerationChain, qaChain, inputKey, outputKey, topK, returnIntermediateSteps, returnDirect } = props;
42
+ this.graph = graph;
43
+ this.cypherGenerationChain = cypherGenerationChain;
44
+ this.qaChain = qaChain;
45
+ if (inputKey) this.inputKey = inputKey;
46
+ if (outputKey) this.outputKey = outputKey;
47
+ if (topK) this.topK = topK;
48
+ if (returnIntermediateSteps) this.returnIntermediateSteps = returnIntermediateSteps;
49
+ if (returnDirect) this.returnDirect = returnDirect;
50
+ }
51
+ _chainType() {
52
+ return "graph_cypher_chain";
53
+ }
54
+ get inputKeys() {
55
+ return [this.inputKey];
56
+ }
57
+ get outputKeys() {
58
+ return [this.outputKey];
59
+ }
60
+ static fromLLM(props) {
61
+ const { graph, qaPrompt = require_prompts.CYPHER_QA_PROMPT, cypherPrompt = require_prompts.CYPHER_GENERATION_PROMPT, llm, cypherLLM, qaLLM, returnIntermediateSteps = false, returnDirect = false } = props;
62
+ if (!cypherLLM && !llm) throw new Error("Either 'llm' or 'cypherLLM' parameters must be provided");
63
+ if (!qaLLM && !llm) throw new Error("Either 'llm' or 'qaLLM' parameters must be provided");
64
+ if (cypherLLM && qaLLM && llm) throw new Error("You can specify up to two of 'cypherLLM', 'qaLLM', and 'llm', but not all three simultaneously.");
65
+ const qaChain = new _langchain_classic_chains.LLMChain({
66
+ llm: qaLLM || llm,
67
+ prompt: qaPrompt
68
+ });
69
+ return new GraphCypherQAChain({
70
+ cypherGenerationChain: new _langchain_classic_chains.LLMChain({
71
+ llm: cypherLLM || llm,
72
+ prompt: cypherPrompt
73
+ }),
74
+ qaChain,
75
+ graph,
76
+ returnIntermediateSteps,
77
+ returnDirect
78
+ });
79
+ }
80
+ extractCypher(text) {
81
+ const matches = text.match(/```(.*?)```/s);
82
+ return matches ? matches[1] : text;
83
+ }
84
+ async _call(values, runManager) {
85
+ const callbacks = runManager?.getChild();
86
+ const question = values[this.inputKey];
87
+ const intermediateSteps = [];
88
+ const generatedCypher = await this.cypherGenerationChain.call({
89
+ question,
90
+ schema: this.graph.getSchema()
91
+ }, callbacks);
92
+ const extractedCypher = this.extractCypher(generatedCypher.text);
93
+ await runManager?.handleText(`Generated Cypher:\n`);
94
+ await runManager?.handleText(`${extractedCypher} green\n`);
95
+ intermediateSteps.push({ query: extractedCypher });
96
+ let chainResult;
97
+ const context = await this.graph.query(extractedCypher, { topK: this.topK });
98
+ if (this.returnDirect) chainResult = { [this.outputKey]: context };
99
+ else {
100
+ await runManager?.handleText("Full Context:\n");
101
+ await runManager?.handleText(`${context} green\n`);
102
+ intermediateSteps.push({ context });
103
+ const result = await this.qaChain.call({
104
+ question,
105
+ context: JSON.stringify(context)
106
+ }, callbacks);
107
+ chainResult = { [this.outputKey]: result[this.qaChain.outputKey] };
108
+ }
109
+ if (this.returnIntermediateSteps) chainResult[INTERMEDIATE_STEPS_KEY] = intermediateSteps;
110
+ return chainResult;
111
+ }
112
+ };
113
+ //#endregion
114
+ exports.GraphCypherQAChain = GraphCypherQAChain;
115
+ exports.INTERMEDIATE_STEPS_KEY = INTERMEDIATE_STEPS_KEY;
116
+
117
+ //# sourceMappingURL=cypher.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cypher.cjs","names":["BaseChain","CYPHER_QA_PROMPT","CYPHER_GENERATION_PROMPT","LLMChain"],"sources":["../../../src/chains/graph_qa/cypher.ts"],"sourcesContent":["import type { BaseLanguageModelInterface } from \"@langchain/core/language_models/base\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport { BasePromptTemplate } from \"@langchain/core/prompts\";\nimport { CallbackManagerForChainRun } from \"@langchain/core/callbacks/manager\";\nimport { LLMChain, BaseChain, ChainInputs } from \"@langchain/classic/chains\";\nimport { Neo4jGraph } from \"../../graphs/neo4j_graph.js\";\nimport { CYPHER_GENERATION_PROMPT, CYPHER_QA_PROMPT } from \"./prompts.js\";\n\nexport const INTERMEDIATE_STEPS_KEY = \"intermediateSteps\";\n\nexport interface GraphCypherQAChainInput extends ChainInputs {\n graph: Neo4jGraph;\n cypherGenerationChain: LLMChain;\n qaChain: LLMChain;\n inputKey?: string;\n outputKey?: string;\n topK?: number;\n returnIntermediateSteps?: boolean;\n returnDirect?: boolean;\n}\n\nexport interface FromLLMInput {\n graph: Neo4jGraph;\n llm?: BaseLanguageModelInterface;\n cypherLLM?: BaseLanguageModelInterface;\n qaLLM?: BaseLanguageModelInterface;\n qaPrompt?: BasePromptTemplate;\n cypherPrompt?: BasePromptTemplate;\n returnIntermediateSteps?: boolean;\n returnDirect?: boolean;\n}\n\n/**\n * Chain for question-answering against a graph by generating Cypher statements.\n *\n * @example\n * ```typescript\n * const chain = new GraphCypherQAChain({\n * llm: new ChatOpenAI({ model: \"gpt-4o-mini\", temperature: 0 }),\n * graph: new Neo4jGraph(),\n * });\n * const res = await chain.invoke(\"Who played in Pulp Fiction?\");\n * ```\n *\n * @security\n * This chain will execute Cypher statements against the provided database.\n * Make sure that the database connection uses credentials\n * that are narrowly-scoped to only include necessary permissions.\n * Failure to do so may result in data corruption or loss, since the calling code\n * may attempt commands that would result in deletion, mutation of data\n * if appropriately prompted or reading sensitive data if such data is present in the database.\n * The best way to guard against such negative outcomes is to (as appropriate) limit the\n * permissions granted to the credentials used with this tool.\n *\n * See https://js.langchain.com/docs/security for more information.\n */\nexport class GraphCypherQAChain extends BaseChain {\n private graph: Neo4jGraph;\n\n private cypherGenerationChain: LLMChain;\n\n private qaChain: LLMChain;\n\n private inputKey = \"query\";\n\n private outputKey = \"result\";\n\n private topK = 10;\n\n private returnDirect = false;\n\n private returnIntermediateSteps = false;\n\n constructor(props: GraphCypherQAChainInput) {\n super(props);\n const {\n graph,\n cypherGenerationChain,\n qaChain,\n inputKey,\n outputKey,\n topK,\n returnIntermediateSteps,\n returnDirect,\n } = props;\n\n this.graph = graph;\n this.cypherGenerationChain = cypherGenerationChain;\n this.qaChain = qaChain;\n\n if (inputKey) {\n this.inputKey = inputKey;\n }\n if (outputKey) {\n this.outputKey = outputKey;\n }\n if (topK) {\n this.topK = topK;\n }\n if (returnIntermediateSteps) {\n this.returnIntermediateSteps = returnIntermediateSteps;\n }\n if (returnDirect) {\n this.returnDirect = returnDirect;\n }\n }\n\n _chainType() {\n return \"graph_cypher_chain\" as const;\n }\n\n get inputKeys(): string[] {\n return [this.inputKey];\n }\n\n get outputKeys(): string[] {\n return [this.outputKey];\n }\n\n static fromLLM(props: FromLLMInput): GraphCypherQAChain {\n const {\n graph,\n qaPrompt = CYPHER_QA_PROMPT,\n cypherPrompt = CYPHER_GENERATION_PROMPT,\n llm,\n cypherLLM,\n qaLLM,\n returnIntermediateSteps = false,\n returnDirect = false,\n } = props;\n\n if (!cypherLLM && !llm) {\n throw new Error(\n \"Either 'llm' or 'cypherLLM' parameters must be provided\"\n );\n }\n\n if (!qaLLM && !llm) {\n throw new Error(\"Either 'llm' or 'qaLLM' parameters must be provided\");\n }\n\n if (cypherLLM && qaLLM && llm) {\n throw new Error(\n \"You can specify up to two of 'cypherLLM', 'qaLLM', and 'llm', but not all three simultaneously.\"\n );\n }\n\n const qaChain = new LLMChain({\n llm: (qaLLM || llm) as BaseLanguageModelInterface,\n prompt: qaPrompt,\n });\n\n const cypherGenerationChain = new LLMChain({\n llm: (cypherLLM || llm) as BaseLanguageModelInterface,\n prompt: cypherPrompt,\n });\n\n return new GraphCypherQAChain({\n cypherGenerationChain,\n qaChain,\n graph,\n returnIntermediateSteps,\n returnDirect,\n });\n }\n\n private extractCypher(text: string): string {\n const pattern = /```(.*?)```/s;\n const matches = text.match(pattern);\n return matches ? matches[1] : text;\n }\n\n async _call(\n values: ChainValues,\n runManager?: CallbackManagerForChainRun\n ): Promise<ChainValues> {\n const callbacks = runManager?.getChild();\n const question = values[this.inputKey];\n\n const intermediateSteps = [];\n\n const generatedCypher = await this.cypherGenerationChain.call(\n { question, schema: this.graph.getSchema() },\n callbacks\n );\n\n const extractedCypher = this.extractCypher(generatedCypher.text);\n\n await runManager?.handleText(`Generated Cypher:\\n`);\n await runManager?.handleText(`${extractedCypher} green\\n`);\n\n intermediateSteps.push({ query: extractedCypher });\n\n let chainResult: ChainValues;\n const context = await this.graph.query(extractedCypher, {\n topK: this.topK,\n });\n\n if (this.returnDirect) {\n chainResult = { [this.outputKey]: context };\n } else {\n await runManager?.handleText(\"Full Context:\\n\");\n await runManager?.handleText(`${context} green\\n`);\n\n intermediateSteps.push({ context });\n\n const result = await this.qaChain.call(\n { question, context: JSON.stringify(context) },\n callbacks\n );\n\n chainResult = {\n [this.outputKey]: result[this.qaChain.outputKey],\n };\n }\n\n if (this.returnIntermediateSteps) {\n chainResult[INTERMEDIATE_STEPS_KEY] = intermediateSteps;\n }\n\n return chainResult;\n }\n}\n"],"mappings":";;;;AAQA,MAAa,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;AAgDtC,IAAa,qBAAb,MAAa,2BAA2BA,0BAAAA,UAAU;CAChD;CAEA;CAEA;CAEA,WAAmB;CAEnB,YAAoB;CAEpB,OAAe;CAEf,eAAuB;CAEvB,0BAAkC;CAElC,YAAY,OAAgC;AAC1C,QAAM,MAAM;EACZ,MAAM,EACJ,OACA,uBACA,SACA,UACA,WACA,MACA,yBACA,iBACE;AAEJ,OAAK,QAAQ;AACb,OAAK,wBAAwB;AAC7B,OAAK,UAAU;AAEf,MAAI,SACF,MAAK,WAAW;AAElB,MAAI,UACF,MAAK,YAAY;AAEnB,MAAI,KACF,MAAK,OAAO;AAEd,MAAI,wBACF,MAAK,0BAA0B;AAEjC,MAAI,aACF,MAAK,eAAe;;CAIxB,aAAa;AACX,SAAO;;CAGT,IAAI,YAAsB;AACxB,SAAO,CAAC,KAAK,SAAS;;CAGxB,IAAI,aAAuB;AACzB,SAAO,CAAC,KAAK,UAAU;;CAGzB,OAAO,QAAQ,OAAyC;EACtD,MAAM,EACJ,OACA,WAAWC,gBAAAA,kBACX,eAAeC,gBAAAA,0BACf,KACA,WACA,OACA,0BAA0B,OAC1B,eAAe,UACb;AAEJ,MAAI,CAAC,aAAa,CAAC,IACjB,OAAM,IAAI,MACR,0DACD;AAGH,MAAI,CAAC,SAAS,CAAC,IACb,OAAM,IAAI,MAAM,sDAAsD;AAGxE,MAAI,aAAa,SAAS,IACxB,OAAM,IAAI,MACR,kGACD;EAGH,MAAM,UAAU,IAAIC,0BAAAA,SAAS;GAC3B,KAAM,SAAS;GACf,QAAQ;GACT,CAAC;AAOF,SAAO,IAAI,mBAAmB;GAC5B,uBAN4B,IAAIA,0BAAAA,SAAS;IACzC,KAAM,aAAa;IACnB,QAAQ;IACT,CAAC;GAIA;GACA;GACA;GACA;GACD,CAAC;;CAGJ,cAAsB,MAAsB;EAE1C,MAAM,UAAU,KAAK,MADL,eACmB;AACnC,SAAO,UAAU,QAAQ,KAAK;;CAGhC,MAAM,MACJ,QACA,YACsB;EACtB,MAAM,YAAY,YAAY,UAAU;EACxC,MAAM,WAAW,OAAO,KAAK;EAE7B,MAAM,oBAAoB,EAAE;EAE5B,MAAM,kBAAkB,MAAM,KAAK,sBAAsB,KACvD;GAAE;GAAU,QAAQ,KAAK,MAAM,WAAW;GAAE,EAC5C,UACD;EAED,MAAM,kBAAkB,KAAK,cAAc,gBAAgB,KAAK;AAEhE,QAAM,YAAY,WAAW,sBAAsB;AACnD,QAAM,YAAY,WAAW,GAAG,gBAAgB,UAAU;AAE1D,oBAAkB,KAAK,EAAE,OAAO,iBAAiB,CAAC;EAElD,IAAI;EACJ,MAAM,UAAU,MAAM,KAAK,MAAM,MAAM,iBAAiB,EACtD,MAAM,KAAK,MACZ,CAAC;AAEF,MAAI,KAAK,aACP,eAAc,GAAG,KAAK,YAAY,SAAS;OACtC;AACL,SAAM,YAAY,WAAW,kBAAkB;AAC/C,SAAM,YAAY,WAAW,GAAG,QAAQ,UAAU;AAElD,qBAAkB,KAAK,EAAE,SAAS,CAAC;GAEnC,MAAM,SAAS,MAAM,KAAK,QAAQ,KAChC;IAAE;IAAU,SAAS,KAAK,UAAU,QAAQ;IAAE,EAC9C,UACD;AAED,iBAAc,GACX,KAAK,YAAY,OAAO,KAAK,QAAQ,YACvC;;AAGH,MAAI,KAAK,wBACP,aAAY,0BAA0B;AAGxC,SAAO"}
@@ -0,0 +1,73 @@
1
+ import { Neo4jGraph } from "../../graphs/neo4j_graph.cjs";
2
+ import { BaseLanguageModelInterface } from "@langchain/core/language_models/base";
3
+ import { ChainValues } from "@langchain/core/utils/types";
4
+ import { BasePromptTemplate } from "@langchain/core/prompts";
5
+ import { CallbackManagerForChainRun } from "@langchain/core/callbacks/manager";
6
+ import { BaseChain, ChainInputs, LLMChain } from "@langchain/classic/chains";
7
+
8
+ //#region src/chains/graph_qa/cypher.d.ts
9
+ declare const INTERMEDIATE_STEPS_KEY = "intermediateSteps";
10
+ interface GraphCypherQAChainInput extends ChainInputs {
11
+ graph: Neo4jGraph;
12
+ cypherGenerationChain: LLMChain;
13
+ qaChain: LLMChain;
14
+ inputKey?: string;
15
+ outputKey?: string;
16
+ topK?: number;
17
+ returnIntermediateSteps?: boolean;
18
+ returnDirect?: boolean;
19
+ }
20
+ interface FromLLMInput {
21
+ graph: Neo4jGraph;
22
+ llm?: BaseLanguageModelInterface;
23
+ cypherLLM?: BaseLanguageModelInterface;
24
+ qaLLM?: BaseLanguageModelInterface;
25
+ qaPrompt?: BasePromptTemplate;
26
+ cypherPrompt?: BasePromptTemplate;
27
+ returnIntermediateSteps?: boolean;
28
+ returnDirect?: boolean;
29
+ }
30
+ /**
31
+ * Chain for question-answering against a graph by generating Cypher statements.
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const chain = new GraphCypherQAChain({
36
+ * llm: new ChatOpenAI({ model: "gpt-4o-mini", temperature: 0 }),
37
+ * graph: new Neo4jGraph(),
38
+ * });
39
+ * const res = await chain.invoke("Who played in Pulp Fiction?");
40
+ * ```
41
+ *
42
+ * @security
43
+ * This chain will execute Cypher statements against the provided database.
44
+ * Make sure that the database connection uses credentials
45
+ * that are narrowly-scoped to only include necessary permissions.
46
+ * Failure to do so may result in data corruption or loss, since the calling code
47
+ * may attempt commands that would result in deletion, mutation of data
48
+ * if appropriately prompted or reading sensitive data if such data is present in the database.
49
+ * The best way to guard against such negative outcomes is to (as appropriate) limit the
50
+ * permissions granted to the credentials used with this tool.
51
+ *
52
+ * See https://js.langchain.com/docs/security for more information.
53
+ */
54
+ declare class GraphCypherQAChain extends BaseChain {
55
+ private graph;
56
+ private cypherGenerationChain;
57
+ private qaChain;
58
+ private inputKey;
59
+ private outputKey;
60
+ private topK;
61
+ private returnDirect;
62
+ private returnIntermediateSteps;
63
+ constructor(props: GraphCypherQAChainInput);
64
+ _chainType(): "graph_cypher_chain";
65
+ get inputKeys(): string[];
66
+ get outputKeys(): string[];
67
+ static fromLLM(props: FromLLMInput): GraphCypherQAChain;
68
+ private extractCypher;
69
+ _call(values: ChainValues, runManager?: CallbackManagerForChainRun): Promise<ChainValues>;
70
+ }
71
+ //#endregion
72
+ export { FromLLMInput, GraphCypherQAChain, GraphCypherQAChainInput, INTERMEDIATE_STEPS_KEY };
73
+ //# sourceMappingURL=cypher.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cypher.d.cts","names":[],"sources":["../../../src/chains/graph_qa/cypher.ts"],"mappings":";;;;;;;;cAQa,sBAAA;AAAA,UAEI,uBAAA,SAAgC,WAAA;EAC/C,KAAA,EAAO,UAAA;EACP,qBAAA,EAAuB,QAAA;EACvB,OAAA,EAAS,QAAA;EACT,QAAA;EACA,SAAA;EACA,IAAA;EACA,uBAAA;EACA,YAAA;AAAA;AAAA,UAGe,YAAA;EACf,KAAA,EAAO,UAAA;EACP,GAAA,GAAM,0BAAA;EACN,SAAA,GAAY,0BAAA;EACZ,KAAA,GAAQ,0BAAA;EACR,QAAA,GAAW,kBAAA;EACX,YAAA,GAAe,kBAAA;EACf,uBAAA;EACA,YAAA;AAAA;;;;;;;;;;AARF;;;;;;;;;;;;;;;cAmCa,kBAAA,SAA2B,SAAA;EAAA,QAC9B,KAAA;EAAA,QAEA,qBAAA;EAAA,QAEA,OAAA;EAAA,QAEA,QAAA;EAAA,QAEA,SAAA;EAAA,QAEA,IAAA;EAAA,QAEA,YAAA;EAAA,QAEA,uBAAA;EAER,WAAA,CAAY,KAAA,EAAO,uBAAA;EAkCnB,UAAA,CAAA;EAAA,IAII,SAAA,CAAA;EAAA,IAIA,UAAA,CAAA;EAAA,OAIG,OAAA,CAAQ,KAAA,EAAO,YAAA,GAAe,kBAAA;EAAA,QA+C7B,aAAA;EAMF,KAAA,CACJ,MAAA,EAAQ,WAAA,EACR,UAAA,GAAa,0BAAA,GACZ,OAAA,CAAQ,WAAA;AAAA"}
@@ -0,0 +1,73 @@
1
+ import { Neo4jGraph } from "../../graphs/neo4j_graph.js";
2
+ import { BaseChain, ChainInputs, LLMChain } from "@langchain/classic/chains";
3
+ import { BasePromptTemplate } from "@langchain/core/prompts";
4
+ import { BaseLanguageModelInterface } from "@langchain/core/language_models/base";
5
+ import { ChainValues } from "@langchain/core/utils/types";
6
+ import { CallbackManagerForChainRun } from "@langchain/core/callbacks/manager";
7
+
8
+ //#region src/chains/graph_qa/cypher.d.ts
9
+ declare const INTERMEDIATE_STEPS_KEY = "intermediateSteps";
10
+ interface GraphCypherQAChainInput extends ChainInputs {
11
+ graph: Neo4jGraph;
12
+ cypherGenerationChain: LLMChain;
13
+ qaChain: LLMChain;
14
+ inputKey?: string;
15
+ outputKey?: string;
16
+ topK?: number;
17
+ returnIntermediateSteps?: boolean;
18
+ returnDirect?: boolean;
19
+ }
20
+ interface FromLLMInput {
21
+ graph: Neo4jGraph;
22
+ llm?: BaseLanguageModelInterface;
23
+ cypherLLM?: BaseLanguageModelInterface;
24
+ qaLLM?: BaseLanguageModelInterface;
25
+ qaPrompt?: BasePromptTemplate;
26
+ cypherPrompt?: BasePromptTemplate;
27
+ returnIntermediateSteps?: boolean;
28
+ returnDirect?: boolean;
29
+ }
30
+ /**
31
+ * Chain for question-answering against a graph by generating Cypher statements.
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const chain = new GraphCypherQAChain({
36
+ * llm: new ChatOpenAI({ model: "gpt-4o-mini", temperature: 0 }),
37
+ * graph: new Neo4jGraph(),
38
+ * });
39
+ * const res = await chain.invoke("Who played in Pulp Fiction?");
40
+ * ```
41
+ *
42
+ * @security
43
+ * This chain will execute Cypher statements against the provided database.
44
+ * Make sure that the database connection uses credentials
45
+ * that are narrowly-scoped to only include necessary permissions.
46
+ * Failure to do so may result in data corruption or loss, since the calling code
47
+ * may attempt commands that would result in deletion, mutation of data
48
+ * if appropriately prompted or reading sensitive data if such data is present in the database.
49
+ * The best way to guard against such negative outcomes is to (as appropriate) limit the
50
+ * permissions granted to the credentials used with this tool.
51
+ *
52
+ * See https://js.langchain.com/docs/security for more information.
53
+ */
54
+ declare class GraphCypherQAChain extends BaseChain {
55
+ private graph;
56
+ private cypherGenerationChain;
57
+ private qaChain;
58
+ private inputKey;
59
+ private outputKey;
60
+ private topK;
61
+ private returnDirect;
62
+ private returnIntermediateSteps;
63
+ constructor(props: GraphCypherQAChainInput);
64
+ _chainType(): "graph_cypher_chain";
65
+ get inputKeys(): string[];
66
+ get outputKeys(): string[];
67
+ static fromLLM(props: FromLLMInput): GraphCypherQAChain;
68
+ private extractCypher;
69
+ _call(values: ChainValues, runManager?: CallbackManagerForChainRun): Promise<ChainValues>;
70
+ }
71
+ //#endregion
72
+ export { FromLLMInput, GraphCypherQAChain, GraphCypherQAChainInput, INTERMEDIATE_STEPS_KEY };
73
+ //# sourceMappingURL=cypher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cypher.d.ts","names":[],"sources":["../../../src/chains/graph_qa/cypher.ts"],"mappings":";;;;;;;;cAQa,sBAAA;AAAA,UAEI,uBAAA,SAAgC,WAAA;EAC/C,KAAA,EAAO,UAAA;EACP,qBAAA,EAAuB,QAAA;EACvB,OAAA,EAAS,QAAA;EACT,QAAA;EACA,SAAA;EACA,IAAA;EACA,uBAAA;EACA,YAAA;AAAA;AAAA,UAGe,YAAA;EACf,KAAA,EAAO,UAAA;EACP,GAAA,GAAM,0BAAA;EACN,SAAA,GAAY,0BAAA;EACZ,KAAA,GAAQ,0BAAA;EACR,QAAA,GAAW,kBAAA;EACX,YAAA,GAAe,kBAAA;EACf,uBAAA;EACA,YAAA;AAAA;;;;;;;;;;AARF;;;;;;;;;;;;;;;cAmCa,kBAAA,SAA2B,SAAA;EAAA,QAC9B,KAAA;EAAA,QAEA,qBAAA;EAAA,QAEA,OAAA;EAAA,QAEA,QAAA;EAAA,QAEA,SAAA;EAAA,QAEA,IAAA;EAAA,QAEA,YAAA;EAAA,QAEA,uBAAA;EAER,WAAA,CAAY,KAAA,EAAO,uBAAA;EAkCnB,UAAA,CAAA;EAAA,IAII,SAAA,CAAA;EAAA,IAIA,UAAA,CAAA;EAAA,OAIG,OAAA,CAAQ,KAAA,EAAO,YAAA,GAAe,kBAAA;EAAA,QA+C7B,aAAA;EAMF,KAAA,CACJ,MAAA,EAAQ,WAAA,EACR,UAAA,GAAa,0BAAA,GACZ,OAAA,CAAQ,WAAA;AAAA"}