claude-brain 0.14.2 → 0.14.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +191 -191
- package/VERSION +1 -1
- package/assets/CLAUDE-unified.md +11 -11
- package/assets/CLAUDE.md +11 -11
- package/bunfig.toml +8 -8
- package/package.json +80 -80
- 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/src/automation/auto-context.ts +240 -240
- package/src/automation/decision-detector.ts +452 -452
- package/src/automation/index.ts +11 -11
- 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 +205 -205
- package/src/cli/auto-setup.ts +82 -82
- package/src/cli/bin.ts +202 -202
- package/src/cli/commands/chroma.ts +573 -573
- package/src/cli/commands/git-hook.ts +189 -189
- package/src/cli/commands/hooks.ts +213 -213
- package/src/cli/commands/init.ts +122 -122
- package/src/cli/commands/install-mcp.ts +92 -92
- package/src/cli/commands/pack.ts +197 -197
- package/src/cli/commands/serve.ts +167 -167
- package/src/cli/commands/start.ts +42 -42
- package/src/cli/commands/uninstall-mcp.ts +41 -41
- package/src/cli/commands/update.ts +121 -121
- package/src/cli/diagnose.ts +4 -4
- package/src/cli/health-check.ts +4 -4
- package/src/cli/migrate-chroma.ts +106 -106
- package/src/cli/setup.ts +4 -4
- 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/config/defaults.ts +50 -50
- package/src/config/home.ts +55 -55
- package/src/config/index.ts +7 -7
- package/src/config/loader.ts +166 -166
- package/src/config/migration.ts +76 -76
- package/src/config/schema.ts +360 -360
- package/src/config/validator.ts +184 -184
- package/src/config/watcher.ts +86 -86
- package/src/context/assembler.ts +398 -398
- package/src/context/cache-manager.ts +101 -101
- package/src/context/formatter.ts +84 -84
- package/src/context/hierarchy.ts +85 -85
- package/src/context/index.ts +83 -83
- package/src/context/progress-tracker.ts +174 -174
- package/src/context/standards-manager.ts +287 -287
- package/src/context/types.ts +252 -252
- package/src/context/validator.ts +58 -58
- package/src/diagnostics/index.ts +123 -123
- package/src/health/index.ts +229 -229
- package/src/hooks/brain-hook.ts +112 -112
- package/src/hooks/capture.ts +168 -168
- package/src/hooks/deduplicator.ts +72 -72
- package/src/hooks/git-capture.ts +109 -109
- package/src/hooks/git-hook-installer.ts +207 -207
- package/src/hooks/index.ts +20 -20
- package/src/hooks/installer.ts +191 -194
- package/src/hooks/passive-classifier.ts +366 -366
- package/src/hooks/queue.ts +129 -129
- package/src/hooks/session-tracker.ts +275 -275
- package/src/hooks/types.ts +47 -47
- package/src/index.ts +7 -7
- package/src/intelligence/cross-project/affinity.ts +162 -162
- package/src/intelligence/cross-project/generalizer.ts +283 -283
- package/src/intelligence/cross-project/index.ts +13 -13
- package/src/intelligence/cross-project/transfer.ts +201 -201
- package/src/intelligence/index.ts +24 -24
- package/src/intelligence/optimization/index.ts +10 -10
- package/src/intelligence/optimization/precompute.ts +202 -202
- package/src/intelligence/optimization/semantic-cache.ts +207 -207
- package/src/intelligence/prediction/context-anticipator.ts +198 -198
- package/src/intelligence/prediction/decision-predictor.ts +184 -184
- package/src/intelligence/prediction/index.ts +13 -13
- package/src/intelligence/prediction/recommender.ts +268 -268
- package/src/intelligence/reasoning/chain-retrieval.ts +247 -247
- package/src/intelligence/reasoning/counterfactual.ts +248 -248
- package/src/intelligence/reasoning/index.ts +13 -13
- package/src/intelligence/reasoning/synthesizer.ts +169 -169
- package/src/intelligence/temporal/evolution.ts +197 -197
- package/src/intelligence/temporal/index.ts +16 -16
- package/src/intelligence/temporal/query-processor.ts +190 -190
- package/src/intelligence/temporal/timeline.ts +259 -259
- package/src/intelligence/temporal/trends.ts +263 -263
- package/src/knowledge/entity-extractor.ts +416 -416
- 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 +168 -168
- package/src/knowledge/relationship-extractor.ts +108 -108
- package/src/memory/chroma/client.ts +174 -174
- package/src/memory/chroma/collection-manager.ts +94 -94
- package/src/memory/chroma/config.ts +57 -57
- package/src/memory/chroma/embeddings.ts +153 -153
- 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 +315 -315
- package/src/memory/chroma/store.ts +741 -741
- package/src/memory/consolidation/archiver.ts +164 -164
- package/src/memory/consolidation/merger.ts +186 -186
- package/src/memory/consolidation/scorer.ts +138 -138
- package/src/memory/context-builder.ts +236 -236
- package/src/memory/database.ts +169 -169
- package/src/memory/embedding-utils.ts +156 -156
- package/src/memory/embeddings.ts +226 -226
- package/src/memory/episodic/detector.ts +108 -108
- package/src/memory/episodic/manager.ts +351 -351
- package/src/memory/episodic/summarizer.ts +179 -179
- package/src/memory/episodic/types.ts +52 -52
- package/src/memory/index.ts +582 -582
- package/src/memory/knowledge-extractor.ts +455 -455
- package/src/memory/learning.ts +378 -378
- package/src/memory/patterns.ts +396 -396
- package/src/memory/schema.ts +88 -88
- package/src/memory/search.ts +309 -309
- package/src/memory/store.ts +787 -787
- package/src/memory/types.ts +121 -121
- package/src/orchestrator/coordinator.ts +272 -272
- package/src/orchestrator/decision-logger.ts +228 -228
- package/src/orchestrator/event-emitter.ts +198 -198
- package/src/orchestrator/event-queue.ts +184 -184
- package/src/orchestrator/handlers/base-handler.ts +70 -70
- package/src/orchestrator/handlers/context-handler.ts +73 -73
- package/src/orchestrator/handlers/decision-handler.ts +204 -204
- package/src/orchestrator/handlers/index.ts +10 -10
- package/src/orchestrator/handlers/status-handler.ts +131 -131
- package/src/orchestrator/handlers/task-handler.ts +171 -171
- package/src/orchestrator/index.ts +275 -275
- package/src/orchestrator/task-parser.ts +284 -284
- package/src/orchestrator/types.ts +98 -98
- 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 -300
- package/src/retrieval/bm25/tokenizer.ts +184 -184
- package/src/retrieval/feedback/adaptive.ts +223 -223
- package/src/retrieval/feedback/index.ts +16 -16
- package/src/retrieval/feedback/metrics.ts +223 -223
- package/src/retrieval/feedback/store.ts +283 -283
- package/src/retrieval/fusion/index.ts +194 -194
- package/src/retrieval/fusion/rrf.ts +163 -163
- package/src/retrieval/index.ts +12 -12
- package/src/retrieval/pipeline.ts +375 -375
- package/src/retrieval/query/expander.ts +198 -198
- package/src/retrieval/query/index.ts +27 -27
- package/src/retrieval/query/intent-classifier.ts +236 -236
- package/src/retrieval/query/temporal-parser.ts +295 -295
- package/src/retrieval/reranker/index.ts +188 -188
- package/src/retrieval/reranker/model.ts +95 -95
- package/src/retrieval/service.ts +125 -125
- package/src/retrieval/types.ts +162 -162
- package/src/routing/entity-extractor.ts +428 -428
- package/src/routing/intent-classifier.ts +436 -436
- package/src/routing/response-filter.ts +258 -254
- package/src/routing/router.ts +1322 -1314
- package/src/routing/search-engine.ts +475 -475
- package/src/routing/types.ts +94 -84
- package/src/scripts/health-check.ts +118 -118
- package/src/scripts/setup.ts +122 -122
- package/src/server/handlers/call-tool.ts +156 -156
- package/src/server/handlers/index.ts +9 -9
- package/src/server/handlers/list-tools.ts +35 -35
- package/src/server/handlers/tools/analyze-decision-evolution.ts +151 -151
- package/src/server/handlers/tools/auto-remember.ts +200 -200
- package/src/server/handlers/tools/brain.ts +85 -85
- package/src/server/handlers/tools/create-project.ts +135 -135
- package/src/server/handlers/tools/detect-trends.ts +144 -144
- package/src/server/handlers/tools/find-cross-project-patterns.ts +168 -168
- package/src/server/handlers/tools/get-activity-log.ts +194 -194
- package/src/server/handlers/tools/get-code-standards.ts +124 -124
- package/src/server/handlers/tools/get-corrections.ts +154 -154
- package/src/server/handlers/tools/get-decision-timeline.ts +172 -172
- package/src/server/handlers/tools/get-episode.ts +103 -103
- package/src/server/handlers/tools/get-patterns.ts +158 -158
- package/src/server/handlers/tools/get-phase12-status.ts +63 -63
- package/src/server/handlers/tools/get-project-context.ts +75 -75
- package/src/server/handlers/tools/get-recommendations.ts +145 -145
- package/src/server/handlers/tools/index.ts +31 -31
- package/src/server/handlers/tools/init-project.ts +757 -757
- package/src/server/handlers/tools/list-episodes.ts +90 -90
- package/src/server/handlers/tools/list-projects.ts +125 -125
- package/src/server/handlers/tools/rate-memory.ts +101 -101
- package/src/server/handlers/tools/recall-similar.ts +87 -87
- package/src/server/handlers/tools/recognize-pattern.ts +126 -126
- package/src/server/handlers/tools/record-correction.ts +125 -125
- package/src/server/handlers/tools/remember-decision.ts +153 -153
- package/src/server/handlers/tools/schemas.ts +253 -253
- package/src/server/handlers/tools/search-knowledge-graph.ts +102 -102
- package/src/server/handlers/tools/smart-context.ts +146 -146
- package/src/server/handlers/tools/update-progress.ts +131 -131
- package/src/server/handlers/tools/what-if-analysis.ts +135 -135
- package/src/server/http-api.ts +693 -693
- package/src/server/index.ts +40 -40
- package/src/server/mcp-server.ts +283 -283
- package/src/server/providers/index.ts +7 -7
- package/src/server/providers/prompts.ts +327 -327
- package/src/server/providers/resources.ts +622 -622
- package/src/server/services.ts +468 -468
- package/src/server/types.ts +39 -39
- package/src/server/utils/error-handler.ts +155 -155
- package/src/server/utils/index.ts +13 -13
- package/src/server/utils/memory-indicator.ts +83 -83
- package/src/server/utils/request-context.ts +122 -122
- package/src/server/utils/response-formatter.ts +129 -124
- package/src/server/utils/validators.ts +210 -210
- package/src/setup/index.ts +48 -48
- package/src/setup/wizard.ts +461 -461
- package/src/tools/index.ts +24 -24
- package/src/tools/registry.ts +115 -115
- package/src/tools/schemas.test.ts +30 -30
- package/src/tools/schemas.ts +617 -617
- package/src/tools/types.ts +412 -412
- package/src/utils/circuit-breaker.ts +130 -130
- package/src/utils/cleanup.ts +34 -34
- package/src/utils/error-handler.ts +132 -132
- package/src/utils/error-messages.ts +60 -60
- package/src/utils/fallback.ts +45 -45
- package/src/utils/index.ts +54 -54
- package/src/utils/logger-utils.ts +80 -80
- package/src/utils/logger.ts +88 -88
- package/src/utils/phase12-helper.ts +56 -56
- package/src/utils/retry.ts +94 -94
- package/src/utils/timing.ts +47 -47
- package/src/utils/transaction.ts +63 -63
- package/src/vault/frontmatter.ts +264 -264
- package/src/vault/index.ts +318 -318
- package/src/vault/paths.ts +106 -106
- package/src/vault/query.ts +422 -422
- package/src/vault/reader.ts +264 -264
- package/src/vault/templates.ts +186 -186
- package/src/vault/types.ts +73 -73
- package/src/vault/watcher.ts +277 -277
- package/src/vault/writer.ts +413 -413
- package/tsconfig.json +30 -30
|
@@ -1,198 +1,198 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Context Anticipator
|
|
3
|
-
* Anticipates what context will be needed based on current activity
|
|
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 AnticipatedContext {
|
|
11
|
-
topic: string
|
|
12
|
-
relevance: number
|
|
13
|
-
relatedDecisions: number
|
|
14
|
-
suggestedQueries: string[]
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class ContextAnticipator {
|
|
18
|
-
private logger: Logger
|
|
19
|
-
private collections: CollectionManager
|
|
20
|
-
private embeddings?: EmbeddingProvider
|
|
21
|
-
private recentTopics: Array<{ topic: string; timestamp: number }> = []
|
|
22
|
-
|
|
23
|
-
constructor(logger: Logger, collections: CollectionManager, embeddings?: EmbeddingProvider) {
|
|
24
|
-
this.logger = logger.child({ component: 'context-anticipator' })
|
|
25
|
-
this.collections = collections
|
|
26
|
-
this.embeddings = embeddings
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Record a topic being worked on for anticipation
|
|
31
|
-
*/
|
|
32
|
-
recordActivity(topic: string): void {
|
|
33
|
-
this.recentTopics.push({ topic, timestamp: Date.now() })
|
|
34
|
-
// Keep last 50 topics
|
|
35
|
-
if (this.recentTopics.length > 50) {
|
|
36
|
-
this.recentTopics = this.recentTopics.slice(-50)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Anticipate what context might be needed next
|
|
42
|
-
*/
|
|
43
|
-
async anticipate(currentTask: string, options: {
|
|
44
|
-
project?: string
|
|
45
|
-
limit?: number
|
|
46
|
-
} = {}): Promise<AnticipatedContext[]> {
|
|
47
|
-
const { project, limit = 5 } = options
|
|
48
|
-
|
|
49
|
-
// Get patterns of what typically follows similar tasks
|
|
50
|
-
const followUpTopics = await this.findFollowUpPatterns(currentTask, project)
|
|
51
|
-
|
|
52
|
-
// Get related but not-yet-accessed topics
|
|
53
|
-
const relatedTopics = await this.findRelatedTopics(currentTask, project)
|
|
54
|
-
|
|
55
|
-
// Merge and rank
|
|
56
|
-
const merged = new Map<string, AnticipatedContext>()
|
|
57
|
-
|
|
58
|
-
for (const t of followUpTopics) {
|
|
59
|
-
merged.set(t.topic, t)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
for (const t of relatedTopics) {
|
|
63
|
-
if (merged.has(t.topic)) {
|
|
64
|
-
const existing = merged.get(t.topic)!
|
|
65
|
-
existing.relevance = Math.max(existing.relevance, t.relevance)
|
|
66
|
-
existing.relatedDecisions = Math.max(existing.relatedDecisions, t.relatedDecisions)
|
|
67
|
-
} else {
|
|
68
|
-
merged.set(t.topic, t)
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return Array.from(merged.values())
|
|
73
|
-
.sort((a, b) => b.relevance - a.relevance)
|
|
74
|
-
.slice(0, limit)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
private async findFollowUpPatterns(
|
|
78
|
-
currentTask: string,
|
|
79
|
-
project?: string
|
|
80
|
-
): Promise<AnticipatedContext[]> {
|
|
81
|
-
try {
|
|
82
|
-
const collection = await this.collections.getDecisions()
|
|
83
|
-
|
|
84
|
-
const where: any = project ? { project: { $eq: project } } : undefined
|
|
85
|
-
|
|
86
|
-
let results: any
|
|
87
|
-
|
|
88
|
-
if (this.embeddings) {
|
|
89
|
-
const embedding = await this.embeddings.generate(currentTask)
|
|
90
|
-
results = await collection.query({
|
|
91
|
-
queryEmbeddings: [embedding],
|
|
92
|
-
nResults: 10,
|
|
93
|
-
where,
|
|
94
|
-
include: ['documents', 'metadatas', 'distances']
|
|
95
|
-
})
|
|
96
|
-
} else {
|
|
97
|
-
results = await collection.query({
|
|
98
|
-
queryTexts: [currentTask],
|
|
99
|
-
nResults: 10,
|
|
100
|
-
where,
|
|
101
|
-
include: ['documents', 'metadatas', 'distances']
|
|
102
|
-
})
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (!results.ids || !results.ids[0]) return []
|
|
106
|
-
|
|
107
|
-
// Extract unique topics from the results
|
|
108
|
-
const topicCounts = new Map<string, { count: number; similarity: number }>()
|
|
109
|
-
const metadatas = results.metadatas?.[0] || []
|
|
110
|
-
const distances = results.distances?.[0] || []
|
|
111
|
-
|
|
112
|
-
for (let i = 0; i < metadatas.length; i++) {
|
|
113
|
-
const tags = String((metadatas[i] as any)?.tags || '').split(',').filter((t: string) => t.trim())
|
|
114
|
-
const similarity = 1 - (distances[i] || 0)
|
|
115
|
-
|
|
116
|
-
for (const tag of tags) {
|
|
117
|
-
const trimmed = tag.trim().toLowerCase()
|
|
118
|
-
if (!trimmed) continue
|
|
119
|
-
|
|
120
|
-
const existing = topicCounts.get(trimmed)
|
|
121
|
-
if (existing) {
|
|
122
|
-
existing.count++
|
|
123
|
-
existing.similarity = Math.max(existing.similarity, similarity)
|
|
124
|
-
} else {
|
|
125
|
-
topicCounts.set(trimmed, { count: 1, similarity })
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return Array.from(topicCounts.entries()).map(([topic, data]) => ({
|
|
131
|
-
topic,
|
|
132
|
-
relevance: data.similarity * (1 + Math.log(data.count + 1) / 5),
|
|
133
|
-
relatedDecisions: data.count,
|
|
134
|
-
suggestedQueries: [`What decisions were made about ${topic}?`, `Show patterns for ${topic}`]
|
|
135
|
-
}))
|
|
136
|
-
} catch (error) {
|
|
137
|
-
this.logger.debug({ error }, 'Failed to find follow-up patterns')
|
|
138
|
-
return []
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
private async findRelatedTopics(
|
|
143
|
-
currentTask: string,
|
|
144
|
-
project?: string
|
|
145
|
-
): Promise<AnticipatedContext[]> {
|
|
146
|
-
try {
|
|
147
|
-
const collection = await this.collections.getPatterns()
|
|
148
|
-
|
|
149
|
-
const where: any = project ? { project: { $eq: project } } : undefined
|
|
150
|
-
|
|
151
|
-
let results: any
|
|
152
|
-
|
|
153
|
-
if (this.embeddings) {
|
|
154
|
-
const embedding = await this.embeddings.generate(currentTask)
|
|
155
|
-
results = await collection.query({
|
|
156
|
-
queryEmbeddings: [embedding],
|
|
157
|
-
nResults: 5,
|
|
158
|
-
where,
|
|
159
|
-
include: ['documents', 'metadatas', 'distances']
|
|
160
|
-
})
|
|
161
|
-
} else {
|
|
162
|
-
results = await collection.query({
|
|
163
|
-
queryTexts: [currentTask],
|
|
164
|
-
nResults: 5,
|
|
165
|
-
where,
|
|
166
|
-
include: ['documents', 'metadatas', 'distances']
|
|
167
|
-
})
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (!results.ids || !results.ids[0]) return []
|
|
171
|
-
|
|
172
|
-
const topics: AnticipatedContext[] = []
|
|
173
|
-
const documents = results.documents?.[0] || []
|
|
174
|
-
const metadatas = results.metadatas?.[0] || []
|
|
175
|
-
const distances = results.distances?.[0] || []
|
|
176
|
-
|
|
177
|
-
for (let i = 0; i < documents.length; i++) {
|
|
178
|
-
const similarity = 1 - (distances[i] || 0)
|
|
179
|
-
if (similarity < 0.3) continue
|
|
180
|
-
|
|
181
|
-
const content = (documents[i] || '').slice(0, 100)
|
|
182
|
-
const patternType = (metadatas[i] as any)?.pattern_type || 'unknown'
|
|
183
|
-
|
|
184
|
-
topics.push({
|
|
185
|
-
topic: `${patternType}: ${content}`,
|
|
186
|
-
relevance: similarity,
|
|
187
|
-
relatedDecisions: 1,
|
|
188
|
-
suggestedQueries: [`Show ${patternType} patterns related to this`]
|
|
189
|
-
})
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return topics
|
|
193
|
-
} catch (error) {
|
|
194
|
-
this.logger.debug({ error }, 'Failed to find related topics')
|
|
195
|
-
return []
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Context Anticipator
|
|
3
|
+
* Anticipates what context will be needed based on current activity
|
|
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 AnticipatedContext {
|
|
11
|
+
topic: string
|
|
12
|
+
relevance: number
|
|
13
|
+
relatedDecisions: number
|
|
14
|
+
suggestedQueries: string[]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class ContextAnticipator {
|
|
18
|
+
private logger: Logger
|
|
19
|
+
private collections: CollectionManager
|
|
20
|
+
private embeddings?: EmbeddingProvider
|
|
21
|
+
private recentTopics: Array<{ topic: string; timestamp: number }> = []
|
|
22
|
+
|
|
23
|
+
constructor(logger: Logger, collections: CollectionManager, embeddings?: EmbeddingProvider) {
|
|
24
|
+
this.logger = logger.child({ component: 'context-anticipator' })
|
|
25
|
+
this.collections = collections
|
|
26
|
+
this.embeddings = embeddings
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Record a topic being worked on for anticipation
|
|
31
|
+
*/
|
|
32
|
+
recordActivity(topic: string): void {
|
|
33
|
+
this.recentTopics.push({ topic, timestamp: Date.now() })
|
|
34
|
+
// Keep last 50 topics
|
|
35
|
+
if (this.recentTopics.length > 50) {
|
|
36
|
+
this.recentTopics = this.recentTopics.slice(-50)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Anticipate what context might be needed next
|
|
42
|
+
*/
|
|
43
|
+
async anticipate(currentTask: string, options: {
|
|
44
|
+
project?: string
|
|
45
|
+
limit?: number
|
|
46
|
+
} = {}): Promise<AnticipatedContext[]> {
|
|
47
|
+
const { project, limit = 5 } = options
|
|
48
|
+
|
|
49
|
+
// Get patterns of what typically follows similar tasks
|
|
50
|
+
const followUpTopics = await this.findFollowUpPatterns(currentTask, project)
|
|
51
|
+
|
|
52
|
+
// Get related but not-yet-accessed topics
|
|
53
|
+
const relatedTopics = await this.findRelatedTopics(currentTask, project)
|
|
54
|
+
|
|
55
|
+
// Merge and rank
|
|
56
|
+
const merged = new Map<string, AnticipatedContext>()
|
|
57
|
+
|
|
58
|
+
for (const t of followUpTopics) {
|
|
59
|
+
merged.set(t.topic, t)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
for (const t of relatedTopics) {
|
|
63
|
+
if (merged.has(t.topic)) {
|
|
64
|
+
const existing = merged.get(t.topic)!
|
|
65
|
+
existing.relevance = Math.max(existing.relevance, t.relevance)
|
|
66
|
+
existing.relatedDecisions = Math.max(existing.relatedDecisions, t.relatedDecisions)
|
|
67
|
+
} else {
|
|
68
|
+
merged.set(t.topic, t)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return Array.from(merged.values())
|
|
73
|
+
.sort((a, b) => b.relevance - a.relevance)
|
|
74
|
+
.slice(0, limit)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private async findFollowUpPatterns(
|
|
78
|
+
currentTask: string,
|
|
79
|
+
project?: string
|
|
80
|
+
): Promise<AnticipatedContext[]> {
|
|
81
|
+
try {
|
|
82
|
+
const collection = await this.collections.getDecisions()
|
|
83
|
+
|
|
84
|
+
const where: any = project ? { project: { $eq: project } } : undefined
|
|
85
|
+
|
|
86
|
+
let results: any
|
|
87
|
+
|
|
88
|
+
if (this.embeddings) {
|
|
89
|
+
const embedding = await this.embeddings.generate(currentTask)
|
|
90
|
+
results = await collection.query({
|
|
91
|
+
queryEmbeddings: [embedding],
|
|
92
|
+
nResults: 10,
|
|
93
|
+
where,
|
|
94
|
+
include: ['documents', 'metadatas', 'distances']
|
|
95
|
+
})
|
|
96
|
+
} else {
|
|
97
|
+
results = await collection.query({
|
|
98
|
+
queryTexts: [currentTask],
|
|
99
|
+
nResults: 10,
|
|
100
|
+
where,
|
|
101
|
+
include: ['documents', 'metadatas', 'distances']
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (!results.ids || !results.ids[0]) return []
|
|
106
|
+
|
|
107
|
+
// Extract unique topics from the results
|
|
108
|
+
const topicCounts = new Map<string, { count: number; similarity: number }>()
|
|
109
|
+
const metadatas = results.metadatas?.[0] || []
|
|
110
|
+
const distances = results.distances?.[0] || []
|
|
111
|
+
|
|
112
|
+
for (let i = 0; i < metadatas.length; i++) {
|
|
113
|
+
const tags = String((metadatas[i] as any)?.tags || '').split(',').filter((t: string) => t.trim())
|
|
114
|
+
const similarity = 1 - (distances[i] || 0)
|
|
115
|
+
|
|
116
|
+
for (const tag of tags) {
|
|
117
|
+
const trimmed = tag.trim().toLowerCase()
|
|
118
|
+
if (!trimmed) continue
|
|
119
|
+
|
|
120
|
+
const existing = topicCounts.get(trimmed)
|
|
121
|
+
if (existing) {
|
|
122
|
+
existing.count++
|
|
123
|
+
existing.similarity = Math.max(existing.similarity, similarity)
|
|
124
|
+
} else {
|
|
125
|
+
topicCounts.set(trimmed, { count: 1, similarity })
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return Array.from(topicCounts.entries()).map(([topic, data]) => ({
|
|
131
|
+
topic,
|
|
132
|
+
relevance: data.similarity * (1 + Math.log(data.count + 1) / 5),
|
|
133
|
+
relatedDecisions: data.count,
|
|
134
|
+
suggestedQueries: [`What decisions were made about ${topic}?`, `Show patterns for ${topic}`]
|
|
135
|
+
}))
|
|
136
|
+
} catch (error) {
|
|
137
|
+
this.logger.debug({ error }, 'Failed to find follow-up patterns')
|
|
138
|
+
return []
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private async findRelatedTopics(
|
|
143
|
+
currentTask: string,
|
|
144
|
+
project?: string
|
|
145
|
+
): Promise<AnticipatedContext[]> {
|
|
146
|
+
try {
|
|
147
|
+
const collection = await this.collections.getPatterns()
|
|
148
|
+
|
|
149
|
+
const where: any = project ? { project: { $eq: project } } : undefined
|
|
150
|
+
|
|
151
|
+
let results: any
|
|
152
|
+
|
|
153
|
+
if (this.embeddings) {
|
|
154
|
+
const embedding = await this.embeddings.generate(currentTask)
|
|
155
|
+
results = await collection.query({
|
|
156
|
+
queryEmbeddings: [embedding],
|
|
157
|
+
nResults: 5,
|
|
158
|
+
where,
|
|
159
|
+
include: ['documents', 'metadatas', 'distances']
|
|
160
|
+
})
|
|
161
|
+
} else {
|
|
162
|
+
results = await collection.query({
|
|
163
|
+
queryTexts: [currentTask],
|
|
164
|
+
nResults: 5,
|
|
165
|
+
where,
|
|
166
|
+
include: ['documents', 'metadatas', 'distances']
|
|
167
|
+
})
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (!results.ids || !results.ids[0]) return []
|
|
171
|
+
|
|
172
|
+
const topics: AnticipatedContext[] = []
|
|
173
|
+
const documents = results.documents?.[0] || []
|
|
174
|
+
const metadatas = results.metadatas?.[0] || []
|
|
175
|
+
const distances = results.distances?.[0] || []
|
|
176
|
+
|
|
177
|
+
for (let i = 0; i < documents.length; i++) {
|
|
178
|
+
const similarity = 1 - (distances[i] || 0)
|
|
179
|
+
if (similarity < 0.3) continue
|
|
180
|
+
|
|
181
|
+
const content = (documents[i] || '').slice(0, 100)
|
|
182
|
+
const patternType = (metadatas[i] as any)?.pattern_type || 'unknown'
|
|
183
|
+
|
|
184
|
+
topics.push({
|
|
185
|
+
topic: `${patternType}: ${content}`,
|
|
186
|
+
relevance: similarity,
|
|
187
|
+
relatedDecisions: 1,
|
|
188
|
+
suggestedQueries: [`Show ${patternType} patterns related to this`]
|
|
189
|
+
})
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return topics
|
|
193
|
+
} catch (error) {
|
|
194
|
+
this.logger.debug({ error }, 'Failed to find related topics')
|
|
195
|
+
return []
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|