@grackle-ai/knowledge-core 0.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/chunker.d.ts +20 -0
  2. package/dist/chunker.d.ts.map +1 -0
  3. package/dist/chunker.js +7 -0
  4. package/dist/chunker.js.map +1 -0
  5. package/dist/client.d.ts +68 -0
  6. package/dist/client.d.ts.map +1 -0
  7. package/dist/client.js +150 -0
  8. package/dist/client.js.map +1 -0
  9. package/dist/constants.d.ts +33 -0
  10. package/dist/constants.d.ts.map +1 -0
  11. package/dist/constants.js +33 -0
  12. package/dist/constants.js.map +1 -0
  13. package/dist/edge-store.d.ts +32 -0
  14. package/dist/edge-store.d.ts.map +1 -0
  15. package/dist/edge-store.js +145 -0
  16. package/dist/edge-store.js.map +1 -0
  17. package/dist/embedder.d.ts +35 -0
  18. package/dist/embedder.d.ts.map +1 -0
  19. package/dist/embedder.js +7 -0
  20. package/dist/embedder.js.map +1 -0
  21. package/dist/expand.d.ts +42 -0
  22. package/dist/expand.d.ts.map +1 -0
  23. package/dist/expand.js +150 -0
  24. package/dist/expand.js.map +1 -0
  25. package/dist/index.d.ts +31 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +23 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/ingest.d.ts +23 -0
  30. package/dist/ingest.d.ts.map +1 -0
  31. package/dist/ingest.js +27 -0
  32. package/dist/ingest.js.map +1 -0
  33. package/dist/local-embedder.d.ts +25 -0
  34. package/dist/local-embedder.d.ts.map +1 -0
  35. package/dist/local-embedder.js +88 -0
  36. package/dist/local-embedder.js.map +1 -0
  37. package/dist/logger.d.ts +9 -0
  38. package/dist/logger.d.ts.map +1 -0
  39. package/dist/logger.js +15 -0
  40. package/dist/logger.js.map +1 -0
  41. package/dist/node-store.d.ts +116 -0
  42. package/dist/node-store.d.ts.map +1 -0
  43. package/dist/node-store.js +268 -0
  44. package/dist/node-store.js.map +1 -0
  45. package/dist/pass-through-chunker.d.ts +16 -0
  46. package/dist/pass-through-chunker.d.ts.map +1 -0
  47. package/dist/pass-through-chunker.js +21 -0
  48. package/dist/pass-through-chunker.js.map +1 -0
  49. package/dist/schema.d.ts +23 -0
  50. package/dist/schema.d.ts.map +1 -0
  51. package/dist/schema.js +73 -0
  52. package/dist/schema.js.map +1 -0
  53. package/dist/search.d.ts +43 -0
  54. package/dist/search.d.ts.map +1 -0
  55. package/dist/search.js +123 -0
  56. package/dist/search.js.map +1 -0
  57. package/dist/transcript-chunker.d.ts +29 -0
  58. package/dist/transcript-chunker.d.ts.map +1 -0
  59. package/dist/transcript-chunker.js +142 -0
  60. package/dist/transcript-chunker.js.map +1 -0
  61. package/dist/types.d.ts +122 -0
  62. package/dist/types.d.ts.map +1 -0
  63. package/dist/types.js +71 -0
  64. package/dist/types.js.map +1 -0
  65. package/package.json +45 -0
@@ -0,0 +1,268 @@
1
+ /**
2
+ * Node CRUD operations for the knowledge graph.
3
+ *
4
+ * Provides create, read, update, and delete operations for both
5
+ * {@link ReferenceNode} and {@link NativeNode} types, backed by Neo4j.
6
+ *
7
+ * @module
8
+ */
9
+ import { randomUUID } from "node:crypto";
10
+ import { getSession } from "./client.js";
11
+ import { logger } from "./logger.js";
12
+ import { NODE_LABEL } from "./constants.js";
13
+ import { NODE_KIND, } from "./types.js";
14
+ // ---------------------------------------------------------------------------
15
+ // Cypher queries
16
+ // ---------------------------------------------------------------------------
17
+ const GET_NODE_WITH_EDGES_CYPHER = `
18
+ MATCH (n:${NODE_LABEL} {id: $id})
19
+ OPTIONAL MATCH (n)-[r]-(m:${NODE_LABEL})
20
+ WITH n, r, m
21
+ WHERE r IS NOT NULL
22
+ RETURN n,
23
+ collect({
24
+ fromId: CASE WHEN startNode(r) = n THEN n.id ELSE m.id END,
25
+ toId: CASE WHEN endNode(r) = n THEN n.id ELSE m.id END,
26
+ type: type(r),
27
+ metadata: r.metadata,
28
+ createdAt: r.createdAt
29
+ }) AS edges
30
+ UNION ALL
31
+ MATCH (n:${NODE_LABEL} {id: $id})
32
+ WHERE NOT (n)-[]-()
33
+ RETURN n, [] AS edges`;
34
+ const DELETE_NODE_CYPHER = `
35
+ MATCH (n:${NODE_LABEL} {id: $id})
36
+ DETACH DELETE n
37
+ RETURN count(n) AS deleted`;
38
+ const UPDATE_NODE_CYPHER = `
39
+ MATCH (n:${NODE_LABEL} {id: $id})
40
+ SET n += $updates
41
+ RETURN n`;
42
+ // ---------------------------------------------------------------------------
43
+ // Helpers
44
+ // ---------------------------------------------------------------------------
45
+ /**
46
+ * Convert Neo4j node properties to a typed {@link KnowledgeNode}.
47
+ *
48
+ * Handles the discriminated union based on the `kind` property.
49
+ */
50
+ export function recordToNode(properties) {
51
+ const base = {
52
+ id: properties.id,
53
+ kind: properties.kind,
54
+ embedding: properties.embedding ?? [],
55
+ createdAt: properties.createdAt,
56
+ updatedAt: properties.updatedAt,
57
+ workspaceId: properties.workspaceId ?? "",
58
+ };
59
+ if (base.kind === NODE_KIND.REFERENCE) {
60
+ return {
61
+ ...base,
62
+ kind: NODE_KIND.REFERENCE,
63
+ sourceType: properties.sourceType,
64
+ sourceId: properties.sourceId,
65
+ label: properties.label ?? "",
66
+ };
67
+ }
68
+ return {
69
+ ...base,
70
+ kind: NODE_KIND.NATIVE,
71
+ category: properties.category,
72
+ title: properties.title ?? "",
73
+ content: properties.content ?? "",
74
+ tags: properties.tags ?? [],
75
+ };
76
+ }
77
+ /**
78
+ * Convert a raw edge object from Cypher `collect()` to a {@link KnowledgeEdge}.
79
+ *
80
+ * @internal Exported for use by search and expand modules within this package.
81
+ */
82
+ export function recordToEdge(raw) {
83
+ let metadata;
84
+ if (raw.metadata !== undefined && raw.metadata !== null) {
85
+ try {
86
+ metadata = JSON.parse(raw.metadata);
87
+ }
88
+ catch {
89
+ metadata = undefined;
90
+ }
91
+ }
92
+ return {
93
+ fromId: raw.fromId,
94
+ toId: raw.toId,
95
+ type: raw.type,
96
+ metadata,
97
+ createdAt: raw.createdAt,
98
+ };
99
+ }
100
+ // ---------------------------------------------------------------------------
101
+ // Public API
102
+ // ---------------------------------------------------------------------------
103
+ /**
104
+ * Create a reference node in the knowledge graph.
105
+ *
106
+ * Generates a UUID and timestamps automatically.
107
+ *
108
+ * @returns The ID of the created node.
109
+ */
110
+ export async function createReferenceNode(input) {
111
+ const id = randomUUID();
112
+ const now = new Date().toISOString();
113
+ const props = {
114
+ id,
115
+ kind: NODE_KIND.REFERENCE,
116
+ sourceType: input.sourceType,
117
+ sourceId: input.sourceId,
118
+ label: input.label,
119
+ embedding: input.embedding,
120
+ workspaceId: input.workspaceId,
121
+ createdAt: now,
122
+ updatedAt: now,
123
+ };
124
+ const session = getSession();
125
+ try {
126
+ await session.run(`CREATE (n:${NODE_LABEL} $props) RETURN n`, { props });
127
+ logger.debug({ nodeId: id, kind: NODE_KIND.REFERENCE }, "Created reference node");
128
+ return id;
129
+ }
130
+ finally {
131
+ try {
132
+ await session.close();
133
+ }
134
+ catch (closeError) {
135
+ logger.warn({ err: closeError }, "Failed to close session after createReferenceNode");
136
+ }
137
+ }
138
+ }
139
+ /**
140
+ * Create a native node in the knowledge graph.
141
+ *
142
+ * Generates a UUID and timestamps automatically.
143
+ *
144
+ * @returns The ID of the created node.
145
+ */
146
+ export async function createNativeNode(input) {
147
+ const id = randomUUID();
148
+ const now = new Date().toISOString();
149
+ const props = {
150
+ id,
151
+ kind: NODE_KIND.NATIVE,
152
+ category: input.category,
153
+ title: input.title,
154
+ content: input.content,
155
+ tags: input.tags,
156
+ embedding: input.embedding,
157
+ workspaceId: input.workspaceId,
158
+ createdAt: now,
159
+ updatedAt: now,
160
+ };
161
+ const session = getSession();
162
+ try {
163
+ await session.run(`CREATE (n:${NODE_LABEL} $props) RETURN n`, { props });
164
+ logger.debug({ nodeId: id, kind: NODE_KIND.NATIVE }, "Created native node");
165
+ return id;
166
+ }
167
+ finally {
168
+ try {
169
+ await session.close();
170
+ }
171
+ catch (closeError) {
172
+ logger.warn({ err: closeError }, "Failed to close session after createNativeNode");
173
+ }
174
+ }
175
+ }
176
+ /**
177
+ * Get a node by ID, including all its edges.
178
+ *
179
+ * @returns The node and its edges, or `undefined` if the node was not found.
180
+ */
181
+ export async function getNode(id) {
182
+ const session = getSession();
183
+ try {
184
+ const result = await session.run(GET_NODE_WITH_EDGES_CYPHER, { id });
185
+ if (result.records.length === 0) {
186
+ return undefined;
187
+ }
188
+ const record = result.records[0];
189
+ const neo4jNode = record.get("n");
190
+ const rawEdges = record.get("edges");
191
+ const node = recordToNode(neo4jNode.properties);
192
+ const edges = rawEdges.map(recordToEdge);
193
+ return { node, edges };
194
+ }
195
+ finally {
196
+ try {
197
+ await session.close();
198
+ }
199
+ catch (closeError) {
200
+ logger.warn({ err: closeError }, "Failed to close session after getNode");
201
+ }
202
+ }
203
+ }
204
+ /**
205
+ * Delete a node and all its edges (`DETACH DELETE`).
206
+ *
207
+ * @returns `true` if a node was deleted, `false` if the node was not found.
208
+ */
209
+ export async function deleteNode(id) {
210
+ const session = getSession();
211
+ try {
212
+ const result = await session.run(DELETE_NODE_CYPHER, { id });
213
+ const deleted = result.records[0]?.get("deleted");
214
+ if (deleted > 0) {
215
+ logger.debug({ nodeId: id }, "Deleted node");
216
+ }
217
+ return deleted > 0;
218
+ }
219
+ finally {
220
+ try {
221
+ await session.close();
222
+ }
223
+ catch (closeError) {
224
+ logger.warn({ err: closeError }, "Failed to close session after deleteNode");
225
+ }
226
+ }
227
+ }
228
+ /**
229
+ * Update a node's mutable properties.
230
+ *
231
+ * Cannot change `kind`, `id`, `createdAt`, or `workspaceId`.
232
+ * Automatically updates the `updatedAt` timestamp.
233
+ *
234
+ * @returns The updated node, or `undefined` if the node was not found.
235
+ */
236
+ export async function updateNode(id, updates) {
237
+ // Strip immutable fields defensively.
238
+ const { ...mutableUpdates } = updates;
239
+ const forbidden = ["kind", "id", "createdAt", "workspaceId"];
240
+ for (const key of forbidden) {
241
+ delete mutableUpdates[key];
242
+ }
243
+ const patchedUpdates = {
244
+ ...mutableUpdates,
245
+ updatedAt: new Date().toISOString(),
246
+ };
247
+ const session = getSession();
248
+ try {
249
+ const result = await session.run(UPDATE_NODE_CYPHER, {
250
+ id,
251
+ updates: patchedUpdates,
252
+ });
253
+ if (result.records.length === 0) {
254
+ return undefined;
255
+ }
256
+ const neo4jNode = result.records[0].get("n");
257
+ return recordToNode(neo4jNode.properties);
258
+ }
259
+ finally {
260
+ try {
261
+ await session.close();
262
+ }
263
+ catch (closeError) {
264
+ logger.warn({ err: closeError }, "Failed to close session after updateNode");
265
+ }
266
+ }
267
+ }
268
+ //# sourceMappingURL=node-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-store.js","sourceRoot":"","sources":["../src/node-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Pass-through chunker that returns the entire input as a single chunk.
3
+ *
4
+ * Suitable for short content such as findings, decisions, and insights
5
+ * that do not need to be split before embedding.
6
+ *
7
+ * @module
8
+ */
9
+ import type { Chunker } from "./chunker.js";
10
+ /**
11
+ * Create a chunker that returns the input as a single chunk unchanged.
12
+ *
13
+ * @returns A {@link Chunker} that produces exactly one chunk per input.
14
+ */
15
+ export declare function createPassThroughChunker(): Chunker;
16
+ //# sourceMappingURL=pass-through-chunker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pass-through-chunker.d.ts","sourceRoot":"","sources":["../src/pass-through-chunker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAS,MAAM,cAAc,CAAC;AAEnD;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAMlD"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Pass-through chunker that returns the entire input as a single chunk.
3
+ *
4
+ * Suitable for short content such as findings, decisions, and insights
5
+ * that do not need to be split before embedding.
6
+ *
7
+ * @module
8
+ */
9
+ /**
10
+ * Create a chunker that returns the input as a single chunk unchanged.
11
+ *
12
+ * @returns A {@link Chunker} that produces exactly one chunk per input.
13
+ */
14
+ export function createPassThroughChunker() {
15
+ return {
16
+ chunk(content, metadata) {
17
+ return [{ text: content, index: 0, metadata }];
18
+ },
19
+ };
20
+ }
21
+ //# sourceMappingURL=pass-through-chunker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pass-through-chunker.js","sourceRoot":"","sources":["../src/pass-through-chunker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;;GAIG;AACH,MAAM,UAAU,wBAAwB;IACtC,OAAO;QACL,KAAK,CAAC,OAAe,EAAE,QAAkC;YACvD,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QACjD,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Neo4j schema initialization — constraints, indexes, and vector index.
3
+ *
4
+ * All statements use `IF NOT EXISTS` for idempotency and are safe to run
5
+ * on every application startup.
6
+ *
7
+ * @module
8
+ */
9
+ /**
10
+ * Cypher statements for schema initialization.
11
+ *
12
+ * Exported so tests can verify the exact statements that will be executed.
13
+ */
14
+ export declare const SCHEMA_STATEMENTS: Record<string, string>;
15
+ /**
16
+ * Initialize the Neo4j schema: constraints, property indexes, and the
17
+ * vector index.
18
+ *
19
+ * All statements are idempotent (`IF NOT EXISTS`). Call once at startup
20
+ * after {@link openNeo4j}.
21
+ */
22
+ export declare function initSchema(): Promise<void>;
23
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA4BpD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAuBhD"}
package/dist/schema.js ADDED
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Neo4j schema initialization — constraints, indexes, and vector index.
3
+ *
4
+ * All statements use `IF NOT EXISTS` for idempotency and are safe to run
5
+ * on every application startup.
6
+ *
7
+ * @module
8
+ */
9
+ import { getSession } from "./client.js";
10
+ import { logger } from "./logger.js";
11
+ import { NODE_LABEL, VECTOR_INDEX_NAME, EMBEDDING_DIMENSIONS, VECTOR_SIMILARITY_FUNCTION, } from "./constants.js";
12
+ /**
13
+ * Cypher statements for schema initialization.
14
+ *
15
+ * Exported so tests can verify the exact statements that will be executed.
16
+ */
17
+ export const SCHEMA_STATEMENTS = {
18
+ /** Uniqueness constraint on node ID. */
19
+ UNIQUE_NODE_ID: `CREATE CONSTRAINT knowledge_node_id_unique IF NOT EXISTS
20
+ FOR (n:${NODE_LABEL}) REQUIRE n.id IS UNIQUE`,
21
+ /** Index on the kind property for efficient filtering. */
22
+ INDEX_KIND: `CREATE INDEX knowledge_node_kind IF NOT EXISTS
23
+ FOR (n:${NODE_LABEL}) ON (n.kind)`,
24
+ /** Index on workspaceId for scoped queries. */
25
+ INDEX_WORKSPACE: `CREATE INDEX knowledge_node_workspace IF NOT EXISTS
26
+ FOR (n:${NODE_LABEL}) ON (n.workspaceId)`,
27
+ /** Composite index for reference node lookups by source. */
28
+ INDEX_SOURCE: `CREATE INDEX knowledge_node_source IF NOT EXISTS
29
+ FOR (n:${NODE_LABEL}) ON (n.sourceType, n.sourceId)`,
30
+ /** Vector index for embedding similarity search. */
31
+ VECTOR_INDEX: [
32
+ `CREATE VECTOR INDEX ${VECTOR_INDEX_NAME} IF NOT EXISTS`,
33
+ `FOR (n:${NODE_LABEL}) ON (n.embedding)`,
34
+ `OPTIONS {`,
35
+ ` indexConfig: {`,
36
+ ` \`vector.dimensions\`: ${EMBEDDING_DIMENSIONS},`,
37
+ ` \`vector.similarity_function\`: '${VECTOR_SIMILARITY_FUNCTION}'`,
38
+ ` }`,
39
+ `}`,
40
+ ].join("\n"),
41
+ };
42
+ /**
43
+ * Initialize the Neo4j schema: constraints, property indexes, and the
44
+ * vector index.
45
+ *
46
+ * All statements are idempotent (`IF NOT EXISTS`). Call once at startup
47
+ * after {@link openNeo4j}.
48
+ */
49
+ export async function initSchema() {
50
+ const session = getSession();
51
+ try {
52
+ for (const [name, cypher] of Object.entries(SCHEMA_STATEMENTS)) {
53
+ logger.debug({ statement: name }, "Running schema statement");
54
+ try {
55
+ await session.run(cypher);
56
+ }
57
+ catch (error) {
58
+ logger.error({ err: error, statement: name }, "Schema statement failed");
59
+ throw new Error(`Schema statement "${name}" failed: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
60
+ }
61
+ }
62
+ logger.info("Knowledge graph schema initialized");
63
+ }
64
+ finally {
65
+ try {
66
+ await session.close();
67
+ }
68
+ catch (closeError) {
69
+ logger.warn({ err: closeError }, "Failed to close Neo4j session after schema initialization");
70
+ }
71
+ }
72
+ }
73
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,gBAAgB,CAAC;AAExB;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA2B;IACvD,wCAAwC;IACxC,cAAc,EAAE;aACL,UAAU,0BAA0B;IAE/C,0DAA0D;IAC1D,UAAU,EAAE;aACD,UAAU,eAAe;IAEpC,+CAA+C;IAC/C,eAAe,EAAE;aACN,UAAU,sBAAsB;IAE3C,4DAA4D;IAC5D,YAAY,EAAE;aACH,UAAU,iCAAiC;IAEtD,oDAAoD;IACpD,YAAY,EAAE;QACZ,uBAAuB,iBAAiB,gBAAgB;QACxD,UAAU,UAAU,oBAAoB;QACxC,WAAW;QACX,kBAAkB;QAClB,8BAA8B,oBAAoB,GAAG;QACrD,wCAAwC,0BAA0B,GAAG;QACrE,KAAK;QACL,GAAG;KACJ,CAAC,IAAI,CAAC,IAAI,CAAC;CACb,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,IAAI,CAAC;QACH,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC/D,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,0BAA0B,CAAC,CAAC;YAC9D,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,yBAAyB,CAAC,CAAC;gBACzE,MAAM,IAAI,KAAK,CACb,qBAAqB,IAAI,aAAa,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAC9F,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;YACJ,CAAC;QACH,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IACpD,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;QAAC,OAAO,UAAU,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,2DAA2D,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Vector-based semantic search across the knowledge graph.
3
+ *
4
+ * Embeds a text query, runs k-NN vector search against Neo4j's vector index,
5
+ * and returns ranked results with similarity scores and immediate edges.
6
+ *
7
+ * @module
8
+ */
9
+ import type { Embedder } from "./embedder.js";
10
+ import type { KnowledgeNode, KnowledgeEdge, NodeKind } from "./types.js";
11
+ /** Options for knowledge graph search. */
12
+ export interface SearchOptions {
13
+ /** Max results to return (default 10). */
14
+ limit?: number;
15
+ /** Filter to specific node kinds (reference, native, or both). */
16
+ nodeKinds?: NodeKind[];
17
+ /** Minimum similarity score threshold (default 0). Passed directly to the Cypher WHERE clause. */
18
+ minScore?: number;
19
+ /** Filter to a specific workspace. */
20
+ workspaceId?: string;
21
+ }
22
+ /** A search result: a node with its similarity score and immediate edges. */
23
+ export interface SearchResult {
24
+ /** The matched node. */
25
+ node: KnowledgeNode;
26
+ /** Cosine similarity score (0-1). */
27
+ score: number;
28
+ /** Edges connected to this node. */
29
+ edges: KnowledgeEdge[];
30
+ }
31
+ /**
32
+ * Search the knowledge graph by semantic similarity.
33
+ *
34
+ * Embeds the query text, runs k-NN vector search in Neo4j, and returns
35
+ * ranked results with similarity scores and immediate edges.
36
+ *
37
+ * @param query - The text to search for.
38
+ * @param embedder - Produces the query embedding vector.
39
+ * @param options - Optional search filters and limits.
40
+ * @returns Ranked search results, highest similarity first.
41
+ */
42
+ export declare function knowledgeSearch(query: string, embedder: Embedder, options?: SearchOptions): Promise<SearchResult[]>;
43
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAMzE,0CAA0C;AAC1C,MAAM,WAAW,aAAa;IAC5B,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,kGAAkG;IAClG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,IAAI,EAAE,aAAa,CAAC;IACpB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAgED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,YAAY,EAAE,CAAC,CA8DzB"}
package/dist/search.js ADDED
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Vector-based semantic search across the knowledge graph.
3
+ *
4
+ * Embeds a text query, runs k-NN vector search against Neo4j's vector index,
5
+ * and returns ranked results with similarity scores and immediate edges.
6
+ *
7
+ * @module
8
+ */
9
+ import { getSession } from "./client.js";
10
+ import { logger } from "./logger.js";
11
+ import { NODE_LABEL, VECTOR_INDEX_NAME } from "./constants.js";
12
+ import { recordToNode, recordToEdge } from "./node-store.js";
13
+ // ---------------------------------------------------------------------------
14
+ // Constants
15
+ // ---------------------------------------------------------------------------
16
+ /** Default number of results to return. */
17
+ const DEFAULT_LIMIT = 10;
18
+ /** Default minimum similarity score. */
19
+ const DEFAULT_MIN_SCORE = 0;
20
+ // ---------------------------------------------------------------------------
21
+ // Cypher
22
+ // ---------------------------------------------------------------------------
23
+ /**
24
+ * Build the Cypher query for vector search with optional filters.
25
+ *
26
+ * Neo4j's `db.index.vector.queryNodes` does not support WHERE clauses
27
+ * directly, so we apply post-filters on the yielded results.
28
+ */
29
+ function buildSearchCypher(options) {
30
+ const filters = ["score >= $minScore"];
31
+ if (options.nodeKinds && options.nodeKinds.length > 0) {
32
+ filters.push("node.kind IN $nodeKinds");
33
+ }
34
+ if (options.workspaceId !== undefined) {
35
+ filters.push("node.workspaceId = $workspaceId");
36
+ }
37
+ const whereClause = filters.length > 0
38
+ ? `WHERE ${filters.join(" AND ")}`
39
+ : "";
40
+ // Neo4j requires integer literals for LIMIT and the vector query count.
41
+ return `
42
+ CALL db.index.vector.queryNodes($indexName, ${options.candidateLimit}, $queryVector)
43
+ YIELD node, score
44
+ ${whereClause}
45
+ WITH node, score
46
+ ORDER BY score DESC
47
+ LIMIT ${options.limit}
48
+ OPTIONAL MATCH (node)-[r]-(m:${NODE_LABEL})
49
+ RETURN node, score,
50
+ collect(DISTINCT {
51
+ fromId: CASE WHEN startNode(r) = node THEN node.id ELSE m.id END,
52
+ toId: CASE WHEN endNode(r) = node THEN node.id ELSE m.id END,
53
+ type: type(r),
54
+ metadata: r.metadata,
55
+ createdAt: r.createdAt
56
+ }) AS edges`;
57
+ }
58
+ // ---------------------------------------------------------------------------
59
+ // Public API
60
+ // ---------------------------------------------------------------------------
61
+ /**
62
+ * Search the knowledge graph by semantic similarity.
63
+ *
64
+ * Embeds the query text, runs k-NN vector search in Neo4j, and returns
65
+ * ranked results with similarity scores and immediate edges.
66
+ *
67
+ * @param query - The text to search for.
68
+ * @param embedder - Produces the query embedding vector.
69
+ * @param options - Optional search filters and limits.
70
+ * @returns Ranked search results, highest similarity first.
71
+ */
72
+ export async function knowledgeSearch(query, embedder, options) {
73
+ const limit = options?.limit ?? DEFAULT_LIMIT;
74
+ const minScore = options?.minScore ?? DEFAULT_MIN_SCORE;
75
+ // Embed the query
76
+ const { vector: queryVector } = await embedder.embed(query);
77
+ // Over-fetch when filtering so we still get enough results after post-filter
78
+ const hasFilters = !!(options?.nodeKinds?.length || options?.workspaceId !== undefined);
79
+ const candidateLimit = hasFilters ? limit * 3 : limit;
80
+ const cypher = buildSearchCypher({
81
+ limit,
82
+ candidateLimit,
83
+ nodeKinds: options?.nodeKinds,
84
+ workspaceId: options?.workspaceId,
85
+ });
86
+ const params = {
87
+ indexName: VECTOR_INDEX_NAME,
88
+ queryVector,
89
+ minScore,
90
+ ...(options?.nodeKinds ? { nodeKinds: options.nodeKinds } : {}),
91
+ ...(options?.workspaceId !== undefined ? { workspaceId: options.workspaceId } : {}),
92
+ };
93
+ const session = getSession();
94
+ try {
95
+ const result = await session.run(cypher, params);
96
+ const searchResults = result.records.map((record) => {
97
+ const neo4jNode = record.get("node");
98
+ const nodeProps = neo4jNode.properties;
99
+ const score = record.get("score");
100
+ const rawEdges = record.get("edges");
101
+ // Filter out null edges (from OPTIONAL MATCH with no relationships)
102
+ const edges = rawEdges
103
+ .filter((e) => e.fromId !== null && e.toId !== null)
104
+ .map(recordToEdge);
105
+ return {
106
+ node: recordToNode(nodeProps),
107
+ score,
108
+ edges,
109
+ };
110
+ });
111
+ logger.debug({ query: query.substring(0, 50), results: searchResults.length, limit }, "Knowledge search completed");
112
+ return searchResults;
113
+ }
114
+ finally {
115
+ try {
116
+ await session.close();
117
+ }
118
+ catch (closeError) {
119
+ logger.warn({ err: closeError }, "Failed to close session after knowledgeSearch");
120
+ }
121
+ }
122
+ }
123
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Session transcript chunker that splits JSONL session logs by conversation turn.
3
+ *
4
+ * Accepts the raw JSONL content of a session's `stream.jsonl` file and groups
5
+ * events into semantic turns (user input → agent response) for embedding.
6
+ *
7
+ * @module
8
+ */
9
+ import type { Chunker } from "./chunker.js";
10
+ /** Options for the session transcript chunker. */
11
+ export interface TranscriptChunkerOptions {
12
+ /** Max characters per chunk before splitting (default 4000). */
13
+ maxChunkSize?: number;
14
+ /** Event types to skip (default: status, signal, usage, system). */
15
+ skipEventTypes?: string[];
16
+ }
17
+ /**
18
+ * Create a chunker that splits JSONL session transcripts by conversation turn.
19
+ *
20
+ * A "turn" starts at a `user_input` event and includes all subsequent events
21
+ * until the next `user_input`. Events before the first `user_input` are grouped
22
+ * into an initial turn (turn 0). Turns exceeding {@link TranscriptChunkerOptions.maxChunkSize}
23
+ * are split into sub-chunks.
24
+ *
25
+ * @param options - Optional chunker configuration.
26
+ * @returns A {@link Chunker} for session transcript JSONL content.
27
+ */
28
+ export declare function createTranscriptChunker(options?: TranscriptChunkerOptions): Chunker;
29
+ //# sourceMappingURL=transcript-chunker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-chunker.d.ts","sourceRoot":"","sources":["../src/transcript-chunker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAS,OAAO,EAAE,MAAM,cAAc,CAAC;AAgBnD,kDAAkD;AAClD,MAAM,WAAW,wBAAwB;IACvC,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAmBD;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAkDnF"}