squish-memory 1.2.0 → 1.2.1
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/bin/squish-mcp.mjs +40 -42
- package/core/scheduler/cron-scheduler.ts +10 -1
- package/core/worker.ts +10 -1
- package/package.json +119 -119
- package/packages/mcp/src/index.ts +99 -36
- package/dist/config.d.ts +0 -106
- package/dist/config.js +0 -194
- package/dist/core/adapters/config/claude-code.d.ts +0 -45
- package/dist/core/adapters/config/claude-code.js +0 -113
- package/dist/core/adapters/config/cursor.d.ts +0 -26
- package/dist/core/adapters/config/cursor.js +0 -74
- package/dist/core/adapters/config/opencode.d.ts +0 -23
- package/dist/core/adapters/config/opencode.js +0 -73
- package/dist/core/adapters/config/windsurf.d.ts +0 -26
- package/dist/core/adapters/config/windsurf.js +0 -74
- package/dist/core/adapters/index.d.ts +0 -45
- package/dist/core/adapters/index.js +0 -84
- package/dist/core/adapters/scripts/install-adapter.d.ts +0 -19
- package/dist/core/adapters/scripts/install-adapter.js +0 -149
- package/dist/core/adapters/timeline.d.ts +0 -23
- package/dist/core/adapters/timeline.js +0 -88
- package/dist/core/adapters/types.d.ts +0 -137
- package/dist/core/adapters/types.js +0 -50
- package/dist/core/agent-preferences.d.ts +0 -16
- package/dist/core/agent-preferences.js +0 -124
- package/dist/core/algorithms/analytics/token-estimator.d.ts +0 -50
- package/dist/core/algorithms/analytics/token-estimator.js +0 -154
- package/dist/core/algorithms/detection/hash-filters.d.ts +0 -47
- package/dist/core/algorithms/detection/hash-filters.js +0 -190
- package/dist/core/algorithms/detection/semantic-ranker.d.ts +0 -32
- package/dist/core/algorithms/detection/semantic-ranker.js +0 -118
- package/dist/core/algorithms/detection/two-stage-detector.d.ts +0 -52
- package/dist/core/algorithms/detection/two-stage-detector.js +0 -299
- package/dist/core/algorithms/handlers/approve-merge.d.ts +0 -22
- package/dist/core/algorithms/handlers/approve-merge.js +0 -179
- package/dist/core/algorithms/handlers/detect-duplicates.d.ts +0 -47
- package/dist/core/algorithms/handlers/detect-duplicates.js +0 -145
- package/dist/core/algorithms/handlers/get-stats.d.ts +0 -39
- package/dist/core/algorithms/handlers/get-stats.js +0 -88
- package/dist/core/algorithms/handlers/list-proposals.d.ts +0 -45
- package/dist/core/algorithms/handlers/list-proposals.js +0 -83
- package/dist/core/algorithms/handlers/preview-merge.d.ts +0 -39
- package/dist/core/algorithms/handlers/preview-merge.js +0 -93
- package/dist/core/algorithms/handlers/reject-merge.d.ts +0 -28
- package/dist/core/algorithms/handlers/reject-merge.js +0 -69
- package/dist/core/algorithms/handlers/reverse-merge.d.ts +0 -21
- package/dist/core/algorithms/handlers/reverse-merge.js +0 -121
- package/dist/core/algorithms/index.d.ts +0 -21
- package/dist/core/algorithms/index.js +0 -26
- package/dist/core/algorithms/operations/cache-maintenance.d.ts +0 -12
- package/dist/core/algorithms/operations/cache-maintenance.js +0 -157
- package/dist/core/algorithms/safety/safety-checks.d.ts +0 -18
- package/dist/core/algorithms/safety/safety-checks.js +0 -179
- package/dist/core/algorithms/strategies/merge-strategies.d.ts +0 -50
- package/dist/core/algorithms/strategies/merge-strategies.js +0 -288
- package/dist/core/algorithms/types.d.ts +0 -125
- package/dist/core/algorithms/types.js +0 -5
- package/dist/core/algorithms/utils/response-builder.d.ts +0 -28
- package/dist/core/algorithms/utils/response-builder.js +0 -37
- package/dist/core/associations.d.ts +0 -33
- package/dist/core/associations.js +0 -284
- package/dist/core/autosave.d.ts +0 -19
- package/dist/core/autosave.js +0 -16
- package/dist/core/beliefs/decay.d.ts +0 -27
- package/dist/core/beliefs/decay.js +0 -217
- package/dist/core/beliefs/extractor.d.ts +0 -9
- package/dist/core/beliefs/extractor.js +0 -113
- package/dist/core/beliefs/store.d.ts +0 -46
- package/dist/core/beliefs/store.js +0 -466
- package/dist/core/beliefs/types.d.ts +0 -28
- package/dist/core/beliefs/types.js +0 -2
- package/dist/core/commands/mcp-server.d.ts +0 -2
- package/dist/core/commands/mcp-server.js +0 -6
- package/dist/core/commands/remember.d.ts +0 -24
- package/dist/core/commands/remember.js +0 -144
- package/dist/core/compression.d.ts +0 -45
- package/dist/core/compression.js +0 -160
- package/dist/core/consolidation.d.ts +0 -37
- package/dist/core/consolidation.js +0 -248
- package/dist/core/context/agent-context.d.ts +0 -106
- package/dist/core/context/agent-context.js +0 -274
- package/dist/core/context/context-paging.d.ts +0 -80
- package/dist/core/context/context-paging.js +0 -328
- package/dist/core/context/context-window.d.ts +0 -40
- package/dist/core/context/context-window.js +0 -177
- package/dist/core/context/context.d.ts +0 -7
- package/dist/core/context/context.js +0 -22
- package/dist/core/embeddings/embeddings.d.ts +0 -29
- package/dist/core/embeddings/embeddings.js +0 -546
- package/dist/core/embeddings/google-multimodal.d.ts +0 -14
- package/dist/core/embeddings/google-multimodal.js +0 -146
- package/dist/core/embeddings/local-embeddings.d.ts +0 -11
- package/dist/core/embeddings/local-embeddings.js +0 -11
- package/dist/core/embeddings/qmd-client.d.ts +0 -136
- package/dist/core/embeddings/qmd-client.js +0 -403
- package/dist/core/embeddings/transformers-local.d.ts +0 -64
- package/dist/core/embeddings/transformers-local.js +0 -213
- package/dist/core/embeddings.d.ts +0 -2
- package/dist/core/embeddings.js +0 -3
- package/dist/core/error-handling.d.ts +0 -63
- package/dist/core/error-handling.js +0 -173
- package/dist/core/graph/entity-deduplicator.d.ts +0 -24
- package/dist/core/graph/entity-deduplicator.js +0 -183
- package/dist/core/graph/graph-builder.d.ts +0 -46
- package/dist/core/graph/graph-builder.js +0 -174
- package/dist/core/graph/graph-traversal.d.ts +0 -80
- package/dist/core/graph/graph-traversal.js +0 -315
- package/dist/core/graph/index.d.ts +0 -19
- package/dist/core/graph/index.js +0 -13
- package/dist/core/graph/llm-entity-extractor.d.ts +0 -49
- package/dist/core/graph/llm-entity-extractor.js +0 -313
- package/dist/core/graph/multi-hop-retrieval.d.ts +0 -48
- package/dist/core/graph/multi-hop-retrieval.js +0 -215
- package/dist/core/graph/relationship-extractor.d.ts +0 -48
- package/dist/core/graph/relationship-extractor.js +0 -351
- package/dist/core/hooks/agent-hooks.d.ts +0 -83
- package/dist/core/hooks/agent-hooks.js +0 -521
- package/dist/core/hooks/auto-tagger.d.ts +0 -19
- package/dist/core/hooks/auto-tagger.js +0 -155
- package/dist/core/hooks/capture-filter.d.ts +0 -41
- package/dist/core/hooks/capture-filter.js +0 -128
- package/dist/core/hot-cache.d.ts +0 -86
- package/dist/core/hot-cache.js +0 -285
- package/dist/core/index.d.ts +0 -10
- package/dist/core/index.js +0 -11
- package/dist/core/ingestion/agent-memory.d.ts +0 -22
- package/dist/core/ingestion/agent-memory.js +0 -109
- package/dist/core/ingestion/core-memory.d.ts +0 -78
- package/dist/core/ingestion/core-memory.js +0 -226
- package/dist/core/ingestion/learnings.d.ts +0 -57
- package/dist/core/ingestion/learnings.js +0 -205
- package/dist/core/ingestion/signal-engine.d.ts +0 -41
- package/dist/core/ingestion/signal-engine.js +0 -201
- package/dist/core/integrations/obsidian-vault.d.ts +0 -31
- package/dist/core/integrations/obsidian-vault.js +0 -156
- package/dist/core/layers/generator.d.ts +0 -25
- package/dist/core/layers/generator.js +0 -76
- package/dist/core/lib/db-client.d.ts +0 -114
- package/dist/core/lib/db-client.js +0 -130
- package/dist/core/lib/parse-embedding.d.ts +0 -9
- package/dist/core/lib/parse-embedding.js +0 -58
- package/dist/core/lib/schemas.d.ts +0 -132
- package/dist/core/lib/schemas.js +0 -87
- package/dist/core/lib/types.d.ts +0 -45
- package/dist/core/lib/types.js +0 -6
- package/dist/core/lib/utils.d.ts +0 -18
- package/dist/core/lib/utils.js +0 -145
- package/dist/core/lib/validation.d.ts +0 -38
- package/dist/core/lib/validation.js +0 -151
- package/dist/core/lifecycle.d.ts +0 -25
- package/dist/core/lifecycle.js +0 -292
- package/dist/core/logger.d.ts +0 -17
- package/dist/core/logger.js +0 -46
- package/dist/core/mcp/client.d.ts +0 -17
- package/dist/core/mcp/client.js +0 -101
- package/dist/core/mcp/index.d.ts +0 -6
- package/dist/core/mcp/index.js +0 -6
- package/dist/core/mcp/server.d.ts +0 -18
- package/dist/core/mcp/server.js +0 -157
- package/dist/core/mcp/standalone-server.d.ts +0 -13
- package/dist/core/mcp/standalone-server.js +0 -46
- package/dist/core/mcp/tools.d.ts +0 -7
- package/dist/core/mcp/tools.js +0 -278
- package/dist/core/mcp/types.d.ts +0 -87
- package/dist/core/mcp/types.js +0 -48
- package/dist/core/memory/bridge-discovery.d.ts +0 -50
- package/dist/core/memory/bridge-discovery.js +0 -291
- package/dist/core/memory/categorizer.d.ts +0 -27
- package/dist/core/memory/categorizer.js +0 -306
- package/dist/core/memory/conflict-detector.d.ts +0 -7
- package/dist/core/memory/conflict-detector.js +0 -43
- package/dist/core/memory/consolidation.d.ts +0 -42
- package/dist/core/memory/consolidation.js +0 -277
- package/dist/core/memory/context-collector.d.ts +0 -10
- package/dist/core/memory/context-collector.js +0 -56
- package/dist/core/memory/contradiction-resolver.d.ts +0 -40
- package/dist/core/memory/contradiction-resolver.js +0 -368
- package/dist/core/memory/edit-workflow.d.ts +0 -19
- package/dist/core/memory/edit-workflow.js +0 -120
- package/dist/core/memory/entity-extractor.d.ts +0 -37
- package/dist/core/memory/entity-extractor.js +0 -350
- package/dist/core/memory/entity-resolver.d.ts +0 -23
- package/dist/core/memory/entity-resolver.js +0 -64
- package/dist/core/memory/explain.d.ts +0 -18
- package/dist/core/memory/explain.js +0 -92
- package/dist/core/memory/fact-deriver.d.ts +0 -31
- package/dist/core/memory/fact-deriver.js +0 -236
- package/dist/core/memory/fact-extractor.d.ts +0 -24
- package/dist/core/memory/fact-extractor.js +0 -89
- package/dist/core/memory/feedback-tracker.d.ts +0 -12
- package/dist/core/memory/feedback-tracker.js +0 -155
- package/dist/core/memory/hooks.d.ts +0 -88
- package/dist/core/memory/hooks.js +0 -174
- package/dist/core/memory/hybrid-retrieval.d.ts +0 -27
- package/dist/core/memory/hybrid-retrieval.js +0 -37
- package/dist/core/memory/hybrid-scorer.d.ts +0 -40
- package/dist/core/memory/hybrid-scorer.js +0 -267
- package/dist/core/memory/hybrid-search.d.ts +0 -23
- package/dist/core/memory/hybrid-search.js +0 -596
- package/dist/core/memory/importance.d.ts +0 -46
- package/dist/core/memory/importance.js +0 -241
- package/dist/core/memory/index.d.ts +0 -9
- package/dist/core/memory/index.js +0 -11
- package/dist/core/memory/loader.d.ts +0 -31
- package/dist/core/memory/loader.js +0 -141
- package/dist/core/memory/markdown/markdown-storage.d.ts +0 -72
- package/dist/core/memory/markdown/markdown-storage.js +0 -243
- package/dist/core/memory/memories.d.ts +0 -43
- package/dist/core/memory/memories.js +0 -452
- package/dist/core/memory/memory-lifecycle.d.ts +0 -8
- package/dist/core/memory/memory-lifecycle.js +0 -47
- package/dist/core/memory/memory-manager.d.ts +0 -15
- package/dist/core/memory/memory-manager.js +0 -46
- package/dist/core/memory/migrate.d.ts +0 -21
- package/dist/core/memory/migrate.js +0 -134
- package/dist/core/memory/normalization.d.ts +0 -7
- package/dist/core/memory/normalization.js +0 -26
- package/dist/core/memory/path-strengthener.d.ts +0 -39
- package/dist/core/memory/path-strengthener.js +0 -150
- package/dist/core/memory/progressive-disclosure.d.ts +0 -43
- package/dist/core/memory/progressive-disclosure.js +0 -280
- package/dist/core/memory/query-processor.d.ts +0 -21
- package/dist/core/memory/query-processor.js +0 -106
- package/dist/core/memory/query-rewriter.d.ts +0 -13
- package/dist/core/memory/query-rewriter.js +0 -118
- package/dist/core/memory/response-analyzer.d.ts +0 -9
- package/dist/core/memory/response-analyzer.js +0 -61
- package/dist/core/memory/retrieval-feedback.d.ts +0 -70
- package/dist/core/memory/retrieval-feedback.js +0 -213
- package/dist/core/memory/serialization.d.ts +0 -10
- package/dist/core/memory/serialization.js +0 -84
- package/dist/core/memory/stale-cleaner.d.ts +0 -26
- package/dist/core/memory/stale-cleaner.js +0 -97
- package/dist/core/memory/stats.d.ts +0 -32
- package/dist/core/memory/stats.js +0 -143
- package/dist/core/memory/telemetry.d.ts +0 -69
- package/dist/core/memory/telemetry.js +0 -313
- package/dist/core/memory/temporal-facts.d.ts +0 -41
- package/dist/core/memory/temporal-facts.js +0 -283
- package/dist/core/memory/temporal-parser.d.ts +0 -32
- package/dist/core/memory/temporal-parser.js +0 -385
- package/dist/core/memory/trigger-detector.d.ts +0 -21
- package/dist/core/memory/trigger-detector.js +0 -79
- package/dist/core/memory/write-gate.d.ts +0 -54
- package/dist/core/memory/write-gate.js +0 -210
- package/dist/core/places/index.d.ts +0 -14
- package/dist/core/places/index.js +0 -14
- package/dist/core/places/memory-places.d.ts +0 -68
- package/dist/core/places/memory-places.js +0 -261
- package/dist/core/places/places.d.ts +0 -88
- package/dist/core/places/places.js +0 -314
- package/dist/core/places/rules.d.ts +0 -74
- package/dist/core/places/rules.js +0 -240
- package/dist/core/places/walking.d.ts +0 -56
- package/dist/core/places/walking.js +0 -121
- package/dist/core/projects.d.ts +0 -17
- package/dist/core/projects.js +0 -116
- package/dist/core/redis.d.ts +0 -11
- package/dist/core/redis.js +0 -69
- package/dist/core/responses.d.ts +0 -96
- package/dist/core/responses.js +0 -122
- package/dist/core/runtime/trust-report.d.ts +0 -102
- package/dist/core/runtime/trust-report.js +0 -107
- package/dist/core/runtime/trust-state.d.ts +0 -12
- package/dist/core/runtime/trust-state.js +0 -309
- package/dist/core/scheduler/cron-scheduler.d.ts +0 -32
- package/dist/core/scheduler/cron-scheduler.js +0 -493
- package/dist/core/scheduler/heartbeat.d.ts +0 -11
- package/dist/core/scheduler/heartbeat.js +0 -73
- package/dist/core/scheduler/index.d.ts +0 -8
- package/dist/core/scheduler/index.js +0 -8
- package/dist/core/scheduler/job-runner.d.ts +0 -11
- package/dist/core/scheduler/job-runner.js +0 -164
- package/dist/core/search/conversations.d.ts +0 -25
- package/dist/core/search/conversations.js +0 -110
- package/dist/core/search/entities.d.ts +0 -12
- package/dist/core/search/entities.js +0 -31
- package/dist/core/search/folder-context.d.ts +0 -25
- package/dist/core/search/folder-context.js +0 -119
- package/dist/core/search/graph-boost.d.ts +0 -7
- package/dist/core/search/graph-boost.js +0 -23
- package/dist/core/search/index.d.ts +0 -4
- package/dist/core/search/index.js +0 -5
- package/dist/core/search/qmd-wrapper.d.ts +0 -36
- package/dist/core/search/qmd-wrapper.js +0 -58
- package/dist/core/security/encrypt.d.ts +0 -6
- package/dist/core/security/encrypt.js +0 -47
- package/dist/core/security/governance.d.ts +0 -26
- package/dist/core/security/governance.js +0 -79
- package/dist/core/security/privacy.d.ts +0 -23
- package/dist/core/security/privacy.js +0 -82
- package/dist/core/security/secret-detector.d.ts +0 -32
- package/dist/core/security/secret-detector.js +0 -88
- package/dist/core/session/auto-load.d.ts +0 -6
- package/dist/core/session/auto-load.js +0 -144
- package/dist/core/session/entity-tracker.d.ts +0 -62
- package/dist/core/session/entity-tracker.js +0 -287
- package/dist/core/session/index.d.ts +0 -7
- package/dist/core/session/index.js +0 -7
- package/dist/core/session/reference-resolver.d.ts +0 -26
- package/dist/core/session/reference-resolver.js +0 -121
- package/dist/core/session/self-iteration-job.d.ts +0 -35
- package/dist/core/session/self-iteration-job.js +0 -387
- package/dist/core/session/session-hooks.d.ts +0 -18
- package/dist/core/session/session-hooks.js +0 -58
- package/dist/core/session/types.d.ts +0 -26
- package/dist/core/session/types.js +0 -10
- package/dist/core/session/working-set.d.ts +0 -50
- package/dist/core/session/working-set.js +0 -212
- package/dist/core/snapshots/cleanup.d.ts +0 -9
- package/dist/core/snapshots/cleanup.js +0 -12
- package/dist/core/snapshots/comparison.d.ts +0 -19
- package/dist/core/snapshots/comparison.js +0 -43
- package/dist/core/snapshots/creation.d.ts +0 -13
- package/dist/core/snapshots/creation.js +0 -117
- package/dist/core/snapshots/retrieval.d.ts +0 -7
- package/dist/core/snapshots/retrieval.js +0 -41
- package/dist/core/snapshots/stats.d.ts +0 -11
- package/dist/core/snapshots/stats.js +0 -52
- package/dist/core/storage/cache.d.ts +0 -13
- package/dist/core/storage/cache.js +0 -202
- package/dist/core/storage/database.d.ts +0 -12
- package/dist/core/storage/database.js +0 -12
- package/dist/core/summarization/cleanup.d.ts +0 -9
- package/dist/core/summarization/cleanup.js +0 -12
- package/dist/core/summarization/queries.d.ts +0 -9
- package/dist/core/summarization/queries.js +0 -28
- package/dist/core/summarization/stats.d.ts +0 -14
- package/dist/core/summarization/stats.js +0 -52
- package/dist/core/summarization/strategies.d.ts +0 -24
- package/dist/core/summarization/strategies.js +0 -28
- package/dist/core/summarization.d.ts +0 -37
- package/dist/core/summarization.js +0 -188
- package/dist/core/temporal-facts.d.ts +0 -54
- package/dist/core/temporal-facts.js +0 -193
- package/dist/core/tracing/collector.d.ts +0 -111
- package/dist/core/tracing/collector.js +0 -350
- package/dist/core/tracing/visualizer.d.ts +0 -32
- package/dist/core/tracing/visualizer.js +0 -165
- package/dist/core/utils/cleanup-operations.d.ts +0 -13
- package/dist/core/utils/cleanup-operations.js +0 -44
- package/dist/core/utils/content-extraction.d.ts +0 -19
- package/dist/core/utils/content-extraction.js +0 -75
- package/dist/core/utils/filter-builder.d.ts +0 -13
- package/dist/core/utils/filter-builder.js +0 -44
- package/dist/core/utils/history-traversal.d.ts +0 -13
- package/dist/core/utils/history-traversal.js +0 -50
- package/dist/core/utils/memory-operations.d.ts +0 -17
- package/dist/core/utils/memory-operations.js +0 -43
- package/dist/core/utils/query-operations.d.ts +0 -18
- package/dist/core/utils/query-operations.js +0 -65
- package/dist/core/utils/summarization-helpers.d.ts +0 -17
- package/dist/core/utils/summarization-helpers.js +0 -33
- package/dist/core/utils/temporal-queries.d.ts +0 -13
- package/dist/core/utils/temporal-queries.js +0 -27
- package/dist/core/utils/vector-operations.d.ts +0 -71
- package/dist/core/utils/vector-operations.js +0 -129
- package/dist/core/utils/version-management.d.ts +0 -9
- package/dist/core/utils/version-management.js +0 -61
- package/dist/core/worker.d.ts +0 -82
- package/dist/core/worker.js +0 -272
- package/dist/db/adapter.d.ts +0 -7
- package/dist/db/adapter.js +0 -175
- package/dist/db/bootstrap.d.ts +0 -11
- package/dist/db/bootstrap.js +0 -1034
- package/dist/db/drizzle/schema-sqlite.d.ts +0 -5538
- package/dist/db/drizzle/schema-sqlite.js +0 -763
- package/dist/db/drizzle/schema.d.ts +0 -4734
- package/dist/db/drizzle/schema.js +0 -859
- package/dist/db/drizzle.config.d.ts +0 -3
- package/dist/db/drizzle.config.js +0 -12
- package/dist/db/index.d.ts +0 -7
- package/dist/db/index.js +0 -89
- package/dist/db/migrations/associations.d.ts +0 -6
- package/dist/db/migrations/associations.js +0 -29
- package/dist/db/migrations/beliefs.d.ts +0 -10
- package/dist/db/migrations/beliefs.js +0 -76
- package/dist/db/migrations/core-memory.d.ts +0 -6
- package/dist/db/migrations/core-memory.js +0 -29
- package/dist/db/migrations/fts.d.ts +0 -6
- package/dist/db/migrations/fts.js +0 -52
- package/dist/db/migrations/index.d.ts +0 -25
- package/dist/db/migrations/index.js +0 -51
- package/dist/db/migrations/indexes.d.ts +0 -6
- package/dist/db/migrations/indexes.js +0 -30
- package/dist/db/migrations/learnings.d.ts +0 -7
- package/dist/db/migrations/learnings.js +0 -26
- package/dist/db/migrations/maintenance.d.ts +0 -6
- package/dist/db/migrations/maintenance.js +0 -61
- package/dist/db/migrations/memories.d.ts +0 -7
- package/dist/db/migrations/memories.js +0 -16
- package/dist/db/migrations/memory-places.d.ts +0 -6
- package/dist/db/migrations/memory-places.js +0 -29
- package/dist/db/migrations/places.d.ts +0 -6
- package/dist/db/migrations/places.js +0 -43
- package/dist/db/migrations/projects.d.ts +0 -3
- package/dist/db/migrations/projects.js +0 -13
- package/dist/db/migrations/tier-conversion.d.ts +0 -7
- package/dist/db/migrations/tier-conversion.js +0 -20
- package/dist/db/neon.d.ts +0 -8
- package/dist/db/neon.js +0 -20
- package/dist/db/schema/beliefs.d.ts +0 -9
- package/dist/db/schema/beliefs.js +0 -46
- package/dist/db/schema/generator.d.ts +0 -38
- package/dist/db/schema/generator.js +0 -108
- package/dist/db/schema/index.d.ts +0 -39
- package/dist/db/schema/index.js +0 -51
- package/dist/db/schema/learnings.d.ts +0 -7
- package/dist/db/schema/learnings.js +0 -30
- package/dist/db/schema/memories.d.ts +0 -7
- package/dist/db/schema/memories.js +0 -81
- package/dist/db/schema/projects.d.ts +0 -4
- package/dist/db/schema/projects.js +0 -31
- package/dist/db/schema/tables/context-sessions.d.ts +0 -9
- package/dist/db/schema/tables/context-sessions.js +0 -37
- package/dist/db/schema/tables/conversations.d.ts +0 -9
- package/dist/db/schema/tables/conversations.js +0 -47
- package/dist/db/schema/tables/core-memory.d.ts +0 -9
- package/dist/db/schema/tables/core-memory.js +0 -41
- package/dist/db/schema/tables/entities.d.ts +0 -9
- package/dist/db/schema/tables/entities.js +0 -39
- package/dist/db/schema/tables/entity-relations.d.ts +0 -9
- package/dist/db/schema/tables/entity-relations.js +0 -31
- package/dist/db/schema/tables/learnings.d.ts +0 -9
- package/dist/db/schema/tables/learnings.js +0 -66
- package/dist/db/schema/tables/memories.d.ts +0 -9
- package/dist/db/schema/tables/memories.js +0 -161
- package/dist/db/schema/tables/memory-associations.d.ts +0 -9
- package/dist/db/schema/tables/memory-associations.js +0 -39
- package/dist/db/schema/tables/memory-hash-cache.d.ts +0 -9
- package/dist/db/schema/tables/memory-hash-cache.js +0 -29
- package/dist/db/schema/tables/memory-merge-history.d.ts +0 -9
- package/dist/db/schema/tables/memory-merge-history.js +0 -33
- package/dist/db/schema/tables/memory-merge-proposals.d.ts +0 -9
- package/dist/db/schema/tables/memory-merge-proposals.js +0 -39
- package/dist/db/schema/tables/messages.d.ts +0 -9
- package/dist/db/schema/tables/messages.js +0 -41
- package/dist/db/schema/tables/namespaces.d.ts +0 -9
- package/dist/db/schema/tables/namespaces.js +0 -37
- package/dist/db/schema/tables/projects.d.ts +0 -9
- package/dist/db/schema/tables/projects.js +0 -31
- package/dist/db/schema/tables/users.d.ts +0 -9
- package/dist/db/schema/tables/users.js +0 -27
- package/dist/db/schema.d.ts +0 -3
- package/dist/db/schema.js +0 -11
- package/dist/db/supabase.d.ts +0 -9
- package/dist/db/supabase.js +0 -24
- package/dist/packages/mcp/src/index.d.ts +0 -3
- package/dist/packages/mcp/src/index.js +0 -733
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* LLM Entity Extractor
|
|
3
|
-
*
|
|
4
|
-
* Extracts named entities and relationships from memory content using
|
|
5
|
-
* LLM-powered analysis. Falls back to regex extraction when LLM is unavailable.
|
|
6
|
-
*/
|
|
7
|
-
import { logger } from '../logger.js';
|
|
8
|
-
import { config } from '../../config.js';
|
|
9
|
-
import { extractEntities as regexExtractEntities, } from '../memory/entity-extractor.js';
|
|
10
|
-
// ─── LLM Prompt ─────────────────────────────────────────────────────────────
|
|
11
|
-
const ENTITY_EXTRACTION_PROMPT = `You are an entity and relationship extractor for an AI memory system. Given text, extract:
|
|
12
|
-
|
|
13
|
-
1. ENTITIES: Named things mentioned (people, projects, systems, tools, concepts, events)
|
|
14
|
-
2. RELATIONSHIPS: How entities connect to each other
|
|
15
|
-
|
|
16
|
-
Return ONLY valid JSON in this exact format:
|
|
17
|
-
{
|
|
18
|
-
"entities": [
|
|
19
|
-
{"name": "Alice", "type": "person", "confidence": 0.95},
|
|
20
|
-
{"name": "Project Atlas", "type": "concept", "confidence": 0.9}
|
|
21
|
-
],
|
|
22
|
-
"relations": [
|
|
23
|
-
{"from": "Alice", "to": "Project Atlas", "type": "works_on", "confidence": 0.85, "context": "Alice is the tech lead on Project Atlas"},
|
|
24
|
-
{"from": "Project Atlas", "to": "PostgreSQL", "type": "uses", "confidence": 0.9, "context": "Project Atlas uses PostgreSQL for its primary datastore"}
|
|
25
|
-
]
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
Entity types: person, file, function, class, concept, tool, date, location, pattern, technique, other
|
|
29
|
-
Relation types: works_on, depends_on, manages, uses, caused, located_in, belongs_to, reports_to, occurred_on, affects, contains, implements, extends, related_to, part_of, owns, created, resolved, blocks
|
|
30
|
-
|
|
31
|
-
Rules:
|
|
32
|
-
- Extract only explicitly mentioned entities and relationships
|
|
33
|
-
- Use the most specific relation type available
|
|
34
|
-
- Include confidence scores (0-1)
|
|
35
|
-
- Keep entity names as they appear in text (preserve capitalization)
|
|
36
|
-
- For ambiguous relationships, use "related_to"
|
|
37
|
-
- Do NOT invent entities or relationships not present in the text`;
|
|
38
|
-
// ─── LLM Call Abstraction ───────────────────────────────────────────────────
|
|
39
|
-
/**
|
|
40
|
-
* Call an LLM for entity extraction.
|
|
41
|
-
* Uses OpenAI-compatible API (works with OpenAI, Ollama, LM Studio, local endpoints).
|
|
42
|
-
*/
|
|
43
|
-
async function callLLM(prompt, content) {
|
|
44
|
-
// Determine which provider to use for extraction
|
|
45
|
-
const provider = config.llmProvider;
|
|
46
|
-
const endpoint = config.llmEndpoint || config.lmStudioUrl || config.ollamaUrl;
|
|
47
|
-
const model = config.llmExtractionModel;
|
|
48
|
-
if (!model) {
|
|
49
|
-
logger.debug('LLM extraction model not configured; using regex fallback');
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
// Try OpenAI first if configured and provider matches
|
|
53
|
-
if ((provider === 'openai' || !provider) && config.openAiApiKey) {
|
|
54
|
-
try {
|
|
55
|
-
const chatUrl = config.openAiApiUrl.replace('/embeddings', '/chat/completions');
|
|
56
|
-
const response = await fetch(chatUrl, {
|
|
57
|
-
method: 'POST',
|
|
58
|
-
headers: {
|
|
59
|
-
'Content-Type': 'application/json',
|
|
60
|
-
Authorization: `Bearer ${config.openAiApiKey}`,
|
|
61
|
-
},
|
|
62
|
-
body: JSON.stringify({
|
|
63
|
-
model,
|
|
64
|
-
messages: [
|
|
65
|
-
{ role: 'system', content: prompt },
|
|
66
|
-
{ role: 'user', content },
|
|
67
|
-
],
|
|
68
|
-
temperature: 0.1,
|
|
69
|
-
max_tokens: 2000,
|
|
70
|
-
}),
|
|
71
|
-
});
|
|
72
|
-
if (!response.ok) {
|
|
73
|
-
logger.warn(`LLM entity extraction failed (OpenAI): ${response.status}`);
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
const payload = await response.json();
|
|
77
|
-
return payload.choices?.[0]?.message?.content ?? null;
|
|
78
|
-
}
|
|
79
|
-
catch (error) {
|
|
80
|
-
logger.warn('LLM entity extraction error (OpenAI):', { error: error });
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
// Try Ollama if configured and provider matches
|
|
84
|
-
if ((provider === 'ollama' || !provider) && config.ollamaUrl) {
|
|
85
|
-
try {
|
|
86
|
-
const response = await fetch(`${config.ollamaUrl}/api/chat`, {
|
|
87
|
-
method: 'POST',
|
|
88
|
-
headers: { 'Content-Type': 'application/json' },
|
|
89
|
-
body: JSON.stringify({
|
|
90
|
-
model,
|
|
91
|
-
messages: [
|
|
92
|
-
{ role: 'system', content: prompt },
|
|
93
|
-
{ role: 'user', content },
|
|
94
|
-
],
|
|
95
|
-
stream: false,
|
|
96
|
-
options: { temperature: 0.1 },
|
|
97
|
-
}),
|
|
98
|
-
});
|
|
99
|
-
if (!response.ok) {
|
|
100
|
-
logger.warn(`Ollama entity extraction failed: ${response.status}`);
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
const payload = await response.json();
|
|
104
|
-
return payload.message?.content ?? null;
|
|
105
|
-
}
|
|
106
|
-
catch (error) {
|
|
107
|
-
logger.warn('LLM entity extraction error (Ollama):', { error: error });
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
// Try LM Studio / custom endpoint if configured and provider matches
|
|
111
|
-
if ((provider === 'lmstudio' || provider === 'local' || !provider) && (config.lmStudioUrl || endpoint)) {
|
|
112
|
-
try {
|
|
113
|
-
const baseUrl = endpoint || config.lmStudioUrl;
|
|
114
|
-
if (!baseUrl)
|
|
115
|
-
return null;
|
|
116
|
-
const response = await fetch(`${baseUrl}/v1/chat/completions`, {
|
|
117
|
-
method: 'POST',
|
|
118
|
-
headers: { 'Content-Type': 'application/json' },
|
|
119
|
-
body: JSON.stringify({
|
|
120
|
-
model,
|
|
121
|
-
messages: [
|
|
122
|
-
{ role: 'system', content: prompt },
|
|
123
|
-
{ role: 'user', content },
|
|
124
|
-
],
|
|
125
|
-
temperature: 0.1,
|
|
126
|
-
max_tokens: 2000,
|
|
127
|
-
}),
|
|
128
|
-
});
|
|
129
|
-
if (!response.ok) {
|
|
130
|
-
logger.warn(`LM Studio entity extraction failed: ${response.status}`);
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
const payload = await response.json();
|
|
134
|
-
return payload.choices?.[0]?.message?.content ?? null;
|
|
135
|
-
}
|
|
136
|
-
catch (error) {
|
|
137
|
-
logger.warn('LLM entity extraction error (LM Studio):', { error: error });
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
return null;
|
|
141
|
-
}
|
|
142
|
-
// ─── JSON Parsing ────────────────────────────────────────────────────────────
|
|
143
|
-
/**
|
|
144
|
-
* Parse LLM response into structured extraction result.
|
|
145
|
-
* Handles various response formats (raw JSON, markdown code blocks, etc.)
|
|
146
|
-
*/
|
|
147
|
-
function parseLLMResponse(response) {
|
|
148
|
-
// Try to extract JSON from the response
|
|
149
|
-
let jsonStr = response.trim();
|
|
150
|
-
// Handle markdown code blocks
|
|
151
|
-
const codeBlockMatch = jsonStr.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
152
|
-
if (codeBlockMatch) {
|
|
153
|
-
jsonStr = codeBlockMatch[1].trim();
|
|
154
|
-
}
|
|
155
|
-
// Try to find JSON object in the response
|
|
156
|
-
const jsonMatch = jsonStr.match(/\{[\s\S]*\}/);
|
|
157
|
-
if (!jsonMatch) {
|
|
158
|
-
logger.debug('No JSON found in LLM response');
|
|
159
|
-
return null;
|
|
160
|
-
}
|
|
161
|
-
try {
|
|
162
|
-
const parsed = JSON.parse(jsonMatch[0]);
|
|
163
|
-
// Validate structure
|
|
164
|
-
if (!parsed.entities || !Array.isArray(parsed.entities)) {
|
|
165
|
-
logger.debug('LLM response missing entities array');
|
|
166
|
-
return null;
|
|
167
|
-
}
|
|
168
|
-
const entities = parsed.entities
|
|
169
|
-
.filter((e) => e.name && e.type)
|
|
170
|
-
.map((e) => ({
|
|
171
|
-
name: String(e.name),
|
|
172
|
-
type: validateEntityType(String(e.type)),
|
|
173
|
-
confidence: typeof e.confidence === 'number' ? Math.min(1, Math.max(0, e.confidence)) : 0.8,
|
|
174
|
-
startIndex: 0,
|
|
175
|
-
endIndex: 0,
|
|
176
|
-
context: String(e.context || ''),
|
|
177
|
-
normalized: e.normalized ? String(e.normalized) : undefined,
|
|
178
|
-
}));
|
|
179
|
-
const relations = (parsed.relations || [])
|
|
180
|
-
.filter((r) => r.from && r.to && r.type)
|
|
181
|
-
.map((r) => ({
|
|
182
|
-
fromEntity: String(r.from),
|
|
183
|
-
toEntity: String(r.to),
|
|
184
|
-
relationType: validateRelationType(String(r.type)),
|
|
185
|
-
confidence: typeof r.confidence === 'number' ? Math.min(1, Math.max(0, r.confidence)) : 0.7,
|
|
186
|
-
context: String(r.context || ''),
|
|
187
|
-
}));
|
|
188
|
-
return { entities, relations };
|
|
189
|
-
}
|
|
190
|
-
catch (error) {
|
|
191
|
-
logger.debug('Failed to parse LLM response as JSON', { error: error });
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
function validateEntityType(type) {
|
|
196
|
-
const validTypes = ['person', 'file', 'function', 'class', 'concept', 'tool', 'date', 'location', 'pattern', 'technique', 'other'];
|
|
197
|
-
const lower = type.toLowerCase();
|
|
198
|
-
if (validTypes.includes(lower))
|
|
199
|
-
return lower;
|
|
200
|
-
return 'other';
|
|
201
|
-
}
|
|
202
|
-
function validateRelationType(type) {
|
|
203
|
-
const validTypes = [
|
|
204
|
-
'works_on', 'depends_on', 'manages', 'uses', 'caused', 'located_in',
|
|
205
|
-
'belongs_to', 'reports_to', 'occurred_on', 'affects', 'contains',
|
|
206
|
-
'implements', 'extends', 'related_to', 'part_of', 'owns', 'created',
|
|
207
|
-
'resolved', 'blocks',
|
|
208
|
-
];
|
|
209
|
-
const lower = type.toLowerCase();
|
|
210
|
-
if (validTypes.includes(lower))
|
|
211
|
-
return lower;
|
|
212
|
-
return 'related_to';
|
|
213
|
-
}
|
|
214
|
-
// ─── Main Extraction Functions ───────────────────────────────────────────────
|
|
215
|
-
/**
|
|
216
|
-
* Extract entities and relationships from text using LLM.
|
|
217
|
-
* Falls back to regex extraction when LLM is unavailable.
|
|
218
|
-
*/
|
|
219
|
-
export async function extractEntitiesAndRelations(content, options) {
|
|
220
|
-
const { preferLLM = true, maxContentLength = 4000 } = options || {};
|
|
221
|
-
// Truncate very long content
|
|
222
|
-
const truncatedContent = content.length > maxContentLength
|
|
223
|
-
? content.substring(0, maxContentLength) + '...'
|
|
224
|
-
: content;
|
|
225
|
-
// Try LLM extraction first if preferred
|
|
226
|
-
if (preferLLM) {
|
|
227
|
-
const llmResult = await extractWithLLM(truncatedContent);
|
|
228
|
-
if (llmResult) {
|
|
229
|
-
logger.debug('LLM entity extraction succeeded', {
|
|
230
|
-
entityCount: llmResult.entities.length,
|
|
231
|
-
relationCount: llmResult.relations.length,
|
|
232
|
-
});
|
|
233
|
-
return { ...llmResult, source: 'llm' };
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
// Fall back to regex extraction
|
|
237
|
-
const regexEntities = await regexExtractEntities(content);
|
|
238
|
-
if (regexEntities.length > 0) {
|
|
239
|
-
logger.debug('Regex entity extraction fallback', {
|
|
240
|
-
entityCount: regexEntities.length,
|
|
241
|
-
});
|
|
242
|
-
return {
|
|
243
|
-
entities: regexEntities,
|
|
244
|
-
relations: [], // Regex extraction doesn't produce relations
|
|
245
|
-
source: 'regex',
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
return { entities: [], relations: [], source: 'none' };
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Extract entities and relations using LLM.
|
|
252
|
-
*/
|
|
253
|
-
async function extractWithLLM(content) {
|
|
254
|
-
const response = await callLLM(ENTITY_EXTRACTION_PROMPT, content);
|
|
255
|
-
if (!response)
|
|
256
|
-
return null;
|
|
257
|
-
const parsed = parseLLMResponse(response);
|
|
258
|
-
if (!parsed)
|
|
259
|
-
return null;
|
|
260
|
-
// Validate that extracted entities actually appear in the content
|
|
261
|
-
const validatedEntities = parsed.entities.filter((entity) => {
|
|
262
|
-
// Allow entities whose name or a significant substring appears in content
|
|
263
|
-
const nameLower = entity.name.toLowerCase();
|
|
264
|
-
const contentLower = content.toLowerCase();
|
|
265
|
-
// Check if the entity name or a key part of it appears in content
|
|
266
|
-
const words = nameLower.split(/\s+/);
|
|
267
|
-
return words.some(word => word.length > 2 && contentLower.includes(word));
|
|
268
|
-
});
|
|
269
|
-
// Validate that relation entities exist in the entity list
|
|
270
|
-
const entityNames = new Set(validatedEntities.map(e => e.name.toLowerCase()));
|
|
271
|
-
const validatedRelations = parsed.relations.filter((relation) => {
|
|
272
|
-
const fromExists = entityNames.has(relation.fromEntity.toLowerCase());
|
|
273
|
-
const toExists = entityNames.has(relation.toEntity.toLowerCase());
|
|
274
|
-
// Allow relations where at least one entity is known
|
|
275
|
-
// (the LLM might use slightly different names)
|
|
276
|
-
return fromExists || toExists ||
|
|
277
|
-
// Also allow if both entity names appear in the content
|
|
278
|
-
(content.toLowerCase().includes(relation.fromEntity.toLowerCase()) &&
|
|
279
|
-
content.toLowerCase().includes(relation.toEntity.toLowerCase()));
|
|
280
|
-
});
|
|
281
|
-
return {
|
|
282
|
-
entities: validatedEntities,
|
|
283
|
-
relations: validatedRelations,
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* Extract entities and relations from multiple memories in batch.
|
|
288
|
-
* More efficient than calling extractEntitiesAndRelations for each memory.
|
|
289
|
-
*/
|
|
290
|
-
export async function batchExtractEntitiesAndRelations(contents, options) {
|
|
291
|
-
const { batchSize = 5 } = options || {};
|
|
292
|
-
const results = [];
|
|
293
|
-
// Process in batches to avoid overwhelming the LLM
|
|
294
|
-
for (let i = 0; i < contents.length; i += batchSize) {
|
|
295
|
-
const batch = contents.slice(i, i + batchSize);
|
|
296
|
-
const batchResults = await Promise.all(batch.map(content => extractEntitiesAndRelations(content, options)));
|
|
297
|
-
results.push(...batchResults);
|
|
298
|
-
}
|
|
299
|
-
return results;
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Get the extraction prompt for testing/debugging purposes.
|
|
303
|
-
*/
|
|
304
|
-
export function getExtractionPrompt() {
|
|
305
|
-
return ENTITY_EXTRACTION_PROMPT;
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Parse an LLM response for testing/debugging purposes.
|
|
309
|
-
*/
|
|
310
|
-
export function testParseLLMResponse(response) {
|
|
311
|
-
return parseLLMResponse(response);
|
|
312
|
-
}
|
|
313
|
-
//# sourceMappingURL=llm-entity-extractor.js.map
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Multi-Hop Retrieval
|
|
3
|
-
*
|
|
4
|
-
* Combines vector search with graph traversal to answer queries that
|
|
5
|
-
* require following relationships across entities.
|
|
6
|
-
*/
|
|
7
|
-
import { type SearchResult } from '../memory/hybrid-search.js';
|
|
8
|
-
import { type TraversalPath } from './graph-traversal.js';
|
|
9
|
-
export interface MultiHopResult extends SearchResult {
|
|
10
|
-
/** How this result was found: 'vector' (direct search) or 'graph' (via traversal) */
|
|
11
|
-
retrievalPath: 'vector' | 'graph' | 'both';
|
|
12
|
-
/** The graph path that led to this result (if found via graph) */
|
|
13
|
-
graphPath?: TraversalPath;
|
|
14
|
-
/** Entities that connected this result to the query */
|
|
15
|
-
connectingEntities?: string[];
|
|
16
|
-
/** Hybrid score for backward compatibility */
|
|
17
|
-
hybridScore?: number;
|
|
18
|
-
}
|
|
19
|
-
export interface MultiHopSearchOptions {
|
|
20
|
-
/** Search query */
|
|
21
|
-
query: string;
|
|
22
|
-
/** Project path for scoping */
|
|
23
|
-
project?: string;
|
|
24
|
-
/** Maximum number of results */
|
|
25
|
-
limit?: number;
|
|
26
|
-
/** Maximum graph traversal depth */
|
|
27
|
-
maxHops?: number;
|
|
28
|
-
/** Whether to include vector-only results */
|
|
29
|
-
includeVectorResults?: boolean;
|
|
30
|
-
/** Whether to include graph-expanded results */
|
|
31
|
-
includeGraphResults?: boolean;
|
|
32
|
-
/** Minimum graph path weight to include */
|
|
33
|
-
minPathWeight?: number;
|
|
34
|
-
/** Session ID for context */
|
|
35
|
-
sessionId?: string;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Perform multi-hop search combining vector search with graph traversal.
|
|
39
|
-
*/
|
|
40
|
-
export declare function multiHopSearch(options: MultiHopSearchOptions): Promise<MultiHopResult[]>;
|
|
41
|
-
/** Check if query needs multi-hop graph traversal. */
|
|
42
|
-
export declare function needsMultiHop(query: string): boolean;
|
|
43
|
-
/**
|
|
44
|
-
* Get a human-readable explanation of how a multi-hop result was found.
|
|
45
|
-
*/
|
|
46
|
-
export declare function explainRetrievalPath(result: MultiHopResult): string;
|
|
47
|
-
export declare const wouldBenefitFromMultiHop: typeof needsMultiHop;
|
|
48
|
-
//# sourceMappingURL=multi-hop-retrieval.d.ts.map
|
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Multi-Hop Retrieval
|
|
3
|
-
*
|
|
4
|
-
* Combines vector search with graph traversal to answer queries that
|
|
5
|
-
* require following relationships across entities.
|
|
6
|
-
*/
|
|
7
|
-
import { eq } from 'drizzle-orm';
|
|
8
|
-
import { getDb } from '../../db/index.js';
|
|
9
|
-
import { getSchema } from '../../db/schema.js';
|
|
10
|
-
import { hybridSearch } from '../memory/hybrid-search.js';
|
|
11
|
-
import { extractEntitiesAndRelations } from './llm-entity-extractor.js';
|
|
12
|
-
import { extractEntityNames } from '../memory/entity-extractor.js';
|
|
13
|
-
import { findEntitiesByName, findPaths, traverse } from './graph-traversal.js';
|
|
14
|
-
import { logger } from '../logger.js';
|
|
15
|
-
import { config } from '../../config.js';
|
|
16
|
-
// ─── Main Multi-Hop Search ──────────────────────────────────────────────────
|
|
17
|
-
/**
|
|
18
|
-
* Perform multi-hop search combining vector search with graph traversal.
|
|
19
|
-
*/
|
|
20
|
-
export async function multiHopSearch(options) {
|
|
21
|
-
const { query, project, limit = 10, maxHops = 3, includeVectorResults = true, includeGraphResults = true, minPathWeight = 1, sessionId, } = options;
|
|
22
|
-
const results = [];
|
|
23
|
-
const seenMemoryIds = new Set();
|
|
24
|
-
// Step 1: Extract query entities (respect global LLM config)
|
|
25
|
-
let queryEntityNames;
|
|
26
|
-
try {
|
|
27
|
-
const extraction = await extractEntitiesAndRelations(query, { preferLLM: config.llmEnabled });
|
|
28
|
-
queryEntityNames = extraction.entities.map(e => e.name);
|
|
29
|
-
logger.debug('Multi-hop search: entity extraction succeeded', {
|
|
30
|
-
query: query.substring(0, 100),
|
|
31
|
-
entities: queryEntityNames,
|
|
32
|
-
source: extraction.source,
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
catch (error) {
|
|
36
|
-
// LLM failed or disabled - fall back to simple keyword extraction
|
|
37
|
-
logger.debug('Multi-hop search: entity extraction failed, falling back to keywords', { error });
|
|
38
|
-
const simpleEntities = extractEntityNames(query);
|
|
39
|
-
queryEntityNames = simpleEntities;
|
|
40
|
-
logger.debug('Multi-hop search: keyword extraction', {
|
|
41
|
-
entities: queryEntityNames,
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
// Step 2: Vector search (baseline results)
|
|
45
|
-
if (includeVectorResults) {
|
|
46
|
-
const vectorResults = await hybridSearch({
|
|
47
|
-
query,
|
|
48
|
-
project,
|
|
49
|
-
limit: limit * 2, // Get more candidates for reranking
|
|
50
|
-
});
|
|
51
|
-
for (const result of vectorResults) {
|
|
52
|
-
if (!seenMemoryIds.has(result.id)) {
|
|
53
|
-
seenMemoryIds.add(result.id);
|
|
54
|
-
results.push({
|
|
55
|
-
...result,
|
|
56
|
-
retrievalPath: 'vector',
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
// Step 3: Graph expansion (if we have entities)
|
|
62
|
-
if (includeGraphResults && queryEntityNames.length > 0 && project) {
|
|
63
|
-
const graphResults = await expandViaGraph(queryEntityNames, project, maxHops, minPathWeight, limit);
|
|
64
|
-
// Find memories connected to graph-expanded entities
|
|
65
|
-
for (const graphResult of graphResults) {
|
|
66
|
-
// Search for memories mentioning the expanded entities
|
|
67
|
-
const expandedMemories = await hybridSearch({
|
|
68
|
-
query: graphResult.entityName,
|
|
69
|
-
project,
|
|
70
|
-
limit: 5,
|
|
71
|
-
});
|
|
72
|
-
for (const memory of expandedMemories) {
|
|
73
|
-
if (!seenMemoryIds.has(memory.id)) {
|
|
74
|
-
seenMemoryIds.add(memory.id);
|
|
75
|
-
results.push({
|
|
76
|
-
...memory,
|
|
77
|
-
retrievalPath: 'graph',
|
|
78
|
-
graphPath: graphResult.path,
|
|
79
|
-
connectingEntities: [graphResult.entityName],
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
// Step 4: Rank combined results
|
|
86
|
-
// Vector results keep their hybrid score, graph results get a boost
|
|
87
|
-
// for being connected to query entities via the knowledge graph
|
|
88
|
-
const ranked = rankMultiHopResults(results, queryEntityNames);
|
|
89
|
-
return ranked.slice(0, limit);
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Expand query entities via the knowledge graph to find related entities.
|
|
93
|
-
*/
|
|
94
|
-
async function expandViaGraph(queryEntityNames, project, maxHops, minPathWeight, limit) {
|
|
95
|
-
const db = await getDb();
|
|
96
|
-
const schema = await getSchema();
|
|
97
|
-
const results = [];
|
|
98
|
-
const seenEntities = new Set();
|
|
99
|
-
// Get project ID
|
|
100
|
-
const projectRows = await db
|
|
101
|
-
.select({ id: schema.projects.id })
|
|
102
|
-
.from(schema.projects)
|
|
103
|
-
.where(eq(schema.projects.path, project))
|
|
104
|
-
.limit(1);
|
|
105
|
-
if (projectRows.length === 0)
|
|
106
|
-
return [];
|
|
107
|
-
const projectId = projectRows[0].id;
|
|
108
|
-
// For each query entity, find it in the graph and expand
|
|
109
|
-
for (const entityName of queryEntityNames) {
|
|
110
|
-
const entities = await findEntitiesByName(entityName, projectId, { limit: 3 });
|
|
111
|
-
for (const entity of entities) {
|
|
112
|
-
if (seenEntities.has(entity.id))
|
|
113
|
-
continue;
|
|
114
|
-
seenEntities.add(entity.id);
|
|
115
|
-
// Traverse the graph from this entity
|
|
116
|
-
const neighbors = await traverse(entity.id, {
|
|
117
|
-
maxDepth: maxHops,
|
|
118
|
-
minWeight: minPathWeight,
|
|
119
|
-
limit: 20,
|
|
120
|
-
});
|
|
121
|
-
for (const neighbor of neighbors) {
|
|
122
|
-
if (seenEntities.has(neighbor.id))
|
|
123
|
-
continue;
|
|
124
|
-
seenEntities.add(neighbor.id);
|
|
125
|
-
// Find the path from query entity to this neighbor
|
|
126
|
-
const paths = await findPaths(entity.id, neighbor.id, {
|
|
127
|
-
maxHops,
|
|
128
|
-
minWeight: minPathWeight,
|
|
129
|
-
maxPaths: 1,
|
|
130
|
-
});
|
|
131
|
-
if (paths.length > 0) {
|
|
132
|
-
const path = paths[0];
|
|
133
|
-
// Score based on path length and weight
|
|
134
|
-
const relevanceScore = 1 / (1 + path.hopCount) * (1 / (1 + path.totalWeight * 0.1));
|
|
135
|
-
results.push({
|
|
136
|
-
entityName: neighbor.name,
|
|
137
|
-
entityId: neighbor.id,
|
|
138
|
-
path,
|
|
139
|
-
relevanceScore,
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
// Sort by relevance score
|
|
146
|
-
results.sort((a, b) => b.relevanceScore - a.relevanceScore);
|
|
147
|
-
return results.slice(0, limit);
|
|
148
|
-
}
|
|
149
|
-
// ─── Result Ranking ──────────────────────────────────────────────────────────
|
|
150
|
-
/**
|
|
151
|
-
* Rank multi-hop results combining vector score with graph connectivity.
|
|
152
|
-
*/
|
|
153
|
-
function rankMultiHopResults(results, queryEntityNames) {
|
|
154
|
-
return results
|
|
155
|
-
.map(result => {
|
|
156
|
-
let score = result.similarity || 0;
|
|
157
|
-
// Boost for graph-connected results
|
|
158
|
-
if (result.retrievalPath === 'graph' || result.retrievalPath === 'both') {
|
|
159
|
-
score *= 1.2; // 20% boost for graph connectivity
|
|
160
|
-
}
|
|
161
|
-
// Boost for matching query entities in content
|
|
162
|
-
const contentLower = (result.content || '').toLowerCase();
|
|
163
|
-
for (const entity of queryEntityNames) {
|
|
164
|
-
if (contentLower.includes(entity.toLowerCase())) {
|
|
165
|
-
score *= 1.1; // 10% boost per entity match
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
// Boost for shorter graph paths (more direct connections)
|
|
169
|
-
if (result.graphPath) {
|
|
170
|
-
const pathBonus = 1 / (1 + result.graphPath.hopCount * 0.2);
|
|
171
|
-
score *= (1 + pathBonus * 0.15); // Up to 15% bonus for short paths
|
|
172
|
-
}
|
|
173
|
-
return {
|
|
174
|
-
...result,
|
|
175
|
-
similarity: Math.round(score * 1000) / 1000,
|
|
176
|
-
hybridScore: Math.round(score * 100) / 100, // Backward compat
|
|
177
|
-
};
|
|
178
|
-
})
|
|
179
|
-
.sort((a, b) => (b.similarity || 0) - (a.similarity || 0));
|
|
180
|
-
}
|
|
181
|
-
// ─── Utility ────────────────────────────────────────────────────────────────
|
|
182
|
-
/** Check if query needs multi-hop graph traversal. */
|
|
183
|
-
export function needsMultiHop(query) {
|
|
184
|
-
// Queries with relationship indicators benefit from multi-hop
|
|
185
|
-
const relationshipPatterns = [
|
|
186
|
-
/\b(affected by|caused by|related to|connected to|depends? on|works? on|uses?|manages?)\b/i,
|
|
187
|
-
/\b(who|what|which|how)\b.*\b(project|team|system|service|database)\b/i,
|
|
188
|
-
/\b(impact|affect|influence|caus\w+|result|lead to)\b/i,
|
|
189
|
-
];
|
|
190
|
-
return relationshipPatterns.some(pattern => pattern.test(query));
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Get a human-readable explanation of how a multi-hop result was found.
|
|
194
|
-
*/
|
|
195
|
-
export function explainRetrievalPath(result) {
|
|
196
|
-
if (result.retrievalPath === 'vector') {
|
|
197
|
-
return `Found via semantic search (score: ${result.similarity?.toFixed(2)})`;
|
|
198
|
-
}
|
|
199
|
-
if (result.retrievalPath === 'graph' && result.graphPath) {
|
|
200
|
-
const pathSteps = result.graphPath.nodes
|
|
201
|
-
.map(n => n.name)
|
|
202
|
-
.join(' → ');
|
|
203
|
-
return `Found via knowledge graph: ${pathSteps} (hops: ${result.graphPath.hopCount})`;
|
|
204
|
-
}
|
|
205
|
-
if (result.retrievalPath === 'both' && result.graphPath) {
|
|
206
|
-
const pathSteps = result.graphPath.nodes
|
|
207
|
-
.map(n => n.name)
|
|
208
|
-
.join(' → ');
|
|
209
|
-
return `Found via both search and graph: ${pathSteps} (score: ${result.similarity?.toFixed(2)})`;
|
|
210
|
-
}
|
|
211
|
-
return `Found via ${result.retrievalPath} search`;
|
|
212
|
-
}
|
|
213
|
-
// Backward compatibility alias
|
|
214
|
-
export const wouldBenefitFromMultiHop = needsMultiHop;
|
|
215
|
-
//# sourceMappingURL=multi-hop-retrieval.js.map
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Relationship Extractor
|
|
3
|
-
*
|
|
4
|
-
* Populates entity_relations table with typed relationships extracted
|
|
5
|
-
* from memory content.
|
|
6
|
-
*/
|
|
7
|
-
import { type RelationType } from './llm-entity-extractor.js';
|
|
8
|
-
export interface StoredRelation {
|
|
9
|
-
id: string;
|
|
10
|
-
fromEntityId: string;
|
|
11
|
-
toEntityId: string;
|
|
12
|
-
fromEntityName: string;
|
|
13
|
-
toEntityName: string;
|
|
14
|
-
relationType: RelationType;
|
|
15
|
-
weight: number;
|
|
16
|
-
properties: Record<string, unknown> | null;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Extract entities and relations from memory content and store them in the database.
|
|
20
|
-
* Returns the stored entities and relations.
|
|
21
|
-
*/
|
|
22
|
-
export declare function extractAndStoreRelations(memoryId: string, content: string, projectId: string, options?: {
|
|
23
|
-
preferLLM?: boolean;
|
|
24
|
-
maxContentLength?: number;
|
|
25
|
-
}): Promise<{
|
|
26
|
-
entities: number;
|
|
27
|
-
relations: number;
|
|
28
|
-
source: 'llm' | 'regex' | 'fallback';
|
|
29
|
-
}>;
|
|
30
|
-
/**
|
|
31
|
-
* Get all relations for a set of entity IDs.
|
|
32
|
-
* Used by graph traversal to find connected entities.
|
|
33
|
-
*/
|
|
34
|
-
export declare function getEntityRelations(entityIds: string[], relationTypes?: RelationType[]): Promise<StoredRelation[]>;
|
|
35
|
-
/**
|
|
36
|
-
* Get all entities for a project.
|
|
37
|
-
*/
|
|
38
|
-
export declare function getProjectEntities(projectId: string, limit?: number): Promise<Array<{
|
|
39
|
-
id: string;
|
|
40
|
-
name: string;
|
|
41
|
-
type: string;
|
|
42
|
-
description: string | null;
|
|
43
|
-
}>>;
|
|
44
|
-
/**
|
|
45
|
-
* Delete all entities and relations for a project (for graph rebuild).
|
|
46
|
-
*/
|
|
47
|
-
export declare function clearProjectGraph(projectId: string): Promise<void>;
|
|
48
|
-
//# sourceMappingURL=relationship-extractor.d.ts.map
|