claude-brain 0.3.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/README.md +157 -0
- package/VERSION +1 -0
- package/assets/CLAUDE.md +307 -0
- package/bunfig.toml +8 -0
- package/package.json +74 -0
- package/src/automation/auto-context.ts +240 -0
- package/src/automation/decision-detector.ts +452 -0
- package/src/automation/index.ts +11 -0
- package/src/automation/proactive-recall.ts +373 -0
- package/src/automation/project-detector.ts +297 -0
- package/src/cli/auto-setup.ts +74 -0
- package/src/cli/bin.ts +110 -0
- package/src/cli/commands/install-mcp.ts +50 -0
- package/src/cli/commands/serve.ts +129 -0
- package/src/cli/diagnose.ts +4 -0
- package/src/cli/health-check.ts +4 -0
- package/src/cli/migrate-chroma.ts +106 -0
- package/src/cli/setup.ts +4 -0
- package/src/config/defaults.ts +47 -0
- package/src/config/home.ts +55 -0
- package/src/config/index.ts +7 -0
- package/src/config/loader.ts +166 -0
- package/src/config/migration.ts +76 -0
- package/src/config/schema.ts +257 -0
- package/src/config/validator.ts +184 -0
- package/src/config/watcher.ts +86 -0
- package/src/context/assembler.ts +398 -0
- package/src/context/cache-manager.ts +101 -0
- package/src/context/formatter.ts +84 -0
- package/src/context/hierarchy.ts +85 -0
- package/src/context/index.ts +83 -0
- package/src/context/progress-tracker.ts +174 -0
- package/src/context/standards-manager.ts +267 -0
- package/src/context/types.ts +252 -0
- package/src/context/validator.ts +58 -0
- package/src/cross-project/affinity.ts +162 -0
- package/src/cross-project/generalizer.ts +283 -0
- package/src/cross-project/index.ts +13 -0
- package/src/cross-project/transfer.ts +201 -0
- package/src/diagnostics/index.ts +123 -0
- package/src/health/index.ts +229 -0
- package/src/index.ts +7 -0
- package/src/knowledge/entity-extractor.ts +416 -0
- package/src/knowledge/graph/builder.ts +159 -0
- package/src/knowledge/graph/linker.ts +201 -0
- package/src/knowledge/graph/memory-graph.ts +359 -0
- package/src/knowledge/graph/schema.ts +99 -0
- package/src/knowledge/graph/search.ts +168 -0
- package/src/knowledge/relationship-extractor.ts +108 -0
- package/src/memory/chroma/client.ts +169 -0
- package/src/memory/chroma/collection-manager.ts +94 -0
- package/src/memory/chroma/config.ts +46 -0
- package/src/memory/chroma/embeddings.ts +153 -0
- package/src/memory/chroma/index.ts +82 -0
- package/src/memory/chroma/migration.ts +270 -0
- package/src/memory/chroma/schemas.ts +69 -0
- package/src/memory/chroma/search.ts +315 -0
- package/src/memory/chroma/store.ts +694 -0
- package/src/memory/consolidation/archiver.ts +164 -0
- package/src/memory/consolidation/merger.ts +186 -0
- package/src/memory/consolidation/scorer.ts +138 -0
- package/src/memory/context-builder.ts +236 -0
- package/src/memory/database.ts +169 -0
- package/src/memory/embedding-utils.ts +156 -0
- package/src/memory/embeddings.ts +226 -0
- package/src/memory/episodic/detector.ts +108 -0
- package/src/memory/episodic/manager.ts +334 -0
- package/src/memory/episodic/summarizer.ts +179 -0
- package/src/memory/episodic/types.ts +52 -0
- package/src/memory/index.ts +395 -0
- package/src/memory/knowledge-extractor.ts +455 -0
- package/src/memory/learning.ts +378 -0
- package/src/memory/patterns.ts +396 -0
- package/src/memory/schema.ts +56 -0
- package/src/memory/search.ts +309 -0
- package/src/memory/store.ts +344 -0
- package/src/memory/types.ts +121 -0
- package/src/optimization/index.ts +10 -0
- package/src/optimization/precompute.ts +202 -0
- package/src/optimization/semantic-cache.ts +207 -0
- package/src/orchestrator/coordinator.ts +272 -0
- package/src/orchestrator/decision-logger.ts +228 -0
- package/src/orchestrator/event-emitter.ts +198 -0
- package/src/orchestrator/event-queue.ts +184 -0
- package/src/orchestrator/handlers/base-handler.ts +70 -0
- package/src/orchestrator/handlers/context-handler.ts +73 -0
- package/src/orchestrator/handlers/decision-handler.ts +204 -0
- package/src/orchestrator/handlers/index.ts +10 -0
- package/src/orchestrator/handlers/status-handler.ts +131 -0
- package/src/orchestrator/handlers/task-handler.ts +171 -0
- package/src/orchestrator/index.ts +275 -0
- package/src/orchestrator/task-parser.ts +284 -0
- package/src/orchestrator/types.ts +98 -0
- package/src/phase12/index.ts +456 -0
- package/src/prediction/context-anticipator.ts +198 -0
- package/src/prediction/decision-predictor.ts +184 -0
- package/src/prediction/index.ts +13 -0
- package/src/prediction/recommender.ts +268 -0
- package/src/reasoning/chain-retrieval.ts +247 -0
- package/src/reasoning/counterfactual.ts +248 -0
- package/src/reasoning/index.ts +13 -0
- package/src/reasoning/synthesizer.ts +169 -0
- package/src/retrieval/bm25/index.ts +300 -0
- package/src/retrieval/bm25/tokenizer.ts +184 -0
- package/src/retrieval/feedback/adaptive.ts +223 -0
- package/src/retrieval/feedback/index.ts +16 -0
- package/src/retrieval/feedback/metrics.ts +223 -0
- package/src/retrieval/feedback/store.ts +283 -0
- package/src/retrieval/fusion/index.ts +194 -0
- package/src/retrieval/fusion/rrf.ts +163 -0
- package/src/retrieval/index.ts +12 -0
- package/src/retrieval/pipeline.ts +375 -0
- package/src/retrieval/query/expander.ts +198 -0
- package/src/retrieval/query/index.ts +27 -0
- package/src/retrieval/query/intent-classifier.ts +236 -0
- package/src/retrieval/query/temporal-parser.ts +295 -0
- package/src/retrieval/reranker/index.ts +188 -0
- package/src/retrieval/reranker/model.ts +95 -0
- package/src/retrieval/service.ts +125 -0
- package/src/retrieval/types.ts +162 -0
- package/src/scripts/health-check.ts +118 -0
- package/src/scripts/setup.ts +122 -0
- package/src/server/handlers/call-tool.ts +194 -0
- package/src/server/handlers/index.ts +9 -0
- package/src/server/handlers/list-tools.ts +18 -0
- package/src/server/handlers/tools/analyze-decision-evolution.ts +71 -0
- package/src/server/handlers/tools/auto-remember.ts +200 -0
- package/src/server/handlers/tools/create-project.ts +135 -0
- package/src/server/handlers/tools/detect-trends.ts +80 -0
- package/src/server/handlers/tools/find-cross-project-patterns.ts +73 -0
- package/src/server/handlers/tools/get-activity-log.ts +194 -0
- package/src/server/handlers/tools/get-code-standards.ts +124 -0
- package/src/server/handlers/tools/get-corrections.ts +154 -0
- package/src/server/handlers/tools/get-decision-timeline.ts +86 -0
- package/src/server/handlers/tools/get-episode.ts +93 -0
- package/src/server/handlers/tools/get-patterns.ts +158 -0
- package/src/server/handlers/tools/get-phase12-status.ts +63 -0
- package/src/server/handlers/tools/get-project-context.ts +75 -0
- package/src/server/handlers/tools/get-recommendations.ts +65 -0
- package/src/server/handlers/tools/index.ts +33 -0
- package/src/server/handlers/tools/init-project.ts +710 -0
- package/src/server/handlers/tools/list-episodes.ts +80 -0
- package/src/server/handlers/tools/list-projects.ts +125 -0
- package/src/server/handlers/tools/rate-memory.ts +95 -0
- package/src/server/handlers/tools/recall-similar.ts +87 -0
- package/src/server/handlers/tools/recognize-pattern.ts +126 -0
- package/src/server/handlers/tools/record-correction.ts +125 -0
- package/src/server/handlers/tools/remember-decision.ts +153 -0
- package/src/server/handlers/tools/schemas.ts +241 -0
- package/src/server/handlers/tools/search-knowledge-graph.ts +89 -0
- package/src/server/handlers/tools/smart-context.ts +124 -0
- package/src/server/handlers/tools/update-progress.ts +114 -0
- package/src/server/handlers/tools/what-if-analysis.ts +73 -0
- package/src/server/http-api.ts +474 -0
- package/src/server/index.ts +40 -0
- package/src/server/mcp-server.ts +283 -0
- package/src/server/providers/index.ts +7 -0
- package/src/server/providers/prompts.ts +327 -0
- package/src/server/providers/resources.ts +427 -0
- package/src/server/services.ts +388 -0
- package/src/server/types.ts +39 -0
- package/src/server/utils/error-handler.ts +155 -0
- package/src/server/utils/index.ts +13 -0
- package/src/server/utils/memory-indicator.ts +83 -0
- package/src/server/utils/request-context.ts +122 -0
- package/src/server/utils/response-formatter.ts +124 -0
- package/src/server/utils/validators.ts +210 -0
- package/src/setup/index.ts +22 -0
- package/src/setup/wizard.ts +321 -0
- package/src/temporal/evolution.ts +197 -0
- package/src/temporal/index.ts +16 -0
- package/src/temporal/query-processor.ts +190 -0
- package/src/temporal/timeline.ts +259 -0
- package/src/temporal/trends.ts +263 -0
- package/src/tools/index.ts +24 -0
- package/src/tools/registry.ts +106 -0
- package/src/tools/schemas.test.ts +30 -0
- package/src/tools/schemas.ts +907 -0
- package/src/tools/types.ts +412 -0
- package/src/utils/circuit-breaker.ts +130 -0
- package/src/utils/cleanup.ts +34 -0
- package/src/utils/error-handler.ts +132 -0
- package/src/utils/error-messages.ts +60 -0
- package/src/utils/fallback.ts +45 -0
- package/src/utils/index.ts +54 -0
- package/src/utils/logger-utils.ts +80 -0
- package/src/utils/logger.ts +88 -0
- package/src/utils/phase12-helper.ts +56 -0
- package/src/utils/retry.ts +94 -0
- package/src/utils/transaction.ts +63 -0
- package/src/vault/frontmatter.ts +264 -0
- package/src/vault/index.ts +318 -0
- package/src/vault/paths.ts +106 -0
- package/src/vault/query.ts +422 -0
- package/src/vault/reader.ts +264 -0
- package/src/vault/templates.ts +186 -0
- package/src/vault/types.ts +73 -0
- package/src/vault/watcher.ts +277 -0
- package/src/vault/writer.ts +393 -0
- package/tsconfig.json +30 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decision Predictor
|
|
3
|
+
* Predicts likely next decisions based on historical patterns
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Logger } from 'pino'
|
|
7
|
+
import type { CollectionManager } from '@/memory/chroma/collection-manager'
|
|
8
|
+
import type { EmbeddingProvider } from '@/memory/chroma/embeddings'
|
|
9
|
+
|
|
10
|
+
export interface PredictedDecision {
|
|
11
|
+
prediction: string
|
|
12
|
+
confidence: number
|
|
13
|
+
basedOn: Array<{
|
|
14
|
+
id: string
|
|
15
|
+
decision: string
|
|
16
|
+
similarity: number
|
|
17
|
+
}>
|
|
18
|
+
reasoning: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class DecisionPredictor {
|
|
22
|
+
private logger: Logger
|
|
23
|
+
private collections: CollectionManager
|
|
24
|
+
private embeddings?: EmbeddingProvider
|
|
25
|
+
|
|
26
|
+
constructor(logger: Logger, collections: CollectionManager, embeddings?: EmbeddingProvider) {
|
|
27
|
+
this.logger = logger.child({ component: 'decision-predictor' })
|
|
28
|
+
this.collections = collections
|
|
29
|
+
this.embeddings = embeddings
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Predict likely decisions for a given context
|
|
34
|
+
*/
|
|
35
|
+
async predict(context: string, options: {
|
|
36
|
+
project?: string
|
|
37
|
+
limit?: number
|
|
38
|
+
} = {}): Promise<PredictedDecision[]> {
|
|
39
|
+
const { project, limit = 5 } = options
|
|
40
|
+
|
|
41
|
+
// Find similar past contexts and their resulting decisions
|
|
42
|
+
const pastDecisions = await this.findSimilarContextDecisions(context, project, limit * 3)
|
|
43
|
+
|
|
44
|
+
if (pastDecisions.length === 0) {
|
|
45
|
+
return []
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Group by similar decisions
|
|
49
|
+
const grouped = this.groupSimilarDecisions(pastDecisions)
|
|
50
|
+
|
|
51
|
+
// Rank by frequency and similarity
|
|
52
|
+
const predictions = grouped
|
|
53
|
+
.map(group => this.buildPrediction(group, context))
|
|
54
|
+
.sort((a, b) => b.confidence - a.confidence)
|
|
55
|
+
.slice(0, limit)
|
|
56
|
+
|
|
57
|
+
return predictions
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private async findSimilarContextDecisions(
|
|
61
|
+
context: string,
|
|
62
|
+
project?: string,
|
|
63
|
+
limit: number = 15
|
|
64
|
+
): Promise<Array<{ id: string; decision: string; context: string; similarity: number }>> {
|
|
65
|
+
try {
|
|
66
|
+
const collection = await this.collections.getDecisions()
|
|
67
|
+
|
|
68
|
+
const where: any = project ? { project: { $eq: project } } : undefined
|
|
69
|
+
|
|
70
|
+
let results: any
|
|
71
|
+
|
|
72
|
+
if (this.embeddings) {
|
|
73
|
+
const embedding = await this.embeddings.generate(context)
|
|
74
|
+
results = await collection.query({
|
|
75
|
+
queryEmbeddings: [embedding],
|
|
76
|
+
nResults: limit,
|
|
77
|
+
where,
|
|
78
|
+
include: ['documents', 'metadatas', 'distances']
|
|
79
|
+
})
|
|
80
|
+
} else {
|
|
81
|
+
results = await collection.query({
|
|
82
|
+
queryTexts: [context],
|
|
83
|
+
nResults: limit,
|
|
84
|
+
where,
|
|
85
|
+
include: ['documents', 'metadatas', 'distances']
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!results.ids || !results.ids[0]) return []
|
|
90
|
+
|
|
91
|
+
const processed: Array<{ id: string; decision: string; context: string; similarity: number }> = []
|
|
92
|
+
const ids = results.ids[0]
|
|
93
|
+
const documents = results.documents?.[0] || []
|
|
94
|
+
const metadatas = results.metadatas?.[0] || []
|
|
95
|
+
const distances = results.distances?.[0] || []
|
|
96
|
+
|
|
97
|
+
for (let i = 0; i < ids.length; i++) {
|
|
98
|
+
const similarity = 1 - (distances[i] || 0)
|
|
99
|
+
if (similarity < 0.3) continue
|
|
100
|
+
|
|
101
|
+
processed.push({
|
|
102
|
+
id: ids[i],
|
|
103
|
+
decision: documents[i] || '',
|
|
104
|
+
context: (metadatas[i] as any)?.context || '',
|
|
105
|
+
similarity
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return processed
|
|
110
|
+
} catch (error) {
|
|
111
|
+
this.logger.warn({ error }, 'Failed to find similar contexts for prediction')
|
|
112
|
+
return []
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private groupSimilarDecisions(
|
|
117
|
+
decisions: Array<{ id: string; decision: string; context: string; similarity: number }>
|
|
118
|
+
): Array<Array<{ id: string; decision: string; context: string; similarity: number }>> {
|
|
119
|
+
const groups: Array<Array<{ id: string; decision: string; context: string; similarity: number }>> = []
|
|
120
|
+
|
|
121
|
+
for (const decision of decisions) {
|
|
122
|
+
let addedToGroup = false
|
|
123
|
+
|
|
124
|
+
for (const group of groups) {
|
|
125
|
+
// Check if this decision is similar to the group leader
|
|
126
|
+
const leader = group[0]
|
|
127
|
+
const jaccardSim = this.jaccardSimilarity(
|
|
128
|
+
leader.decision.toLowerCase(),
|
|
129
|
+
decision.decision.toLowerCase()
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
if (jaccardSim > 0.4) {
|
|
133
|
+
group.push(decision)
|
|
134
|
+
addedToGroup = true
|
|
135
|
+
break
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!addedToGroup) {
|
|
140
|
+
groups.push([decision])
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return groups.sort((a, b) => b.length - a.length)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private buildPrediction(
|
|
148
|
+
group: Array<{ id: string; decision: string; context: string; similarity: number }>,
|
|
149
|
+
queryContext: string
|
|
150
|
+
): PredictedDecision {
|
|
151
|
+
// Use the most similar decision as the prediction
|
|
152
|
+
const best = group.reduce((a, b) => a.similarity > b.similarity ? a : b)
|
|
153
|
+
|
|
154
|
+
// Confidence based on group size + similarity
|
|
155
|
+
const groupSizeFactor = Math.min(group.length / 3, 1) // Saturates at 3
|
|
156
|
+
const similarityFactor = best.similarity
|
|
157
|
+
const confidence = (groupSizeFactor * 0.4) + (similarityFactor * 0.6)
|
|
158
|
+
|
|
159
|
+
const basedOn = group.slice(0, 3).map(d => ({
|
|
160
|
+
id: d.id,
|
|
161
|
+
decision: d.decision.slice(0, 150),
|
|
162
|
+
similarity: d.similarity
|
|
163
|
+
}))
|
|
164
|
+
|
|
165
|
+
const reasoning = group.length > 1
|
|
166
|
+
? `Based on ${group.length} similar past decisions with avg ${Math.round(group.reduce((s, d) => s + d.similarity, 0) / group.length * 100)}% match`
|
|
167
|
+
: `Based on a similar past decision with ${Math.round(best.similarity * 100)}% match`
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
prediction: best.decision,
|
|
171
|
+
confidence,
|
|
172
|
+
basedOn,
|
|
173
|
+
reasoning
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private jaccardSimilarity(a: string, b: string): number {
|
|
178
|
+
const setA = new Set(a.split(/\s+/))
|
|
179
|
+
const setB = new Set(b.split(/\s+/))
|
|
180
|
+
const intersection = new Set([...setA].filter(x => setB.has(x)))
|
|
181
|
+
const union = new Set([...setA, ...setB])
|
|
182
|
+
return union.size > 0 ? intersection.size / union.size : 0
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Predictive Intelligence Module
|
|
3
|
+
* Phase 15.3 - Decision prediction, context anticipation, recommendations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { DecisionPredictor } from './decision-predictor'
|
|
7
|
+
export type { PredictedDecision } from './decision-predictor'
|
|
8
|
+
|
|
9
|
+
export { ContextAnticipator } from './context-anticipator'
|
|
10
|
+
export type { AnticipatedContext } from './context-anticipator'
|
|
11
|
+
|
|
12
|
+
export { Recommender } from './recommender'
|
|
13
|
+
export type { Recommendation, RecommendationResult } from './recommender'
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recommender
|
|
3
|
+
* Provides recommendations based on project history, patterns, and corrections
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Logger } from 'pino'
|
|
7
|
+
import type { CollectionManager } from '@/memory/chroma/collection-manager'
|
|
8
|
+
import type { EmbeddingProvider } from '@/memory/chroma/embeddings'
|
|
9
|
+
|
|
10
|
+
export interface Recommendation {
|
|
11
|
+
type: 'pattern' | 'correction' | 'decision' | 'best-practice'
|
|
12
|
+
content: string
|
|
13
|
+
confidence: number
|
|
14
|
+
source: string
|
|
15
|
+
sourceId: string
|
|
16
|
+
reasoning: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface RecommendationResult {
|
|
20
|
+
query: string
|
|
21
|
+
project?: string
|
|
22
|
+
recommendations: Recommendation[]
|
|
23
|
+
totalConsidered: number
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class Recommender {
|
|
27
|
+
private logger: Logger
|
|
28
|
+
private collections: CollectionManager
|
|
29
|
+
private embeddings?: EmbeddingProvider
|
|
30
|
+
|
|
31
|
+
constructor(logger: Logger, collections: CollectionManager, embeddings?: EmbeddingProvider) {
|
|
32
|
+
this.logger = logger.child({ component: 'recommender' })
|
|
33
|
+
this.collections = collections
|
|
34
|
+
this.embeddings = embeddings
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get recommendations for a given context
|
|
39
|
+
*/
|
|
40
|
+
async getRecommendations(query: string, options: {
|
|
41
|
+
project?: string
|
|
42
|
+
limit?: number
|
|
43
|
+
types?: Array<'pattern' | 'correction' | 'decision'>
|
|
44
|
+
} = {}): Promise<RecommendationResult> {
|
|
45
|
+
const {
|
|
46
|
+
project,
|
|
47
|
+
limit = 10,
|
|
48
|
+
types = ['pattern', 'correction', 'decision']
|
|
49
|
+
} = options
|
|
50
|
+
|
|
51
|
+
const allRecommendations: Recommendation[] = []
|
|
52
|
+
let totalConsidered = 0
|
|
53
|
+
|
|
54
|
+
// Fetch from patterns
|
|
55
|
+
if (types.includes('pattern')) {
|
|
56
|
+
const patterns = await this.fetchPatternRecommendations(query, project, limit)
|
|
57
|
+
allRecommendations.push(...patterns.recommendations)
|
|
58
|
+
totalConsidered += patterns.considered
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Fetch from corrections (things to avoid)
|
|
62
|
+
if (types.includes('correction')) {
|
|
63
|
+
const corrections = await this.fetchCorrectionRecommendations(query, project, limit)
|
|
64
|
+
allRecommendations.push(...corrections.recommendations)
|
|
65
|
+
totalConsidered += corrections.considered
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Fetch from past decisions
|
|
69
|
+
if (types.includes('decision')) {
|
|
70
|
+
const decisions = await this.fetchDecisionRecommendations(query, project, limit)
|
|
71
|
+
allRecommendations.push(...decisions.recommendations)
|
|
72
|
+
totalConsidered += decisions.considered
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Sort by confidence and deduplicate
|
|
76
|
+
const sorted = allRecommendations
|
|
77
|
+
.sort((a, b) => b.confidence - a.confidence)
|
|
78
|
+
.slice(0, limit)
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
query,
|
|
82
|
+
project,
|
|
83
|
+
recommendations: sorted,
|
|
84
|
+
totalConsidered
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private async fetchPatternRecommendations(
|
|
89
|
+
query: string,
|
|
90
|
+
project?: string,
|
|
91
|
+
limit: number = 5
|
|
92
|
+
): Promise<{ recommendations: Recommendation[]; considered: number }> {
|
|
93
|
+
try {
|
|
94
|
+
const collection = await this.collections.getPatterns()
|
|
95
|
+
|
|
96
|
+
const where: any = project ? { project: { $eq: project } } : undefined
|
|
97
|
+
|
|
98
|
+
let results: any
|
|
99
|
+
|
|
100
|
+
if (this.embeddings) {
|
|
101
|
+
const embedding = await this.embeddings.generate(query)
|
|
102
|
+
results = await collection.query({
|
|
103
|
+
queryEmbeddings: [embedding],
|
|
104
|
+
nResults: limit,
|
|
105
|
+
where,
|
|
106
|
+
include: ['documents', 'metadatas', 'distances']
|
|
107
|
+
})
|
|
108
|
+
} else {
|
|
109
|
+
results = await collection.query({
|
|
110
|
+
queryTexts: [query],
|
|
111
|
+
nResults: limit,
|
|
112
|
+
where,
|
|
113
|
+
include: ['documents', 'metadatas', 'distances']
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (!results.ids || !results.ids[0]) return { recommendations: [], considered: 0 }
|
|
118
|
+
|
|
119
|
+
const recommendations: Recommendation[] = []
|
|
120
|
+
const ids = results.ids[0]
|
|
121
|
+
const documents = results.documents?.[0] || []
|
|
122
|
+
const metadatas = results.metadatas?.[0] || []
|
|
123
|
+
const distances = results.distances?.[0] || []
|
|
124
|
+
|
|
125
|
+
for (let i = 0; i < ids.length; i++) {
|
|
126
|
+
const similarity = 1 - (distances[i] || 0)
|
|
127
|
+
if (similarity < 0.3) continue
|
|
128
|
+
|
|
129
|
+
const meta = metadatas[i] as any
|
|
130
|
+
const patternType = meta?.pattern_type || 'pattern'
|
|
131
|
+
|
|
132
|
+
recommendations.push({
|
|
133
|
+
type: patternType === 'best-practice' ? 'best-practice' : 'pattern',
|
|
134
|
+
content: documents[i] || '',
|
|
135
|
+
confidence: similarity * (meta?.confidence || 0.8),
|
|
136
|
+
source: `Pattern (${patternType})`,
|
|
137
|
+
sourceId: ids[i],
|
|
138
|
+
reasoning: meta?.context || `Relevant ${patternType} pattern found`
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return { recommendations, considered: ids.length }
|
|
143
|
+
} catch (error) {
|
|
144
|
+
this.logger.debug({ error }, 'Failed to fetch pattern recommendations')
|
|
145
|
+
return { recommendations: [], considered: 0 }
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private async fetchCorrectionRecommendations(
|
|
150
|
+
query: string,
|
|
151
|
+
project?: string,
|
|
152
|
+
limit: number = 5
|
|
153
|
+
): Promise<{ recommendations: Recommendation[]; considered: number }> {
|
|
154
|
+
try {
|
|
155
|
+
const collection = await this.collections.getCorrections()
|
|
156
|
+
|
|
157
|
+
const where: any = project ? { project: { $eq: project } } : undefined
|
|
158
|
+
|
|
159
|
+
let results: any
|
|
160
|
+
|
|
161
|
+
if (this.embeddings) {
|
|
162
|
+
const embedding = await this.embeddings.generate(query)
|
|
163
|
+
results = await collection.query({
|
|
164
|
+
queryEmbeddings: [embedding],
|
|
165
|
+
nResults: limit,
|
|
166
|
+
where,
|
|
167
|
+
include: ['documents', 'metadatas', 'distances']
|
|
168
|
+
})
|
|
169
|
+
} else {
|
|
170
|
+
results = await collection.query({
|
|
171
|
+
queryTexts: [query],
|
|
172
|
+
nResults: limit,
|
|
173
|
+
where,
|
|
174
|
+
include: ['documents', 'metadatas', 'distances']
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (!results.ids || !results.ids[0]) return { recommendations: [], considered: 0 }
|
|
179
|
+
|
|
180
|
+
const recommendations: Recommendation[] = []
|
|
181
|
+
const ids = results.ids[0]
|
|
182
|
+
const documents = results.documents?.[0] || []
|
|
183
|
+
const metadatas = results.metadatas?.[0] || []
|
|
184
|
+
const distances = results.distances?.[0] || []
|
|
185
|
+
|
|
186
|
+
for (let i = 0; i < ids.length; i++) {
|
|
187
|
+
const similarity = 1 - (distances[i] || 0)
|
|
188
|
+
if (similarity < 0.3) continue
|
|
189
|
+
|
|
190
|
+
const meta = metadatas[i] as any
|
|
191
|
+
|
|
192
|
+
recommendations.push({
|
|
193
|
+
type: 'correction',
|
|
194
|
+
content: `Avoid: ${meta?.original || ''}\nDo instead: ${documents[i] || ''}`,
|
|
195
|
+
confidence: similarity * (meta?.confidence || 0.9),
|
|
196
|
+
source: 'Lesson Learned',
|
|
197
|
+
sourceId: ids[i],
|
|
198
|
+
reasoning: meta?.reasoning || 'Based on a past correction'
|
|
199
|
+
})
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return { recommendations, considered: ids.length }
|
|
203
|
+
} catch (error) {
|
|
204
|
+
this.logger.debug({ error }, 'Failed to fetch correction recommendations')
|
|
205
|
+
return { recommendations: [], considered: 0 }
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private async fetchDecisionRecommendations(
|
|
210
|
+
query: string,
|
|
211
|
+
project?: string,
|
|
212
|
+
limit: number = 5
|
|
213
|
+
): Promise<{ recommendations: Recommendation[]; considered: number }> {
|
|
214
|
+
try {
|
|
215
|
+
const collection = await this.collections.getDecisions()
|
|
216
|
+
|
|
217
|
+
const where: any = project ? { project: { $eq: project } } : undefined
|
|
218
|
+
|
|
219
|
+
let results: any
|
|
220
|
+
|
|
221
|
+
if (this.embeddings) {
|
|
222
|
+
const embedding = await this.embeddings.generate(query)
|
|
223
|
+
results = await collection.query({
|
|
224
|
+
queryEmbeddings: [embedding],
|
|
225
|
+
nResults: limit,
|
|
226
|
+
where,
|
|
227
|
+
include: ['documents', 'metadatas', 'distances']
|
|
228
|
+
})
|
|
229
|
+
} else {
|
|
230
|
+
results = await collection.query({
|
|
231
|
+
queryTexts: [query],
|
|
232
|
+
nResults: limit,
|
|
233
|
+
where,
|
|
234
|
+
include: ['documents', 'metadatas', 'distances']
|
|
235
|
+
})
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (!results.ids || !results.ids[0]) return { recommendations: [], considered: 0 }
|
|
239
|
+
|
|
240
|
+
const recommendations: Recommendation[] = []
|
|
241
|
+
const ids = results.ids[0]
|
|
242
|
+
const documents = results.documents?.[0] || []
|
|
243
|
+
const metadatas = results.metadatas?.[0] || []
|
|
244
|
+
const distances = results.distances?.[0] || []
|
|
245
|
+
|
|
246
|
+
for (let i = 0; i < ids.length; i++) {
|
|
247
|
+
const similarity = 1 - (distances[i] || 0)
|
|
248
|
+
if (similarity < 0.5) continue // Higher threshold for past decisions
|
|
249
|
+
|
|
250
|
+
const meta = metadatas[i] as any
|
|
251
|
+
|
|
252
|
+
recommendations.push({
|
|
253
|
+
type: 'decision',
|
|
254
|
+
content: documents[i] || '',
|
|
255
|
+
confidence: similarity,
|
|
256
|
+
source: 'Past Decision',
|
|
257
|
+
sourceId: ids[i],
|
|
258
|
+
reasoning: meta?.reasoning || 'Based on a previous decision in similar context'
|
|
259
|
+
})
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return { recommendations, considered: ids.length }
|
|
263
|
+
} catch (error) {
|
|
264
|
+
this.logger.debug({ error }, 'Failed to fetch decision recommendations')
|
|
265
|
+
return { recommendations: [], considered: 0 }
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|