lmgrep 0.1.18 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +226 -63
- package/completions/_lmgrep +49 -40
- package/dist/application/Lmgrep.d.ts +107 -0
- package/dist/application/Lmgrep.js +99 -0
- package/dist/application/Lmgrep.js.map +1 -0
- package/dist/application/LmgrepFactory.d.ts +40 -0
- package/dist/application/LmgrepFactory.js +155 -0
- package/dist/application/LmgrepFactory.js.map +1 -0
- package/dist/application/indexing/BranchBootstrapper.d.ts +21 -0
- package/dist/application/indexing/BranchBootstrapper.js +52 -0
- package/dist/application/indexing/BranchBootstrapper.js.map +1 -0
- package/dist/application/indexing/BranchManifestSweeper.d.ts +17 -0
- package/dist/application/indexing/BranchManifestSweeper.js +35 -0
- package/dist/application/indexing/BranchManifestSweeper.js.map +1 -0
- package/dist/application/indexing/Duration.d.ts +9 -0
- package/dist/application/indexing/Duration.js +25 -0
- package/dist/application/indexing/Duration.js.map +1 -0
- package/dist/application/indexing/EmbeddingAbortError.d.ts +11 -0
- package/dist/application/indexing/EmbeddingAbortError.js +20 -0
- package/dist/application/indexing/EmbeddingAbortError.js.map +1 -0
- package/dist/application/indexing/EmbeddingPipeline.d.ts +59 -0
- package/dist/application/indexing/EmbeddingPipeline.js +140 -0
- package/dist/application/indexing/EmbeddingPipeline.js.map +1 -0
- package/dist/application/indexing/IndexBuilder.d.ts +112 -0
- package/dist/application/indexing/IndexBuilder.js +370 -0
- package/dist/application/indexing/IndexBuilder.js.map +1 -0
- package/dist/application/indexing/IndexingProgress.d.ts +34 -0
- package/dist/application/indexing/IndexingProgress.js +2 -0
- package/dist/application/indexing/IndexingProgress.js.map +1 -0
- package/dist/application/operations/Deadline.d.ts +13 -0
- package/dist/application/operations/Deadline.js +29 -0
- package/dist/application/operations/Deadline.js.map +1 -0
- package/dist/application/operations/HealthMonitor.d.ts +58 -0
- package/dist/application/operations/HealthMonitor.js +128 -0
- package/dist/application/operations/HealthMonitor.js.map +1 -0
- package/dist/application/operations/IndexAlternatives.d.ts +35 -0
- package/dist/application/operations/IndexAlternatives.js +61 -0
- package/dist/application/operations/IndexAlternatives.js.map +1 -0
- package/dist/application/operations/IndexInventory.d.ts +69 -0
- package/dist/application/operations/IndexInventory.js +99 -0
- package/dist/application/operations/IndexInventory.js.map +1 -0
- package/dist/application/operations/StatusService.d.ts +90 -0
- package/dist/application/operations/StatusService.js +171 -0
- package/dist/application/operations/StatusService.js.map +1 -0
- package/dist/application/operations/WatchService.d.ts +67 -0
- package/dist/application/operations/WatchService.js +145 -0
- package/dist/application/operations/WatchService.js.map +1 -0
- package/dist/application/operations/WorkingTreeDiff.d.ts +19 -0
- package/dist/application/operations/WorkingTreeDiff.js +36 -0
- package/dist/application/operations/WorkingTreeDiff.js.map +1 -0
- package/dist/application/research/ResearchAgent.d.ts +68 -0
- package/dist/application/research/ResearchAgent.js +201 -0
- package/dist/application/research/ResearchAgent.js.map +1 -0
- package/dist/application/research/ResearchPrompts.d.ts +16 -0
- package/dist/application/research/ResearchPrompts.js +34 -0
- package/dist/application/research/ResearchPrompts.js.map +1 -0
- package/dist/application/search/SearchCriteria.d.ts +37 -0
- package/dist/application/search/SearchCriteria.js +48 -0
- package/dist/application/search/SearchCriteria.js.map +1 -0
- package/dist/application/search/SearchService.d.ts +36 -0
- package/dist/application/search/SearchService.js +108 -0
- package/dist/application/search/SearchService.js.map +1 -0
- package/dist/application/search/SearchTargetResolver.d.ts +56 -0
- package/dist/application/search/SearchTargetResolver.js +104 -0
- package/dist/application/search/SearchTargetResolver.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +4 -953
- package/dist/cli.js.map +1 -1
- package/dist/domain/config/ConfigSource.d.ts +16 -0
- package/dist/domain/config/ConfigSource.js +2 -0
- package/dist/domain/config/ConfigSource.js.map +1 -0
- package/dist/domain/config/LmgrepConfig.d.ts +53 -0
- package/dist/domain/config/LmgrepConfig.js +2 -0
- package/dist/domain/config/LmgrepConfig.js.map +1 -0
- package/dist/domain/corpus/Chunk.d.ts +49 -0
- package/dist/domain/corpus/Chunk.js +60 -0
- package/dist/domain/corpus/Chunk.js.map +1 -0
- package/dist/domain/corpus/CodeLocation.d.ts +18 -0
- package/dist/domain/corpus/CodeLocation.js +34 -0
- package/dist/domain/corpus/CodeLocation.js.map +1 -0
- package/dist/domain/corpus/ContentHash.d.ts +15 -0
- package/dist/domain/corpus/ContentHash.js +30 -0
- package/dist/domain/corpus/ContentHash.js.map +1 -0
- package/dist/domain/corpus/FileVersion.d.ts +31 -0
- package/dist/domain/corpus/FileVersion.js +47 -0
- package/dist/domain/corpus/FileVersion.js.map +1 -0
- package/dist/domain/corpus/SourceFile.d.ts +26 -0
- package/dist/domain/corpus/SourceFile.js +47 -0
- package/dist/domain/corpus/SourceFile.js.map +1 -0
- package/dist/domain/corpus/Vector.d.ts +37 -0
- package/dist/domain/corpus/Vector.js +96 -0
- package/dist/domain/corpus/Vector.js.map +1 -0
- package/dist/domain/ports/ChatModelPort.d.ts +57 -0
- package/dist/domain/ports/ChatModelPort.js +2 -0
- package/dist/domain/ports/ChatModelPort.js.map +1 -0
- package/dist/domain/ports/ChunkRepositoryPort.d.ts +42 -0
- package/dist/domain/ports/ChunkRepositoryPort.js +2 -0
- package/dist/domain/ports/ChunkRepositoryPort.js.map +1 -0
- package/dist/domain/ports/ChunkerPort.d.ts +5 -0
- package/dist/domain/ports/ChunkerPort.js +2 -0
- package/dist/domain/ports/ChunkerPort.js.map +1 -0
- package/dist/domain/ports/DatabaseSessionPort.d.ts +10 -0
- package/dist/domain/ports/DatabaseSessionPort.js +2 -0
- package/dist/domain/ports/DatabaseSessionPort.js.map +1 -0
- package/dist/domain/ports/EmbedderPort.d.ts +14 -0
- package/dist/domain/ports/EmbedderPort.js +2 -0
- package/dist/domain/ports/EmbedderPort.js.map +1 -0
- package/dist/domain/ports/FileManifestRepositoryPort.d.ts +32 -0
- package/dist/domain/ports/FileManifestRepositoryPort.js +2 -0
- package/dist/domain/ports/FileManifestRepositoryPort.js.map +1 -0
- package/dist/domain/ports/GitPort.d.ts +24 -0
- package/dist/domain/ports/GitPort.js +2 -0
- package/dist/domain/ports/GitPort.js.map +1 -0
- package/dist/domain/ports/IndexMaintenancePort.d.ts +58 -0
- package/dist/domain/ports/IndexMaintenancePort.js +2 -0
- package/dist/domain/ports/IndexMaintenancePort.js.map +1 -0
- package/dist/domain/ports/IndexMetadataPort.d.ts +23 -0
- package/dist/domain/ports/IndexMetadataPort.js +2 -0
- package/dist/domain/ports/IndexMetadataPort.js.map +1 -0
- package/dist/domain/ports/LockPort.d.ts +17 -0
- package/dist/domain/ports/LockPort.js +2 -0
- package/dist/domain/ports/LockPort.js.map +1 -0
- package/dist/domain/ports/LoggerPort.d.ts +5 -0
- package/dist/domain/ports/LoggerPort.js +2 -0
- package/dist/domain/ports/LoggerPort.js.map +1 -0
- package/dist/domain/ports/ProjectIndexesPort.d.ts +20 -0
- package/dist/domain/ports/ProjectIndexesPort.js +2 -0
- package/dist/domain/ports/ProjectIndexesPort.js.map +1 -0
- package/dist/domain/ports/ProjectRegistryPort.d.ts +42 -0
- package/dist/domain/ports/ProjectRegistryPort.js +2 -0
- package/dist/domain/ports/ProjectRegistryPort.js.map +1 -0
- package/dist/domain/ports/StateDirectoryPort.d.ts +29 -0
- package/dist/domain/ports/StateDirectoryPort.js +2 -0
- package/dist/domain/ports/StateDirectoryPort.js.map +1 -0
- package/dist/domain/ports/WorkspacePort.d.ts +38 -0
- package/dist/domain/ports/WorkspacePort.js +2 -0
- package/dist/domain/ports/WorkspacePort.js.map +1 -0
- package/dist/domain/project/Branch.d.ts +20 -0
- package/dist/domain/project/Branch.js +33 -0
- package/dist/domain/project/Branch.js.map +1 -0
- package/dist/domain/project/DatabaseLocation.d.ts +32 -0
- package/dist/domain/project/DatabaseLocation.js +35 -0
- package/dist/domain/project/DatabaseLocation.js.map +1 -0
- package/dist/domain/project/IndexMetadata.d.ts +17 -0
- package/dist/domain/project/IndexMetadata.js +2 -0
- package/dist/domain/project/IndexMetadata.js.map +1 -0
- package/dist/domain/project/ModelIdentity.d.ts +58 -0
- package/dist/domain/project/ModelIdentity.js +97 -0
- package/dist/domain/project/ModelIdentity.js.map +1 -0
- package/dist/domain/project/Project.d.ts +17 -0
- package/dist/domain/project/Project.js +21 -0
- package/dist/domain/project/Project.js.map +1 -0
- package/dist/domain/project/ProjectId.d.ts +28 -0
- package/dist/domain/project/ProjectId.js +58 -0
- package/dist/domain/project/ProjectId.js.map +1 -0
- package/dist/domain/project/ProjectLocator.d.ts +112 -0
- package/dist/domain/project/ProjectLocator.js +178 -0
- package/dist/domain/project/ProjectLocator.js.map +1 -0
- package/dist/domain/research/Citation.d.ts +27 -0
- package/dist/domain/research/Citation.js +43 -0
- package/dist/domain/research/Citation.js.map +1 -0
- package/dist/domain/research/EvidenceLedger.d.ts +47 -0
- package/dist/domain/research/EvidenceLedger.js +111 -0
- package/dist/domain/research/EvidenceLedger.js.map +1 -0
- package/dist/domain/research/ResearchTrace.d.ts +19 -0
- package/dist/domain/research/ResearchTrace.js +22 -0
- package/dist/domain/research/ResearchTrace.js.map +1 -0
- package/dist/domain/retrieval/Hit.d.ts +19 -0
- package/dist/domain/retrieval/Hit.js +28 -0
- package/dist/domain/retrieval/Hit.js.map +1 -0
- package/dist/domain/retrieval/HitList.d.ts +35 -0
- package/dist/domain/retrieval/HitList.js +81 -0
- package/dist/domain/retrieval/HitList.js.map +1 -0
- package/dist/domain/retrieval/MissingIndexError.d.ts +11 -0
- package/dist/domain/retrieval/MissingIndexError.js +15 -0
- package/dist/domain/retrieval/MissingIndexError.js.map +1 -0
- package/dist/index.d.ts +43 -45
- package/dist/index.js +30 -567
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/ai/AiSdkChatModel.d.ts +31 -0
- package/dist/infrastructure/ai/AiSdkChatModel.js +137 -0
- package/dist/infrastructure/ai/AiSdkChatModel.js.map +1 -0
- package/dist/infrastructure/ai/AiSdkEmbedder.d.ts +28 -0
- package/dist/infrastructure/ai/AiSdkEmbedder.js +79 -0
- package/dist/infrastructure/ai/AiSdkEmbedder.js.map +1 -0
- package/dist/infrastructure/ai/EmbeddingPrefixes.d.ts +21 -0
- package/dist/infrastructure/ai/EmbeddingPrefixes.js +40 -0
- package/dist/infrastructure/ai/EmbeddingPrefixes.js.map +1 -0
- package/dist/infrastructure/ai/LmStudioProbe.d.ts +18 -0
- package/dist/infrastructure/ai/LmStudioProbe.js +49 -0
- package/dist/infrastructure/ai/LmStudioProbe.js.map +1 -0
- package/dist/infrastructure/ai/LocalModelReloader.d.ts +21 -0
- package/dist/infrastructure/ai/LocalModelReloader.js +61 -0
- package/dist/infrastructure/ai/LocalModelReloader.js.map +1 -0
- package/dist/infrastructure/ai/LocalRuntimeDetector.d.ts +36 -0
- package/dist/infrastructure/ai/LocalRuntimeDetector.js +61 -0
- package/dist/infrastructure/ai/LocalRuntimeDetector.js.map +1 -0
- package/dist/infrastructure/ai/ModelRuntime.d.ts +32 -0
- package/dist/infrastructure/ai/ModelRuntime.js +2 -0
- package/dist/infrastructure/ai/ModelRuntime.js.map +1 -0
- package/dist/infrastructure/ai/OllamaProbe.d.ts +21 -0
- package/dist/infrastructure/ai/OllamaProbe.js +69 -0
- package/dist/infrastructure/ai/OllamaProbe.js.map +1 -0
- package/dist/infrastructure/ai/ProviderFailure.d.ts +16 -0
- package/dist/infrastructure/ai/ProviderFailure.js +35 -0
- package/dist/infrastructure/ai/ProviderFailure.js.map +1 -0
- package/dist/infrastructure/ai/ProviderModuleLoader.d.ts +13 -0
- package/dist/infrastructure/ai/ProviderModuleLoader.js +49 -0
- package/dist/infrastructure/ai/ProviderModuleLoader.js.map +1 -0
- package/dist/infrastructure/ai/ProviderRegistry.d.ts +37 -0
- package/dist/infrastructure/ai/ProviderRegistry.js +55 -0
- package/dist/infrastructure/ai/ProviderRegistry.js.map +1 -0
- package/dist/infrastructure/fs/ConfigLoader.d.ts +59 -0
- package/dist/infrastructure/fs/ConfigLoader.js +194 -0
- package/dist/infrastructure/fs/ConfigLoader.js.map +1 -0
- package/dist/infrastructure/fs/DatabaseLocks.d.ts +52 -0
- package/dist/infrastructure/fs/DatabaseLocks.js +92 -0
- package/dist/infrastructure/fs/DatabaseLocks.js.map +1 -0
- package/dist/infrastructure/fs/DiskUsage.d.ts +6 -0
- package/dist/infrastructure/fs/DiskUsage.js +41 -0
- package/dist/infrastructure/fs/DiskUsage.js.map +1 -0
- package/dist/infrastructure/fs/IndexableFileRules.d.ts +33 -0
- package/dist/infrastructure/fs/IndexableFileRules.js +177 -0
- package/dist/infrastructure/fs/IndexableFileRules.js.map +1 -0
- package/dist/infrastructure/fs/Loggers.d.ts +14 -0
- package/dist/infrastructure/fs/Loggers.js +18 -0
- package/dist/infrastructure/fs/Loggers.js.map +1 -0
- package/dist/infrastructure/fs/PidFileLock.d.ts +40 -0
- package/dist/infrastructure/fs/PidFileLock.js +97 -0
- package/dist/infrastructure/fs/PidFileLock.js.map +1 -0
- package/dist/infrastructure/fs/ProjectIndexes.d.ts +8 -0
- package/dist/infrastructure/fs/ProjectIndexes.js +35 -0
- package/dist/infrastructure/fs/ProjectIndexes.js.map +1 -0
- package/dist/infrastructure/fs/ProjectMetadataStore.d.ts +42 -0
- package/dist/infrastructure/fs/ProjectMetadataStore.js +86 -0
- package/dist/infrastructure/fs/ProjectMetadataStore.js.map +1 -0
- package/dist/infrastructure/fs/ProjectRegistry.d.ts +25 -0
- package/dist/infrastructure/fs/ProjectRegistry.js +83 -0
- package/dist/infrastructure/fs/ProjectRegistry.js.map +1 -0
- package/dist/infrastructure/fs/StateDirectory.d.ts +28 -0
- package/dist/infrastructure/fs/StateDirectory.js +71 -0
- package/dist/infrastructure/fs/StateDirectory.js.map +1 -0
- package/dist/infrastructure/fs/Workspace.d.ts +25 -0
- package/dist/infrastructure/fs/Workspace.js +90 -0
- package/dist/infrastructure/fs/Workspace.js.map +1 -0
- package/dist/infrastructure/git/GitClient.d.ts +34 -0
- package/dist/infrastructure/git/GitClient.js +74 -0
- package/dist/infrastructure/git/GitClient.js.map +1 -0
- package/dist/infrastructure/lancedb/ChunkRepository.d.ts +38 -0
- package/dist/infrastructure/lancedb/ChunkRepository.js +166 -0
- package/dist/infrastructure/lancedb/ChunkRepository.js.map +1 -0
- package/dist/infrastructure/lancedb/DatabaseImporter.d.ts +22 -0
- package/dist/infrastructure/lancedb/DatabaseImporter.js +74 -0
- package/dist/infrastructure/lancedb/DatabaseImporter.js.map +1 -0
- package/dist/infrastructure/lancedb/FileManifestRepository.d.ts +34 -0
- package/dist/infrastructure/lancedb/FileManifestRepository.js +137 -0
- package/dist/infrastructure/lancedb/FileManifestRepository.js.map +1 -0
- package/dist/infrastructure/lancedb/IndexMaintenance.d.ts +53 -0
- package/dist/infrastructure/lancedb/IndexMaintenance.js +227 -0
- package/dist/infrastructure/lancedb/IndexMaintenance.js.map +1 -0
- package/dist/infrastructure/lancedb/LanceTables.d.ts +67 -0
- package/dist/infrastructure/lancedb/LanceTables.js +159 -0
- package/dist/infrastructure/lancedb/LanceTables.js.map +1 -0
- package/dist/{lib/native-tuning.js → infrastructure/lancedb/NativeTuning.js} +1 -1
- package/dist/infrastructure/lancedb/NativeTuning.js.map +1 -0
- package/dist/infrastructure/lancedb/RowReplication.d.ts +27 -0
- package/dist/infrastructure/lancedb/RowReplication.js +82 -0
- package/dist/infrastructure/lancedb/RowReplication.js.map +1 -0
- package/dist/infrastructure/lancedb/VectorIndexPolicy.d.ts +60 -0
- package/dist/infrastructure/lancedb/VectorIndexPolicy.js +72 -0
- package/dist/infrastructure/lancedb/VectorIndexPolicy.js.map +1 -0
- package/dist/infrastructure/p2p/IndexShare.d.ts +45 -0
- package/dist/infrastructure/p2p/IndexShare.js +160 -0
- package/dist/infrastructure/p2p/IndexShare.js.map +1 -0
- package/dist/infrastructure/p2p/PeerSwarm.d.ts +16 -0
- package/dist/infrastructure/p2p/PeerSwarm.js +41 -0
- package/dist/infrastructure/p2p/PeerSwarm.js.map +1 -0
- package/dist/infrastructure/p2p/SecureChannel.d.ts +60 -0
- package/dist/infrastructure/p2p/SecureChannel.js +71 -0
- package/dist/infrastructure/p2p/SecureChannel.js.map +1 -0
- package/dist/infrastructure/p2p/ShareCode.d.ts +25 -0
- package/dist/infrastructure/p2p/ShareCode.js +304 -0
- package/dist/infrastructure/p2p/ShareCode.js.map +1 -0
- package/dist/infrastructure/process/ProcessRegistry.d.ts +50 -0
- package/dist/infrastructure/process/ProcessRegistry.js +109 -0
- package/dist/infrastructure/process/ProcessRegistry.js.map +1 -0
- package/dist/infrastructure/treesitter/ChunkContextBuilder.d.ts +45 -0
- package/dist/infrastructure/treesitter/ChunkContextBuilder.js +159 -0
- package/dist/infrastructure/treesitter/ChunkContextBuilder.js.map +1 -0
- package/dist/infrastructure/treesitter/LanguageCatalog.d.ts +30 -0
- package/dist/{lib/chunker/languages.js → infrastructure/treesitter/LanguageCatalog.js} +34 -29
- package/dist/infrastructure/treesitter/LanguageCatalog.js.map +1 -0
- package/dist/infrastructure/treesitter/SlidingWindowChunker.d.ts +15 -0
- package/dist/infrastructure/treesitter/SlidingWindowChunker.js +42 -0
- package/dist/infrastructure/treesitter/SlidingWindowChunker.js.map +1 -0
- package/dist/infrastructure/treesitter/TreeSitterChunker.d.ts +42 -0
- package/dist/infrastructure/treesitter/TreeSitterChunker.js +163 -0
- package/dist/infrastructure/treesitter/TreeSitterChunker.js.map +1 -0
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +14 -72
- package/dist/mcp.js.map +1 -1
- package/dist/presentation/cli/Cli.d.ts +31 -0
- package/dist/presentation/cli/Cli.js +120 -0
- package/dist/presentation/cli/Cli.js.map +1 -0
- package/dist/presentation/cli/CliOptions.d.ts +18 -0
- package/dist/presentation/cli/CliOptions.js +25 -0
- package/dist/presentation/cli/CliOptions.js.map +1 -0
- package/dist/presentation/cli/CommandContext.d.ts +50 -0
- package/dist/presentation/cli/CommandContext.js +88 -0
- package/dist/presentation/cli/CommandContext.js.map +1 -0
- package/dist/presentation/cli/ConfigTemplate.d.ts +31 -0
- package/dist/presentation/cli/ConfigTemplate.js +83 -0
- package/dist/presentation/cli/ConfigTemplate.js.map +1 -0
- package/dist/presentation/cli/Renderer.d.ts +90 -0
- package/dist/presentation/cli/Renderer.js +290 -0
- package/dist/presentation/cli/Renderer.js.map +1 -0
- package/dist/presentation/cli/commands/AskCommand.d.ts +14 -0
- package/dist/presentation/cli/commands/AskCommand.js +48 -0
- package/dist/presentation/cli/commands/AskCommand.js.map +1 -0
- package/dist/presentation/cli/commands/CompletionsCommand.d.ts +18 -0
- package/dist/presentation/cli/commands/CompletionsCommand.js +96 -0
- package/dist/presentation/cli/commands/CompletionsCommand.js.map +1 -0
- package/dist/presentation/cli/commands/ConfigCommands.d.ts +55 -0
- package/dist/presentation/cli/commands/ConfigCommands.js +204 -0
- package/dist/presentation/cli/commands/ConfigCommands.js.map +1 -0
- package/dist/presentation/cli/commands/IndexCommand.d.ts +18 -0
- package/dist/presentation/cli/commands/IndexCommand.js +54 -0
- package/dist/presentation/cli/commands/IndexCommand.js.map +1 -0
- package/dist/presentation/cli/commands/ProjectsCommand.d.ts +48 -0
- package/dist/presentation/cli/commands/ProjectsCommand.js +240 -0
- package/dist/presentation/cli/commands/ProjectsCommand.js.map +1 -0
- package/dist/presentation/cli/commands/SearchCommand.d.ts +19 -0
- package/dist/presentation/cli/commands/SearchCommand.js +55 -0
- package/dist/presentation/cli/commands/SearchCommand.js.map +1 -0
- package/dist/presentation/cli/commands/ServerCommands.d.ts +13 -0
- package/dist/presentation/cli/commands/ServerCommands.js +40 -0
- package/dist/presentation/cli/commands/ServerCommands.js.map +1 -0
- package/dist/presentation/cli/commands/ShareCommands.d.ts +22 -0
- package/dist/presentation/cli/commands/ShareCommands.js +134 -0
- package/dist/presentation/cli/commands/ShareCommands.js.map +1 -0
- package/dist/presentation/cli/commands/StatusCommand.d.ts +15 -0
- package/dist/presentation/cli/commands/StatusCommand.js +53 -0
- package/dist/presentation/cli/commands/StatusCommand.js.map +1 -0
- package/dist/presentation/mcp/HitFormatter.d.ts +17 -0
- package/dist/presentation/mcp/HitFormatter.js +42 -0
- package/dist/presentation/mcp/HitFormatter.js.map +1 -0
- package/dist/presentation/mcp/IndexWatchController.d.ts +17 -0
- package/dist/presentation/mcp/IndexWatchController.js +31 -0
- package/dist/presentation/mcp/IndexWatchController.js.map +1 -0
- package/dist/presentation/mcp/LmgrepCore.d.ts +66 -0
- package/dist/presentation/mcp/LmgrepCore.js +178 -0
- package/dist/presentation/mcp/LmgrepCore.js.map +1 -0
- package/dist/presentation/mcp/McpServer.d.ts +18 -0
- package/dist/presentation/mcp/McpServer.js +63 -0
- package/dist/presentation/mcp/McpServer.js.map +1 -0
- package/dist/presentation/mcp/ToolDescriptions.d.ts +40 -0
- package/dist/presentation/mcp/ToolDescriptions.js +85 -0
- package/dist/presentation/mcp/ToolDescriptions.js.map +1 -0
- package/package.json +84 -89
- package/dist/lib/build.d.ts +0 -21
- package/dist/lib/build.js +0 -374
- package/dist/lib/build.js.map +0 -1
- package/dist/lib/chunker/context.d.ts +0 -21
- package/dist/lib/chunker/context.js +0 -131
- package/dist/lib/chunker/context.js.map +0 -1
- package/dist/lib/chunker/index.d.ts +0 -7
- package/dist/lib/chunker/index.js +0 -209
- package/dist/lib/chunker/index.js.map +0 -1
- package/dist/lib/chunker/languages.d.ts +0 -15
- package/dist/lib/chunker/languages.js.map +0 -1
- package/dist/lib/config.d.ts +0 -12
- package/dist/lib/config.js +0 -83
- package/dist/lib/config.js.map +0 -1
- package/dist/lib/embedder.d.ts +0 -65
- package/dist/lib/embedder.js +0 -236
- package/dist/lib/embedder.js.map +0 -1
- package/dist/lib/facet-session.d.ts +0 -44
- package/dist/lib/facet-session.js +0 -125
- package/dist/lib/facet-session.js.map +0 -1
- package/dist/lib/native-tuning.js.map +0 -1
- package/dist/lib/p2p.d.ts +0 -32
- package/dist/lib/p2p.js +0 -281
- package/dist/lib/p2p.js.map +0 -1
- package/dist/lib/providers.d.ts +0 -1
- package/dist/lib/providers.js +0 -41
- package/dist/lib/providers.js.map +0 -1
- package/dist/lib/repair.d.ts +0 -10
- package/dist/lib/repair.js +0 -57
- package/dist/lib/repair.js.map +0 -1
- package/dist/lib/scanner.d.ts +0 -34
- package/dist/lib/scanner.js +0 -242
- package/dist/lib/scanner.js.map +0 -1
- package/dist/lib/search-tool.d.ts +0 -55
- package/dist/lib/search-tool.js +0 -319
- package/dist/lib/search-tool.js.map +0 -1
- package/dist/lib/serve.d.ts +0 -11
- package/dist/lib/serve.js +0 -144
- package/dist/lib/serve.js.map +0 -1
- package/dist/lib/store.d.ts +0 -252
- package/dist/lib/store.js +0 -1216
- package/dist/lib/store.js.map +0 -1
- package/dist/lib/types.d.ts +0 -194
- package/dist/lib/types.js +0 -13
- package/dist/lib/types.js.map +0 -1
- package/dist/lib/vocab.d.ts +0 -20
- package/dist/lib/vocab.js +0 -275
- package/dist/lib/vocab.js.map +0 -1
- /package/dist/{lib/native-tuning.d.ts → infrastructure/lancedb/NativeTuning.d.ts} +0 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { Index } from "@lancedb/lancedb";
|
|
2
|
+
import { ChunkRepository } from "./ChunkRepository.js";
|
|
3
|
+
import { TableName } from "./LanceTables.js";
|
|
4
|
+
import { VectorIndexPolicy } from "./VectorIndexPolicy.js";
|
|
5
|
+
/**
|
|
6
|
+
* Keeps the LanceDB tables compact and their ANN indexes current.
|
|
7
|
+
*
|
|
8
|
+
* Without a vector index LanceDB answers a search by brute force: it decodes
|
|
9
|
+
* every stored embedding to score it. At high dimensions that walks the whole
|
|
10
|
+
* table through memory per query, so peak RSS tracks index size roughly 1:1.
|
|
11
|
+
* IVF-PQ turns that into a handful of probes.
|
|
12
|
+
*
|
|
13
|
+
* Compaction matters for the same reason — small appends leave hundreds of
|
|
14
|
+
* fragments, each carrying its own decode buffers.
|
|
15
|
+
*/
|
|
16
|
+
export class IndexMaintenance {
|
|
17
|
+
tables;
|
|
18
|
+
manifest;
|
|
19
|
+
/** Tables holding embeddings, and therefore wanting a vector index. */
|
|
20
|
+
static VECTOR_TABLES = [TableName.Chunks];
|
|
21
|
+
constructor(tables, manifest) {
|
|
22
|
+
this.tables = tables;
|
|
23
|
+
this.manifest = manifest;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Cheap and idempotent when there is nothing to do, so it is safe to call
|
|
27
|
+
* after every build.
|
|
28
|
+
*/
|
|
29
|
+
async optimize(options = {}) {
|
|
30
|
+
const report = { tables: [] };
|
|
31
|
+
for (const name of IndexMaintenance.VECTOR_TABLES) {
|
|
32
|
+
const table = await this.tables.table(name);
|
|
33
|
+
if (!table)
|
|
34
|
+
continue;
|
|
35
|
+
report.tables.push(await this.optimizeTable(name, table, options.force ?? false, options.create ?? false));
|
|
36
|
+
}
|
|
37
|
+
return report;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* What `lmgrep compact` runs: the same work as {@link optimize} but
|
|
41
|
+
* unconditional, plus compaction of the files table (which holds no
|
|
42
|
+
* embeddings, so it never needs a vector index).
|
|
43
|
+
*/
|
|
44
|
+
async compact() {
|
|
45
|
+
const report = await this.optimize({ force: true, create: true });
|
|
46
|
+
await this.dropLegacyTables(report);
|
|
47
|
+
const files = await this.tables.table(TableName.Files);
|
|
48
|
+
if (files) {
|
|
49
|
+
await files.optimize();
|
|
50
|
+
report.tables.push({
|
|
51
|
+
table: TableName.Files,
|
|
52
|
+
rows: await files.countRows(),
|
|
53
|
+
action: "optimized",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return report;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Remove tables no longer part of the schema.
|
|
60
|
+
*
|
|
61
|
+
* Databases built before faceting was removed still carry a `vocab` table
|
|
62
|
+
* holding one embedding per corpus term — nothing reads it now, and at
|
|
63
|
+
* full embedding width that is real disk. Dropping it here means users
|
|
64
|
+
* reclaim the space by running the command they already run.
|
|
65
|
+
*/
|
|
66
|
+
async dropLegacyTables(report) {
|
|
67
|
+
const vocab = await this.tables.table(TableName.LegacyVocab);
|
|
68
|
+
if (!vocab)
|
|
69
|
+
return;
|
|
70
|
+
const rows = await vocab.countRows();
|
|
71
|
+
await this.tables.dropTable(TableName.LegacyVocab);
|
|
72
|
+
report.tables.push({
|
|
73
|
+
table: TableName.LegacyVocab,
|
|
74
|
+
rows,
|
|
75
|
+
action: "dropped",
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
async optimizeTable(name, table, force, create) {
|
|
79
|
+
const rows = await table.countRows();
|
|
80
|
+
// listIndices reports the columns each index covers, so this stays
|
|
81
|
+
// correct if a scalar index is ever added alongside the vector one.
|
|
82
|
+
const indices = await table.listIndices();
|
|
83
|
+
const vectorIndex = indices.find((i) => i.columns.includes("vector"));
|
|
84
|
+
if (!vectorIndex) {
|
|
85
|
+
// The size guard is not overridable. `force` means "don't wait for
|
|
86
|
+
// the tail to grow", not "cluster a table with too few vectors to
|
|
87
|
+
// cluster" — IVF-PQ on a small table trains empty partitions and
|
|
88
|
+
// degrades recall for no memory saving.
|
|
89
|
+
if (rows < VectorIndexPolicy.MIN_ROWS_FOR_ANN) {
|
|
90
|
+
return { table: name, rows, action: "skipped-small" };
|
|
91
|
+
}
|
|
92
|
+
if (!create) {
|
|
93
|
+
return { table: name, rows, action: "needs-index" };
|
|
94
|
+
}
|
|
95
|
+
// numPartitions and numSubVectors are left to LanceDB, which
|
|
96
|
+
// derives them from row count and dimensionality. Hard-coding them
|
|
97
|
+
// would only reproduce that rule for dimensions already seen.
|
|
98
|
+
await table.createIndex("vector", {
|
|
99
|
+
config: Index.ivfPq({
|
|
100
|
+
distanceType: VectorIndexPolicy.DISTANCE_TYPE,
|
|
101
|
+
}),
|
|
102
|
+
replace: true,
|
|
103
|
+
});
|
|
104
|
+
await table.optimize();
|
|
105
|
+
return { table: name, rows, action: "created" };
|
|
106
|
+
}
|
|
107
|
+
const stats = await table.indexStats(vectorIndex.name);
|
|
108
|
+
const unindexed = stats?.numUnindexedRows ?? 0;
|
|
109
|
+
const indexed = stats?.numIndexedRows ?? 0;
|
|
110
|
+
const tolerated = Math.max(VectorIndexPolicy.UNINDEXED_REINDEX_FLOOR, Math.floor(indexed * VectorIndexPolicy.UNINDEXED_REINDEX_RATIO));
|
|
111
|
+
if (!force && unindexed <= tolerated) {
|
|
112
|
+
return { table: name, rows, action: "up-to-date", unindexed };
|
|
113
|
+
}
|
|
114
|
+
// optimize() both compacts fragments and folds the unindexed tail into
|
|
115
|
+
// the existing index — no retraining from scratch.
|
|
116
|
+
await table.optimize();
|
|
117
|
+
return { table: name, rows, action: "optimized", unindexed };
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Remove rows that should not be there: exact id duplicates (from
|
|
121
|
+
* concurrent unlocked indexing) and chunks whose file version no branch
|
|
122
|
+
* references any more. Survivors are rewritten into a fresh table, which is
|
|
123
|
+
* also what reclaims the disk the dropped rows held.
|
|
124
|
+
*/
|
|
125
|
+
async dedupe() {
|
|
126
|
+
const table = await this.tables.table(TableName.Chunks);
|
|
127
|
+
if (!table) {
|
|
128
|
+
return { before: 0, after: 0, duplicateIds: 0, staleVersions: 0 };
|
|
129
|
+
}
|
|
130
|
+
const before = await table.countRows();
|
|
131
|
+
// (filePath, fileHash) pairs any branch still references.
|
|
132
|
+
const referenced = new Map();
|
|
133
|
+
for (const entry of await this.manifest.allEntries()) {
|
|
134
|
+
const set = referenced.get(entry.filePath) ?? new Set();
|
|
135
|
+
set.add(entry.fileHash.toString());
|
|
136
|
+
referenced.set(entry.filePath, set);
|
|
137
|
+
}
|
|
138
|
+
const kept = [];
|
|
139
|
+
const seenIds = new Set();
|
|
140
|
+
let duplicateIds = 0;
|
|
141
|
+
let staleVersions = 0;
|
|
142
|
+
const total = before;
|
|
143
|
+
const BATCH = 2000;
|
|
144
|
+
for (let offset = 0; offset < total; offset += BATCH) {
|
|
145
|
+
const rows = await table.query().limit(BATCH).offset(offset).toArray();
|
|
146
|
+
if (rows.length === 0)
|
|
147
|
+
break;
|
|
148
|
+
for (const row of rows) {
|
|
149
|
+
const id = row.id;
|
|
150
|
+
if (seenIds.has(id)) {
|
|
151
|
+
duplicateIds++;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
seenIds.add(id);
|
|
155
|
+
const filePath = row.filePath;
|
|
156
|
+
const fileHash = row.fileHash ?? "";
|
|
157
|
+
// "" is the legacy wildcard — never stale.
|
|
158
|
+
if (fileHash !== "" && !referenced.get(filePath)?.has(fileHash)) {
|
|
159
|
+
staleVersions++;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
kept.push(this.toPlainRow(row));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (duplicateIds + staleVersions === 0) {
|
|
166
|
+
return { before, after: before, duplicateIds, staleVersions };
|
|
167
|
+
}
|
|
168
|
+
await this.tables.dropTable(TableName.Chunks);
|
|
169
|
+
if (kept.length > 0) {
|
|
170
|
+
const { table: rebuilt, seeded } = await this.tables.tableOrCreate(TableName.Chunks, kept);
|
|
171
|
+
if (!seeded)
|
|
172
|
+
await rebuilt.add(kept);
|
|
173
|
+
}
|
|
174
|
+
return { before, after: kept.length, duplicateIds, staleVersions };
|
|
175
|
+
}
|
|
176
|
+
async vectorIndexState() {
|
|
177
|
+
const table = await this.tables.table(TableName.Chunks);
|
|
178
|
+
if (!table) {
|
|
179
|
+
return { rows: 0, built: false, unindexed: 0, worthBuilding: false };
|
|
180
|
+
}
|
|
181
|
+
const rows = await table.countRows();
|
|
182
|
+
const index = (await table.listIndices()).find((i) => i.columns.includes("vector"));
|
|
183
|
+
if (!index) {
|
|
184
|
+
return {
|
|
185
|
+
rows,
|
|
186
|
+
built: false,
|
|
187
|
+
unindexed: rows,
|
|
188
|
+
worthBuilding: rows >= VectorIndexPolicy.MIN_ROWS_FOR_ANN,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
const stats = await table.indexStats(index.name);
|
|
192
|
+
return {
|
|
193
|
+
rows,
|
|
194
|
+
built: true,
|
|
195
|
+
unindexed: stats?.numUnindexedRows ?? 0,
|
|
196
|
+
worthBuilding: true,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
async reset() {
|
|
200
|
+
for (const name of [
|
|
201
|
+
TableName.Chunks,
|
|
202
|
+
TableName.Files,
|
|
203
|
+
TableName.LegacyVocab,
|
|
204
|
+
]) {
|
|
205
|
+
await this.tables.dropTable(name);
|
|
206
|
+
}
|
|
207
|
+
this.manifest.invalidate();
|
|
208
|
+
}
|
|
209
|
+
/** Arrow rows carry typed arrays; LanceDB needs plain values to re-infer a schema. */
|
|
210
|
+
toPlainRow(row) {
|
|
211
|
+
const chunk = ChunkRepository.rowToChunk(row);
|
|
212
|
+
return {
|
|
213
|
+
id: row.id,
|
|
214
|
+
filePath: chunk.location.filePath,
|
|
215
|
+
startLine: chunk.location.startLine,
|
|
216
|
+
endLine: chunk.location.endLine,
|
|
217
|
+
type: chunk.type,
|
|
218
|
+
name: chunk.name,
|
|
219
|
+
content: chunk.content,
|
|
220
|
+
context: chunk.context,
|
|
221
|
+
hash: chunk.hash.toString(),
|
|
222
|
+
fileHash: chunk.fileVersion.toStored(),
|
|
223
|
+
vector: Array.from(row.vector),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=IndexMaintenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IndexMaintenance.js","sourceRoot":"","sources":["../../../src/infrastructure/lancedb/IndexMaintenance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAc,MAAM,kBAAkB,CAAC;AAUrD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAoB,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,MAAM,OAAO,gBAAgB;IAKV;IACA;IALlB,uEAAuE;IAC/D,MAAM,CAAU,aAAa,GAAG,CAAC,SAAS,CAAC,MAAM,CAAU,CAAC;IAEpE,YACkB,MAAmB,EACnB,QAAoC;QADpC,WAAM,GAAN,MAAM,CAAa;QACnB,aAAQ,GAAR,QAAQ,CAA4B;IACnD,CAAC;IAEJ;;;OAGG;IACH,KAAK,CAAC,QAAQ,CAAC,UAA2B,EAAE;QAC3C,MAAM,MAAM,GAAmB,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAC9C,KAAK,MAAM,IAAI,IAAI,gBAAgB,CAAC,aAAa,EAAE,CAAC;YACnD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5C,IAAI,CAAC,KAAK;gBAAE,SAAS;YACrB,MAAM,CAAC,MAAM,CAAC,IAAI,CACjB,MAAM,IAAI,CAAC,aAAa,CACvB,IAAI,EACJ,KAAK,EACL,OAAO,CAAC,KAAK,IAAI,KAAK,EACtB,OAAO,CAAC,MAAM,IAAI,KAAK,CACvB,CACD,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAO;QACZ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACvD,IAAI,KAAK,EAAE,CAAC;YACX,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC;YACvB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;gBAClB,KAAK,EAAE,SAAS,CAAC,KAAK;gBACtB,IAAI,EAAE,MAAM,KAAK,CAAC,SAAS,EAAE;gBAC7B,MAAM,EAAE,WAAW;aACnB,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;;;;;;OAOG;IACK,KAAK,CAAC,gBAAgB,CAAC,MAAsB;QACpD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC7D,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;YAClB,KAAK,EAAE,SAAS,CAAC,WAAW;YAC5B,IAAI;YACJ,MAAM,EAAE,SAAS;SACjB,CAAC,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,aAAa,CAC1B,IAAY,EACZ,KAAY,EACZ,KAAc,EACd,MAAe;QAEf,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC;QAErC,mEAAmE;QACnE,oEAAoE;QACpE,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC;QAC1C,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEtE,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,mEAAmE;YACnE,kEAAkE;YAClE,iEAAiE;YACjE,wCAAwC;YACxC,IAAI,IAAI,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,CAAC;gBAC/C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;YACvD,CAAC;YACD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACb,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;YACrD,CAAC;YACD,6DAA6D;YAC7D,mEAAmE;YACnE,8DAA8D;YAC9D,MAAM,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE;gBACjC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC;oBACnB,YAAY,EAAE,iBAAiB,CAAC,aAAa;iBAC7C,CAAC;gBACF,OAAO,EAAE,IAAI;aACb,CAAC,CAAC;YACH,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC;YACvB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QACjD,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,SAAS,GAAG,KAAK,EAAE,gBAAgB,IAAI,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,KAAK,EAAE,cAAc,IAAI,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CACzB,iBAAiB,CAAC,uBAAuB,EACzC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,iBAAiB,CAAC,uBAAuB,CAAC,CAC/D,CAAC;QAEF,IAAI,CAAC,KAAK,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;YACtC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;QAC/D,CAAC;QAED,uEAAuE;QACvE,mDAAmD;QACnD,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC;QACvB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;IAC9D,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM;QACX,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACxD,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;QACnE,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC;QAEvC,0DAA0D;QAC1D,MAAM,UAAU,GAAG,IAAI,GAAG,EAAuB,CAAC;QAClD,KAAK,MAAM,KAAK,IAAI,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC;YACtD,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;YAChE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;YACnC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC;QAED,MAAM,IAAI,GAA8B,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,aAAa,GAAG,CAAC,CAAC;QAEtB,MAAM,KAAK,GAAG,MAAM,CAAC;QACrB,MAAM,KAAK,GAAG,IAAI,CAAC;QACnB,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,EAAE,MAAM,IAAI,KAAK,EAAE,CAAC;YACtD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;YACvE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM;YAC7B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACxB,MAAM,EAAE,GAAG,GAAG,CAAC,EAAY,CAAC;gBAC5B,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBACrB,YAAY,EAAE,CAAC;oBACf,SAAS;gBACV,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAEhB,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAkB,CAAC;gBACxC,MAAM,QAAQ,GAAI,GAAG,CAAC,QAAmB,IAAI,EAAE,CAAC;gBAChD,2CAA2C;gBAC3C,IAAI,QAAQ,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACjE,aAAa,EAAE,CAAC;oBAChB,SAAS;gBACV,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;YACjC,CAAC;QACF,CAAC;QAED,IAAI,YAAY,GAAG,aAAa,KAAK,CAAC,EAAE,CAAC;YACxC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;QAC/D,CAAC;QAED,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC9C,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CACjE,SAAS,CAAC,MAAM,EAChB,IAAI,CACJ,CAAC;YACF,IAAI,CAAC,MAAM;gBAAE,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,gBAAgB;QACrB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACxD,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;QACtE,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACpD,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC5B,CAAC;QACF,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,OAAO;gBACN,IAAI;gBACJ,KAAK,EAAE,KAAK;gBACZ,SAAS,EAAE,IAAI;gBACf,aAAa,EAAE,IAAI,IAAI,iBAAiB,CAAC,gBAAgB;aACzD,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjD,OAAO;YACN,IAAI;YACJ,KAAK,EAAE,IAAI;YACX,SAAS,EAAE,KAAK,EAAE,gBAAgB,IAAI,CAAC;YACvC,aAAa,EAAE,IAAI;SACnB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACV,KAAK,MAAM,IAAI,IAAI;YAClB,SAAS,CAAC,MAAM;YAChB,SAAS,CAAC,KAAK;YACf,SAAS,CAAC,WAAW;SACrB,EAAE,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;IAC5B,CAAC;IAED,sFAAsF;IAC9E,UAAU,CAAC,GAA4B;QAC9C,MAAM,KAAK,GAAG,eAAe,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC9C,OAAO;YACN,EAAE,EAAE,GAAG,CAAC,EAAY;YACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ;YACjC,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,SAAS;YACnC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,OAAO;YAC/B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC3B,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE;YACtC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAA0B,CAAC;SAClD,CAAC;IACH,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { type Table } from "@lancedb/lancedb";
|
|
2
|
+
import type { Branch } from "../../domain/project/Branch.js";
|
|
3
|
+
/**
|
|
4
|
+
* Table names inside a LanceDB database directory.
|
|
5
|
+
*
|
|
6
|
+
* A const object rather than a `const enum`: const enums are erased at emit,
|
|
7
|
+
* so importing one across modules compiles but can vanish at runtime.
|
|
8
|
+
*/
|
|
9
|
+
export declare const TableName: {
|
|
10
|
+
readonly Chunks: "chunks";
|
|
11
|
+
readonly Files: "files";
|
|
12
|
+
/**
|
|
13
|
+
* Written by the removed faceting feature. Nothing reads it; it is listed
|
|
14
|
+
* so maintenance can drop it and give the disk back.
|
|
15
|
+
*/
|
|
16
|
+
readonly LegacyVocab: "vocab";
|
|
17
|
+
};
|
|
18
|
+
export type TableName = (typeof TableName)[keyof typeof TableName];
|
|
19
|
+
/**
|
|
20
|
+
* Shared access to one LanceDB database: connecting, opening tables lazily,
|
|
21
|
+
* and running the schema backfills legacy databases need.
|
|
22
|
+
*
|
|
23
|
+
* The repositories share an instance so they share a connection — LanceDB
|
|
24
|
+
* connections are per-directory and opening several would multiply the native
|
|
25
|
+
* runtime's memory.
|
|
26
|
+
*/
|
|
27
|
+
export declare class LanceTables {
|
|
28
|
+
readonly path: string;
|
|
29
|
+
private readonly branch;
|
|
30
|
+
/**
|
|
31
|
+
* Predicates are built by string interpolation, so batches are kept small
|
|
32
|
+
* enough that no single filter grows unreasonably long.
|
|
33
|
+
*/
|
|
34
|
+
static readonly FILTER_BATCH_SIZE = 50;
|
|
35
|
+
private db;
|
|
36
|
+
private readonly open;
|
|
37
|
+
constructor(path: string, branch: Branch);
|
|
38
|
+
private connection;
|
|
39
|
+
/** Open a table, or undefined when the database has never held it. */
|
|
40
|
+
table(name: TableName): Promise<Table | undefined>;
|
|
41
|
+
/**
|
|
42
|
+
* Open a table, creating it from `seed` rows when it does not exist.
|
|
43
|
+
* `seeded` says whether creation consumed the rows, so the caller knows not
|
|
44
|
+
* to insert them a second time.
|
|
45
|
+
*/
|
|
46
|
+
tableOrCreate(name: TableName, seed: Record<string, unknown>[]): Promise<{
|
|
47
|
+
table: Table;
|
|
48
|
+
seeded: boolean;
|
|
49
|
+
}>;
|
|
50
|
+
tableNames(): Promise<string[]>;
|
|
51
|
+
dropTable(name: TableName): Promise<void>;
|
|
52
|
+
/** Forget cached handles so the next access re-opens and re-migrates. */
|
|
53
|
+
forget(name?: TableName): void;
|
|
54
|
+
close(): void;
|
|
55
|
+
/** `column IN ('a', 'b')`, with values single-quote escaped. */
|
|
56
|
+
static inFilter(column: string, values: readonly string[]): string;
|
|
57
|
+
static quote(value: string): string;
|
|
58
|
+
/** Run `column IN (...)` deletes in batches small enough for one predicate. */
|
|
59
|
+
static deleteIn(table: Table, column: string, values: readonly string[]): Promise<void>;
|
|
60
|
+
/** Run a batched `column IN (...)` select, collecting one column's values. */
|
|
61
|
+
static selectIn(table: Table, column: string, values: readonly string[]): Promise<Set<string>>;
|
|
62
|
+
/**
|
|
63
|
+
* Backfill columns that legacy databases predate. Both are additive and
|
|
64
|
+
* idempotent — a table that already has the column is left alone.
|
|
65
|
+
*/
|
|
66
|
+
private migrate;
|
|
67
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { mkdirSync } from "node:fs";
|
|
2
|
+
import { connect } from "@lancedb/lancedb";
|
|
3
|
+
/**
|
|
4
|
+
* Table names inside a LanceDB database directory.
|
|
5
|
+
*
|
|
6
|
+
* A const object rather than a `const enum`: const enums are erased at emit,
|
|
7
|
+
* so importing one across modules compiles but can vanish at runtime.
|
|
8
|
+
*/
|
|
9
|
+
export const TableName = {
|
|
10
|
+
Chunks: "chunks",
|
|
11
|
+
Files: "files",
|
|
12
|
+
/**
|
|
13
|
+
* Written by the removed faceting feature. Nothing reads it; it is listed
|
|
14
|
+
* so maintenance can drop it and give the disk back.
|
|
15
|
+
*/
|
|
16
|
+
LegacyVocab: "vocab",
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Shared access to one LanceDB database: connecting, opening tables lazily,
|
|
20
|
+
* and running the schema backfills legacy databases need.
|
|
21
|
+
*
|
|
22
|
+
* The repositories share an instance so they share a connection — LanceDB
|
|
23
|
+
* connections are per-directory and opening several would multiply the native
|
|
24
|
+
* runtime's memory.
|
|
25
|
+
*/
|
|
26
|
+
export class LanceTables {
|
|
27
|
+
path;
|
|
28
|
+
branch;
|
|
29
|
+
/**
|
|
30
|
+
* Predicates are built by string interpolation, so batches are kept small
|
|
31
|
+
* enough that no single filter grows unreasonably long.
|
|
32
|
+
*/
|
|
33
|
+
static FILTER_BATCH_SIZE = 50;
|
|
34
|
+
db;
|
|
35
|
+
open = new Map();
|
|
36
|
+
constructor(path, branch) {
|
|
37
|
+
this.path = path;
|
|
38
|
+
this.branch = branch;
|
|
39
|
+
}
|
|
40
|
+
async connection() {
|
|
41
|
+
if (this.db)
|
|
42
|
+
return this.db;
|
|
43
|
+
mkdirSync(this.path, { recursive: true });
|
|
44
|
+
this.db = await connect(this.path);
|
|
45
|
+
return this.db;
|
|
46
|
+
}
|
|
47
|
+
/** Open a table, or undefined when the database has never held it. */
|
|
48
|
+
async table(name) {
|
|
49
|
+
const cached = this.open.get(name);
|
|
50
|
+
if (cached)
|
|
51
|
+
return cached;
|
|
52
|
+
const conn = await this.connection();
|
|
53
|
+
const names = await conn.tableNames();
|
|
54
|
+
if (!names.includes(name))
|
|
55
|
+
return undefined;
|
|
56
|
+
const table = await conn.openTable(name);
|
|
57
|
+
await this.migrate(name, table);
|
|
58
|
+
this.open.set(name, table);
|
|
59
|
+
return table;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Open a table, creating it from `seed` rows when it does not exist.
|
|
63
|
+
* `seeded` says whether creation consumed the rows, so the caller knows not
|
|
64
|
+
* to insert them a second time.
|
|
65
|
+
*/
|
|
66
|
+
async tableOrCreate(name, seed) {
|
|
67
|
+
const existing = await this.table(name);
|
|
68
|
+
if (existing)
|
|
69
|
+
return { table: existing, seeded: false };
|
|
70
|
+
const conn = await this.connection();
|
|
71
|
+
const created = await conn.createTable(name, seed);
|
|
72
|
+
this.open.set(name, created);
|
|
73
|
+
return { table: created, seeded: true };
|
|
74
|
+
}
|
|
75
|
+
async tableNames() {
|
|
76
|
+
return (await this.connection()).tableNames();
|
|
77
|
+
}
|
|
78
|
+
async dropTable(name) {
|
|
79
|
+
const conn = await this.connection();
|
|
80
|
+
const names = await conn.tableNames();
|
|
81
|
+
if (names.includes(name))
|
|
82
|
+
await conn.dropTable(name);
|
|
83
|
+
this.open.delete(name);
|
|
84
|
+
}
|
|
85
|
+
/** Forget cached handles so the next access re-opens and re-migrates. */
|
|
86
|
+
forget(name) {
|
|
87
|
+
if (name)
|
|
88
|
+
this.open.delete(name);
|
|
89
|
+
else
|
|
90
|
+
this.open.clear();
|
|
91
|
+
}
|
|
92
|
+
close() {
|
|
93
|
+
this.open.clear();
|
|
94
|
+
this.db = undefined;
|
|
95
|
+
}
|
|
96
|
+
/** `column IN ('a', 'b')`, with values single-quote escaped. */
|
|
97
|
+
static inFilter(column, values) {
|
|
98
|
+
const escaped = values.map((v) => `'${v.replace(/'/g, "''")}'`);
|
|
99
|
+
return `${column} IN (${escaped.join(", ")})`;
|
|
100
|
+
}
|
|
101
|
+
static quote(value) {
|
|
102
|
+
return value.replace(/'/g, "''");
|
|
103
|
+
}
|
|
104
|
+
/** Run `column IN (...)` deletes in batches small enough for one predicate. */
|
|
105
|
+
static async deleteIn(table, column, values) {
|
|
106
|
+
for (let i = 0; i < values.length; i += LanceTables.FILTER_BATCH_SIZE) {
|
|
107
|
+
const batch = values.slice(i, i + LanceTables.FILTER_BATCH_SIZE);
|
|
108
|
+
await table.delete(LanceTables.inFilter(column, batch));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/** Run a batched `column IN (...)` select, collecting one column's values. */
|
|
112
|
+
static async selectIn(table, column, values) {
|
|
113
|
+
const found = new Set();
|
|
114
|
+
for (let i = 0; i < values.length; i += LanceTables.FILTER_BATCH_SIZE) {
|
|
115
|
+
const batch = values.slice(i, i + LanceTables.FILTER_BATCH_SIZE);
|
|
116
|
+
const rows = await table
|
|
117
|
+
.query()
|
|
118
|
+
.where(LanceTables.inFilter(column, batch))
|
|
119
|
+
.select([column])
|
|
120
|
+
.toArray();
|
|
121
|
+
for (const r of rows)
|
|
122
|
+
found.add(r[column]);
|
|
123
|
+
}
|
|
124
|
+
return found;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Backfill columns that legacy databases predate. Both are additive and
|
|
128
|
+
* idempotent — a table that already has the column is left alone.
|
|
129
|
+
*/
|
|
130
|
+
async migrate(name, table) {
|
|
131
|
+
if (name === TableName.Files) {
|
|
132
|
+
// Pre branch-scoping `files` tables have no `branch` column. Fill it
|
|
133
|
+
// with the current branch so branch-filtered queries keep working.
|
|
134
|
+
const schema = await table.schema();
|
|
135
|
+
if (schema.fields.some((f) => f.name === "branch"))
|
|
136
|
+
return;
|
|
137
|
+
await table.addColumns([
|
|
138
|
+
{
|
|
139
|
+
name: "branch",
|
|
140
|
+
valueSql: `CAST('${LanceTables.quote(this.branch.toString())}' AS STRING)`,
|
|
141
|
+
},
|
|
142
|
+
]);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (name === TableName.Chunks) {
|
|
146
|
+
// Pre version-scoping `chunks` tables have no `fileHash`. Fill it
|
|
147
|
+
// with "" — treated as a wildcard at search time, so legacy chunks
|
|
148
|
+
// keep appearing until their file is re-indexed and gets a real
|
|
149
|
+
// version hash.
|
|
150
|
+
const schema = await table.schema();
|
|
151
|
+
if (schema.fields.some((f) => f.name === "fileHash"))
|
|
152
|
+
return;
|
|
153
|
+
await table.addColumns([
|
|
154
|
+
{ name: "fileHash", valueSql: `CAST('' AS STRING)` },
|
|
155
|
+
]);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=LanceTables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LanceTables.js","sourceRoot":"","sources":["../../../src/infrastructure/lancedb/LanceTables.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativeTuning.js","sourceRoot":"","sources":["../../../src/infrastructure/lancedb/NativeTuning.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,wEAAwE;AACxE,wDAAwD;AACxD,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,GAAG,CAAC;AACzC,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,GAAG,CAAC;AACvC,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,GAAG,CAAC;AACtC,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,GAAG,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Branch } from "../../domain/project/Branch.js";
|
|
2
|
+
import { type LanceTables } from "./LanceTables.js";
|
|
3
|
+
/** A manifest row as it travels between peers. */
|
|
4
|
+
export interface ManifestRow {
|
|
5
|
+
filePath: string;
|
|
6
|
+
fileHash: string;
|
|
7
|
+
branch: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Row-level access to the tables, for replication between databases.
|
|
11
|
+
*
|
|
12
|
+
* Peer sharing copies rows verbatim — embeddings included, since avoiding
|
|
13
|
+
* re-embedding is the entire point — so it works below the domain model rather
|
|
14
|
+
* than through it. Keeping that access behind this one class means the rest of
|
|
15
|
+
* the system never sees raw rows.
|
|
16
|
+
*/
|
|
17
|
+
export declare class RowReplication {
|
|
18
|
+
private readonly tables;
|
|
19
|
+
private readonly branch;
|
|
20
|
+
constructor(tables: LanceTables, branch: Branch);
|
|
21
|
+
chunkCount(): Promise<number>;
|
|
22
|
+
/** Stream chunk rows in pages, so a large index never loads at once. */
|
|
23
|
+
streamChunkRows(batchSize: number): AsyncGenerator<Record<string, unknown>[]>;
|
|
24
|
+
allManifestRows(): Promise<ManifestRow[]>;
|
|
25
|
+
addChunkRows(rows: Record<string, unknown>[]): Promise<void>;
|
|
26
|
+
addManifestRows(rows: ManifestRow[]): Promise<void>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { TableName } from "./LanceTables.js";
|
|
2
|
+
/**
|
|
3
|
+
* Row-level access to the tables, for replication between databases.
|
|
4
|
+
*
|
|
5
|
+
* Peer sharing copies rows verbatim — embeddings included, since avoiding
|
|
6
|
+
* re-embedding is the entire point — so it works below the domain model rather
|
|
7
|
+
* than through it. Keeping that access behind this one class means the rest of
|
|
8
|
+
* the system never sees raw rows.
|
|
9
|
+
*/
|
|
10
|
+
export class RowReplication {
|
|
11
|
+
tables;
|
|
12
|
+
branch;
|
|
13
|
+
constructor(tables, branch) {
|
|
14
|
+
this.tables = tables;
|
|
15
|
+
this.branch = branch;
|
|
16
|
+
}
|
|
17
|
+
async chunkCount() {
|
|
18
|
+
const table = await this.tables.table(TableName.Chunks);
|
|
19
|
+
return table ? table.countRows() : 0;
|
|
20
|
+
}
|
|
21
|
+
/** Stream chunk rows in pages, so a large index never loads at once. */
|
|
22
|
+
async *streamChunkRows(batchSize) {
|
|
23
|
+
const table = await this.tables.table(TableName.Chunks);
|
|
24
|
+
if (!table)
|
|
25
|
+
return;
|
|
26
|
+
const total = await table.countRows();
|
|
27
|
+
for (let offset = 0; offset < total; offset += batchSize) {
|
|
28
|
+
const rows = await table
|
|
29
|
+
.query()
|
|
30
|
+
.limit(batchSize)
|
|
31
|
+
.offset(offset)
|
|
32
|
+
.toArray();
|
|
33
|
+
if (rows.length === 0)
|
|
34
|
+
break;
|
|
35
|
+
yield rows.map((r) => ({
|
|
36
|
+
id: r.id,
|
|
37
|
+
filePath: r.filePath,
|
|
38
|
+
startLine: r.startLine,
|
|
39
|
+
endLine: r.endLine,
|
|
40
|
+
type: r.type,
|
|
41
|
+
name: r.name,
|
|
42
|
+
content: r.content,
|
|
43
|
+
context: r.context,
|
|
44
|
+
hash: r.hash,
|
|
45
|
+
fileHash: r.fileHash ?? "",
|
|
46
|
+
// Arrow typed arrays do not survive JSON; send plain numbers.
|
|
47
|
+
vector: Array.from(r.vector),
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async allManifestRows() {
|
|
52
|
+
const table = await this.tables.table(TableName.Files);
|
|
53
|
+
if (!table)
|
|
54
|
+
return [];
|
|
55
|
+
const rows = await table.query().toArray();
|
|
56
|
+
return rows.map((r) => ({
|
|
57
|
+
filePath: r.filePath,
|
|
58
|
+
fileHash: r.fileHash,
|
|
59
|
+
branch: r.branch ?? this.branch.toString(),
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
async addChunkRows(rows) {
|
|
63
|
+
if (rows.length === 0)
|
|
64
|
+
return;
|
|
65
|
+
const { table, seeded } = await this.tables.tableOrCreate(TableName.Chunks, rows);
|
|
66
|
+
if (!seeded)
|
|
67
|
+
await table.add(rows);
|
|
68
|
+
}
|
|
69
|
+
async addManifestRows(rows) {
|
|
70
|
+
if (rows.length === 0)
|
|
71
|
+
return;
|
|
72
|
+
const records = rows.map((r) => ({
|
|
73
|
+
filePath: r.filePath,
|
|
74
|
+
fileHash: r.fileHash,
|
|
75
|
+
branch: r.branch ?? this.branch.toString(),
|
|
76
|
+
}));
|
|
77
|
+
const { table, seeded } = await this.tables.tableOrCreate(TableName.Files, records);
|
|
78
|
+
if (!seeded)
|
|
79
|
+
await table.add(records);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=RowReplication.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RowReplication.js","sourceRoot":"","sources":["../../../src/infrastructure/lancedb/RowReplication.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tuning for the LanceDB vector index. The numbers here were measured on a
|
|
3
|
+
* 43k-chunk / 3584-dimension index; the comments record what they bought so a
|
|
4
|
+
* later change can tell a tuned value from an arbitrary one.
|
|
5
|
+
*/
|
|
6
|
+
export declare const VectorIndexPolicy: {
|
|
7
|
+
/**
|
|
8
|
+
* Below this row count a brute-force scan is cheap enough that training an
|
|
9
|
+
* index costs more than it saves, and IVF-PQ has too few vectors to cluster
|
|
10
|
+
* well.
|
|
11
|
+
*/
|
|
12
|
+
readonly MIN_ROWS_FOR_ANN: 5000;
|
|
13
|
+
/**
|
|
14
|
+
* Re-absorb new rows into the index once the unindexed tail passes this
|
|
15
|
+
* share of the indexed body. Rows outside the index are searched by flat
|
|
16
|
+
* scan, so the tail is exactly what needs bounding.
|
|
17
|
+
*/
|
|
18
|
+
readonly UNINDEXED_REINDEX_RATIO: 0.2;
|
|
19
|
+
/** ...but always tolerate a small tail, so a 3-chunk edit never retrains. */
|
|
20
|
+
readonly UNINDEXED_REINDEX_FLOOR: 2000;
|
|
21
|
+
/**
|
|
22
|
+
* Vector searches run without an explicit distance type, which LanceDB
|
|
23
|
+
* resolves to L2. The index has its own default, so it is pinned: an index
|
|
24
|
+
* built on a different metric would silently reorder every result.
|
|
25
|
+
*/
|
|
26
|
+
readonly DISTANCE_TYPE: "l2";
|
|
27
|
+
/**
|
|
28
|
+
* IVF-PQ stores compressed vectors, so its raw distances approximate the
|
|
29
|
+
* real ones. `refineFactor` makes LanceDB pull the uncompressed vectors for
|
|
30
|
+
* the top `limit * factor` candidates and re-score them exactly.
|
|
31
|
+
*
|
|
32
|
+
* It is not optional. Measured mean recall@20 against an exact scan:
|
|
33
|
+
*
|
|
34
|
+
* off -> 53% 1 -> 75% 3 -> 86% 10 -> 91% 20 -> 94% 50 -> 94%
|
|
35
|
+
*
|
|
36
|
+
* and without it `_distance` is wrong by ~0.07, which matters because score
|
|
37
|
+
* is derived from it and users filter on `--min-score`. With refinement the
|
|
38
|
+
* scores match an exact scan to the digit.
|
|
39
|
+
*
|
|
40
|
+
* 20 sits at the knee: ~94% recall at ~11ms/query versus ~115ms for an
|
|
41
|
+
* exact scan. Beyond it recall flattens (the probed partitions run out of
|
|
42
|
+
* candidates) while latency keeps climbing. The refined set is bounded by
|
|
43
|
+
* the query limit, not by table size, so this costs a fixed few MB.
|
|
44
|
+
*
|
|
45
|
+
* Harmless on tables with no index: a flat scan already computes exact
|
|
46
|
+
* distances and returns identical rows.
|
|
47
|
+
*/
|
|
48
|
+
readonly REFINE_FACTOR: 20;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Columns a search reads off a result row.
|
|
52
|
+
*
|
|
53
|
+
* Selecting explicitly keeps the embedding out of the result set — without it
|
|
54
|
+
* LanceDB ships every over-fetched row's full vector back into JS for nothing.
|
|
55
|
+
*
|
|
56
|
+
* `_distance` is listed on purpose: LanceDB currently auto-projects it into any
|
|
57
|
+
* scoring query but warns that it will stop, so naming it pins the behaviour
|
|
58
|
+
* rather than relying on a deprecated default.
|
|
59
|
+
*/
|
|
60
|
+
export declare const SEARCH_COLUMNS: readonly ["id", "filePath", "startLine", "endLine", "type", "name", "content", "context", "fileHash", "_distance"];
|