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.
Files changed (200) hide show
  1. package/README.md +157 -0
  2. package/VERSION +1 -0
  3. package/assets/CLAUDE.md +307 -0
  4. package/bunfig.toml +8 -0
  5. package/package.json +74 -0
  6. package/src/automation/auto-context.ts +240 -0
  7. package/src/automation/decision-detector.ts +452 -0
  8. package/src/automation/index.ts +11 -0
  9. package/src/automation/proactive-recall.ts +373 -0
  10. package/src/automation/project-detector.ts +297 -0
  11. package/src/cli/auto-setup.ts +74 -0
  12. package/src/cli/bin.ts +110 -0
  13. package/src/cli/commands/install-mcp.ts +50 -0
  14. package/src/cli/commands/serve.ts +129 -0
  15. package/src/cli/diagnose.ts +4 -0
  16. package/src/cli/health-check.ts +4 -0
  17. package/src/cli/migrate-chroma.ts +106 -0
  18. package/src/cli/setup.ts +4 -0
  19. package/src/config/defaults.ts +47 -0
  20. package/src/config/home.ts +55 -0
  21. package/src/config/index.ts +7 -0
  22. package/src/config/loader.ts +166 -0
  23. package/src/config/migration.ts +76 -0
  24. package/src/config/schema.ts +257 -0
  25. package/src/config/validator.ts +184 -0
  26. package/src/config/watcher.ts +86 -0
  27. package/src/context/assembler.ts +398 -0
  28. package/src/context/cache-manager.ts +101 -0
  29. package/src/context/formatter.ts +84 -0
  30. package/src/context/hierarchy.ts +85 -0
  31. package/src/context/index.ts +83 -0
  32. package/src/context/progress-tracker.ts +174 -0
  33. package/src/context/standards-manager.ts +267 -0
  34. package/src/context/types.ts +252 -0
  35. package/src/context/validator.ts +58 -0
  36. package/src/cross-project/affinity.ts +162 -0
  37. package/src/cross-project/generalizer.ts +283 -0
  38. package/src/cross-project/index.ts +13 -0
  39. package/src/cross-project/transfer.ts +201 -0
  40. package/src/diagnostics/index.ts +123 -0
  41. package/src/health/index.ts +229 -0
  42. package/src/index.ts +7 -0
  43. package/src/knowledge/entity-extractor.ts +416 -0
  44. package/src/knowledge/graph/builder.ts +159 -0
  45. package/src/knowledge/graph/linker.ts +201 -0
  46. package/src/knowledge/graph/memory-graph.ts +359 -0
  47. package/src/knowledge/graph/schema.ts +99 -0
  48. package/src/knowledge/graph/search.ts +168 -0
  49. package/src/knowledge/relationship-extractor.ts +108 -0
  50. package/src/memory/chroma/client.ts +169 -0
  51. package/src/memory/chroma/collection-manager.ts +94 -0
  52. package/src/memory/chroma/config.ts +46 -0
  53. package/src/memory/chroma/embeddings.ts +153 -0
  54. package/src/memory/chroma/index.ts +82 -0
  55. package/src/memory/chroma/migration.ts +270 -0
  56. package/src/memory/chroma/schemas.ts +69 -0
  57. package/src/memory/chroma/search.ts +315 -0
  58. package/src/memory/chroma/store.ts +694 -0
  59. package/src/memory/consolidation/archiver.ts +164 -0
  60. package/src/memory/consolidation/merger.ts +186 -0
  61. package/src/memory/consolidation/scorer.ts +138 -0
  62. package/src/memory/context-builder.ts +236 -0
  63. package/src/memory/database.ts +169 -0
  64. package/src/memory/embedding-utils.ts +156 -0
  65. package/src/memory/embeddings.ts +226 -0
  66. package/src/memory/episodic/detector.ts +108 -0
  67. package/src/memory/episodic/manager.ts +334 -0
  68. package/src/memory/episodic/summarizer.ts +179 -0
  69. package/src/memory/episodic/types.ts +52 -0
  70. package/src/memory/index.ts +395 -0
  71. package/src/memory/knowledge-extractor.ts +455 -0
  72. package/src/memory/learning.ts +378 -0
  73. package/src/memory/patterns.ts +396 -0
  74. package/src/memory/schema.ts +56 -0
  75. package/src/memory/search.ts +309 -0
  76. package/src/memory/store.ts +344 -0
  77. package/src/memory/types.ts +121 -0
  78. package/src/optimization/index.ts +10 -0
  79. package/src/optimization/precompute.ts +202 -0
  80. package/src/optimization/semantic-cache.ts +207 -0
  81. package/src/orchestrator/coordinator.ts +272 -0
  82. package/src/orchestrator/decision-logger.ts +228 -0
  83. package/src/orchestrator/event-emitter.ts +198 -0
  84. package/src/orchestrator/event-queue.ts +184 -0
  85. package/src/orchestrator/handlers/base-handler.ts +70 -0
  86. package/src/orchestrator/handlers/context-handler.ts +73 -0
  87. package/src/orchestrator/handlers/decision-handler.ts +204 -0
  88. package/src/orchestrator/handlers/index.ts +10 -0
  89. package/src/orchestrator/handlers/status-handler.ts +131 -0
  90. package/src/orchestrator/handlers/task-handler.ts +171 -0
  91. package/src/orchestrator/index.ts +275 -0
  92. package/src/orchestrator/task-parser.ts +284 -0
  93. package/src/orchestrator/types.ts +98 -0
  94. package/src/phase12/index.ts +456 -0
  95. package/src/prediction/context-anticipator.ts +198 -0
  96. package/src/prediction/decision-predictor.ts +184 -0
  97. package/src/prediction/index.ts +13 -0
  98. package/src/prediction/recommender.ts +268 -0
  99. package/src/reasoning/chain-retrieval.ts +247 -0
  100. package/src/reasoning/counterfactual.ts +248 -0
  101. package/src/reasoning/index.ts +13 -0
  102. package/src/reasoning/synthesizer.ts +169 -0
  103. package/src/retrieval/bm25/index.ts +300 -0
  104. package/src/retrieval/bm25/tokenizer.ts +184 -0
  105. package/src/retrieval/feedback/adaptive.ts +223 -0
  106. package/src/retrieval/feedback/index.ts +16 -0
  107. package/src/retrieval/feedback/metrics.ts +223 -0
  108. package/src/retrieval/feedback/store.ts +283 -0
  109. package/src/retrieval/fusion/index.ts +194 -0
  110. package/src/retrieval/fusion/rrf.ts +163 -0
  111. package/src/retrieval/index.ts +12 -0
  112. package/src/retrieval/pipeline.ts +375 -0
  113. package/src/retrieval/query/expander.ts +198 -0
  114. package/src/retrieval/query/index.ts +27 -0
  115. package/src/retrieval/query/intent-classifier.ts +236 -0
  116. package/src/retrieval/query/temporal-parser.ts +295 -0
  117. package/src/retrieval/reranker/index.ts +188 -0
  118. package/src/retrieval/reranker/model.ts +95 -0
  119. package/src/retrieval/service.ts +125 -0
  120. package/src/retrieval/types.ts +162 -0
  121. package/src/scripts/health-check.ts +118 -0
  122. package/src/scripts/setup.ts +122 -0
  123. package/src/server/handlers/call-tool.ts +194 -0
  124. package/src/server/handlers/index.ts +9 -0
  125. package/src/server/handlers/list-tools.ts +18 -0
  126. package/src/server/handlers/tools/analyze-decision-evolution.ts +71 -0
  127. package/src/server/handlers/tools/auto-remember.ts +200 -0
  128. package/src/server/handlers/tools/create-project.ts +135 -0
  129. package/src/server/handlers/tools/detect-trends.ts +80 -0
  130. package/src/server/handlers/tools/find-cross-project-patterns.ts +73 -0
  131. package/src/server/handlers/tools/get-activity-log.ts +194 -0
  132. package/src/server/handlers/tools/get-code-standards.ts +124 -0
  133. package/src/server/handlers/tools/get-corrections.ts +154 -0
  134. package/src/server/handlers/tools/get-decision-timeline.ts +86 -0
  135. package/src/server/handlers/tools/get-episode.ts +93 -0
  136. package/src/server/handlers/tools/get-patterns.ts +158 -0
  137. package/src/server/handlers/tools/get-phase12-status.ts +63 -0
  138. package/src/server/handlers/tools/get-project-context.ts +75 -0
  139. package/src/server/handlers/tools/get-recommendations.ts +65 -0
  140. package/src/server/handlers/tools/index.ts +33 -0
  141. package/src/server/handlers/tools/init-project.ts +710 -0
  142. package/src/server/handlers/tools/list-episodes.ts +80 -0
  143. package/src/server/handlers/tools/list-projects.ts +125 -0
  144. package/src/server/handlers/tools/rate-memory.ts +95 -0
  145. package/src/server/handlers/tools/recall-similar.ts +87 -0
  146. package/src/server/handlers/tools/recognize-pattern.ts +126 -0
  147. package/src/server/handlers/tools/record-correction.ts +125 -0
  148. package/src/server/handlers/tools/remember-decision.ts +153 -0
  149. package/src/server/handlers/tools/schemas.ts +241 -0
  150. package/src/server/handlers/tools/search-knowledge-graph.ts +89 -0
  151. package/src/server/handlers/tools/smart-context.ts +124 -0
  152. package/src/server/handlers/tools/update-progress.ts +114 -0
  153. package/src/server/handlers/tools/what-if-analysis.ts +73 -0
  154. package/src/server/http-api.ts +474 -0
  155. package/src/server/index.ts +40 -0
  156. package/src/server/mcp-server.ts +283 -0
  157. package/src/server/providers/index.ts +7 -0
  158. package/src/server/providers/prompts.ts +327 -0
  159. package/src/server/providers/resources.ts +427 -0
  160. package/src/server/services.ts +388 -0
  161. package/src/server/types.ts +39 -0
  162. package/src/server/utils/error-handler.ts +155 -0
  163. package/src/server/utils/index.ts +13 -0
  164. package/src/server/utils/memory-indicator.ts +83 -0
  165. package/src/server/utils/request-context.ts +122 -0
  166. package/src/server/utils/response-formatter.ts +124 -0
  167. package/src/server/utils/validators.ts +210 -0
  168. package/src/setup/index.ts +22 -0
  169. package/src/setup/wizard.ts +321 -0
  170. package/src/temporal/evolution.ts +197 -0
  171. package/src/temporal/index.ts +16 -0
  172. package/src/temporal/query-processor.ts +190 -0
  173. package/src/temporal/timeline.ts +259 -0
  174. package/src/temporal/trends.ts +263 -0
  175. package/src/tools/index.ts +24 -0
  176. package/src/tools/registry.ts +106 -0
  177. package/src/tools/schemas.test.ts +30 -0
  178. package/src/tools/schemas.ts +907 -0
  179. package/src/tools/types.ts +412 -0
  180. package/src/utils/circuit-breaker.ts +130 -0
  181. package/src/utils/cleanup.ts +34 -0
  182. package/src/utils/error-handler.ts +132 -0
  183. package/src/utils/error-messages.ts +60 -0
  184. package/src/utils/fallback.ts +45 -0
  185. package/src/utils/index.ts +54 -0
  186. package/src/utils/logger-utils.ts +80 -0
  187. package/src/utils/logger.ts +88 -0
  188. package/src/utils/phase12-helper.ts +56 -0
  189. package/src/utils/retry.ts +94 -0
  190. package/src/utils/transaction.ts +63 -0
  191. package/src/vault/frontmatter.ts +264 -0
  192. package/src/vault/index.ts +318 -0
  193. package/src/vault/paths.ts +106 -0
  194. package/src/vault/query.ts +422 -0
  195. package/src/vault/reader.ts +264 -0
  196. package/src/vault/templates.ts +186 -0
  197. package/src/vault/types.ts +73 -0
  198. package/src/vault/watcher.ts +277 -0
  199. package/src/vault/writer.ts +393 -0
  200. 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
+ }