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,75 +1,75 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Get Project Context Handler
|
|
3
|
-
* Retrieves complete project context including standards, progress, and memories
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { Logger } from 'pino'
|
|
7
|
-
import type { ToolResponse } from '@/tools/types'
|
|
8
|
-
import { getContextService } from '@/server/services'
|
|
9
|
-
import { ToolValidator } from '@/server/utils/validators'
|
|
10
|
-
import { ResponseFormatter } from '@/server/utils/response-formatter'
|
|
11
|
-
import { ErrorHandler } from '@/server/utils/error-handler'
|
|
12
|
-
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'
|
|
13
|
-
import { GetProjectContextSchema } from './schemas'
|
|
14
|
-
|
|
15
|
-
export async function handleGetProjectContext(
|
|
16
|
-
args: unknown,
|
|
17
|
-
logger: Logger
|
|
18
|
-
): Promise<ToolResponse> {
|
|
19
|
-
try {
|
|
20
|
-
const input = ToolValidator.validate(args, GetProjectContextSchema)
|
|
21
|
-
const { project_name, include_memories, memory_limit } = input
|
|
22
|
-
|
|
23
|
-
logger.debug({
|
|
24
|
-
project_name,
|
|
25
|
-
include_memories,
|
|
26
|
-
memory_limit
|
|
27
|
-
}, 'Getting project context')
|
|
28
|
-
|
|
29
|
-
const contextService = getContextService()
|
|
30
|
-
|
|
31
|
-
const context = await contextService.getContext(project_name, {
|
|
32
|
-
includeMemories: include_memories,
|
|
33
|
-
includeProgress: true,
|
|
34
|
-
includeStandards: true,
|
|
35
|
-
maxTokens: 8000,
|
|
36
|
-
relevanceThreshold: 0.6
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
if (context.memories.length > memory_limit) {
|
|
40
|
-
context.memories = context.memories.slice(0, memory_limit)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const formatted = contextService.formatter.format(context)
|
|
44
|
-
|
|
45
|
-
logger.info(
|
|
46
|
-
{
|
|
47
|
-
projectName: project_name,
|
|
48
|
-
tokenCount: context.metadata.tokenCount,
|
|
49
|
-
memories: context.memories.length
|
|
50
|
-
},
|
|
51
|
-
'Context retrieved successfully'
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
return ResponseFormatter.text(formatted)
|
|
55
|
-
|
|
56
|
-
} catch (error) {
|
|
57
|
-
ErrorHandler.logError(logger, error, { tool: 'get_project_context', args })
|
|
58
|
-
|
|
59
|
-
if (error instanceof McpError) {
|
|
60
|
-
throw error
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (error instanceof Error && (error.message.includes('ENOENT') || error.message.includes('not found'))) {
|
|
64
|
-
throw new McpError(
|
|
65
|
-
ErrorCode.InvalidParams,
|
|
66
|
-
`Project "${(args as any).project_name}" not found. Available projects can be listed using list_projects tool.`
|
|
67
|
-
)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
throw new McpError(
|
|
71
|
-
ErrorCode.InternalError,
|
|
72
|
-
`Failed to get project context: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
73
|
-
)
|
|
74
|
-
}
|
|
75
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Get Project Context Handler
|
|
3
|
+
* Retrieves complete project context including standards, progress, and memories
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Logger } from 'pino'
|
|
7
|
+
import type { ToolResponse } from '@/tools/types'
|
|
8
|
+
import { getContextService } from '@/server/services'
|
|
9
|
+
import { ToolValidator } from '@/server/utils/validators'
|
|
10
|
+
import { ResponseFormatter } from '@/server/utils/response-formatter'
|
|
11
|
+
import { ErrorHandler } from '@/server/utils/error-handler'
|
|
12
|
+
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'
|
|
13
|
+
import { GetProjectContextSchema } from './schemas'
|
|
14
|
+
|
|
15
|
+
export async function handleGetProjectContext(
|
|
16
|
+
args: unknown,
|
|
17
|
+
logger: Logger
|
|
18
|
+
): Promise<ToolResponse> {
|
|
19
|
+
try {
|
|
20
|
+
const input = ToolValidator.validate(args, GetProjectContextSchema)
|
|
21
|
+
const { project_name, include_memories, memory_limit } = input
|
|
22
|
+
|
|
23
|
+
logger.debug({
|
|
24
|
+
project_name,
|
|
25
|
+
include_memories,
|
|
26
|
+
memory_limit
|
|
27
|
+
}, 'Getting project context')
|
|
28
|
+
|
|
29
|
+
const contextService = getContextService()
|
|
30
|
+
|
|
31
|
+
const context = await contextService.getContext(project_name, {
|
|
32
|
+
includeMemories: include_memories,
|
|
33
|
+
includeProgress: true,
|
|
34
|
+
includeStandards: true,
|
|
35
|
+
maxTokens: 8000,
|
|
36
|
+
relevanceThreshold: 0.6
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
if (context.memories.length > memory_limit) {
|
|
40
|
+
context.memories = context.memories.slice(0, memory_limit)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const formatted = contextService.formatter.format(context)
|
|
44
|
+
|
|
45
|
+
logger.info(
|
|
46
|
+
{
|
|
47
|
+
projectName: project_name,
|
|
48
|
+
tokenCount: context.metadata.tokenCount,
|
|
49
|
+
memories: context.memories.length
|
|
50
|
+
},
|
|
51
|
+
'Context retrieved successfully'
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
return ResponseFormatter.text(formatted)
|
|
55
|
+
|
|
56
|
+
} catch (error) {
|
|
57
|
+
ErrorHandler.logError(logger, error, { tool: 'get_project_context', args })
|
|
58
|
+
|
|
59
|
+
if (error instanceof McpError) {
|
|
60
|
+
throw error
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (error instanceof Error && (error.message.includes('ENOENT') || error.message.includes('not found'))) {
|
|
64
|
+
throw new McpError(
|
|
65
|
+
ErrorCode.InvalidParams,
|
|
66
|
+
`Project "${(args as any).project_name}" not found. Available projects can be listed using list_projects tool.`
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
throw new McpError(
|
|
71
|
+
ErrorCode.InternalError,
|
|
72
|
+
`Failed to get project context: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -1,145 +1,145 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Get Recommendations Handler
|
|
3
|
-
* Provides recommendations based on project history, patterns, and corrections
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { Logger } from 'pino'
|
|
7
|
-
import type { ToolResponse } from '@/tools/types'
|
|
8
|
-
import { getMemoryService } from '@/server/services'
|
|
9
|
-
import { ToolValidator } from '@/server/utils/validators'
|
|
10
|
-
import { ResponseFormatter } from '@/server/utils/response-formatter'
|
|
11
|
-
import { withMemoryIndicator, formatMemoryStats } from '@/server/utils/memory-indicator'
|
|
12
|
-
import { ErrorHandler } from '@/server/utils/error-handler'
|
|
13
|
-
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'
|
|
14
|
-
import { GetRecommendationsSchema } from './schemas'
|
|
15
|
-
import { Recommender } from '@/intelligence/prediction/recommender'
|
|
16
|
-
|
|
17
|
-
export async function handleGetRecommendations(
|
|
18
|
-
args: unknown,
|
|
19
|
-
logger: Logger
|
|
20
|
-
): Promise<ToolResponse> {
|
|
21
|
-
try {
|
|
22
|
-
const input = ToolValidator.validate(args, GetRecommendationsSchema)
|
|
23
|
-
const { query, project_name, limit } = input
|
|
24
|
-
|
|
25
|
-
const memory = getMemoryService()
|
|
26
|
-
|
|
27
|
-
if (!memory.isChromaDBEnabled()) {
|
|
28
|
-
// SQLite fallback: combine searchRaw + searchPatterns + searchCorrections
|
|
29
|
-
const [rawResults, patternResults, correctionResults] = await Promise.all([
|
|
30
|
-
memory.searchRaw(query, { project: project_name, limit: limit || 5, minSimilarity: 0.2 }),
|
|
31
|
-
memory.searchPatterns(query, { project: project_name, limit: limit || 5, minSimilarity: 0.2 }),
|
|
32
|
-
memory.searchCorrections(query, { project: project_name, limit: limit || 5, minSimilarity: 0.2 })
|
|
33
|
-
])
|
|
34
|
-
|
|
35
|
-
// Combine and format as recommendations
|
|
36
|
-
const recommendations: Array<{ type: string; source: string; content: string; reasoning: string; confidence: number }> = []
|
|
37
|
-
|
|
38
|
-
// Corrections get highest priority (lessons learned)
|
|
39
|
-
for (const c of correctionResults) {
|
|
40
|
-
recommendations.push({
|
|
41
|
-
type: 'correction',
|
|
42
|
-
source: 'Past Correction',
|
|
43
|
-
content: `Original: ${c.metadata?.original || ''}\nCorrection: ${c.metadata?.correction || c.content || ''}`,
|
|
44
|
-
reasoning: c.metadata?.reasoning || 'Based on previous lesson learned',
|
|
45
|
-
confidence: c.similarity || c.metadata?.confidence || 0.5
|
|
46
|
-
})
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Patterns
|
|
50
|
-
for (const p of patternResults) {
|
|
51
|
-
recommendations.push({
|
|
52
|
-
type: p.metadata?.pattern_type || 'pattern',
|
|
53
|
-
source: `Pattern (${p.metadata?.pattern_type || 'general'})`,
|
|
54
|
-
content: p.metadata?.description || p.content || '',
|
|
55
|
-
reasoning: p.metadata?.context || 'Based on recognized pattern',
|
|
56
|
-
confidence: p.similarity || p.metadata?.confidence || 0.5
|
|
57
|
-
})
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Decisions
|
|
61
|
-
for (const r of rawResults) {
|
|
62
|
-
recommendations.push({
|
|
63
|
-
type: 'decision',
|
|
64
|
-
source: 'Past Decision',
|
|
65
|
-
content: r.decision?.decision || r.memory?.content?.slice(0, 300) || '',
|
|
66
|
-
reasoning: r.decision?.reasoning || 'Based on similar past decision',
|
|
67
|
-
confidence: r.similarity || 0.5
|
|
68
|
-
})
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Sort by confidence, deduplicate, and limit
|
|
72
|
-
const seen = new Set<string>()
|
|
73
|
-
const deduped = recommendations.filter(r => {
|
|
74
|
-
const key = r.content.slice(0, 50)
|
|
75
|
-
if (seen.has(key)) return false
|
|
76
|
-
seen.add(key)
|
|
77
|
-
return true
|
|
78
|
-
})
|
|
79
|
-
.sort((a, b) => b.confidence - a.confidence)
|
|
80
|
-
.slice(0, limit || 5)
|
|
81
|
-
|
|
82
|
-
if (deduped.length === 0) {
|
|
83
|
-
return ResponseFormatter.text(`No recommendations found for: "${query}"`)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const parts: string[] = []
|
|
87
|
-
parts.push(`## Recommendations (SQLite)`)
|
|
88
|
-
parts.push(`**Query:** ${query}`)
|
|
89
|
-
if (project_name) parts.push(`**Project:** ${project_name}`)
|
|
90
|
-
parts.push(`**Found:** ${deduped.length}`)
|
|
91
|
-
parts.push('')
|
|
92
|
-
|
|
93
|
-
for (const rec of deduped) {
|
|
94
|
-
const confidence = Math.round(rec.confidence * 100)
|
|
95
|
-
const icon = rec.type === 'correction' ? '⚠️' : rec.type === 'best-practice' ? '✅' : rec.type === 'pattern' ? '🔄' : '📋'
|
|
96
|
-
parts.push(`### ${icon} ${rec.source} (${confidence}% confidence)`)
|
|
97
|
-
parts.push(rec.content.slice(0, 300))
|
|
98
|
-
parts.push(`*${rec.reasoning}*`)
|
|
99
|
-
parts.push('')
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const statsLine = formatMemoryStats({ recalled: deduped.length })
|
|
103
|
-
return ResponseFormatter.text(withMemoryIndicator(parts.join('\n'), deduped.length) + '\n\n' + statsLine)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const recommender = new Recommender(
|
|
107
|
-
logger,
|
|
108
|
-
memory.chroma.collections,
|
|
109
|
-
memory.chroma.embeddings
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
const result = await recommender.getRecommendations(query, {
|
|
113
|
-
project: project_name,
|
|
114
|
-
limit
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
if (result.recommendations.length === 0) {
|
|
118
|
-
return ResponseFormatter.text(`No recommendations found for: "${query}"`)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const parts: string[] = []
|
|
122
|
-
parts.push(`## Recommendations`)
|
|
123
|
-
parts.push(`**Query:** ${query}`)
|
|
124
|
-
if (project_name) parts.push(`**Project:** ${project_name}`)
|
|
125
|
-
parts.push(`**Found:** ${result.recommendations.length} (from ${result.totalConsidered} considered)`)
|
|
126
|
-
parts.push('')
|
|
127
|
-
|
|
128
|
-
for (const rec of result.recommendations) {
|
|
129
|
-
const confidence = Math.round(rec.confidence * 100)
|
|
130
|
-
const icon = rec.type === 'correction' ? '⚠️' : rec.type === 'best-practice' ? '✅' : rec.type === 'pattern' ? '🔄' : '📋'
|
|
131
|
-
parts.push(`### ${icon} ${rec.source} (${confidence}% confidence)`)
|
|
132
|
-
parts.push(rec.content.slice(0, 300))
|
|
133
|
-
parts.push(`*${rec.reasoning}*`)
|
|
134
|
-
parts.push('')
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const statsLine = formatMemoryStats({ recalled: result.recommendations.length })
|
|
138
|
-
return ResponseFormatter.text(withMemoryIndicator(parts.join('\n'), result.recommendations.length) + '\n\n' + statsLine)
|
|
139
|
-
|
|
140
|
-
} catch (error) {
|
|
141
|
-
ErrorHandler.logError(logger, error, { tool: 'get_recommendations' })
|
|
142
|
-
if (error instanceof McpError) throw error
|
|
143
|
-
throw new McpError(ErrorCode.InternalError, `Recommendations failed: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
144
|
-
}
|
|
145
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Get Recommendations Handler
|
|
3
|
+
* Provides recommendations based on project history, patterns, and corrections
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Logger } from 'pino'
|
|
7
|
+
import type { ToolResponse } from '@/tools/types'
|
|
8
|
+
import { getMemoryService } from '@/server/services'
|
|
9
|
+
import { ToolValidator } from '@/server/utils/validators'
|
|
10
|
+
import { ResponseFormatter } from '@/server/utils/response-formatter'
|
|
11
|
+
import { withMemoryIndicator, formatMemoryStats } from '@/server/utils/memory-indicator'
|
|
12
|
+
import { ErrorHandler } from '@/server/utils/error-handler'
|
|
13
|
+
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'
|
|
14
|
+
import { GetRecommendationsSchema } from './schemas'
|
|
15
|
+
import { Recommender } from '@/intelligence/prediction/recommender'
|
|
16
|
+
|
|
17
|
+
export async function handleGetRecommendations(
|
|
18
|
+
args: unknown,
|
|
19
|
+
logger: Logger
|
|
20
|
+
): Promise<ToolResponse> {
|
|
21
|
+
try {
|
|
22
|
+
const input = ToolValidator.validate(args, GetRecommendationsSchema)
|
|
23
|
+
const { query, project_name, limit } = input
|
|
24
|
+
|
|
25
|
+
const memory = getMemoryService()
|
|
26
|
+
|
|
27
|
+
if (!memory.isChromaDBEnabled()) {
|
|
28
|
+
// SQLite fallback: combine searchRaw + searchPatterns + searchCorrections
|
|
29
|
+
const [rawResults, patternResults, correctionResults] = await Promise.all([
|
|
30
|
+
memory.searchRaw(query, { project: project_name, limit: limit || 5, minSimilarity: 0.2 }),
|
|
31
|
+
memory.searchPatterns(query, { project: project_name, limit: limit || 5, minSimilarity: 0.2 }),
|
|
32
|
+
memory.searchCorrections(query, { project: project_name, limit: limit || 5, minSimilarity: 0.2 })
|
|
33
|
+
])
|
|
34
|
+
|
|
35
|
+
// Combine and format as recommendations
|
|
36
|
+
const recommendations: Array<{ type: string; source: string; content: string; reasoning: string; confidence: number }> = []
|
|
37
|
+
|
|
38
|
+
// Corrections get highest priority (lessons learned)
|
|
39
|
+
for (const c of correctionResults) {
|
|
40
|
+
recommendations.push({
|
|
41
|
+
type: 'correction',
|
|
42
|
+
source: 'Past Correction',
|
|
43
|
+
content: `Original: ${c.metadata?.original || ''}\nCorrection: ${c.metadata?.correction || c.content || ''}`,
|
|
44
|
+
reasoning: c.metadata?.reasoning || 'Based on previous lesson learned',
|
|
45
|
+
confidence: c.similarity || c.metadata?.confidence || 0.5
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Patterns
|
|
50
|
+
for (const p of patternResults) {
|
|
51
|
+
recommendations.push({
|
|
52
|
+
type: p.metadata?.pattern_type || 'pattern',
|
|
53
|
+
source: `Pattern (${p.metadata?.pattern_type || 'general'})`,
|
|
54
|
+
content: p.metadata?.description || p.content || '',
|
|
55
|
+
reasoning: p.metadata?.context || 'Based on recognized pattern',
|
|
56
|
+
confidence: p.similarity || p.metadata?.confidence || 0.5
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Decisions
|
|
61
|
+
for (const r of rawResults) {
|
|
62
|
+
recommendations.push({
|
|
63
|
+
type: 'decision',
|
|
64
|
+
source: 'Past Decision',
|
|
65
|
+
content: r.decision?.decision || r.memory?.content?.slice(0, 300) || '',
|
|
66
|
+
reasoning: r.decision?.reasoning || 'Based on similar past decision',
|
|
67
|
+
confidence: r.similarity || 0.5
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Sort by confidence, deduplicate, and limit
|
|
72
|
+
const seen = new Set<string>()
|
|
73
|
+
const deduped = recommendations.filter(r => {
|
|
74
|
+
const key = r.content.slice(0, 50)
|
|
75
|
+
if (seen.has(key)) return false
|
|
76
|
+
seen.add(key)
|
|
77
|
+
return true
|
|
78
|
+
})
|
|
79
|
+
.sort((a, b) => b.confidence - a.confidence)
|
|
80
|
+
.slice(0, limit || 5)
|
|
81
|
+
|
|
82
|
+
if (deduped.length === 0) {
|
|
83
|
+
return ResponseFormatter.text(`No recommendations found for: "${query}"`)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const parts: string[] = []
|
|
87
|
+
parts.push(`## Recommendations (SQLite)`)
|
|
88
|
+
parts.push(`**Query:** ${query}`)
|
|
89
|
+
if (project_name) parts.push(`**Project:** ${project_name}`)
|
|
90
|
+
parts.push(`**Found:** ${deduped.length}`)
|
|
91
|
+
parts.push('')
|
|
92
|
+
|
|
93
|
+
for (const rec of deduped) {
|
|
94
|
+
const confidence = Math.round(rec.confidence * 100)
|
|
95
|
+
const icon = rec.type === 'correction' ? '⚠️' : rec.type === 'best-practice' ? '✅' : rec.type === 'pattern' ? '🔄' : '📋'
|
|
96
|
+
parts.push(`### ${icon} ${rec.source} (${confidence}% confidence)`)
|
|
97
|
+
parts.push(rec.content.slice(0, 300))
|
|
98
|
+
parts.push(`*${rec.reasoning}*`)
|
|
99
|
+
parts.push('')
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const statsLine = formatMemoryStats({ recalled: deduped.length })
|
|
103
|
+
return ResponseFormatter.text(withMemoryIndicator(parts.join('\n'), deduped.length) + '\n\n' + statsLine)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const recommender = new Recommender(
|
|
107
|
+
logger,
|
|
108
|
+
memory.chroma.collections,
|
|
109
|
+
memory.chroma.embeddings
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
const result = await recommender.getRecommendations(query, {
|
|
113
|
+
project: project_name,
|
|
114
|
+
limit
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
if (result.recommendations.length === 0) {
|
|
118
|
+
return ResponseFormatter.text(`No recommendations found for: "${query}"`)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const parts: string[] = []
|
|
122
|
+
parts.push(`## Recommendations`)
|
|
123
|
+
parts.push(`**Query:** ${query}`)
|
|
124
|
+
if (project_name) parts.push(`**Project:** ${project_name}`)
|
|
125
|
+
parts.push(`**Found:** ${result.recommendations.length} (from ${result.totalConsidered} considered)`)
|
|
126
|
+
parts.push('')
|
|
127
|
+
|
|
128
|
+
for (const rec of result.recommendations) {
|
|
129
|
+
const confidence = Math.round(rec.confidence * 100)
|
|
130
|
+
const icon = rec.type === 'correction' ? '⚠️' : rec.type === 'best-practice' ? '✅' : rec.type === 'pattern' ? '🔄' : '📋'
|
|
131
|
+
parts.push(`### ${icon} ${rec.source} (${confidence}% confidence)`)
|
|
132
|
+
parts.push(rec.content.slice(0, 300))
|
|
133
|
+
parts.push(`*${rec.reasoning}*`)
|
|
134
|
+
parts.push('')
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const statsLine = formatMemoryStats({ recalled: result.recommendations.length })
|
|
138
|
+
return ResponseFormatter.text(withMemoryIndicator(parts.join('\n'), result.recommendations.length) + '\n\n' + statsLine)
|
|
139
|
+
|
|
140
|
+
} catch (error) {
|
|
141
|
+
ErrorHandler.logError(logger, error, { tool: 'get_recommendations' })
|
|
142
|
+
if (error instanceof McpError) throw error
|
|
143
|
+
throw new McpError(ErrorCode.InternalError, `Recommendations failed: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool Handlers Exports
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export { handleGetProjectContext } from './get-project-context'
|
|
6
|
-
export { handleUpdateProgress } from './update-progress'
|
|
7
|
-
export { handleRememberDecision } from './remember-decision'
|
|
8
|
-
export { handleRecallSimilar } from './recall-similar'
|
|
9
|
-
export { handleGetCodeStandards } from './get-code-standards'
|
|
10
|
-
export { handleListProjects } from './list-projects'
|
|
11
|
-
|
|
12
|
-
// Phase 12 Tools
|
|
13
|
-
export { handleSmartContext } from './smart-context'
|
|
14
|
-
export { handleAutoRemember } from './auto-remember'
|
|
15
|
-
export { handleGetPhase12Status } from './get-phase12-status'
|
|
16
|
-
|
|
17
|
-
// Pattern & Correction Tools
|
|
18
|
-
export { handleRecognizePattern } from './recognize-pattern'
|
|
19
|
-
export { handleRecordCorrection } from './record-correction'
|
|
20
|
-
export { handleGetPatterns } from './get-patterns'
|
|
21
|
-
export { handleGetCorrections } from './get-corrections'
|
|
22
|
-
|
|
23
|
-
// Project Management
|
|
24
|
-
export { handleCreateProject } from './create-project'
|
|
25
|
-
export { handleInitProject } from './init-project'
|
|
26
|
-
|
|
27
|
-
// Phase 19: Removed 9 redundant tool exports.
|
|
28
|
-
// rate_memory, search_knowledge_graph, get_episode, list_episodes,
|
|
29
|
-
// get_decision_timeline, analyze_decision_evolution, detect_trends,
|
|
30
|
-
// what_if_analysis, get_recommendations, find_cross_project_patterns
|
|
31
|
-
// are now absorbed into brain(). Handler files kept for reference.
|
|
1
|
+
/**
|
|
2
|
+
* Tool Handlers Exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export { handleGetProjectContext } from './get-project-context'
|
|
6
|
+
export { handleUpdateProgress } from './update-progress'
|
|
7
|
+
export { handleRememberDecision } from './remember-decision'
|
|
8
|
+
export { handleRecallSimilar } from './recall-similar'
|
|
9
|
+
export { handleGetCodeStandards } from './get-code-standards'
|
|
10
|
+
export { handleListProjects } from './list-projects'
|
|
11
|
+
|
|
12
|
+
// Phase 12 Tools
|
|
13
|
+
export { handleSmartContext } from './smart-context'
|
|
14
|
+
export { handleAutoRemember } from './auto-remember'
|
|
15
|
+
export { handleGetPhase12Status } from './get-phase12-status'
|
|
16
|
+
|
|
17
|
+
// Pattern & Correction Tools
|
|
18
|
+
export { handleRecognizePattern } from './recognize-pattern'
|
|
19
|
+
export { handleRecordCorrection } from './record-correction'
|
|
20
|
+
export { handleGetPatterns } from './get-patterns'
|
|
21
|
+
export { handleGetCorrections } from './get-corrections'
|
|
22
|
+
|
|
23
|
+
// Project Management
|
|
24
|
+
export { handleCreateProject } from './create-project'
|
|
25
|
+
export { handleInitProject } from './init-project'
|
|
26
|
+
|
|
27
|
+
// Phase 19: Removed 9 redundant tool exports.
|
|
28
|
+
// rate_memory, search_knowledge_graph, get_episode, list_episodes,
|
|
29
|
+
// get_decision_timeline, analyze_decision_evolution, detect_trends,
|
|
30
|
+
// what_if_analysis, get_recommendations, find_cross_project_patterns
|
|
31
|
+
// are now absorbed into brain(). Handler files kept for reference.
|