claude-brain 0.30.2 → 0.30.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +241 -191
- package/VERSION +1 -1
- package/assets/CLAUDE-unified.md +11 -11
- package/assets/CLAUDE.md +29 -29
- package/package.json +7 -3
- package/packs/backend/node.json +173 -173
- package/packs/core/javascript.json +176 -176
- package/packs/core/typescript.json +222 -222
- package/packs/frontend/react.json +254 -254
- package/packs/meta/testing.json +172 -172
- package/scripts/postinstall.mjs +531 -531
- package/src/automation/decision-detector.ts +452 -452
- package/src/automation/phase12-manager.ts +456 -456
- package/src/automation/proactive-recall.ts +373 -373
- package/src/automation/project-detector.ts +310 -310
- package/src/automation/repo-scanner.ts +210 -205
- package/src/cli/auto-setup.ts +75 -75
- package/src/cli/auto-start.ts +266 -266
- package/src/cli/bin.ts +264 -264
- package/src/cli/commands/autostart.ts +90 -90
- package/src/cli/commands/chroma.ts +578 -577
- package/src/cli/commands/export-training.ts +70 -70
- package/src/cli/commands/export.ts +130 -130
- package/src/cli/commands/git-hook.ts +183 -183
- package/src/cli/commands/hooks.ts +217 -217
- package/src/cli/commands/init.ts +123 -123
- package/src/cli/commands/install-mcp.ts +122 -111
- package/src/cli/commands/models.ts +979 -979
- package/src/cli/commands/pack.ts +200 -200
- package/src/cli/commands/refresh.ts +344 -339
- package/src/cli/commands/reindex.ts +120 -120
- package/src/cli/commands/serve.ts +466 -463
- package/src/cli/commands/start.ts +44 -44
- package/src/cli/commands/status.ts +220 -203
- package/src/cli/commands/uninstall-mcp.ts +45 -41
- package/src/cli/commands/update.ts +130 -124
- package/src/cli/migrate-chroma.ts +106 -106
- package/src/cli/ui/animations.ts +80 -80
- package/src/cli/ui/components.ts +82 -82
- package/src/cli/ui/index.ts +4 -4
- package/src/cli/ui/logo.ts +36 -36
- package/src/cli/ui/theme.ts +55 -55
- package/src/code-intelligence/indexer.ts +352 -352
- package/src/code-intelligence/linker.ts +178 -178
- package/src/code-intelligence/parser.ts +484 -484
- package/src/code-intelligence/query.ts +291 -291
- package/src/code-intelligence/schema.ts +83 -83
- package/src/code-intelligence/types.ts +95 -95
- package/src/config/defaults.ts +52 -52
- package/src/config/home.ts +56 -56
- package/src/config/index.ts +5 -5
- package/src/config/loader.ts +192 -192
- package/src/config/schema.ts +446 -415
- package/src/config/validator.ts +182 -182
- package/src/context/assembler.ts +407 -400
- package/src/context/index.ts +79 -79
- package/src/context/progress-tracker.ts +174 -174
- package/src/context/standards-manager.ts +287 -287
- package/src/context/validator.ts +58 -58
- package/src/diagnostics/index.ts +122 -121
- package/src/health/index.ts +233 -232
- package/src/hooks/brain-hook.ts +134 -131
- package/src/hooks/capture.ts +168 -168
- package/src/hooks/claude-code-mastery.md +112 -112
- package/src/hooks/context-hook.ts +260 -245
- package/src/hooks/deduplicator.ts +72 -72
- package/src/hooks/git-capture.ts +109 -109
- package/src/hooks/git-hook-installer.ts +211 -207
- package/src/hooks/index.ts +20 -20
- package/src/hooks/installer.ts +306 -288
- package/src/hooks/interceptor-hook.ts +204 -201
- package/src/hooks/passive-classifier.ts +397 -397
- package/src/hooks/queue.ts +160 -129
- package/src/hooks/session-tracker.ts +312 -312
- package/src/hooks/types.ts +52 -52
- package/src/index.ts +7 -7
- package/src/intelligence/cross-project/generalizer.ts +283 -283
- package/src/intelligence/cross-project/index.ts +7 -7
- package/src/intelligence/hf-downloader.ts +222 -222
- package/src/intelligence/hf-manifest.json +78 -78
- package/src/intelligence/index.ts +24 -24
- package/src/intelligence/inference-router.ts +762 -762
- package/src/intelligence/model-manager.ts +263 -245
- package/src/intelligence/optimization/index.ts +10 -10
- package/src/intelligence/optimization/precompute.ts +202 -202
- package/src/intelligence/optimization/semantic-cache.ts +213 -207
- package/src/intelligence/prediction/index.ts +7 -7
- package/src/intelligence/prediction/recommender.ts +276 -268
- package/src/intelligence/reasoning/chain-retrieval.ts +243 -247
- package/src/intelligence/reasoning/index.ts +7 -7
- package/src/intelligence/temporal/evolution.ts +193 -197
- package/src/intelligence/temporal/index.ts +16 -16
- package/src/intelligence/temporal/query-processor.ts +190 -190
- package/src/intelligence/temporal/timeline.ts +272 -259
- package/src/intelligence/temporal/trends.ts +263 -263
- package/src/intelligence/tokenizer.ts +118 -118
- package/src/knowledge/entity-extractor.ts +447 -443
- package/src/knowledge/graph/builder.ts +185 -185
- package/src/knowledge/graph/linker.ts +201 -201
- package/src/knowledge/graph/memory-graph.ts +359 -359
- package/src/knowledge/graph/schema.ts +99 -99
- package/src/knowledge/graph/search.ts +166 -166
- package/src/knowledge/relationship-extractor.ts +108 -108
- package/src/memory/chroma/client.ts +211 -192
- package/src/memory/chroma/collection-manager.ts +92 -92
- package/src/memory/chroma/config.ts +57 -57
- package/src/memory/chroma/embeddings.ts +177 -175
- package/src/memory/chroma/index.ts +82 -82
- package/src/memory/chroma/migration.ts +270 -270
- package/src/memory/chroma/schemas.ts +69 -69
- package/src/memory/chroma/search.ts +319 -315
- package/src/memory/chroma/store.ts +755 -747
- package/src/memory/compression.ts +121 -121
- package/src/memory/consolidation/archiver.ts +162 -165
- package/src/memory/consolidation/merger.ts +182 -186
- package/src/memory/consolidation/scorer.ts +136 -136
- package/src/memory/database.ts +9 -0
- package/src/memory/dual-write.ts +145 -0
- package/src/memory/embeddings.ts +226 -226
- package/src/memory/episodic/detector.ts +108 -108
- package/src/memory/episodic/manager.ts +347 -351
- package/src/memory/episodic/summarizer.ts +179 -179
- package/src/memory/episodic/types.ts +52 -52
- package/src/memory/fts5-search.ts +692 -633
- package/src/memory/index.ts +943 -1060
- package/src/memory/migrations/add-fts5.ts +118 -108
- package/src/memory/patterns.ts +438 -438
- package/src/memory/pruning.ts +60 -60
- package/src/memory/schema.ts +88 -88
- package/src/memory/store.ts +911 -787
- package/src/orchestrator/handlers/decision-handler.ts +204 -204
- package/src/packs/index.ts +9 -9
- package/src/packs/loader.ts +134 -134
- package/src/packs/manager.ts +204 -204
- package/src/packs/ranker.ts +78 -78
- package/src/packs/types.ts +81 -81
- package/src/phase12/index.ts +5 -5
- package/src/retrieval/bm25/index.ts +300 -297
- package/src/retrieval/bm25/tokenizer.ts +184 -184
- package/src/retrieval/feedback/adaptive.ts +221 -221
- package/src/retrieval/feedback/index.ts +16 -16
- package/src/retrieval/feedback/metrics.ts +221 -221
- package/src/retrieval/feedback/store.ts +283 -283
- package/src/retrieval/fusion/index.ts +194 -194
- package/src/retrieval/fusion/rrf.ts +165 -165
- package/src/retrieval/index.ts +12 -12
- package/src/retrieval/pipeline.ts +375 -375
- package/src/retrieval/query/expander.ts +203 -203
- package/src/retrieval/query/index.ts +27 -27
- package/src/retrieval/query/intent-classifier.ts +252 -252
- package/src/retrieval/query/temporal-parser.ts +295 -295
- package/src/retrieval/reranker/index.ts +189 -188
- package/src/retrieval/reranker/model.ts +99 -95
- package/src/retrieval/service.ts +125 -125
- package/src/retrieval/types.ts +162 -162
- package/src/routing/entity-extractor.ts +454 -454
- package/src/routing/handlers/exploration-handler.ts +369 -0
- package/src/routing/handlers/index.ts +19 -0
- package/src/routing/handlers/memory-handler.ts +273 -0
- package/src/routing/handlers/mutation-handler.ts +241 -0
- package/src/routing/handlers/recall-handler.ts +642 -0
- package/src/routing/handlers/shared.ts +515 -0
- package/src/routing/handlers/types.ts +48 -0
- package/src/routing/intent-classifier.ts +552 -552
- package/src/routing/response-filter.ts +399 -391
- package/src/routing/router.ts +245 -2193
- package/src/routing/search-engine.ts +521 -514
- package/src/routing/types.ts +104 -94
- package/src/scripts/health-check.ts +118 -118
- package/src/scripts/setup.ts +122 -122
- package/src/server/auto-updater.ts +283 -276
- package/src/server/handlers/call-tool.ts +159 -159
- package/src/server/handlers/list-tools.ts +35 -35
- package/src/server/handlers/tools/auto-remember.ts +165 -165
- package/src/server/handlers/tools/brain.ts +86 -86
- package/src/server/handlers/tools/create-project.ts +135 -135
- package/src/server/handlers/tools/get-code-standards.ts +123 -123
- package/src/server/handlers/tools/get-corrections.ts +152 -152
- package/src/server/handlers/tools/get-patterns.ts +156 -156
- package/src/server/handlers/tools/get-project-context.ts +75 -75
- package/src/server/handlers/tools/index.ts +30 -30
- package/src/server/handlers/tools/init-project.ts +756 -756
- package/src/server/handlers/tools/list-projects.ts +126 -126
- package/src/server/handlers/tools/recall-similar.ts +87 -87
- package/src/server/handlers/tools/recognize-pattern.ts +132 -132
- package/src/server/handlers/tools/record-correction.ts +131 -131
- package/src/server/handlers/tools/remember-decision.ts +168 -168
- package/src/server/handlers/tools/schemas.ts +179 -179
- package/src/server/handlers/tools/search-code.ts +122 -122
- package/src/server/handlers/tools/smart-context.ts +146 -146
- package/src/server/handlers/tools/update-progress.ts +131 -131
- package/src/server/http-api.ts +215 -1229
- package/src/server/mcp-proxy.ts +85 -84
- package/src/server/mcp-server.ts +285 -284
- package/src/server/middleware/auth.ts +39 -0
- package/src/server/middleware/error-handler.ts +37 -0
- package/src/server/middleware/rate-limit.ts +53 -0
- package/src/server/middleware/validate.ts +42 -0
- package/src/server/pid-manager.ts +137 -136
- package/src/server/providers/resources.ts +581 -581
- package/src/server/routes/code.ts +228 -0
- package/src/server/routes/context.ts +26 -0
- package/src/server/routes/health.ts +19 -0
- package/src/server/routes/helpers.ts +100 -0
- package/src/server/routes/hooks.ts +197 -0
- package/src/server/routes/mcp.ts +47 -0
- package/src/server/routes/memory.ts +397 -0
- package/src/server/routes/models.ts +96 -0
- package/src/server/routes/projects.ts +89 -0
- package/src/server/routes/types.ts +21 -0
- package/src/server/schemas/api-schemas.ts +202 -0
- package/src/server/services.ts +720 -720
- package/src/server/utils/memory-indicator.ts +84 -84
- package/src/server/utils/response-formatter.ts +129 -129
- package/src/server/web-viewer.ts +1145 -1115
- package/src/setup/index.ts +38 -38
- package/src/tools/registry.ts +115 -115
- package/src/tools/schemas.ts +666 -666
- package/src/tools/types.ts +412 -412
- package/src/training/data-store.ts +320 -298
- package/src/training/retrain-pipeline.ts +399 -394
- package/src/utils/error-handler.ts +136 -136
- package/src/utils/index.ts +58 -58
- package/src/utils/kill-port.ts +55 -53
- package/src/utils/phase12-helper.ts +56 -56
- package/src/utils/safe-path.ts +43 -0
- package/src/utils/timing.ts +47 -47
- package/src/utils/transaction.ts +63 -63
- package/src/vault/index.ts +4 -3
- package/src/vault/paths.ts +106 -106
- package/src/vault/query.ts +4 -1
- package/src/vault/reader.ts +44 -1
- package/src/vault/watcher.ts +24 -1
- package/src/vault/writer.ts +487 -413
- package/skills/persistent-memory/SKILL.md +0 -148
- package/skills/persistent-memory/references/tool-reference.md +0 -90
|
@@ -1,185 +1,185 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Knowledge Graph Builder
|
|
3
|
-
* Auto-populates the graph when decisions/patterns/corrections are stored
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { Logger } from 'pino'
|
|
7
|
-
import type { InMemoryKnowledgeGraph } from './memory-graph'
|
|
8
|
-
import { EntityExtractor } from '../entity-extractor'
|
|
9
|
-
import { RelationshipExtractor } from '../relationship-extractor'
|
|
10
|
-
import type { StoreDecisionInput } from '../../memory/chroma/store'
|
|
11
|
-
import type { CollectionManager } from '../../memory/chroma/collection-manager'
|
|
12
|
-
|
|
13
|
-
export class KnowledgeGraphBuilder {
|
|
14
|
-
private graph: InMemoryKnowledgeGraph
|
|
15
|
-
private entityExtractor: EntityExtractor
|
|
16
|
-
private relationshipExtractor: RelationshipExtractor
|
|
17
|
-
private logger: Logger
|
|
18
|
-
|
|
19
|
-
constructor(graph: InMemoryKnowledgeGraph, logger: Logger) {
|
|
20
|
-
this.graph = graph
|
|
21
|
-
this.entityExtractor = new EntityExtractor()
|
|
22
|
-
this.relationshipExtractor = new RelationshipExtractor()
|
|
23
|
-
this.logger = logger.child({ component: 'graph-builder' })
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async initialize(): Promise<void> {
|
|
27
|
-
await this.entityExtractor.initialize()
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Remove a decision node and its edges from the knowledge graph by decision ID.
|
|
32
|
-
* Used when a decision is deleted from the store.
|
|
33
|
-
*/
|
|
34
|
-
removeDecision(decisionId: string): void {
|
|
35
|
-
try {
|
|
36
|
-
const nodes = this.graph.findNodes({
|
|
37
|
-
type: 'decision',
|
|
38
|
-
properties: { decision_id: decisionId }
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
for (const node of nodes) {
|
|
42
|
-
this.graph.deleteNode(node.id)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (nodes.length > 0) {
|
|
46
|
-
this.logger.debug({ decisionId, nodesRemoved: nodes.length }, 'Decision removed from knowledge graph')
|
|
47
|
-
}
|
|
48
|
-
} catch (error) {
|
|
49
|
-
this.logger.error({ error, decisionId }, 'Failed to remove decision from graph')
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
processDecision(input: StoreDecisionInput & { id: string }): void {
|
|
54
|
-
try {
|
|
55
|
-
// Dedup guard: remove existing node with same decision_id before re-creating
|
|
56
|
-
this.removeDecision(input.id)
|
|
57
|
-
|
|
58
|
-
const fullText = `${input.decision} ${input.context} ${input.reasoning}`
|
|
59
|
-
const entities = this.entityExtractor.extract(fullText)
|
|
60
|
-
const relationships = this.relationshipExtractor.extract(fullText, entities)
|
|
61
|
-
|
|
62
|
-
// Create decision node
|
|
63
|
-
const decisionNode = this.graph.addNode({
|
|
64
|
-
name: input.decision.slice(0, 100),
|
|
65
|
-
type: 'decision',
|
|
66
|
-
properties: {
|
|
67
|
-
decision_id: input.id,
|
|
68
|
-
project: input.project,
|
|
69
|
-
context: input.context,
|
|
70
|
-
reasoning: input.reasoning,
|
|
71
|
-
full_decision: input.decision
|
|
72
|
-
}
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
// Create project node if it doesn't exist
|
|
76
|
-
let projectNode = this.graph.findNodeByName(input.project, 'project')
|
|
77
|
-
if (!projectNode) {
|
|
78
|
-
projectNode = this.graph.addNode({
|
|
79
|
-
name: input.project,
|
|
80
|
-
type: 'project',
|
|
81
|
-
properties: {}
|
|
82
|
-
})
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Link decision to project
|
|
86
|
-
this.graph.addEdge({
|
|
87
|
-
source: decisionNode.id,
|
|
88
|
-
target: projectNode.id,
|
|
89
|
-
relationship: 'decided_in',
|
|
90
|
-
weight: 1.0,
|
|
91
|
-
properties: {}
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
// Create entity nodes and link to decision
|
|
95
|
-
const entityNodeMap = new Map<string, string>() // normalizedName → nodeId
|
|
96
|
-
for (const entity of entities) {
|
|
97
|
-
let entityNode = this.graph.findNodeByName(entity.normalizedName, entity.type)
|
|
98
|
-
if (!entityNode) {
|
|
99
|
-
entityNode = this.graph.addNode({
|
|
100
|
-
name: entity.normalizedName,
|
|
101
|
-
type: entity.type,
|
|
102
|
-
properties: {
|
|
103
|
-
confidence: entity.confidence,
|
|
104
|
-
source: entity.source
|
|
105
|
-
}
|
|
106
|
-
})
|
|
107
|
-
}
|
|
108
|
-
entityNodeMap.set(entity.normalizedName, entityNode.id)
|
|
109
|
-
|
|
110
|
-
// Link decision to entity
|
|
111
|
-
this.graph.addEdge({
|
|
112
|
-
source: decisionNode.id,
|
|
113
|
-
target: entityNode.id,
|
|
114
|
-
relationship: 'relates_to',
|
|
115
|
-
weight: entity.confidence,
|
|
116
|
-
properties: {}
|
|
117
|
-
})
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Create relationship edges between entities
|
|
121
|
-
for (const rel of relationships) {
|
|
122
|
-
const sourceId = entityNodeMap.get(rel.sourceEntity)
|
|
123
|
-
const targetId = entityNodeMap.get(rel.targetEntity)
|
|
124
|
-
|
|
125
|
-
if (sourceId && targetId) {
|
|
126
|
-
this.graph.addEdge({
|
|
127
|
-
source: sourceId,
|
|
128
|
-
target: targetId,
|
|
129
|
-
relationship: rel.relationship,
|
|
130
|
-
weight: rel.confidence,
|
|
131
|
-
properties: { evidence: rel.evidence }
|
|
132
|
-
})
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
this.logger.debug({
|
|
137
|
-
decisionId: input.id,
|
|
138
|
-
entities: entities.length,
|
|
139
|
-
relationships: relationships.length
|
|
140
|
-
}, 'Decision processed into knowledge graph')
|
|
141
|
-
} catch (error) {
|
|
142
|
-
this.logger.error({ error, decisionId: input.id }, 'Failed to process decision into graph')
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
async migrateExistingDecisions(collections: CollectionManager): Promise<{ processed: number; errors: number }> {
|
|
147
|
-
let processed = 0
|
|
148
|
-
let errors = 0
|
|
149
|
-
|
|
150
|
-
try {
|
|
151
|
-
const collection = await collections.getDecisions()
|
|
152
|
-
const result = await collection.get({
|
|
153
|
-
include: ['documents', 'metadatas']
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
for (let i = 0; i < result.ids.length; i++) {
|
|
157
|
-
try {
|
|
158
|
-
const id = result.ids[i]!
|
|
159
|
-
const document = result.documents?.[i] as string
|
|
160
|
-
const metadata = result.metadatas?.[i] as Record<string, any>
|
|
161
|
-
|
|
162
|
-
if (!document || !metadata) continue
|
|
163
|
-
|
|
164
|
-
this.processDecision({
|
|
165
|
-
id,
|
|
166
|
-
project: metadata.project || 'unknown',
|
|
167
|
-
context: metadata.context || '',
|
|
168
|
-
decision: document,
|
|
169
|
-
reasoning: metadata.reasoning || ''
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
processed++
|
|
173
|
-
} catch {
|
|
174
|
-
errors++
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
this.logger.info({ processed, errors }, 'Migration of existing decisions complete')
|
|
179
|
-
} catch (error) {
|
|
180
|
-
this.logger.error({ error }, 'Failed to migrate existing decisions')
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return { processed, errors }
|
|
184
|
-
}
|
|
185
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge Graph Builder
|
|
3
|
+
* Auto-populates the graph when decisions/patterns/corrections are stored
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Logger } from 'pino'
|
|
7
|
+
import type { InMemoryKnowledgeGraph } from './memory-graph'
|
|
8
|
+
import { EntityExtractor } from '../entity-extractor'
|
|
9
|
+
import { RelationshipExtractor } from '../relationship-extractor'
|
|
10
|
+
import type { StoreDecisionInput } from '../../memory/chroma/store'
|
|
11
|
+
import type { CollectionManager } from '../../memory/chroma/collection-manager'
|
|
12
|
+
|
|
13
|
+
export class KnowledgeGraphBuilder {
|
|
14
|
+
private graph: InMemoryKnowledgeGraph
|
|
15
|
+
private entityExtractor: EntityExtractor
|
|
16
|
+
private relationshipExtractor: RelationshipExtractor
|
|
17
|
+
private logger: Logger
|
|
18
|
+
|
|
19
|
+
constructor(graph: InMemoryKnowledgeGraph, logger: Logger) {
|
|
20
|
+
this.graph = graph
|
|
21
|
+
this.entityExtractor = new EntityExtractor()
|
|
22
|
+
this.relationshipExtractor = new RelationshipExtractor()
|
|
23
|
+
this.logger = logger.child({ component: 'graph-builder' })
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async initialize(): Promise<void> {
|
|
27
|
+
await this.entityExtractor.initialize()
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Remove a decision node and its edges from the knowledge graph by decision ID.
|
|
32
|
+
* Used when a decision is deleted from the store.
|
|
33
|
+
*/
|
|
34
|
+
removeDecision(decisionId: string): void {
|
|
35
|
+
try {
|
|
36
|
+
const nodes = this.graph.findNodes({
|
|
37
|
+
type: 'decision',
|
|
38
|
+
properties: { decision_id: decisionId }
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
for (const node of nodes) {
|
|
42
|
+
this.graph.deleteNode(node.id)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (nodes.length > 0) {
|
|
46
|
+
this.logger.debug({ decisionId, nodesRemoved: nodes.length }, 'Decision removed from knowledge graph')
|
|
47
|
+
}
|
|
48
|
+
} catch (error) {
|
|
49
|
+
this.logger.error({ error, decisionId }, 'Failed to remove decision from graph')
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
processDecision(input: StoreDecisionInput & { id: string }): void {
|
|
54
|
+
try {
|
|
55
|
+
// Dedup guard: remove existing node with same decision_id before re-creating
|
|
56
|
+
this.removeDecision(input.id)
|
|
57
|
+
|
|
58
|
+
const fullText = `${input.decision} ${input.context} ${input.reasoning}`
|
|
59
|
+
const entities = this.entityExtractor.extract(fullText)
|
|
60
|
+
const relationships = this.relationshipExtractor.extract(fullText, entities)
|
|
61
|
+
|
|
62
|
+
// Create decision node
|
|
63
|
+
const decisionNode = this.graph.addNode({
|
|
64
|
+
name: input.decision.slice(0, 100),
|
|
65
|
+
type: 'decision',
|
|
66
|
+
properties: {
|
|
67
|
+
decision_id: input.id,
|
|
68
|
+
project: input.project,
|
|
69
|
+
context: input.context,
|
|
70
|
+
reasoning: input.reasoning,
|
|
71
|
+
full_decision: input.decision
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
// Create project node if it doesn't exist
|
|
76
|
+
let projectNode = this.graph.findNodeByName(input.project, 'project')
|
|
77
|
+
if (!projectNode) {
|
|
78
|
+
projectNode = this.graph.addNode({
|
|
79
|
+
name: input.project,
|
|
80
|
+
type: 'project',
|
|
81
|
+
properties: {}
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Link decision to project
|
|
86
|
+
this.graph.addEdge({
|
|
87
|
+
source: decisionNode.id,
|
|
88
|
+
target: projectNode.id,
|
|
89
|
+
relationship: 'decided_in',
|
|
90
|
+
weight: 1.0,
|
|
91
|
+
properties: {}
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
// Create entity nodes and link to decision
|
|
95
|
+
const entityNodeMap = new Map<string, string>() // normalizedName → nodeId
|
|
96
|
+
for (const entity of entities) {
|
|
97
|
+
let entityNode = this.graph.findNodeByName(entity.normalizedName, entity.type)
|
|
98
|
+
if (!entityNode) {
|
|
99
|
+
entityNode = this.graph.addNode({
|
|
100
|
+
name: entity.normalizedName,
|
|
101
|
+
type: entity.type,
|
|
102
|
+
properties: {
|
|
103
|
+
confidence: entity.confidence,
|
|
104
|
+
source: entity.source
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
entityNodeMap.set(entity.normalizedName, entityNode.id)
|
|
109
|
+
|
|
110
|
+
// Link decision to entity
|
|
111
|
+
this.graph.addEdge({
|
|
112
|
+
source: decisionNode.id,
|
|
113
|
+
target: entityNode.id,
|
|
114
|
+
relationship: 'relates_to',
|
|
115
|
+
weight: entity.confidence,
|
|
116
|
+
properties: {}
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Create relationship edges between entities
|
|
121
|
+
for (const rel of relationships) {
|
|
122
|
+
const sourceId = entityNodeMap.get(rel.sourceEntity)
|
|
123
|
+
const targetId = entityNodeMap.get(rel.targetEntity)
|
|
124
|
+
|
|
125
|
+
if (sourceId && targetId) {
|
|
126
|
+
this.graph.addEdge({
|
|
127
|
+
source: sourceId,
|
|
128
|
+
target: targetId,
|
|
129
|
+
relationship: rel.relationship,
|
|
130
|
+
weight: rel.confidence,
|
|
131
|
+
properties: { evidence: rel.evidence }
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
this.logger.debug({
|
|
137
|
+
decisionId: input.id,
|
|
138
|
+
entities: entities.length,
|
|
139
|
+
relationships: relationships.length
|
|
140
|
+
}, 'Decision processed into knowledge graph')
|
|
141
|
+
} catch (error) {
|
|
142
|
+
this.logger.error({ error, decisionId: input.id }, 'Failed to process decision into graph')
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async migrateExistingDecisions(collections: CollectionManager): Promise<{ processed: number; errors: number }> {
|
|
147
|
+
let processed = 0
|
|
148
|
+
let errors = 0
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
const collection = await collections.getDecisions()
|
|
152
|
+
const result = await collection.get({
|
|
153
|
+
include: ['documents', 'metadatas']
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
for (let i = 0; i < result.ids.length; i++) {
|
|
157
|
+
try {
|
|
158
|
+
const id = result.ids[i]!
|
|
159
|
+
const document = result.documents?.[i] as string
|
|
160
|
+
const metadata = result.metadatas?.[i] as Record<string, any>
|
|
161
|
+
|
|
162
|
+
if (!document || !metadata) continue
|
|
163
|
+
|
|
164
|
+
this.processDecision({
|
|
165
|
+
id,
|
|
166
|
+
project: metadata.project || 'unknown',
|
|
167
|
+
context: metadata.context || '',
|
|
168
|
+
decision: document,
|
|
169
|
+
reasoning: metadata.reasoning || ''
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
processed++
|
|
173
|
+
} catch {
|
|
174
|
+
errors++
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
this.logger.info({ processed, errors }, 'Migration of existing decisions complete')
|
|
179
|
+
} catch (error) {
|
|
180
|
+
this.logger.error({ error }, 'Failed to migrate existing decisions')
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return { processed, errors }
|
|
184
|
+
}
|
|
185
|
+
}
|