@knowledgine/core 0.0.1 → 0.2.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.
- package/dist/config/config-loader.d.ts +15 -0
- package/dist/config/config-loader.d.ts.map +1 -0
- package/dist/config/config-loader.js +46 -0
- package/dist/config/config-loader.js.map +1 -0
- package/dist/config.d.ts +16 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -1
- package/dist/embedding/embedding-provider.d.ts +9 -0
- package/dist/embedding/embedding-provider.d.ts.map +1 -0
- package/dist/embedding/embedding-provider.js +2 -0
- package/dist/embedding/embedding-provider.js.map +1 -0
- package/dist/embedding/model-downloader.d.ts +34 -0
- package/dist/embedding/model-downloader.d.ts.map +1 -0
- package/dist/embedding/model-downloader.js +149 -0
- package/dist/embedding/model-downloader.js.map +1 -0
- package/dist/embedding/model-manager.d.ts +10 -0
- package/dist/embedding/model-manager.d.ts.map +1 -0
- package/dist/embedding/model-manager.js +32 -0
- package/dist/embedding/model-manager.js.map +1 -0
- package/dist/embedding/onnx-embedding-provider.d.ts +18 -0
- package/dist/embedding/onnx-embedding-provider.d.ts.map +1 -0
- package/dist/embedding/onnx-embedding-provider.js +121 -0
- package/dist/embedding/onnx-embedding-provider.js.map +1 -0
- package/dist/embedding/tokenizer.d.ts +19 -0
- package/dist/embedding/tokenizer.d.ts.map +1 -0
- package/dist/embedding/tokenizer.js +80 -0
- package/dist/embedding/tokenizer.js.map +1 -0
- package/dist/errors.d.ts +12 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +21 -0
- package/dist/errors.js.map +1 -1
- package/dist/feedback/feedback-learner.d.ts +29 -0
- package/dist/feedback/feedback-learner.d.ts.map +1 -0
- package/dist/feedback/feedback-learner.js +88 -0
- package/dist/feedback/feedback-learner.js.map +1 -0
- package/dist/feedback/feedback-repository.d.ts +41 -0
- package/dist/feedback/feedback-repository.d.ts.map +1 -0
- package/dist/feedback/feedback-repository.js +94 -0
- package/dist/feedback/feedback-repository.js.map +1 -0
- package/dist/feedback/index.d.ts +5 -0
- package/dist/feedback/index.d.ts.map +1 -0
- package/dist/feedback/index.js +3 -0
- package/dist/feedback/index.js.map +1 -0
- package/dist/graph/entity-extractor.d.ts +26 -0
- package/dist/graph/entity-extractor.d.ts.map +1 -0
- package/dist/graph/entity-extractor.js +237 -0
- package/dist/graph/entity-extractor.js.map +1 -0
- package/dist/graph/graph-repository.d.ts +72 -0
- package/dist/graph/graph-repository.d.ts.map +1 -0
- package/dist/graph/graph-repository.js +442 -0
- package/dist/graph/graph-repository.js.map +1 -0
- package/dist/graph/index.d.ts +4 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +4 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/relation-inferrer.d.ts +23 -0
- package/dist/graph/relation-inferrer.d.ts.map +1 -0
- package/dist/graph/relation-inferrer.js +89 -0
- package/dist/graph/relation-inferrer.js.map +1 -0
- package/dist/index.d.ts +33 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -4
- package/dist/index.js.map +1 -1
- package/dist/provenance/provenance-repository.d.ts +47 -0
- package/dist/provenance/provenance-repository.d.ts.map +1 -0
- package/dist/provenance/provenance-repository.js +121 -0
- package/dist/provenance/provenance-repository.js.map +1 -0
- package/dist/search/hybrid-searcher.d.ts +14 -0
- package/dist/search/hybrid-searcher.d.ts.map +1 -0
- package/dist/search/hybrid-searcher.js +67 -0
- package/dist/search/hybrid-searcher.js.map +1 -0
- package/dist/search/knowledge-searcher.d.ts +8 -4
- package/dist/search/knowledge-searcher.d.ts.map +1 -1
- package/dist/search/knowledge-searcher.js +47 -16
- package/dist/search/knowledge-searcher.js.map +1 -1
- package/dist/search/link-generator.d.ts +7 -1
- package/dist/search/link-generator.d.ts.map +1 -1
- package/dist/search/link-generator.js +37 -1
- package/dist/search/link-generator.js.map +1 -1
- package/dist/search/semantic-searcher.d.ts +14 -0
- package/dist/search/semantic-searcher.d.ts.map +1 -0
- package/dist/search/semantic-searcher.js +30 -0
- package/dist/search/semantic-searcher.js.map +1 -0
- package/dist/services/knowledge-service.d.ts +128 -0
- package/dist/services/knowledge-service.d.ts.map +1 -0
- package/dist/services/knowledge-service.js +168 -0
- package/dist/services/knowledge-service.js.map +1 -0
- package/dist/storage/database.d.ts +9 -1
- package/dist/storage/database.d.ts.map +1 -1
- package/dist/storage/database.js +28 -1
- package/dist/storage/database.js.map +1 -1
- package/dist/storage/knowledge-repository.d.ts +27 -0
- package/dist/storage/knowledge-repository.d.ts.map +1 -1
- package/dist/storage/knowledge-repository.js +107 -3
- package/dist/storage/knowledge-repository.js.map +1 -1
- package/dist/storage/migrations/003_vector_embeddings.d.ts +3 -0
- package/dist/storage/migrations/003_vector_embeddings.d.ts.map +1 -0
- package/dist/storage/migrations/003_vector_embeddings.js +50 -0
- package/dist/storage/migrations/003_vector_embeddings.js.map +1 -0
- package/dist/storage/migrations/004_knowledge_graph.d.ts +3 -0
- package/dist/storage/migrations/004_knowledge_graph.d.ts.map +1 -0
- package/dist/storage/migrations/004_knowledge_graph.js +106 -0
- package/dist/storage/migrations/004_knowledge_graph.js.map +1 -0
- package/dist/storage/migrations/005a_events_layer.d.ts +3 -0
- package/dist/storage/migrations/005a_events_layer.d.ts.map +1 -0
- package/dist/storage/migrations/005a_events_layer.js +55 -0
- package/dist/storage/migrations/005a_events_layer.js.map +1 -0
- package/dist/storage/migrations/005b_bitemporal.d.ts +3 -0
- package/dist/storage/migrations/005b_bitemporal.d.ts.map +1 -0
- package/dist/storage/migrations/005b_bitemporal.js +53 -0
- package/dist/storage/migrations/005b_bitemporal.js.map +1 -0
- package/dist/storage/migrations/005c_provenance.d.ts +3 -0
- package/dist/storage/migrations/005c_provenance.d.ts.map +1 -0
- package/dist/storage/migrations/005c_provenance.js +56 -0
- package/dist/storage/migrations/005c_provenance.js.map +1 -0
- package/dist/storage/migrations/006_extraction_feedback.d.ts +3 -0
- package/dist/storage/migrations/006_extraction_feedback.d.ts.map +1 -0
- package/dist/storage/migrations/006_extraction_feedback.js +30 -0
- package/dist/storage/migrations/006_extraction_feedback.js.map +1 -0
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +15 -4
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
import { DatabaseError, ValidationError } from "../errors.js";
|
|
2
|
+
function rowToEntity(row) {
|
|
3
|
+
return {
|
|
4
|
+
id: row.id,
|
|
5
|
+
name: row.name,
|
|
6
|
+
entityType: row.entity_type,
|
|
7
|
+
description: row.description ?? undefined,
|
|
8
|
+
createdAt: row.created_at,
|
|
9
|
+
updatedAt: row.updated_at ?? undefined,
|
|
10
|
+
metadata: row.metadata_json
|
|
11
|
+
? JSON.parse(row.metadata_json)
|
|
12
|
+
: undefined,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function rowToRelation(row) {
|
|
16
|
+
return {
|
|
17
|
+
id: row.id,
|
|
18
|
+
fromEntityId: row.from_entity_id,
|
|
19
|
+
toEntityId: row.to_entity_id,
|
|
20
|
+
relationType: row.relation_type,
|
|
21
|
+
strength: row.strength,
|
|
22
|
+
description: row.description ?? undefined,
|
|
23
|
+
createdAt: row.created_at,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function rowToObservation(row) {
|
|
27
|
+
return {
|
|
28
|
+
id: row.id,
|
|
29
|
+
entityId: row.entity_id,
|
|
30
|
+
content: row.content,
|
|
31
|
+
observationType: row.observation_type,
|
|
32
|
+
confidence: row.confidence ?? undefined,
|
|
33
|
+
sourceNoteId: row.source_note_id ?? undefined,
|
|
34
|
+
sourcePatternId: row.source_pattern_id ?? undefined,
|
|
35
|
+
createdAt: row.created_at,
|
|
36
|
+
metadata: row.metadata_json
|
|
37
|
+
? JSON.parse(row.metadata_json)
|
|
38
|
+
: undefined,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export class GraphRepository {
|
|
42
|
+
db;
|
|
43
|
+
constructor(db) {
|
|
44
|
+
this.db = db;
|
|
45
|
+
}
|
|
46
|
+
// ── Entity CRUD ──────────────────────────────────────────────
|
|
47
|
+
createEntity(entity) {
|
|
48
|
+
if (!entity.name || entity.name.trim() === "") {
|
|
49
|
+
throw new ValidationError("name", entity.name, "Entity name is required");
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const now = new Date().toISOString();
|
|
53
|
+
const stmt = this.db.prepare(`
|
|
54
|
+
INSERT INTO entities (name, entity_type, description, created_at, updated_at, metadata_json)
|
|
55
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
56
|
+
`);
|
|
57
|
+
const info = stmt.run(entity.name.toLowerCase(), entity.entityType, entity.description ?? null, entity.createdAt || now, entity.updatedAt ?? null, entity.metadata ? JSON.stringify(entity.metadata) : null);
|
|
58
|
+
return Number(info.lastInsertRowid);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error instanceof ValidationError)
|
|
62
|
+
throw error;
|
|
63
|
+
throw new DatabaseError("createEntity", error, { name: entity.name });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 名前を小文字正規化してupsert。同名・同タイプのエンティティは更新する。
|
|
68
|
+
*/
|
|
69
|
+
upsertEntity(entity) {
|
|
70
|
+
if (!entity.name || entity.name.trim() === "") {
|
|
71
|
+
throw new ValidationError("name", entity.name, "Entity name is required");
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
const normalizedName = entity.name.toLowerCase();
|
|
75
|
+
const now = new Date().toISOString();
|
|
76
|
+
const stmt = this.db.prepare(`
|
|
77
|
+
INSERT INTO entities (name, entity_type, description, created_at, updated_at, metadata_json)
|
|
78
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
79
|
+
ON CONFLICT(name, entity_type) DO UPDATE SET
|
|
80
|
+
description = COALESCE(excluded.description, description),
|
|
81
|
+
updated_at = excluded.updated_at,
|
|
82
|
+
metadata_json = COALESCE(excluded.metadata_json, metadata_json)
|
|
83
|
+
`);
|
|
84
|
+
stmt.run(normalizedName, entity.entityType, entity.description ?? null, entity.createdAt || now, now, entity.metadata ? JSON.stringify(entity.metadata) : null);
|
|
85
|
+
const existing = this.getEntityByName(normalizedName, entity.entityType);
|
|
86
|
+
return existing.id;
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
if (error instanceof ValidationError)
|
|
90
|
+
throw error;
|
|
91
|
+
throw new DatabaseError("upsertEntity", error, { name: entity.name });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
getEntityById(id) {
|
|
95
|
+
const row = this.db.prepare("SELECT * FROM entities WHERE id = ?").get(id);
|
|
96
|
+
return row ? rowToEntity(row) : undefined;
|
|
97
|
+
}
|
|
98
|
+
getEntityByName(name, entityType) {
|
|
99
|
+
const normalizedName = name.toLowerCase();
|
|
100
|
+
if (entityType) {
|
|
101
|
+
const row = this.db
|
|
102
|
+
.prepare("SELECT * FROM entities WHERE name = ? AND entity_type = ?")
|
|
103
|
+
.get(normalizedName, entityType);
|
|
104
|
+
return row ? rowToEntity(row) : undefined;
|
|
105
|
+
}
|
|
106
|
+
const row = this.db
|
|
107
|
+
.prepare("SELECT * FROM entities WHERE name = ? LIMIT 1")
|
|
108
|
+
.get(normalizedName);
|
|
109
|
+
return row ? rowToEntity(row) : undefined;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* FTS5 trigram検索。3文字未満はLIKEフォールバック。
|
|
113
|
+
*/
|
|
114
|
+
searchEntities(query, limit = 20) {
|
|
115
|
+
if (query.length < 3) {
|
|
116
|
+
// LIKE fallback for short queries
|
|
117
|
+
const rows = this.db
|
|
118
|
+
.prepare(`SELECT * FROM entities WHERE name LIKE ? OR description LIKE ? LIMIT ?`)
|
|
119
|
+
.all(`%${query}%`, `%${query}%`, limit);
|
|
120
|
+
return rows.map(rowToEntity);
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
const rows = this.db
|
|
124
|
+
.prepare(`
|
|
125
|
+
SELECT e.* FROM entities e
|
|
126
|
+
JOIN entities_fts fts ON e.id = fts.rowid
|
|
127
|
+
WHERE entities_fts MATCH ?
|
|
128
|
+
ORDER BY rank
|
|
129
|
+
LIMIT ?
|
|
130
|
+
`)
|
|
131
|
+
.all(query, limit);
|
|
132
|
+
return rows.map(rowToEntity);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// FTS失敗時はLIKEフォールバック
|
|
136
|
+
const rows = this.db
|
|
137
|
+
.prepare(`SELECT * FROM entities WHERE name LIKE ? OR description LIKE ? LIMIT ?`)
|
|
138
|
+
.all(`%${query}%`, `%${query}%`, limit);
|
|
139
|
+
return rows.map(rowToEntity);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
deleteEntity(id) {
|
|
143
|
+
try {
|
|
144
|
+
const info = this.db.prepare("DELETE FROM entities WHERE id = ?").run(id);
|
|
145
|
+
return info.changes > 0;
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
throw new DatabaseError("deleteEntity", error, { id });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// ── Relation CRUD ─────────────────────────────────────────────
|
|
152
|
+
createRelation(relation) {
|
|
153
|
+
try {
|
|
154
|
+
const now = new Date().toISOString();
|
|
155
|
+
const stmt = this.db.prepare(`
|
|
156
|
+
INSERT INTO relations (from_entity_id, to_entity_id, relation_type, strength, description, created_at, valid_from, recorded_at)
|
|
157
|
+
VALUES (?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
|
|
158
|
+
`);
|
|
159
|
+
const info = stmt.run(relation.fromEntityId, relation.toEntityId, relation.relationType, relation.strength ?? 1.0, relation.description ?? null, relation.createdAt || now);
|
|
160
|
+
return Number(info.lastInsertRowid);
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
throw new DatabaseError("createRelation", error, {
|
|
164
|
+
fromEntityId: relation.fromEntityId,
|
|
165
|
+
toEntityId: relation.toEntityId,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* 同一 (from, to, type) のrelationが存在する場合はstrengthをMAXで更新。
|
|
171
|
+
*/
|
|
172
|
+
upsertRelation(relation) {
|
|
173
|
+
try {
|
|
174
|
+
const now = new Date().toISOString();
|
|
175
|
+
const strength = relation.strength ?? 1.0;
|
|
176
|
+
const insertStmt = this.db.prepare(`
|
|
177
|
+
INSERT OR IGNORE INTO relations
|
|
178
|
+
(from_entity_id, to_entity_id, relation_type, strength, description, created_at, valid_from, recorded_at)
|
|
179
|
+
VALUES (?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
|
|
180
|
+
`);
|
|
181
|
+
insertStmt.run(relation.fromEntityId, relation.toEntityId, relation.relationType, strength, relation.description ?? null, relation.createdAt || now);
|
|
182
|
+
const updateStmt = this.db.prepare(`
|
|
183
|
+
UPDATE relations
|
|
184
|
+
SET strength = MAX(strength, ?)
|
|
185
|
+
WHERE from_entity_id = ? AND to_entity_id = ? AND relation_type = ?
|
|
186
|
+
`);
|
|
187
|
+
updateStmt.run(strength, relation.fromEntityId, relation.toEntityId, relation.relationType);
|
|
188
|
+
const existing = this.db
|
|
189
|
+
.prepare("SELECT id FROM relations WHERE from_entity_id = ? AND to_entity_id = ? AND relation_type = ?")
|
|
190
|
+
.get(relation.fromEntityId, relation.toEntityId, relation.relationType);
|
|
191
|
+
return existing?.id ?? 0;
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
throw new DatabaseError("upsertRelation", error, {
|
|
195
|
+
fromEntityId: relation.fromEntityId,
|
|
196
|
+
toEntityId: relation.toEntityId,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
getRelationsByEntityId(entityId) {
|
|
201
|
+
const rows = this.db
|
|
202
|
+
.prepare("SELECT * FROM active_relations WHERE from_entity_id = ? OR to_entity_id = ? ORDER BY strength DESC")
|
|
203
|
+
.all(entityId, entityId);
|
|
204
|
+
return rows.map(rowToRelation);
|
|
205
|
+
}
|
|
206
|
+
deleteRelation(id) {
|
|
207
|
+
try {
|
|
208
|
+
const info = this.db.prepare("DELETE FROM relations WHERE id = ?").run(id);
|
|
209
|
+
return info.changes > 0;
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
throw new DatabaseError("deleteRelation", error, { id });
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// ── Observation CRUD ──────────────────────────────────────────
|
|
216
|
+
createObservation(observation) {
|
|
217
|
+
try {
|
|
218
|
+
const now = new Date().toISOString();
|
|
219
|
+
const stmt = this.db.prepare(`
|
|
220
|
+
INSERT INTO observations
|
|
221
|
+
(entity_id, content, observation_type, confidence, source_note_id, source_pattern_id, created_at, metadata_json, valid_from, recorded_at)
|
|
222
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
|
|
223
|
+
`);
|
|
224
|
+
const info = stmt.run(observation.entityId, observation.content, observation.observationType, observation.confidence ?? null, observation.sourceNoteId ?? null, observation.sourcePatternId ?? null, observation.createdAt || now, observation.metadata ? JSON.stringify(observation.metadata) : null);
|
|
225
|
+
return Number(info.lastInsertRowid);
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
throw new DatabaseError("createObservation", error, { entityId: observation.entityId });
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
getObservationsByEntityId(entityId) {
|
|
232
|
+
const rows = this.db
|
|
233
|
+
.prepare("SELECT * FROM active_observations WHERE entity_id = ? ORDER BY created_at DESC")
|
|
234
|
+
.all(entityId);
|
|
235
|
+
return rows.map(rowToObservation);
|
|
236
|
+
}
|
|
237
|
+
deleteObservation(id) {
|
|
238
|
+
try {
|
|
239
|
+
const info = this.db.prepare("DELETE FROM observations WHERE id = ?").run(id);
|
|
240
|
+
return info.changes > 0;
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
throw new DatabaseError("deleteObservation", error, { id });
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// ── Entity-Note Links ─────────────────────────────────────────
|
|
247
|
+
linkEntityToNote(entityId, noteId) {
|
|
248
|
+
try {
|
|
249
|
+
this.db
|
|
250
|
+
.prepare("INSERT OR IGNORE INTO entity_note_links (entity_id, note_id) VALUES (?, ?)")
|
|
251
|
+
.run(entityId, noteId);
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
throw new DatabaseError("linkEntityToNote", error, { entityId, noteId });
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
getLinkedNotes(entityId) {
|
|
258
|
+
const rows = this.db
|
|
259
|
+
.prepare("SELECT entity_id, note_id FROM entity_note_links WHERE entity_id = ?")
|
|
260
|
+
.all(entityId);
|
|
261
|
+
return rows.map((r) => ({ entityId: r.entity_id, noteId: r.note_id }));
|
|
262
|
+
}
|
|
263
|
+
getLinkedEntities(noteId) {
|
|
264
|
+
const rows = this.db
|
|
265
|
+
.prepare(`
|
|
266
|
+
SELECT e.* FROM entities e
|
|
267
|
+
JOIN entity_note_links l ON e.id = l.entity_id
|
|
268
|
+
WHERE l.note_id = ?
|
|
269
|
+
`)
|
|
270
|
+
.all(noteId);
|
|
271
|
+
return rows.map(rowToEntity);
|
|
272
|
+
}
|
|
273
|
+
// ── Graph Traversal ───────────────────────────────────────────
|
|
274
|
+
getEntityWithGraph(entityId) {
|
|
275
|
+
const entity = this.getEntityById(entityId);
|
|
276
|
+
if (!entity)
|
|
277
|
+
return undefined;
|
|
278
|
+
const observations = this.getObservationsByEntityId(entityId);
|
|
279
|
+
const outgoingRows = this.db
|
|
280
|
+
.prepare(`
|
|
281
|
+
SELECT r.*, e.id as te_id, e.name as te_name, e.entity_type as te_type,
|
|
282
|
+
e.description as te_desc, e.created_at as te_created, e.updated_at as te_updated, e.metadata_json as te_meta
|
|
283
|
+
FROM active_relations r
|
|
284
|
+
JOIN entities e ON e.id = r.to_entity_id
|
|
285
|
+
WHERE r.from_entity_id = ?
|
|
286
|
+
ORDER BY r.strength DESC
|
|
287
|
+
`)
|
|
288
|
+
.all(entityId);
|
|
289
|
+
const outgoingRelations = outgoingRows.map((row) => ({
|
|
290
|
+
...rowToRelation(row),
|
|
291
|
+
targetEntity: rowToEntity({
|
|
292
|
+
id: row.te_id,
|
|
293
|
+
name: row.te_name,
|
|
294
|
+
entity_type: row.te_type,
|
|
295
|
+
description: row.te_desc,
|
|
296
|
+
created_at: row.te_created,
|
|
297
|
+
updated_at: row.te_updated,
|
|
298
|
+
metadata_json: row.te_meta,
|
|
299
|
+
}),
|
|
300
|
+
}));
|
|
301
|
+
const incomingRows = this.db
|
|
302
|
+
.prepare(`
|
|
303
|
+
SELECT r.*, e.id as se_id, e.name as se_name, e.entity_type as se_type,
|
|
304
|
+
e.description as se_desc, e.created_at as se_created, e.updated_at as se_updated, e.metadata_json as se_meta
|
|
305
|
+
FROM active_relations r
|
|
306
|
+
JOIN entities e ON e.id = r.from_entity_id
|
|
307
|
+
WHERE r.to_entity_id = ?
|
|
308
|
+
ORDER BY r.strength DESC
|
|
309
|
+
`)
|
|
310
|
+
.all(entityId);
|
|
311
|
+
const incomingRelations = incomingRows.map((row) => ({
|
|
312
|
+
...rowToRelation(row),
|
|
313
|
+
sourceEntity: rowToEntity({
|
|
314
|
+
id: row.se_id,
|
|
315
|
+
name: row.se_name,
|
|
316
|
+
entity_type: row.se_type,
|
|
317
|
+
description: row.se_desc,
|
|
318
|
+
created_at: row.se_created,
|
|
319
|
+
updated_at: row.se_updated,
|
|
320
|
+
metadata_json: row.se_meta,
|
|
321
|
+
}),
|
|
322
|
+
}));
|
|
323
|
+
const linkedNoteRows = this.db
|
|
324
|
+
.prepare(`
|
|
325
|
+
SELECT l.entity_id, l.note_id, n.file_path, n.title, n.created_at
|
|
326
|
+
FROM entity_note_links l
|
|
327
|
+
JOIN knowledge_notes n ON n.id = l.note_id
|
|
328
|
+
WHERE l.entity_id = ?
|
|
329
|
+
`)
|
|
330
|
+
.all(entityId);
|
|
331
|
+
const linkedNotes = linkedNoteRows.map((row) => ({
|
|
332
|
+
entityId: row.entity_id,
|
|
333
|
+
noteId: row.note_id,
|
|
334
|
+
note: {
|
|
335
|
+
filePath: row.file_path,
|
|
336
|
+
title: row.title,
|
|
337
|
+
createdAt: row.created_at,
|
|
338
|
+
},
|
|
339
|
+
}));
|
|
340
|
+
return {
|
|
341
|
+
...entity,
|
|
342
|
+
observations,
|
|
343
|
+
outgoingRelations,
|
|
344
|
+
incomingRelations,
|
|
345
|
+
linkedNotes,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* 幅優先探索でhops内の関連エンティティを取得。
|
|
350
|
+
* 循環グラフ対策: visitedセットで重複訪問を防ぐ。maxHops上限は3。
|
|
351
|
+
*/
|
|
352
|
+
findRelatedEntities(entityId, maxHops = 1) {
|
|
353
|
+
const safeMaxHops = Math.min(maxHops, 3);
|
|
354
|
+
const visited = new Set([entityId]);
|
|
355
|
+
const result = [];
|
|
356
|
+
let frontier = [entityId];
|
|
357
|
+
for (let hop = 1; hop <= safeMaxHops; hop++) {
|
|
358
|
+
if (frontier.length === 0)
|
|
359
|
+
break;
|
|
360
|
+
const placeholders = frontier.map(() => "?").join(",");
|
|
361
|
+
const nextIds = [];
|
|
362
|
+
const rows = this.db
|
|
363
|
+
.prepare(`
|
|
364
|
+
SELECT DISTINCT
|
|
365
|
+
CASE WHEN r.from_entity_id IN (${placeholders}) THEN r.to_entity_id
|
|
366
|
+
ELSE r.from_entity_id END as neighbor_id
|
|
367
|
+
FROM active_relations r
|
|
368
|
+
WHERE r.from_entity_id IN (${placeholders}) OR r.to_entity_id IN (${placeholders})
|
|
369
|
+
`)
|
|
370
|
+
.all(...frontier, ...frontier, ...frontier);
|
|
371
|
+
for (const { neighbor_id } of rows) {
|
|
372
|
+
if (visited.has(neighbor_id))
|
|
373
|
+
continue;
|
|
374
|
+
visited.add(neighbor_id);
|
|
375
|
+
nextIds.push(neighbor_id);
|
|
376
|
+
const entity = this.getEntityById(neighbor_id);
|
|
377
|
+
if (entity) {
|
|
378
|
+
result.push({ ...entity, hops: hop });
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
frontier = nextIds;
|
|
382
|
+
}
|
|
383
|
+
return result;
|
|
384
|
+
}
|
|
385
|
+
// ── Stats ─────────────────────────────────────────────────────
|
|
386
|
+
getGraphStats() {
|
|
387
|
+
const totalEntities = this.db.prepare("SELECT COUNT(*) as count FROM entities").get().count;
|
|
388
|
+
const totalRelations = this.db.prepare("SELECT COUNT(*) as count FROM active_relations").get().count;
|
|
389
|
+
const totalObservations = this.db.prepare("SELECT COUNT(*) as count FROM active_observations").get().count;
|
|
390
|
+
const entityTypeRows = this.db
|
|
391
|
+
.prepare("SELECT entity_type, COUNT(*) as count FROM entities GROUP BY entity_type")
|
|
392
|
+
.all();
|
|
393
|
+
const entitiesByType = {};
|
|
394
|
+
for (const row of entityTypeRows) {
|
|
395
|
+
entitiesByType[row.entity_type] = row.count;
|
|
396
|
+
}
|
|
397
|
+
const relationTypeRows = this.db
|
|
398
|
+
.prepare("SELECT relation_type, COUNT(*) as count FROM active_relations GROUP BY relation_type")
|
|
399
|
+
.all();
|
|
400
|
+
const relationsByType = {};
|
|
401
|
+
for (const row of relationTypeRows) {
|
|
402
|
+
relationsByType[row.relation_type] = row.count;
|
|
403
|
+
}
|
|
404
|
+
return { totalEntities, totalRelations, totalObservations, entitiesByType, relationsByType };
|
|
405
|
+
}
|
|
406
|
+
// ── Bi-temporal Operations ────────────────────────────────────
|
|
407
|
+
invalidateRelation(id, validTo) {
|
|
408
|
+
try {
|
|
409
|
+
const info = this.db
|
|
410
|
+
.prepare(`UPDATE relations SET valid_to = COALESCE(?, datetime('now')) WHERE id = ? AND valid_to IS NULL`)
|
|
411
|
+
.run(validTo ?? null, id);
|
|
412
|
+
return info.changes > 0;
|
|
413
|
+
}
|
|
414
|
+
catch (error) {
|
|
415
|
+
throw new DatabaseError("invalidateRelation", error, { id });
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
invalidateObservation(id, validTo) {
|
|
419
|
+
try {
|
|
420
|
+
const info = this.db
|
|
421
|
+
.prepare(`UPDATE observations SET valid_to = COALESCE(?, datetime('now')) WHERE id = ? AND valid_to IS NULL`)
|
|
422
|
+
.run(validTo ?? null, id);
|
|
423
|
+
return info.changes > 0;
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
throw new DatabaseError("invalidateObservation", error, { id });
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
getRelationHistory(fromEntityId, toEntityId) {
|
|
430
|
+
const rows = this.db
|
|
431
|
+
.prepare(`SELECT * FROM relations WHERE from_entity_id = ? AND to_entity_id = ? ORDER BY recorded_at DESC`)
|
|
432
|
+
.all(fromEntityId, toEntityId);
|
|
433
|
+
return rows.map((row) => ({
|
|
434
|
+
...rowToRelation(row),
|
|
435
|
+
validFrom: row.valid_from,
|
|
436
|
+
validTo: row.valid_to,
|
|
437
|
+
recordedAt: row.recorded_at,
|
|
438
|
+
supersededAt: row.superseded_at,
|
|
439
|
+
}));
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
//# sourceMappingURL=graph-repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-repository.js","sourceRoot":"","sources":["../../src/graph/graph-repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { RelationType, EntityType } from "../types.js";
|
|
2
|
+
export interface InferredRelation {
|
|
3
|
+
fromName: string;
|
|
4
|
+
fromType: EntityType;
|
|
5
|
+
toName: string;
|
|
6
|
+
toType: EntityType;
|
|
7
|
+
relationType: RelationType;
|
|
8
|
+
strength: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class RelationInferrer {
|
|
11
|
+
/**
|
|
12
|
+
* 同一ノート内のエンティティ群から関係を推論する。
|
|
13
|
+
*
|
|
14
|
+
* @param entities - ノートから抽出されたエンティティ(name + entityType)
|
|
15
|
+
* @param frontmatter - フロントマターデータ
|
|
16
|
+
*/
|
|
17
|
+
infer(entities: Array<{
|
|
18
|
+
name: string;
|
|
19
|
+
entityType: EntityType;
|
|
20
|
+
}>, frontmatter?: Record<string, unknown>): InferredRelation[];
|
|
21
|
+
private deduplicate;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=relation-inferrer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation-inferrer.d.ts","sourceRoot":"","sources":["../../src/graph/relation-inferrer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE5D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,UAAU,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,UAAU,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,gBAAgB;IAC3B;;;;;OAKG;IACH,KAAK,CACH,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,UAAU,CAAA;KAAE,CAAC,EACzD,WAAW,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACxC,gBAAgB,EAAE;IAgFrB,OAAO,CAAC,WAAW;CAWpB"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export class RelationInferrer {
|
|
2
|
+
/**
|
|
3
|
+
* 同一ノート内のエンティティ群から関係を推論する。
|
|
4
|
+
*
|
|
5
|
+
* @param entities - ノートから抽出されたエンティティ(name + entityType)
|
|
6
|
+
* @param frontmatter - フロントマターデータ
|
|
7
|
+
*/
|
|
8
|
+
infer(entities, frontmatter = {}) {
|
|
9
|
+
const results = [];
|
|
10
|
+
const persons = entities.filter((e) => e.entityType === "person");
|
|
11
|
+
const projects = entities.filter((e) => e.entityType === "project");
|
|
12
|
+
const technologies = entities.filter((e) => e.entityType === "technology" || e.entityType === "tool");
|
|
13
|
+
// author → project: created_by
|
|
14
|
+
const author = frontmatter["author"];
|
|
15
|
+
const projectName = frontmatter["project"];
|
|
16
|
+
if (typeof author === "string" &&
|
|
17
|
+
author.trim() &&
|
|
18
|
+
typeof projectName === "string" &&
|
|
19
|
+
projectName.trim()) {
|
|
20
|
+
results.push({
|
|
21
|
+
fromName: author.trim().toLowerCase(),
|
|
22
|
+
fromType: "person",
|
|
23
|
+
toName: projectName.trim().toLowerCase(),
|
|
24
|
+
toType: "project",
|
|
25
|
+
relationType: "created_by",
|
|
26
|
+
strength: 0.9,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
// person → project: works_on (from frontmatter project field)
|
|
30
|
+
if (typeof projectName === "string" && projectName.trim()) {
|
|
31
|
+
for (const person of persons) {
|
|
32
|
+
if (person.name !== author?.toString().toLowerCase()) {
|
|
33
|
+
results.push({
|
|
34
|
+
fromName: person.name,
|
|
35
|
+
fromType: "person",
|
|
36
|
+
toName: projectName.trim().toLowerCase(),
|
|
37
|
+
toType: "project",
|
|
38
|
+
relationType: "works_on",
|
|
39
|
+
strength: 0.7,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// import → depends_on: technology depends on other technology
|
|
45
|
+
// (This is simplified: if note has multiple imports, they co-occur in same context)
|
|
46
|
+
// technology → project: uses (project uses technology when co-occurring)
|
|
47
|
+
for (const project of projects) {
|
|
48
|
+
for (const tech of technologies) {
|
|
49
|
+
results.push({
|
|
50
|
+
fromName: project.name,
|
|
51
|
+
fromType: "project",
|
|
52
|
+
toName: tech.name,
|
|
53
|
+
toType: tech.entityType,
|
|
54
|
+
relationType: "uses",
|
|
55
|
+
strength: 0.5,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// technology depends_on: inferred from import patterns (same note)
|
|
60
|
+
// Only if there are multiple technologies
|
|
61
|
+
if (technologies.length >= 2) {
|
|
62
|
+
for (let i = 0; i < technologies.length; i++) {
|
|
63
|
+
for (let j = i + 1; j < technologies.length; j++) {
|
|
64
|
+
results.push({
|
|
65
|
+
fromName: technologies[i].name,
|
|
66
|
+
fromType: technologies[i].entityType,
|
|
67
|
+
toName: technologies[j].name,
|
|
68
|
+
toType: technologies[j].entityType,
|
|
69
|
+
relationType: "related_to",
|
|
70
|
+
strength: 0.3,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return this.deduplicate(results);
|
|
76
|
+
}
|
|
77
|
+
deduplicate(relations) {
|
|
78
|
+
const seen = new Map();
|
|
79
|
+
for (const r of relations) {
|
|
80
|
+
const key = `${r.fromName}:${r.fromType}→${r.toName}:${r.toType}:${r.relationType}`;
|
|
81
|
+
const existing = seen.get(key);
|
|
82
|
+
if (!existing || r.strength > existing.strength) {
|
|
83
|
+
seen.set(key, r);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return Array.from(seen.values());
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=relation-inferrer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation-inferrer.js","sourceRoot":"","sources":["../../src/graph/relation-inferrer.ts"],"names":[],"mappings":"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"}
|