@powerhousedao/knowledge-note 1.0.2 → 1.0.4

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 (62) hide show
  1. package/README.md +359 -122
  2. package/dist/editors/knowledge-vault/components/DriveExplorer.d.ts.map +1 -1
  3. package/dist/editors/knowledge-vault/components/DriveExplorer.js +8 -2
  4. package/dist/editors/knowledge-vault/components/GraphView.d.ts.map +1 -1
  5. package/dist/editors/knowledge-vault/components/GraphView.js +210 -32
  6. package/dist/editors/knowledge-vault/components/NoteList.d.ts.map +1 -1
  7. package/dist/editors/knowledge-vault/components/NoteList.js +13 -16
  8. package/dist/editors/knowledge-vault/components/SearchView.d.ts +2 -0
  9. package/dist/editors/knowledge-vault/components/SearchView.d.ts.map +1 -0
  10. package/dist/editors/knowledge-vault/components/SearchView.js +96 -0
  11. package/dist/editors/knowledge-vault/hooks/use-drive-init.d.ts.map +1 -1
  12. package/dist/editors/knowledge-vault/hooks/use-drive-init.js +0 -2
  13. package/dist/editors/knowledge-vault/hooks/use-graph-search.d.ts +25 -0
  14. package/dist/editors/knowledge-vault/hooks/use-graph-search.d.ts.map +1 -0
  15. package/dist/editors/knowledge-vault/hooks/use-graph-search.js +198 -0
  16. package/dist/package.json +3 -2
  17. package/dist/processors/factory.d.ts.map +1 -1
  18. package/dist/processors/factory.js +0 -3
  19. package/dist/processors/graph-indexer/embedder.d.ts +5 -0
  20. package/dist/processors/graph-indexer/embedder.d.ts.map +1 -0
  21. package/dist/processors/graph-indexer/embedder.js +27 -0
  22. package/dist/processors/graph-indexer/embedding-store.d.ts +11 -0
  23. package/dist/processors/graph-indexer/embedding-store.d.ts.map +1 -0
  24. package/dist/processors/graph-indexer/embedding-store.js +70 -0
  25. package/dist/processors/graph-indexer/index.d.ts.map +1 -1
  26. package/dist/processors/graph-indexer/index.js +53 -8
  27. package/dist/processors/graph-indexer/migrations.d.ts.map +1 -1
  28. package/dist/processors/graph-indexer/migrations.js +35 -0
  29. package/dist/processors/graph-indexer/query.d.ts +21 -0
  30. package/dist/processors/graph-indexer/query.d.ts.map +1 -1
  31. package/dist/processors/graph-indexer/query.js +154 -13
  32. package/dist/processors/graph-indexer/schema.d.ts +11 -0
  33. package/dist/processors/graph-indexer/schema.d.ts.map +1 -1
  34. package/dist/style.css +130 -0
  35. package/dist/subgraphs/index.d.ts +0 -1
  36. package/dist/subgraphs/index.d.ts.map +1 -1
  37. package/dist/subgraphs/index.js +0 -1
  38. package/dist/subgraphs/knowledge-graph/subgraph.d.ts +348 -24
  39. package/dist/subgraphs/knowledge-graph/subgraph.d.ts.map +1 -1
  40. package/dist/subgraphs/knowledge-graph/subgraph.js +334 -20
  41. package/package.json +4 -3
  42. package/dist/processors/methodology-indexer/factory.d.ts +0 -4
  43. package/dist/processors/methodology-indexer/factory.d.ts.map +0 -1
  44. package/dist/processors/methodology-indexer/factory.js +0 -23
  45. package/dist/processors/methodology-indexer/index.d.ts +0 -11
  46. package/dist/processors/methodology-indexer/index.d.ts.map +0 -1
  47. package/dist/processors/methodology-indexer/index.js +0 -116
  48. package/dist/processors/methodology-indexer/migrations.d.ts +0 -4
  49. package/dist/processors/methodology-indexer/migrations.d.ts.map +0 -1
  50. package/dist/processors/methodology-indexer/migrations.js +0 -39
  51. package/dist/processors/methodology-indexer/query.d.ts +0 -35
  52. package/dist/processors/methodology-indexer/query.d.ts.map +0 -1
  53. package/dist/processors/methodology-indexer/query.js +0 -114
  54. package/dist/processors/methodology-indexer/schema.d.ts +0 -22
  55. package/dist/processors/methodology-indexer/schema.d.ts.map +0 -1
  56. package/dist/processors/methodology-indexer/schema.js +0 -1
  57. package/dist/subgraphs/methodology/index.d.ts +0 -2
  58. package/dist/subgraphs/methodology/index.d.ts.map +0 -1
  59. package/dist/subgraphs/methodology/index.js +0 -1
  60. package/dist/subgraphs/methodology/subgraph.d.ts +0 -47
  61. package/dist/subgraphs/methodology/subgraph.d.ts.map +0 -1
  62. package/dist/subgraphs/methodology/subgraph.js +0 -100
@@ -1,7 +1,9 @@
1
1
  import { gql } from "graphql-tag";
2
- import { BaseSubgraph, } from "@powerhousedao/reactor-api";
2
+ import { BaseSubgraph } from "@powerhousedao/reactor-api";
3
3
  import { GraphIndexerProcessor } from "../../processors/graph-indexer/index.js";
4
4
  import { createGraphQuery } from "../../processors/graph-indexer/query.js";
5
+ import { generateEmbedding } from "../../processors/graph-indexer/embedder.js";
6
+ import { searchSimilar, getEmbedding, upsertEmbedding, } from "../../processors/graph-indexer/embedding-store.js";
5
7
  export class KnowledgeGraphSubgraph extends BaseSubgraph {
6
8
  name = "knowledgeGraph";
7
9
  typeDefs = gql `
@@ -12,6 +14,11 @@ export class KnowledgeGraphSubgraph extends BaseSubgraph {
12
14
  description: String
13
15
  noteType: String
14
16
  status: String
17
+ content: String
18
+ author: String
19
+ sourceOrigin: String
20
+ createdAt: String
21
+ topics: [String!]!
15
22
  updatedAt: String!
16
23
  }
17
24
 
@@ -36,6 +43,17 @@ export class KnowledgeGraphSubgraph extends BaseSubgraph {
36
43
  viaLinkType: String
37
44
  }
38
45
 
46
+ type TopicInfo {
47
+ name: String!
48
+ noteCount: Int!
49
+ }
50
+
51
+ type RelatedNode {
52
+ node: KnowledgeGraphNode!
53
+ sharedTopics: [String!]!
54
+ sharedTopicCount: Int!
55
+ }
56
+
39
57
  extend type Query {
40
58
  knowledgeGraphNodes(driveId: ID!): [KnowledgeGraphNode!]!
41
59
  knowledgeGraphEdges(driveId: ID!): [KnowledgeGraphEdge!]!
@@ -72,6 +90,46 @@ export class KnowledgeGraphSubgraph extends BaseSubgraph {
72
90
  documentId: String!
73
91
  ): [KnowledgeGraphEdge!]!
74
92
 
93
+ knowledgeGraphTopics(driveId: ID!): [TopicInfo!]!
94
+ knowledgeGraphByTopic(
95
+ driveId: ID!
96
+ topic: String!
97
+ ): [KnowledgeGraphNode!]!
98
+ knowledgeGraphRelatedByTopic(
99
+ driveId: ID!
100
+ documentId: String!
101
+ limit: Int
102
+ ): [RelatedNode!]!
103
+ knowledgeGraphFullSearch(
104
+ driveId: ID!
105
+ query: String!
106
+ limit: Int
107
+ ): [KnowledgeGraphNode!]!
108
+ knowledgeGraphByAuthor(
109
+ driveId: ID!
110
+ author: String!
111
+ ): [KnowledgeGraphNode!]!
112
+ knowledgeGraphByOrigin(
113
+ driveId: ID!
114
+ origin: String!
115
+ ): [KnowledgeGraphNode!]!
116
+ knowledgeGraphRecent(
117
+ driveId: ID!
118
+ limit: Int
119
+ since: String
120
+ ): [KnowledgeGraphNode!]!
121
+
122
+ knowledgeGraphSemanticSearch(
123
+ driveId: ID!
124
+ query: String!
125
+ limit: Int
126
+ ): [SemanticResult!]!
127
+ knowledgeGraphSimilar(
128
+ driveId: ID!
129
+ documentId: String!
130
+ limit: Int
131
+ ): [SemanticResult!]!
132
+
75
133
  """
76
134
  Debug: raw processor DB tables
77
135
  """
@@ -84,6 +142,11 @@ export class KnowledgeGraphSubgraph extends BaseSubgraph {
84
142
  sharedTarget: KnowledgeGraphNode!
85
143
  }
86
144
 
145
+ type SemanticResult {
146
+ node: KnowledgeGraphNode!
147
+ similarity: Float!
148
+ }
149
+
87
150
  type GraphDebugInfo {
88
151
  rawNodeCount: Int!
89
152
  rawEdgeCount: Int!
@@ -91,13 +154,44 @@ export class KnowledgeGraphSubgraph extends BaseSubgraph {
91
154
  rawEdges: [KnowledgeGraphEdge!]!
92
155
  processorNamespace: String!
93
156
  }
157
+
158
+ type ReindexResult {
159
+ indexedNodes: Int!
160
+ indexedEdges: Int!
161
+ errors: [String!]!
162
+ }
163
+
164
+ extend type Mutation {
165
+ """
166
+ Backfill the graph index by reading all bai/knowledge-note documents
167
+ in the drive. Use when the processor missed historical operations.
168
+ """
169
+ knowledgeGraphReindex(driveId: ID!): ReindexResult!
170
+ }
94
171
  `;
95
172
  resolvers = {
173
+ KnowledgeGraphNode: {
174
+ topics: async (parent) => {
175
+ // If topics were already resolved inline, return them
176
+ if (parent.topics)
177
+ return parent.topics;
178
+ // Otherwise resolve via field resolver using _driveId hint
179
+ if (parent._driveId) {
180
+ const query = this.getQuery(parent._driveId);
181
+ return query.topicsForNode(parent.documentId);
182
+ }
183
+ return [];
184
+ },
185
+ },
186
+ Mutation: {
187
+ knowledgeGraphReindex: (_, args) => this.reindexDrive(args.driveId),
188
+ },
96
189
  Query: {
97
190
  knowledgeGraphNodes: async (_, args) => {
98
191
  await this.ensureGraphDoc(args.driveId);
99
192
  const query = this.getQuery(args.driveId);
100
- return query.allNodes();
193
+ const nodes = await query.allNodes();
194
+ return nodes.map((n) => ({ ...n, _driveId: args.driveId }));
101
195
  },
102
196
  knowledgeGraphEdges: async (_, args) => {
103
197
  await this.ensureGraphDoc(args.driveId);
@@ -111,19 +205,26 @@ export class KnowledgeGraphSubgraph extends BaseSubgraph {
111
205
  },
112
206
  knowledgeGraphNodeByDocumentId: async (_, args) => {
113
207
  const query = this.getQuery(args.driveId);
114
- return query.nodeByDocumentId(args.documentId) ?? null;
208
+ const node = await query.nodeByDocumentId(args.documentId);
209
+ return node ? { ...node, _driveId: args.driveId } : null;
115
210
  },
116
211
  knowledgeGraphOrphans: async (_, args) => {
117
212
  const query = this.getQuery(args.driveId);
118
- return query.orphanNodes();
213
+ const nodes = await query.orphanNodes();
214
+ return nodes.map((n) => ({ ...n, _driveId: args.driveId }));
119
215
  },
120
216
  knowledgeGraphConnections: async (_, args) => {
121
217
  const query = this.getQuery(args.driveId);
122
- return query.connections(args.documentId, args.depth ?? 2);
218
+ const connections = await query.connections(args.documentId, args.depth ?? 2);
219
+ return connections.map((c) => ({
220
+ ...c,
221
+ node: { ...c.node, _driveId: args.driveId },
222
+ }));
123
223
  },
124
224
  knowledgeGraphNodesByStatus: async (_, args) => {
125
225
  const query = this.getQuery(args.driveId);
126
- return query.nodesByStatus(args.status);
226
+ const nodes = await query.nodesByStatus(args.status);
227
+ return nodes.map((n) => ({ ...n, _driveId: args.driveId }));
127
228
  },
128
229
  knowledgeGraphBacklinks: async (_, args) => {
129
230
  const query = this.getQuery(args.driveId);
@@ -135,33 +236,110 @@ export class KnowledgeGraphSubgraph extends BaseSubgraph {
135
236
  },
136
237
  knowledgeGraphSearch: async (_, args) => {
137
238
  const query = this.getQuery(args.driveId);
138
- return query.searchNodes(args.query, args.limit ?? 50);
239
+ const nodes = await query.searchNodes(args.query, args.limit ?? 50);
240
+ return nodes.map((n) => ({ ...n, _driveId: args.driveId }));
139
241
  },
140
242
  knowledgeGraphTriangles: async (_, args) => {
141
243
  const query = this.getQuery(args.driveId);
142
244
  const triangles = await query.triangles(args.limit ?? 20);
143
245
  return triangles.map((t) => ({
144
- noteA: t.a,
145
- noteB: t.b,
146
- sharedTarget: t.sharedTarget,
246
+ noteA: { ...t.a, _driveId: args.driveId },
247
+ noteB: { ...t.b, _driveId: args.driveId },
248
+ sharedTarget: { ...t.sharedTarget, _driveId: args.driveId },
147
249
  }));
148
250
  },
149
251
  knowledgeGraphBridges: async (_, args) => {
150
252
  const query = this.getQuery(args.driveId);
151
- return query.bridges();
253
+ const nodes = await query.bridges();
254
+ return nodes.map((n) => ({ ...n, _driveId: args.driveId }));
152
255
  },
153
256
  knowledgeGraphForwardLinks: async (_, args) => {
154
257
  const query = this.getQuery(args.driveId);
155
258
  return query.forwardLinks(args.documentId);
156
259
  },
260
+ // --- Phase 1: new query resolvers ---
261
+ knowledgeGraphTopics: async (_, args) => {
262
+ const query = this.getQuery(args.driveId);
263
+ return query.topicStats();
264
+ },
265
+ knowledgeGraphByTopic: async (_, args) => {
266
+ const query = this.getQuery(args.driveId);
267
+ const nodes = await query.nodesByTopic(args.topic);
268
+ return nodes.map((n) => ({ ...n, _driveId: args.driveId }));
269
+ },
270
+ knowledgeGraphRelatedByTopic: async (_, args) => {
271
+ const query = this.getQuery(args.driveId);
272
+ const results = await query.relatedByTopic(args.documentId, args.limit ?? 10);
273
+ return results.map((r) => ({
274
+ ...r,
275
+ node: { ...r.node, _driveId: args.driveId },
276
+ }));
277
+ },
278
+ knowledgeGraphFullSearch: async (_, args) => {
279
+ const query = this.getQuery(args.driveId);
280
+ const nodes = await query.fullSearch(args.query, args.limit ?? 50);
281
+ return nodes.map((n) => ({ ...n, _driveId: args.driveId }));
282
+ },
283
+ knowledgeGraphByAuthor: async (_, args) => {
284
+ const query = this.getQuery(args.driveId);
285
+ const nodes = await query.nodesByAuthor(args.author);
286
+ return nodes.map((n) => ({ ...n, _driveId: args.driveId }));
287
+ },
288
+ knowledgeGraphByOrigin: async (_, args) => {
289
+ const query = this.getQuery(args.driveId);
290
+ const nodes = await query.nodesByOrigin(args.origin);
291
+ return nodes.map((n) => ({ ...n, _driveId: args.driveId }));
292
+ },
293
+ knowledgeGraphRecent: async (_, args) => {
294
+ const query = this.getQuery(args.driveId);
295
+ const nodes = await query.recentNodes(args.limit ?? 20, args.since ?? undefined);
296
+ return nodes.map((n) => ({ ...n, _driveId: args.driveId }));
297
+ },
298
+ knowledgeGraphSemanticSearch: async (_, args) => {
299
+ const queryEmbedding = await generateEmbedding(args.query);
300
+ const results = await searchSimilar(queryEmbedding, args.limit ?? 10);
301
+ const graphQuery = this.getQuery(args.driveId);
302
+ const semanticResults = [];
303
+ for (const result of results) {
304
+ const node = await graphQuery.nodeByDocumentId(result.documentId);
305
+ if (node) {
306
+ semanticResults.push({
307
+ node: { ...node, _driveId: args.driveId },
308
+ similarity: result.similarity,
309
+ });
310
+ }
311
+ }
312
+ return semanticResults;
313
+ },
314
+ knowledgeGraphSimilar: async (_, args) => {
315
+ const embedding = await getEmbedding(args.documentId);
316
+ if (!embedding)
317
+ return [];
318
+ const results = await searchSimilar(embedding, (args.limit ?? 10) + 1);
319
+ const graphQuery = this.getQuery(args.driveId);
320
+ const semanticResults = [];
321
+ for (const result of results) {
322
+ if (result.documentId === args.documentId)
323
+ continue;
324
+ const node = await graphQuery.nodeByDocumentId(result.documentId);
325
+ if (node) {
326
+ semanticResults.push({
327
+ node: { ...node, _driveId: args.driveId },
328
+ similarity: result.similarity,
329
+ });
330
+ }
331
+ }
332
+ return semanticResults.slice(0, args.limit ?? 10);
333
+ },
157
334
  knowledgeGraphDebug: async (_, args) => {
158
335
  const namespace = GraphIndexerProcessor.getNamespace(args.driveId);
159
336
  try {
160
- const rawNodes = await GraphIndexerProcessor.query(args.driveId, this.relationalDb)
337
+ const db = this.getDb(args.driveId);
338
+ const rawNodes = await db
161
339
  .selectFrom("graph_nodes")
162
340
  .selectAll()
163
341
  .execute();
164
- const rawEdges = await GraphIndexerProcessor.query(args.driveId, this.relationalDb)
342
+ const rawEdges = await db
165
343
  .selectFrom("graph_edges")
166
344
  .selectAll()
167
345
  .execute();
@@ -175,7 +353,13 @@ export class KnowledgeGraphSubgraph extends BaseSubgraph {
175
353
  description: r.description,
176
354
  noteType: r.note_type,
177
355
  status: r.status,
356
+ content: r.content,
357
+ author: r.author,
358
+ sourceOrigin: r.source_origin,
359
+ createdAt: r.created_at,
360
+ topics: [],
178
361
  updatedAt: r.updated_at,
362
+ _driveId: args.driveId,
179
363
  })),
180
364
  rawEdges: rawEdges.map((r) => ({
181
365
  id: r.id,
@@ -204,18 +388,148 @@ export class KnowledgeGraphSubgraph extends BaseSubgraph {
204
388
  constructor(args) {
205
389
  super(args);
206
390
  }
391
+ /**
392
+ * Returns a Kysely<DB> instance scoped to the processor's namespace
393
+ * for the given drive. Centralizes the Legacy -> IRelationalDb cast.
394
+ */
395
+ /**
396
+ * Read-only namespaced query builder — use for all SELECT resolvers.
397
+ */
398
+ getDb(driveId) {
399
+ return GraphIndexerProcessor.query(driveId, this.relationalDb);
400
+ }
401
+ /**
402
+ * Writable namespaced Kysely instance — use for reindex (INSERT/DELETE).
403
+ * createNamespace returns a full Kysely, not the read-only query builder.
404
+ */
405
+ async getWritableDb(driveId) {
406
+ const namespace = GraphIndexerProcessor.getNamespace(driveId);
407
+ return (await this.relationalDb.createNamespace(namespace));
408
+ }
207
409
  getQuery(driveId) {
208
- // Use the processor's static query method for correct namespace scoping
209
- // (same pattern as the working workstreams example)
210
- const queryBuilder = GraphIndexerProcessor.query(driveId, this.relationalDb);
211
- return createGraphQuery(queryBuilder);
410
+ return createGraphQuery(this.getDb(driveId));
212
411
  }
213
412
  /**
214
413
  * Ensures a bai/knowledge-graph document exists in the given drive.
215
- * Called lazily on first query supports API/plugin access without
414
+ * Called lazily on first query -- supports API/plugin access without
216
415
  * requiring the Connect UI to have initialized the drive first.
217
416
  */
218
417
  ensuredDrives = new Set();
418
+ async reindexDrive(driveId) {
419
+ const errors = [];
420
+ let indexedNodes = 0;
421
+ let indexedEdges = 0;
422
+ try {
423
+ const drive = await this.reactorClient.get(driveId);
424
+ const nodes = drive.state.global.nodes;
425
+ const noteNodes = nodes.filter((n) => n.kind === "file" && n.documentType === "bai/knowledge-note");
426
+ const db = await this.getWritableDb(driveId);
427
+ const now = new Date().toISOString();
428
+ for (const node of noteNodes) {
429
+ try {
430
+ const doc = await this.reactorClient.get(node.id);
431
+ const state = doc.state;
432
+ const global = state.global;
433
+ // Extract provenance
434
+ const provenance = global.provenance;
435
+ await db
436
+ .insertInto("graph_nodes")
437
+ .values({
438
+ id: node.id,
439
+ document_id: node.id,
440
+ title: global.title ?? null,
441
+ description: global.description ?? null,
442
+ note_type: global.noteType ?? null,
443
+ status: global.status ?? "DRAFT",
444
+ content: global.content ?? null,
445
+ author: provenance?.author ?? null,
446
+ source_origin: provenance?.sourceOrigin ?? null,
447
+ created_at: provenance?.createdAt ?? null,
448
+ updated_at: now,
449
+ })
450
+ .onConflict((oc) => oc.column("document_id").doUpdateSet({
451
+ title: global.title ?? null,
452
+ description: global.description ?? null,
453
+ note_type: global.noteType ?? null,
454
+ status: global.status ?? "DRAFT",
455
+ content: global.content ?? null,
456
+ author: provenance?.author ?? null,
457
+ source_origin: provenance?.sourceOrigin ?? null,
458
+ created_at: provenance?.createdAt ?? null,
459
+ updated_at: now,
460
+ }))
461
+ .execute();
462
+ indexedNodes++;
463
+ // Reconcile topics
464
+ await db
465
+ .deleteFrom("graph_topics")
466
+ .where("document_id", "=", node.id)
467
+ .execute();
468
+ const topics = global.topics ?? [];
469
+ if (topics.length > 0) {
470
+ await db
471
+ .insertInto("graph_topics")
472
+ .values(topics.map((topic, idx) => {
473
+ const name = typeof topic === "string"
474
+ ? topic
475
+ : (topic.name ?? "");
476
+ return {
477
+ id: `${node.id}-topic-${idx}`,
478
+ document_id: node.id,
479
+ name,
480
+ updated_at: now,
481
+ };
482
+ }))
483
+ .execute();
484
+ }
485
+ // Reconcile edges
486
+ await db
487
+ .deleteFrom("graph_edges")
488
+ .where("source_document_id", "=", node.id)
489
+ .execute();
490
+ const links = global.links ?? [];
491
+ if (links.length > 0) {
492
+ await db
493
+ .insertInto("graph_edges")
494
+ .values(links.map((link) => ({
495
+ id: link.id ??
496
+ `${node.id}-${link.targetDocumentId}`,
497
+ source_document_id: node.id,
498
+ target_document_id: link.targetDocumentId ?? "",
499
+ link_type: link.linkType ?? null,
500
+ target_title: link.targetTitle ?? null,
501
+ updated_at: now,
502
+ })))
503
+ .execute();
504
+ indexedEdges += links.length;
505
+ }
506
+ // Generate embedding for semantic search
507
+ const text = [global.title, global.description, global.content]
508
+ .filter(Boolean)
509
+ .join(" ");
510
+ if (text.length > 0) {
511
+ try {
512
+ const emb = await generateEmbedding(text);
513
+ await upsertEmbedding(node.id, emb);
514
+ }
515
+ catch (embErr) {
516
+ console.warn(`[KnowledgeGraphSubgraph] Embedding failed for ${node.id}:`, embErr);
517
+ }
518
+ }
519
+ }
520
+ catch (err) {
521
+ const msg = err instanceof Error ? err.message : String(err);
522
+ errors.push(`${node.id}: ${msg}`);
523
+ }
524
+ }
525
+ console.log(`[KnowledgeGraphSubgraph] Reindex complete: ${indexedNodes} nodes, ${indexedEdges} edges, ${errors.length} errors`);
526
+ }
527
+ catch (err) {
528
+ const msg = err instanceof Error ? err.message : String(err);
529
+ errors.push(`Drive read failed: ${msg}`);
530
+ }
531
+ return { indexedNodes, indexedEdges, errors };
532
+ }
219
533
  async ensureGraphDoc(driveId) {
220
534
  if (this.ensuredDrives.has(driveId))
221
535
  return;
@@ -235,12 +549,12 @@ export class KnowledgeGraphSubgraph extends BaseSubgraph {
235
549
  console.log(`[KnowledgeGraphSubgraph] Auto-created KnowledgeGraph in drive ${driveId}` +
236
550
  (parentFolder
237
551
  ? ` (folder: /self/)`
238
- : ` (drive root /self/ folder not found)`));
552
+ : ` (drive root -- /self/ folder not found)`));
239
553
  }
240
554
  }
241
555
  catch (err) {
242
556
  console.error(`[KnowledgeGraphSubgraph] Failed to ensure graph doc:`, err);
243
- // Don't block queries if this fails processor data still works
557
+ // Don't block queries if this fails -- processor data still works
244
558
  }
245
559
  }
246
560
  }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@powerhousedao/knowledge-note",
3
3
  "description": "Knowledge Note document model package for Powerhouse",
4
- "version": "1.0.2",
4
+ "version": "1.0.4",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",
7
7
  "files": [
8
8
  "/dist"
9
9
  ],
10
- "publishConfig": {
10
+ "publishConfig": {
11
11
  "access": "public"
12
12
  },
13
13
  "exports": {
@@ -107,13 +107,14 @@
107
107
  },
108
108
  "dependencies": {
109
109
  "@electric-sql/pglite": "0.3.15",
110
+ "@huggingface/transformers": "^4.0.1",
110
111
  "@powerhousedao/builder-tools": "6.0.0-dev.105",
111
112
  "@powerhousedao/common": "6.0.0-dev.105",
112
113
  "@powerhousedao/design-system": "6.0.0-dev.105",
113
114
  "@powerhousedao/document-engineering": "1.40.1",
114
115
  "@powerhousedao/vetra": "6.0.0-dev.105",
115
116
  "cytoscape": "^3.33.1",
116
- "cytoscape-cose-bilkent": "^4.1.0",
117
+ "cytoscape-fcose": "^2.2.0",
117
118
  "document-model": "6.0.0-dev.105",
118
119
  "graphql": "16.12.0",
119
120
  "graphql-tag": "^2.12.6",
@@ -1,4 +0,0 @@
1
- import type { ProcessorRecord, IProcessorHostModule } from "@powerhousedao/reactor-browser";
2
- import type { PHDocumentHeader } from "document-model";
3
- export declare const methodologyIndexerProcessorFactory: (module: IProcessorHostModule) => (driveHeader: PHDocumentHeader) => Promise<ProcessorRecord[]>;
4
- //# sourceMappingURL=factory.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../processors/methodology-indexer/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,oBAAoB,EACrB,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGvD,eAAO,MAAM,kCAAkC,GAC5C,QAAQ,oBAAoB,MACtB,aAAa,gBAAgB,KAAG,OAAO,CAAC,eAAe,EAAE,CAgC/D,CAAC"}
@@ -1,23 +0,0 @@
1
- import {} from "@powerhousedao/shared/processors";
2
- import { MethodologyIndexerProcessor } from "./index.js";
3
- export const methodologyIndexerProcessorFactory = (module) => async (driveHeader) => {
4
- const namespace = MethodologyIndexerProcessor.getNamespace(driveHeader.id);
5
- console.log(`[MethodologyIndexer] Factory called for drive: ${driveHeader.id}, namespace: ${namespace}`);
6
- const store = await module.relationalDb.createNamespace(namespace);
7
- const filter = {
8
- branch: ["main"],
9
- documentId: ["*"],
10
- documentType: ["bai/research-claim", "powerhouse/document-drive"],
11
- scope: ["global"],
12
- };
13
- const processor = new MethodologyIndexerProcessor(namespace, filter, store);
14
- await processor.initAndUpgrade();
15
- console.log(`[MethodologyIndexer] Processor created for drive: ${driveHeader.id}`);
16
- return [
17
- {
18
- processor,
19
- filter,
20
- startFrom: "beginning",
21
- },
22
- ];
23
- };
@@ -1,11 +0,0 @@
1
- import { RelationalDbProcessor } from "@powerhousedao/shared/processors";
2
- import type { OperationWithContext } from "@powerhousedao/shared/document-model";
3
- import type { MethodologyDB } from "./schema.js";
4
- export declare class MethodologyIndexerProcessor extends RelationalDbProcessor<MethodologyDB> {
5
- static getNamespace(driveId: string): string;
6
- initAndUpgrade(): Promise<void>;
7
- onOperations(operations: OperationWithContext[]): Promise<void>;
8
- onDisconnect(): Promise<void>;
9
- private deleteClaim;
10
- }
11
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../processors/methodology-indexer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAEjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,qBAAa,2BAA4B,SAAQ,qBAAqB,CAAC,aAAa,CAAC;WACnE,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAItC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,YAAY,CACzB,UAAU,EAAE,oBAAoB,EAAE,GACjC,OAAO,CAAC,IAAI,CAAC;IAsGV,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;YAYrB,WAAW;CAkB1B"}
@@ -1,116 +0,0 @@
1
- import { RelationalDbProcessor } from "@powerhousedao/shared/processors";
2
- import { up } from "./migrations.js";
3
- export class MethodologyIndexerProcessor extends RelationalDbProcessor {
4
- static getNamespace(driveId) {
5
- return super.getNamespace(driveId);
6
- }
7
- async initAndUpgrade() {
8
- await up(this.relationalDb);
9
- }
10
- async onOperations(operations) {
11
- if (operations.length === 0)
12
- return;
13
- const lastByDocument = new Map();
14
- for (const entry of operations) {
15
- const { operation, context } = entry;
16
- const documentId = context.documentId;
17
- // Handle deletion from drive
18
- if (context.documentType === "powerhouse/document-drive" &&
19
- operation.action.type === "DELETE_NODE") {
20
- const deleteInput = operation.action.input;
21
- await this.deleteClaim(deleteInput.id);
22
- lastByDocument.delete(deleteInput.id);
23
- continue;
24
- }
25
- // Only process research-claim documents
26
- if (context.documentType !== "bai/research-claim")
27
- continue;
28
- if (context.resultingState) {
29
- lastByDocument.set(documentId, entry);
30
- }
31
- }
32
- for (const [documentId, entry] of lastByDocument) {
33
- try {
34
- const stateJson = entry.context.resultingState;
35
- if (!stateJson)
36
- continue;
37
- const parsed = JSON.parse(stateJson);
38
- const global = (parsed.global ?? parsed);
39
- const now = new Date().toISOString();
40
- // Upsert claim
41
- const topics = global.topics ?? [];
42
- const methodology = global.methodology ?? [];
43
- await this.relationalDb
44
- .insertInto("methodology_claims")
45
- .values({
46
- id: documentId,
47
- document_id: documentId,
48
- title: global.title ?? null,
49
- description: global.description ?? null,
50
- kind: global.kind ?? null,
51
- topics: JSON.stringify(topics),
52
- methodology: JSON.stringify(methodology),
53
- updated_at: now,
54
- })
55
- .onConflict((oc) => oc.column("document_id").doUpdateSet({
56
- title: global.title ?? null,
57
- description: global.description ?? null,
58
- kind: global.kind ?? null,
59
- topics: JSON.stringify(topics),
60
- methodology: JSON.stringify(methodology),
61
- updated_at: now,
62
- }))
63
- .execute();
64
- // Reconcile connections
65
- await this.relationalDb
66
- .deleteFrom("methodology_connections")
67
- .where("source_document_id", "=", documentId)
68
- .execute();
69
- const connections = global.connections ?? [];
70
- if (connections.length > 0) {
71
- await this.relationalDb
72
- .insertInto("methodology_connections")
73
- .values(connections.map((conn) => ({
74
- id: conn.id ??
75
- `${documentId}-${conn.targetRef}`,
76
- source_document_id: documentId,
77
- target_ref: conn.targetRef ?? "",
78
- context_phrase: conn.contextPhrase ?? null,
79
- updated_at: now,
80
- })))
81
- .execute();
82
- }
83
- console.log(`[MethodologyIndexer] Reconciled ${documentId}: ${connections.length} connections`);
84
- }
85
- catch (err) {
86
- console.error(`[MethodologyIndexer] Error reconciling ${documentId}:`, err);
87
- }
88
- }
89
- }
90
- async onDisconnect() {
91
- try {
92
- await this.relationalDb.deleteFrom("methodology_connections").execute();
93
- await this.relationalDb.deleteFrom("methodology_claims").execute();
94
- console.log(`[MethodologyIndexer] Cleaned up namespace: ${this.namespace}`);
95
- }
96
- catch (err) {
97
- console.error(`[MethodologyIndexer] Error cleaning up:`, err);
98
- }
99
- }
100
- async deleteClaim(documentId) {
101
- try {
102
- await this.relationalDb
103
- .deleteFrom("methodology_connections")
104
- .where("source_document_id", "=", documentId)
105
- .execute();
106
- await this.relationalDb
107
- .deleteFrom("methodology_claims")
108
- .where("document_id", "=", documentId)
109
- .execute();
110
- console.log(`[MethodologyIndexer] Deleted claim ${documentId}`);
111
- }
112
- catch (err) {
113
- console.error(`[MethodologyIndexer] Error deleting claim ${documentId}:`, err);
114
- }
115
- }
116
- }
@@ -1,4 +0,0 @@
1
- import type { IRelationalDb } from "@powerhousedao/shared/processors";
2
- export declare function up(db: IRelationalDb<any>): Promise<void>;
3
- export declare function down(db: IRelationalDb<any>): Promise<void>;
4
- //# sourceMappingURL=migrations.d.ts.map