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.
Files changed (408) hide show
  1. package/README.md +226 -63
  2. package/completions/_lmgrep +49 -40
  3. package/dist/application/Lmgrep.d.ts +107 -0
  4. package/dist/application/Lmgrep.js +99 -0
  5. package/dist/application/Lmgrep.js.map +1 -0
  6. package/dist/application/LmgrepFactory.d.ts +40 -0
  7. package/dist/application/LmgrepFactory.js +155 -0
  8. package/dist/application/LmgrepFactory.js.map +1 -0
  9. package/dist/application/indexing/BranchBootstrapper.d.ts +21 -0
  10. package/dist/application/indexing/BranchBootstrapper.js +52 -0
  11. package/dist/application/indexing/BranchBootstrapper.js.map +1 -0
  12. package/dist/application/indexing/BranchManifestSweeper.d.ts +17 -0
  13. package/dist/application/indexing/BranchManifestSweeper.js +35 -0
  14. package/dist/application/indexing/BranchManifestSweeper.js.map +1 -0
  15. package/dist/application/indexing/Duration.d.ts +9 -0
  16. package/dist/application/indexing/Duration.js +25 -0
  17. package/dist/application/indexing/Duration.js.map +1 -0
  18. package/dist/application/indexing/EmbeddingAbortError.d.ts +11 -0
  19. package/dist/application/indexing/EmbeddingAbortError.js +20 -0
  20. package/dist/application/indexing/EmbeddingAbortError.js.map +1 -0
  21. package/dist/application/indexing/EmbeddingPipeline.d.ts +59 -0
  22. package/dist/application/indexing/EmbeddingPipeline.js +140 -0
  23. package/dist/application/indexing/EmbeddingPipeline.js.map +1 -0
  24. package/dist/application/indexing/IndexBuilder.d.ts +112 -0
  25. package/dist/application/indexing/IndexBuilder.js +370 -0
  26. package/dist/application/indexing/IndexBuilder.js.map +1 -0
  27. package/dist/application/indexing/IndexingProgress.d.ts +34 -0
  28. package/dist/application/indexing/IndexingProgress.js +2 -0
  29. package/dist/application/indexing/IndexingProgress.js.map +1 -0
  30. package/dist/application/operations/Deadline.d.ts +13 -0
  31. package/dist/application/operations/Deadline.js +29 -0
  32. package/dist/application/operations/Deadline.js.map +1 -0
  33. package/dist/application/operations/HealthMonitor.d.ts +58 -0
  34. package/dist/application/operations/HealthMonitor.js +128 -0
  35. package/dist/application/operations/HealthMonitor.js.map +1 -0
  36. package/dist/application/operations/IndexAlternatives.d.ts +35 -0
  37. package/dist/application/operations/IndexAlternatives.js +61 -0
  38. package/dist/application/operations/IndexAlternatives.js.map +1 -0
  39. package/dist/application/operations/IndexInventory.d.ts +69 -0
  40. package/dist/application/operations/IndexInventory.js +99 -0
  41. package/dist/application/operations/IndexInventory.js.map +1 -0
  42. package/dist/application/operations/StatusService.d.ts +90 -0
  43. package/dist/application/operations/StatusService.js +171 -0
  44. package/dist/application/operations/StatusService.js.map +1 -0
  45. package/dist/application/operations/WatchService.d.ts +67 -0
  46. package/dist/application/operations/WatchService.js +145 -0
  47. package/dist/application/operations/WatchService.js.map +1 -0
  48. package/dist/application/operations/WorkingTreeDiff.d.ts +19 -0
  49. package/dist/application/operations/WorkingTreeDiff.js +36 -0
  50. package/dist/application/operations/WorkingTreeDiff.js.map +1 -0
  51. package/dist/application/research/ResearchAgent.d.ts +68 -0
  52. package/dist/application/research/ResearchAgent.js +201 -0
  53. package/dist/application/research/ResearchAgent.js.map +1 -0
  54. package/dist/application/research/ResearchPrompts.d.ts +16 -0
  55. package/dist/application/research/ResearchPrompts.js +34 -0
  56. package/dist/application/research/ResearchPrompts.js.map +1 -0
  57. package/dist/application/search/SearchCriteria.d.ts +37 -0
  58. package/dist/application/search/SearchCriteria.js +48 -0
  59. package/dist/application/search/SearchCriteria.js.map +1 -0
  60. package/dist/application/search/SearchService.d.ts +36 -0
  61. package/dist/application/search/SearchService.js +108 -0
  62. package/dist/application/search/SearchService.js.map +1 -0
  63. package/dist/application/search/SearchTargetResolver.d.ts +56 -0
  64. package/dist/application/search/SearchTargetResolver.js +104 -0
  65. package/dist/application/search/SearchTargetResolver.js.map +1 -0
  66. package/dist/cli.d.ts +1 -1
  67. package/dist/cli.js +4 -953
  68. package/dist/cli.js.map +1 -1
  69. package/dist/domain/config/ConfigSource.d.ts +16 -0
  70. package/dist/domain/config/ConfigSource.js +2 -0
  71. package/dist/domain/config/ConfigSource.js.map +1 -0
  72. package/dist/domain/config/LmgrepConfig.d.ts +53 -0
  73. package/dist/domain/config/LmgrepConfig.js +2 -0
  74. package/dist/domain/config/LmgrepConfig.js.map +1 -0
  75. package/dist/domain/corpus/Chunk.d.ts +49 -0
  76. package/dist/domain/corpus/Chunk.js +60 -0
  77. package/dist/domain/corpus/Chunk.js.map +1 -0
  78. package/dist/domain/corpus/CodeLocation.d.ts +18 -0
  79. package/dist/domain/corpus/CodeLocation.js +34 -0
  80. package/dist/domain/corpus/CodeLocation.js.map +1 -0
  81. package/dist/domain/corpus/ContentHash.d.ts +15 -0
  82. package/dist/domain/corpus/ContentHash.js +30 -0
  83. package/dist/domain/corpus/ContentHash.js.map +1 -0
  84. package/dist/domain/corpus/FileVersion.d.ts +31 -0
  85. package/dist/domain/corpus/FileVersion.js +47 -0
  86. package/dist/domain/corpus/FileVersion.js.map +1 -0
  87. package/dist/domain/corpus/SourceFile.d.ts +26 -0
  88. package/dist/domain/corpus/SourceFile.js +47 -0
  89. package/dist/domain/corpus/SourceFile.js.map +1 -0
  90. package/dist/domain/corpus/Vector.d.ts +37 -0
  91. package/dist/domain/corpus/Vector.js +96 -0
  92. package/dist/domain/corpus/Vector.js.map +1 -0
  93. package/dist/domain/ports/ChatModelPort.d.ts +57 -0
  94. package/dist/domain/ports/ChatModelPort.js +2 -0
  95. package/dist/domain/ports/ChatModelPort.js.map +1 -0
  96. package/dist/domain/ports/ChunkRepositoryPort.d.ts +42 -0
  97. package/dist/domain/ports/ChunkRepositoryPort.js +2 -0
  98. package/dist/domain/ports/ChunkRepositoryPort.js.map +1 -0
  99. package/dist/domain/ports/ChunkerPort.d.ts +5 -0
  100. package/dist/domain/ports/ChunkerPort.js +2 -0
  101. package/dist/domain/ports/ChunkerPort.js.map +1 -0
  102. package/dist/domain/ports/DatabaseSessionPort.d.ts +10 -0
  103. package/dist/domain/ports/DatabaseSessionPort.js +2 -0
  104. package/dist/domain/ports/DatabaseSessionPort.js.map +1 -0
  105. package/dist/domain/ports/EmbedderPort.d.ts +14 -0
  106. package/dist/domain/ports/EmbedderPort.js +2 -0
  107. package/dist/domain/ports/EmbedderPort.js.map +1 -0
  108. package/dist/domain/ports/FileManifestRepositoryPort.d.ts +32 -0
  109. package/dist/domain/ports/FileManifestRepositoryPort.js +2 -0
  110. package/dist/domain/ports/FileManifestRepositoryPort.js.map +1 -0
  111. package/dist/domain/ports/GitPort.d.ts +24 -0
  112. package/dist/domain/ports/GitPort.js +2 -0
  113. package/dist/domain/ports/GitPort.js.map +1 -0
  114. package/dist/domain/ports/IndexMaintenancePort.d.ts +58 -0
  115. package/dist/domain/ports/IndexMaintenancePort.js +2 -0
  116. package/dist/domain/ports/IndexMaintenancePort.js.map +1 -0
  117. package/dist/domain/ports/IndexMetadataPort.d.ts +23 -0
  118. package/dist/domain/ports/IndexMetadataPort.js +2 -0
  119. package/dist/domain/ports/IndexMetadataPort.js.map +1 -0
  120. package/dist/domain/ports/LockPort.d.ts +17 -0
  121. package/dist/domain/ports/LockPort.js +2 -0
  122. package/dist/domain/ports/LockPort.js.map +1 -0
  123. package/dist/domain/ports/LoggerPort.d.ts +5 -0
  124. package/dist/domain/ports/LoggerPort.js +2 -0
  125. package/dist/domain/ports/LoggerPort.js.map +1 -0
  126. package/dist/domain/ports/ProjectIndexesPort.d.ts +20 -0
  127. package/dist/domain/ports/ProjectIndexesPort.js +2 -0
  128. package/dist/domain/ports/ProjectIndexesPort.js.map +1 -0
  129. package/dist/domain/ports/ProjectRegistryPort.d.ts +42 -0
  130. package/dist/domain/ports/ProjectRegistryPort.js +2 -0
  131. package/dist/domain/ports/ProjectRegistryPort.js.map +1 -0
  132. package/dist/domain/ports/StateDirectoryPort.d.ts +29 -0
  133. package/dist/domain/ports/StateDirectoryPort.js +2 -0
  134. package/dist/domain/ports/StateDirectoryPort.js.map +1 -0
  135. package/dist/domain/ports/WorkspacePort.d.ts +38 -0
  136. package/dist/domain/ports/WorkspacePort.js +2 -0
  137. package/dist/domain/ports/WorkspacePort.js.map +1 -0
  138. package/dist/domain/project/Branch.d.ts +20 -0
  139. package/dist/domain/project/Branch.js +33 -0
  140. package/dist/domain/project/Branch.js.map +1 -0
  141. package/dist/domain/project/DatabaseLocation.d.ts +32 -0
  142. package/dist/domain/project/DatabaseLocation.js +35 -0
  143. package/dist/domain/project/DatabaseLocation.js.map +1 -0
  144. package/dist/domain/project/IndexMetadata.d.ts +17 -0
  145. package/dist/domain/project/IndexMetadata.js +2 -0
  146. package/dist/domain/project/IndexMetadata.js.map +1 -0
  147. package/dist/domain/project/ModelIdentity.d.ts +58 -0
  148. package/dist/domain/project/ModelIdentity.js +97 -0
  149. package/dist/domain/project/ModelIdentity.js.map +1 -0
  150. package/dist/domain/project/Project.d.ts +17 -0
  151. package/dist/domain/project/Project.js +21 -0
  152. package/dist/domain/project/Project.js.map +1 -0
  153. package/dist/domain/project/ProjectId.d.ts +28 -0
  154. package/dist/domain/project/ProjectId.js +58 -0
  155. package/dist/domain/project/ProjectId.js.map +1 -0
  156. package/dist/domain/project/ProjectLocator.d.ts +112 -0
  157. package/dist/domain/project/ProjectLocator.js +178 -0
  158. package/dist/domain/project/ProjectLocator.js.map +1 -0
  159. package/dist/domain/research/Citation.d.ts +27 -0
  160. package/dist/domain/research/Citation.js +43 -0
  161. package/dist/domain/research/Citation.js.map +1 -0
  162. package/dist/domain/research/EvidenceLedger.d.ts +47 -0
  163. package/dist/domain/research/EvidenceLedger.js +111 -0
  164. package/dist/domain/research/EvidenceLedger.js.map +1 -0
  165. package/dist/domain/research/ResearchTrace.d.ts +19 -0
  166. package/dist/domain/research/ResearchTrace.js +22 -0
  167. package/dist/domain/research/ResearchTrace.js.map +1 -0
  168. package/dist/domain/retrieval/Hit.d.ts +19 -0
  169. package/dist/domain/retrieval/Hit.js +28 -0
  170. package/dist/domain/retrieval/Hit.js.map +1 -0
  171. package/dist/domain/retrieval/HitList.d.ts +35 -0
  172. package/dist/domain/retrieval/HitList.js +81 -0
  173. package/dist/domain/retrieval/HitList.js.map +1 -0
  174. package/dist/domain/retrieval/MissingIndexError.d.ts +11 -0
  175. package/dist/domain/retrieval/MissingIndexError.js +15 -0
  176. package/dist/domain/retrieval/MissingIndexError.js.map +1 -0
  177. package/dist/index.d.ts +43 -45
  178. package/dist/index.js +30 -567
  179. package/dist/index.js.map +1 -1
  180. package/dist/infrastructure/ai/AiSdkChatModel.d.ts +31 -0
  181. package/dist/infrastructure/ai/AiSdkChatModel.js +137 -0
  182. package/dist/infrastructure/ai/AiSdkChatModel.js.map +1 -0
  183. package/dist/infrastructure/ai/AiSdkEmbedder.d.ts +28 -0
  184. package/dist/infrastructure/ai/AiSdkEmbedder.js +79 -0
  185. package/dist/infrastructure/ai/AiSdkEmbedder.js.map +1 -0
  186. package/dist/infrastructure/ai/EmbeddingPrefixes.d.ts +21 -0
  187. package/dist/infrastructure/ai/EmbeddingPrefixes.js +40 -0
  188. package/dist/infrastructure/ai/EmbeddingPrefixes.js.map +1 -0
  189. package/dist/infrastructure/ai/LmStudioProbe.d.ts +18 -0
  190. package/dist/infrastructure/ai/LmStudioProbe.js +49 -0
  191. package/dist/infrastructure/ai/LmStudioProbe.js.map +1 -0
  192. package/dist/infrastructure/ai/LocalModelReloader.d.ts +21 -0
  193. package/dist/infrastructure/ai/LocalModelReloader.js +61 -0
  194. package/dist/infrastructure/ai/LocalModelReloader.js.map +1 -0
  195. package/dist/infrastructure/ai/LocalRuntimeDetector.d.ts +36 -0
  196. package/dist/infrastructure/ai/LocalRuntimeDetector.js +61 -0
  197. package/dist/infrastructure/ai/LocalRuntimeDetector.js.map +1 -0
  198. package/dist/infrastructure/ai/ModelRuntime.d.ts +32 -0
  199. package/dist/infrastructure/ai/ModelRuntime.js +2 -0
  200. package/dist/infrastructure/ai/ModelRuntime.js.map +1 -0
  201. package/dist/infrastructure/ai/OllamaProbe.d.ts +21 -0
  202. package/dist/infrastructure/ai/OllamaProbe.js +69 -0
  203. package/dist/infrastructure/ai/OllamaProbe.js.map +1 -0
  204. package/dist/infrastructure/ai/ProviderFailure.d.ts +16 -0
  205. package/dist/infrastructure/ai/ProviderFailure.js +35 -0
  206. package/dist/infrastructure/ai/ProviderFailure.js.map +1 -0
  207. package/dist/infrastructure/ai/ProviderModuleLoader.d.ts +13 -0
  208. package/dist/infrastructure/ai/ProviderModuleLoader.js +49 -0
  209. package/dist/infrastructure/ai/ProviderModuleLoader.js.map +1 -0
  210. package/dist/infrastructure/ai/ProviderRegistry.d.ts +37 -0
  211. package/dist/infrastructure/ai/ProviderRegistry.js +55 -0
  212. package/dist/infrastructure/ai/ProviderRegistry.js.map +1 -0
  213. package/dist/infrastructure/fs/ConfigLoader.d.ts +59 -0
  214. package/dist/infrastructure/fs/ConfigLoader.js +194 -0
  215. package/dist/infrastructure/fs/ConfigLoader.js.map +1 -0
  216. package/dist/infrastructure/fs/DatabaseLocks.d.ts +52 -0
  217. package/dist/infrastructure/fs/DatabaseLocks.js +92 -0
  218. package/dist/infrastructure/fs/DatabaseLocks.js.map +1 -0
  219. package/dist/infrastructure/fs/DiskUsage.d.ts +6 -0
  220. package/dist/infrastructure/fs/DiskUsage.js +41 -0
  221. package/dist/infrastructure/fs/DiskUsage.js.map +1 -0
  222. package/dist/infrastructure/fs/IndexableFileRules.d.ts +33 -0
  223. package/dist/infrastructure/fs/IndexableFileRules.js +177 -0
  224. package/dist/infrastructure/fs/IndexableFileRules.js.map +1 -0
  225. package/dist/infrastructure/fs/Loggers.d.ts +14 -0
  226. package/dist/infrastructure/fs/Loggers.js +18 -0
  227. package/dist/infrastructure/fs/Loggers.js.map +1 -0
  228. package/dist/infrastructure/fs/PidFileLock.d.ts +40 -0
  229. package/dist/infrastructure/fs/PidFileLock.js +97 -0
  230. package/dist/infrastructure/fs/PidFileLock.js.map +1 -0
  231. package/dist/infrastructure/fs/ProjectIndexes.d.ts +8 -0
  232. package/dist/infrastructure/fs/ProjectIndexes.js +35 -0
  233. package/dist/infrastructure/fs/ProjectIndexes.js.map +1 -0
  234. package/dist/infrastructure/fs/ProjectMetadataStore.d.ts +42 -0
  235. package/dist/infrastructure/fs/ProjectMetadataStore.js +86 -0
  236. package/dist/infrastructure/fs/ProjectMetadataStore.js.map +1 -0
  237. package/dist/infrastructure/fs/ProjectRegistry.d.ts +25 -0
  238. package/dist/infrastructure/fs/ProjectRegistry.js +83 -0
  239. package/dist/infrastructure/fs/ProjectRegistry.js.map +1 -0
  240. package/dist/infrastructure/fs/StateDirectory.d.ts +28 -0
  241. package/dist/infrastructure/fs/StateDirectory.js +71 -0
  242. package/dist/infrastructure/fs/StateDirectory.js.map +1 -0
  243. package/dist/infrastructure/fs/Workspace.d.ts +25 -0
  244. package/dist/infrastructure/fs/Workspace.js +90 -0
  245. package/dist/infrastructure/fs/Workspace.js.map +1 -0
  246. package/dist/infrastructure/git/GitClient.d.ts +34 -0
  247. package/dist/infrastructure/git/GitClient.js +74 -0
  248. package/dist/infrastructure/git/GitClient.js.map +1 -0
  249. package/dist/infrastructure/lancedb/ChunkRepository.d.ts +38 -0
  250. package/dist/infrastructure/lancedb/ChunkRepository.js +166 -0
  251. package/dist/infrastructure/lancedb/ChunkRepository.js.map +1 -0
  252. package/dist/infrastructure/lancedb/DatabaseImporter.d.ts +22 -0
  253. package/dist/infrastructure/lancedb/DatabaseImporter.js +74 -0
  254. package/dist/infrastructure/lancedb/DatabaseImporter.js.map +1 -0
  255. package/dist/infrastructure/lancedb/FileManifestRepository.d.ts +34 -0
  256. package/dist/infrastructure/lancedb/FileManifestRepository.js +137 -0
  257. package/dist/infrastructure/lancedb/FileManifestRepository.js.map +1 -0
  258. package/dist/infrastructure/lancedb/IndexMaintenance.d.ts +53 -0
  259. package/dist/infrastructure/lancedb/IndexMaintenance.js +227 -0
  260. package/dist/infrastructure/lancedb/IndexMaintenance.js.map +1 -0
  261. package/dist/infrastructure/lancedb/LanceTables.d.ts +67 -0
  262. package/dist/infrastructure/lancedb/LanceTables.js +159 -0
  263. package/dist/infrastructure/lancedb/LanceTables.js.map +1 -0
  264. package/dist/{lib/native-tuning.js → infrastructure/lancedb/NativeTuning.js} +1 -1
  265. package/dist/infrastructure/lancedb/NativeTuning.js.map +1 -0
  266. package/dist/infrastructure/lancedb/RowReplication.d.ts +27 -0
  267. package/dist/infrastructure/lancedb/RowReplication.js +82 -0
  268. package/dist/infrastructure/lancedb/RowReplication.js.map +1 -0
  269. package/dist/infrastructure/lancedb/VectorIndexPolicy.d.ts +60 -0
  270. package/dist/infrastructure/lancedb/VectorIndexPolicy.js +72 -0
  271. package/dist/infrastructure/lancedb/VectorIndexPolicy.js.map +1 -0
  272. package/dist/infrastructure/p2p/IndexShare.d.ts +45 -0
  273. package/dist/infrastructure/p2p/IndexShare.js +160 -0
  274. package/dist/infrastructure/p2p/IndexShare.js.map +1 -0
  275. package/dist/infrastructure/p2p/PeerSwarm.d.ts +16 -0
  276. package/dist/infrastructure/p2p/PeerSwarm.js +41 -0
  277. package/dist/infrastructure/p2p/PeerSwarm.js.map +1 -0
  278. package/dist/infrastructure/p2p/SecureChannel.d.ts +60 -0
  279. package/dist/infrastructure/p2p/SecureChannel.js +71 -0
  280. package/dist/infrastructure/p2p/SecureChannel.js.map +1 -0
  281. package/dist/infrastructure/p2p/ShareCode.d.ts +25 -0
  282. package/dist/infrastructure/p2p/ShareCode.js +304 -0
  283. package/dist/infrastructure/p2p/ShareCode.js.map +1 -0
  284. package/dist/infrastructure/process/ProcessRegistry.d.ts +50 -0
  285. package/dist/infrastructure/process/ProcessRegistry.js +109 -0
  286. package/dist/infrastructure/process/ProcessRegistry.js.map +1 -0
  287. package/dist/infrastructure/treesitter/ChunkContextBuilder.d.ts +45 -0
  288. package/dist/infrastructure/treesitter/ChunkContextBuilder.js +159 -0
  289. package/dist/infrastructure/treesitter/ChunkContextBuilder.js.map +1 -0
  290. package/dist/infrastructure/treesitter/LanguageCatalog.d.ts +30 -0
  291. package/dist/{lib/chunker/languages.js → infrastructure/treesitter/LanguageCatalog.js} +34 -29
  292. package/dist/infrastructure/treesitter/LanguageCatalog.js.map +1 -0
  293. package/dist/infrastructure/treesitter/SlidingWindowChunker.d.ts +15 -0
  294. package/dist/infrastructure/treesitter/SlidingWindowChunker.js +42 -0
  295. package/dist/infrastructure/treesitter/SlidingWindowChunker.js.map +1 -0
  296. package/dist/infrastructure/treesitter/TreeSitterChunker.d.ts +42 -0
  297. package/dist/infrastructure/treesitter/TreeSitterChunker.js +163 -0
  298. package/dist/infrastructure/treesitter/TreeSitterChunker.js.map +1 -0
  299. package/dist/mcp.d.ts +1 -1
  300. package/dist/mcp.js +14 -72
  301. package/dist/mcp.js.map +1 -1
  302. package/dist/presentation/cli/Cli.d.ts +31 -0
  303. package/dist/presentation/cli/Cli.js +120 -0
  304. package/dist/presentation/cli/Cli.js.map +1 -0
  305. package/dist/presentation/cli/CliOptions.d.ts +18 -0
  306. package/dist/presentation/cli/CliOptions.js +25 -0
  307. package/dist/presentation/cli/CliOptions.js.map +1 -0
  308. package/dist/presentation/cli/CommandContext.d.ts +50 -0
  309. package/dist/presentation/cli/CommandContext.js +88 -0
  310. package/dist/presentation/cli/CommandContext.js.map +1 -0
  311. package/dist/presentation/cli/ConfigTemplate.d.ts +31 -0
  312. package/dist/presentation/cli/ConfigTemplate.js +83 -0
  313. package/dist/presentation/cli/ConfigTemplate.js.map +1 -0
  314. package/dist/presentation/cli/Renderer.d.ts +90 -0
  315. package/dist/presentation/cli/Renderer.js +290 -0
  316. package/dist/presentation/cli/Renderer.js.map +1 -0
  317. package/dist/presentation/cli/commands/AskCommand.d.ts +14 -0
  318. package/dist/presentation/cli/commands/AskCommand.js +48 -0
  319. package/dist/presentation/cli/commands/AskCommand.js.map +1 -0
  320. package/dist/presentation/cli/commands/CompletionsCommand.d.ts +18 -0
  321. package/dist/presentation/cli/commands/CompletionsCommand.js +96 -0
  322. package/dist/presentation/cli/commands/CompletionsCommand.js.map +1 -0
  323. package/dist/presentation/cli/commands/ConfigCommands.d.ts +55 -0
  324. package/dist/presentation/cli/commands/ConfigCommands.js +204 -0
  325. package/dist/presentation/cli/commands/ConfigCommands.js.map +1 -0
  326. package/dist/presentation/cli/commands/IndexCommand.d.ts +18 -0
  327. package/dist/presentation/cli/commands/IndexCommand.js +54 -0
  328. package/dist/presentation/cli/commands/IndexCommand.js.map +1 -0
  329. package/dist/presentation/cli/commands/ProjectsCommand.d.ts +48 -0
  330. package/dist/presentation/cli/commands/ProjectsCommand.js +240 -0
  331. package/dist/presentation/cli/commands/ProjectsCommand.js.map +1 -0
  332. package/dist/presentation/cli/commands/SearchCommand.d.ts +19 -0
  333. package/dist/presentation/cli/commands/SearchCommand.js +55 -0
  334. package/dist/presentation/cli/commands/SearchCommand.js.map +1 -0
  335. package/dist/presentation/cli/commands/ServerCommands.d.ts +13 -0
  336. package/dist/presentation/cli/commands/ServerCommands.js +40 -0
  337. package/dist/presentation/cli/commands/ServerCommands.js.map +1 -0
  338. package/dist/presentation/cli/commands/ShareCommands.d.ts +22 -0
  339. package/dist/presentation/cli/commands/ShareCommands.js +134 -0
  340. package/dist/presentation/cli/commands/ShareCommands.js.map +1 -0
  341. package/dist/presentation/cli/commands/StatusCommand.d.ts +15 -0
  342. package/dist/presentation/cli/commands/StatusCommand.js +53 -0
  343. package/dist/presentation/cli/commands/StatusCommand.js.map +1 -0
  344. package/dist/presentation/mcp/HitFormatter.d.ts +17 -0
  345. package/dist/presentation/mcp/HitFormatter.js +42 -0
  346. package/dist/presentation/mcp/HitFormatter.js.map +1 -0
  347. package/dist/presentation/mcp/IndexWatchController.d.ts +17 -0
  348. package/dist/presentation/mcp/IndexWatchController.js +31 -0
  349. package/dist/presentation/mcp/IndexWatchController.js.map +1 -0
  350. package/dist/presentation/mcp/LmgrepCore.d.ts +66 -0
  351. package/dist/presentation/mcp/LmgrepCore.js +178 -0
  352. package/dist/presentation/mcp/LmgrepCore.js.map +1 -0
  353. package/dist/presentation/mcp/McpServer.d.ts +18 -0
  354. package/dist/presentation/mcp/McpServer.js +63 -0
  355. package/dist/presentation/mcp/McpServer.js.map +1 -0
  356. package/dist/presentation/mcp/ToolDescriptions.d.ts +40 -0
  357. package/dist/presentation/mcp/ToolDescriptions.js +85 -0
  358. package/dist/presentation/mcp/ToolDescriptions.js.map +1 -0
  359. package/package.json +84 -89
  360. package/dist/lib/build.d.ts +0 -21
  361. package/dist/lib/build.js +0 -374
  362. package/dist/lib/build.js.map +0 -1
  363. package/dist/lib/chunker/context.d.ts +0 -21
  364. package/dist/lib/chunker/context.js +0 -131
  365. package/dist/lib/chunker/context.js.map +0 -1
  366. package/dist/lib/chunker/index.d.ts +0 -7
  367. package/dist/lib/chunker/index.js +0 -209
  368. package/dist/lib/chunker/index.js.map +0 -1
  369. package/dist/lib/chunker/languages.d.ts +0 -15
  370. package/dist/lib/chunker/languages.js.map +0 -1
  371. package/dist/lib/config.d.ts +0 -12
  372. package/dist/lib/config.js +0 -83
  373. package/dist/lib/config.js.map +0 -1
  374. package/dist/lib/embedder.d.ts +0 -65
  375. package/dist/lib/embedder.js +0 -236
  376. package/dist/lib/embedder.js.map +0 -1
  377. package/dist/lib/facet-session.d.ts +0 -44
  378. package/dist/lib/facet-session.js +0 -125
  379. package/dist/lib/facet-session.js.map +0 -1
  380. package/dist/lib/native-tuning.js.map +0 -1
  381. package/dist/lib/p2p.d.ts +0 -32
  382. package/dist/lib/p2p.js +0 -281
  383. package/dist/lib/p2p.js.map +0 -1
  384. package/dist/lib/providers.d.ts +0 -1
  385. package/dist/lib/providers.js +0 -41
  386. package/dist/lib/providers.js.map +0 -1
  387. package/dist/lib/repair.d.ts +0 -10
  388. package/dist/lib/repair.js +0 -57
  389. package/dist/lib/repair.js.map +0 -1
  390. package/dist/lib/scanner.d.ts +0 -34
  391. package/dist/lib/scanner.js +0 -242
  392. package/dist/lib/scanner.js.map +0 -1
  393. package/dist/lib/search-tool.d.ts +0 -55
  394. package/dist/lib/search-tool.js +0 -319
  395. package/dist/lib/search-tool.js.map +0 -1
  396. package/dist/lib/serve.d.ts +0 -11
  397. package/dist/lib/serve.js +0 -144
  398. package/dist/lib/serve.js.map +0 -1
  399. package/dist/lib/store.d.ts +0 -252
  400. package/dist/lib/store.js +0 -1216
  401. package/dist/lib/store.js.map +0 -1
  402. package/dist/lib/types.d.ts +0 -194
  403. package/dist/lib/types.js +0 -13
  404. package/dist/lib/types.js.map +0 -1
  405. package/dist/lib/vocab.d.ts +0 -20
  406. package/dist/lib/vocab.js +0 -275
  407. package/dist/lib/vocab.js.map +0 -1
  408. /package/dist/{lib/native-tuning.d.ts → infrastructure/lancedb/NativeTuning.d.ts} +0 -0
@@ -0,0 +1,31 @@
1
+ import type { LmgrepConfig } from "../../domain/config/LmgrepConfig.js";
2
+ import type { ChatModelPort, ChatOutcome, CompletionRequest, ToolLoopRequest } from "../../domain/ports/ChatModelPort.js";
3
+ import { ProviderRegistry } from "./ProviderRegistry.js";
4
+ /**
5
+ * The generative model behind `lmgrep ask`.
6
+ *
7
+ * It defaults to the embedding provider's package and baseURL, so enabling
8
+ * `ask` on a local LM Studio or Ollama setup is a single config line rather
9
+ * than a second provider block.
10
+ */
11
+ export declare class AiSdkChatModel implements ChatModelPort {
12
+ private readonly config;
13
+ private readonly providers;
14
+ private model;
15
+ constructor(config: LmgrepConfig, providers?: ProviderRegistry);
16
+ /** Whether a chat model is configured at all — `ask` is hidden when not. */
17
+ get isConfigured(): boolean;
18
+ /**
19
+ * Run the agentic loop, translating provider failures into outcomes.
20
+ *
21
+ * A timeout or an overflowed context is reported as `interrupted` rather
22
+ * than thrown: the caller still holds usable evidence and can synthesize
23
+ * from it, which is the difference between a slow answer and no answer.
24
+ */
25
+ runToolLoop(request: ToolLoopRequest): Promise<ChatOutcome>;
26
+ complete(request: CompletionRequest): Promise<string | undefined>;
27
+ private resolve;
28
+ /** Env overrides exist so several models can be benchmarked without edits. */
29
+ private get modelString();
30
+ private get baseURL();
31
+ }
@@ -0,0 +1,137 @@
1
+ import { createProviderRegistry, generateText, stepCountIs, tool, } from "ai";
2
+ import { z } from "zod";
3
+ import { ProviderFailure } from "./ProviderFailure.js";
4
+ import { ModelReference, ProviderRegistry } from "./ProviderRegistry.js";
5
+ /**
6
+ * The generative model behind `lmgrep ask`.
7
+ *
8
+ * It defaults to the embedding provider's package and baseURL, so enabling
9
+ * `ask` on a local LM Studio or Ollama setup is a single config line rather
10
+ * than a second provider block.
11
+ */
12
+ export class AiSdkChatModel {
13
+ config;
14
+ providers;
15
+ model;
16
+ constructor(config, providers = new ProviderRegistry()) {
17
+ this.config = config;
18
+ this.providers = providers;
19
+ }
20
+ /** Whether a chat model is configured at all — `ask` is hidden when not. */
21
+ get isConfigured() {
22
+ return Boolean(this.modelString);
23
+ }
24
+ /**
25
+ * Run the agentic loop, translating provider failures into outcomes.
26
+ *
27
+ * A timeout or an overflowed context is reported as `interrupted` rather
28
+ * than thrown: the caller still holds usable evidence and can synthesize
29
+ * from it, which is the difference between a slow answer and no answer.
30
+ */
31
+ async runToolLoop(request) {
32
+ const model = await this.resolve();
33
+ let steps = 0;
34
+ const searchTool = tool({
35
+ description: request.toolDescription,
36
+ inputSchema: z.object({
37
+ query: z
38
+ .string()
39
+ .describe("Natural-language intent, phrased as a question."),
40
+ filePrefix: z
41
+ .string()
42
+ .optional()
43
+ .describe("Restrict to files under this path prefix."),
44
+ type: z
45
+ .array(z.string())
46
+ .optional()
47
+ .describe("Filter by AST node type (e.g. ['function_declaration'])."),
48
+ language: z
49
+ .array(z.string())
50
+ .optional()
51
+ .describe("Filter by file extension (e.g. ['.ts'])."),
52
+ limit: z.number().optional().describe("Max hits (default 5)."),
53
+ }),
54
+ execute: async (call) => request.onSearch(call),
55
+ });
56
+ try {
57
+ const result = await generateText({
58
+ model,
59
+ system: request.system,
60
+ prompt: request.prompt,
61
+ tools: { search: searchTool },
62
+ stopWhen: stepCountIs(request.maxSteps),
63
+ temperature: 0,
64
+ abortSignal: AbortSignal.timeout(request.timeoutMs),
65
+ onStepFinish: () => {
66
+ steps++;
67
+ },
68
+ });
69
+ return { status: "completed", text: result.text.trim(), steps };
70
+ }
71
+ catch (err) {
72
+ if (ProviderFailure.isAbort(err)) {
73
+ return { status: "interrupted", reason: "timeout", steps };
74
+ }
75
+ if (ProviderFailure.isContextOverflow(err)) {
76
+ return {
77
+ status: "interrupted",
78
+ reason: "context-overflow",
79
+ steps,
80
+ };
81
+ }
82
+ return { status: "failed", error: err, steps };
83
+ }
84
+ }
85
+ async complete(request) {
86
+ try {
87
+ const result = await generateText({
88
+ model: await this.resolve(),
89
+ system: request.system,
90
+ prompt: request.prompt,
91
+ temperature: 0,
92
+ abortSignal: AbortSignal.timeout(request.timeoutMs),
93
+ });
94
+ return result.text.trim() || undefined;
95
+ }
96
+ catch (err) {
97
+ ProviderFailure.debug("completion", err);
98
+ return undefined;
99
+ }
100
+ }
101
+ async resolve() {
102
+ if (this.model)
103
+ return this.model;
104
+ const modelString = this.modelString;
105
+ if (!modelString) {
106
+ throw new Error("No chat model configured. Set `chatModel` in your lmgrep config " +
107
+ "(e.g. `chatModel: lmstudio:qwen/qwen3.5-9b`) to use `lmgrep ask`.");
108
+ }
109
+ const reference = ModelReference.parse(modelString, "chatModel");
110
+ const instance = await this.providers.instantiate({
111
+ reference,
112
+ // Reuse the embedding provider package unless overridden — on a
113
+ // shared local endpoint chat and embeddings sit behind one
114
+ // OpenAI-compatible provider.
115
+ packageName: this.config.chatProvider ?? this.config.provider,
116
+ baseURL: this.baseURL,
117
+ // A bare default export ignores baseURL and would hit the cloud, so
118
+ // prefer the factory whenever one is configured.
119
+ preferFactoryWhenBaseUrlSet: true,
120
+ });
121
+ const registry = createProviderRegistry({
122
+ [reference.provider]: instance,
123
+ });
124
+ this.model = registry.languageModel(reference.full);
125
+ return this.model;
126
+ }
127
+ /** Env overrides exist so several models can be benchmarked without edits. */
128
+ get modelString() {
129
+ return process.env.LMGREP_CHAT_MODEL ?? this.config.chatModel;
130
+ }
131
+ get baseURL() {
132
+ return (process.env.LMGREP_CHAT_BASEURL ??
133
+ this.config.chatBaseURL ??
134
+ this.config.baseURL);
135
+ }
136
+ }
137
+ //# sourceMappingURL=AiSdkChatModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AiSdkChatModel.js","sourceRoot":"","sources":["../../../src/infrastructure/ai/AiSdkChatModel.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,sBAAsB,EACtB,YAAY,EAEZ,WAAW,EACX,IAAI,GACJ,MAAM,IAAI,CAAC;AACZ,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzE;;;;;;GAMG;AACH,MAAM,OAAO,cAAc;IAIR;IACA;IAJV,KAAK,CAA4B;IAEzC,YACkB,MAAoB,EACpB,YAA8B,IAAI,gBAAgB,EAAE;QADpD,WAAM,GAAN,MAAM,CAAc;QACpB,cAAS,GAAT,SAAS,CAA2C;IACnE,CAAC;IAEJ,4EAA4E;IAC5E,IAAI,YAAY;QACf,OAAO,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAClC,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,WAAW,CAAC,OAAwB;QACzC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACnC,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,MAAM,UAAU,GAAG,IAAI,CAAC;YACvB,WAAW,EAAE,OAAO,CAAC,eAAe;YACpC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;gBACrB,KAAK,EAAE,CAAC;qBACN,MAAM,EAAE;qBACR,QAAQ,CAAC,iDAAiD,CAAC;gBAC7D,UAAU,EAAE,CAAC;qBACX,MAAM,EAAE;qBACR,QAAQ,EAAE;qBACV,QAAQ,CAAC,2CAA2C,CAAC;gBACvD,IAAI,EAAE,CAAC;qBACL,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;qBACjB,QAAQ,EAAE;qBACV,QAAQ,CAAC,0DAA0D,CAAC;gBACtE,QAAQ,EAAE,CAAC;qBACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;qBACjB,QAAQ,EAAE;qBACV,QAAQ,CAAC,0CAA0C,CAAC;gBACtD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;aAC9D,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;SAC/C,CAAC,CAAC;QAEH,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;gBACjC,KAAK;gBACL,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;gBAC7B,QAAQ,EAAE,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACvC,WAAW,EAAE,CAAC;gBACd,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;gBACnD,YAAY,EAAE,GAAG,EAAE;oBAClB,KAAK,EAAE,CAAC;gBACT,CAAC;aACD,CAAC,CAAC;YACH,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC;QACjE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YAC5D,CAAC;YACD,IAAI,eAAe,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC5C,OAAO;oBACN,MAAM,EAAE,aAAa;oBACrB,MAAM,EAAE,kBAAkB;oBAC1B,KAAK;iBACL,CAAC;YACH,CAAC;YACD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QAChD,CAAC;IACF,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAA0B;QACxC,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;gBACjC,KAAK,EAAE,MAAM,IAAI,CAAC,OAAO,EAAE;gBAC3B,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,WAAW,EAAE,CAAC;gBACd,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;aACnD,CAAC,CAAC;YACH,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,eAAe,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;YACzC,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IAEO,KAAK,CAAC,OAAO;QACpB,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC;QAElC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACrC,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACd,kEAAkE;gBACjE,mEAAmE,CACpE,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;YACjD,SAAS;YACT,gEAAgE;YAChE,2DAA2D;YAC3D,8BAA8B;YAC9B,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC7D,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,oEAAoE;YACpE,iDAAiD;YACjD,2BAA2B,EAAE,IAAI;SACjC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,sBAAsB,CAAC;YACvC,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,QAAQ;SACL,CAAC,CAAC;QAE5B,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,aAAa,CAClC,SAAS,CAAC,IAA6B,CACtB,CAAC;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED,8EAA8E;IAC9E,IAAY,WAAW;QACtB,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;IAC/D,CAAC;IAED,IAAY,OAAO;QAClB,OAAO,CACN,OAAO,CAAC,GAAG,CAAC,mBAAmB;YAC/B,IAAI,CAAC,MAAM,CAAC,WAAW;YACvB,IAAI,CAAC,MAAM,CAAC,OAAO,CACnB,CAAC;IACH,CAAC;CACD"}
@@ -0,0 +1,28 @@
1
+ import type { LmgrepConfig } from "../../domain/config/LmgrepConfig.js";
2
+ import { Vector } from "../../domain/corpus/Vector.js";
3
+ import type { EmbedderPort } from "../../domain/ports/EmbedderPort.js";
4
+ import { ProviderRegistry } from "./ProviderRegistry.js";
5
+ /**
6
+ * Embeddings via the Vercel AI SDK.
7
+ *
8
+ * Documents and queries take different prefixes because asymmetric models
9
+ * (nomic, e5, bge) are trained to expect them; omitting them degrades recall
10
+ * without any visible error, so the distinction is enforced by having two
11
+ * methods rather than one with a flag.
12
+ */
13
+ export declare class AiSdkEmbedder implements EmbedderPort {
14
+ private readonly config;
15
+ private readonly providers;
16
+ private model;
17
+ private dimensionsChecked;
18
+ constructor(config: LmgrepConfig, providers?: ProviderRegistry);
19
+ embedDocuments(texts: string[]): Promise<Vector[]>;
20
+ embedQuery(query: string): Promise<Vector>;
21
+ /**
22
+ * Check the configured width once, on the first embedding seen. A mismatch
23
+ * means the model is not the one the config describes, and every vector
24
+ * after this would be silently unusable against the index.
25
+ */
26
+ private verifyDimensions;
27
+ private getModel;
28
+ }
@@ -0,0 +1,79 @@
1
+ import { createProviderRegistry, embed, embedMany, } from "ai";
2
+ import { Vector } from "../../domain/corpus/Vector.js";
3
+ import { ModelReference, ProviderRegistry } from "./ProviderRegistry.js";
4
+ /**
5
+ * Embeddings via the Vercel AI SDK.
6
+ *
7
+ * Documents and queries take different prefixes because asymmetric models
8
+ * (nomic, e5, bge) are trained to expect them; omitting them degrades recall
9
+ * without any visible error, so the distinction is enforced by having two
10
+ * methods rather than one with a flag.
11
+ */
12
+ export class AiSdkEmbedder {
13
+ config;
14
+ providers;
15
+ model;
16
+ dimensionsChecked = false;
17
+ constructor(config, providers = new ProviderRegistry()) {
18
+ this.config = config;
19
+ this.providers = providers;
20
+ }
21
+ async embedDocuments(texts) {
22
+ const model = await this.getModel();
23
+ const prefix = this.config.documentPrefix ?? "";
24
+ const out = [];
25
+ // Sub-batch to the configured size: providers reject oversized requests,
26
+ // and a local server will happily OOM on one.
27
+ for (let i = 0; i < texts.length; i += this.config.batchSize) {
28
+ const batch = texts.slice(i, i + this.config.batchSize);
29
+ const values = prefix ? batch.map((t) => prefix + t) : batch;
30
+ const { embeddings } = await embedMany({ model, values });
31
+ if (embeddings.length > 0)
32
+ this.verifyDimensions(embeddings[0]);
33
+ for (const e of embeddings)
34
+ out.push(Vector.from(e));
35
+ }
36
+ return out;
37
+ }
38
+ async embedQuery(query) {
39
+ const model = await this.getModel();
40
+ const prefix = this.config.queryPrefix ?? "";
41
+ const { embedding } = await embed({ model, value: prefix + query });
42
+ this.verifyDimensions(embedding);
43
+ return Vector.from(embedding);
44
+ }
45
+ /**
46
+ * Check the configured width once, on the first embedding seen. A mismatch
47
+ * means the model is not the one the config describes, and every vector
48
+ * after this would be silently unusable against the index.
49
+ */
50
+ verifyDimensions(vector) {
51
+ if (this.dimensionsChecked)
52
+ return;
53
+ this.dimensionsChecked = true;
54
+ if (this.config.dimensions != null &&
55
+ vector.length !== this.config.dimensions) {
56
+ throw new Error(`Embedding dimension mismatch: expected ${this.config.dimensions}, ` +
57
+ `got ${vector.length}. Check your model and config.dimensions.`);
58
+ }
59
+ }
60
+ async getModel() {
61
+ if (this.model)
62
+ return this.model;
63
+ const reference = ModelReference.parse(this.config.model, "Model");
64
+ const instance = await this.providers.instantiate({
65
+ reference,
66
+ packageName: this.config.provider,
67
+ baseURL: this.config.baseURL,
68
+ // Historically the embedding path only falls back to the factory
69
+ // when there is no default export; see ProviderRequest.
70
+ preferFactoryWhenBaseUrlSet: false,
71
+ });
72
+ const registry = createProviderRegistry({
73
+ [reference.provider]: instance,
74
+ });
75
+ this.model = registry.embeddingModel(reference.full);
76
+ return this.model;
77
+ }
78
+ }
79
+ //# sourceMappingURL=AiSdkEmbedder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AiSdkEmbedder.js","sourceRoot":"","sources":["../../../src/infrastructure/ai/AiSdkEmbedder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Query and document prefixes required by asymmetric embedding models.
3
+ *
4
+ * These models are trained with the prefixes present, and omitting them
5
+ * degrades retrieval without producing any error — the vectors are still
6
+ * valid, just worse. Nobody discovers that from the tool; they discover it
7
+ * from the model card, if at all. Setting them at `init` time is the only
8
+ * point where the model is actually known.
9
+ *
10
+ * Deliberately short: it covers only families whose prefixes are documented
11
+ * and unambiguous. An unrecognized model gets none, which is the safe default.
12
+ */
13
+ export declare class EmbeddingPrefixes {
14
+ private static readonly KNOWN;
15
+ /** Prefixes for a model id, or undefined when none are known to apply. */
16
+ static forModel(modelId: string): {
17
+ query: string;
18
+ document: string;
19
+ family: string;
20
+ } | undefined;
21
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Query and document prefixes required by asymmetric embedding models.
3
+ *
4
+ * These models are trained with the prefixes present, and omitting them
5
+ * degrades retrieval without producing any error — the vectors are still
6
+ * valid, just worse. Nobody discovers that from the tool; they discover it
7
+ * from the model card, if at all. Setting them at `init` time is the only
8
+ * point where the model is actually known.
9
+ *
10
+ * Deliberately short: it covers only families whose prefixes are documented
11
+ * and unambiguous. An unrecognized model gets none, which is the safe default.
12
+ */
13
+ export class EmbeddingPrefixes {
14
+ static KNOWN = [
15
+ {
16
+ match: /nomic-embed/i,
17
+ query: "search_query: ",
18
+ document: "search_document: ",
19
+ family: "nomic-embed",
20
+ },
21
+ {
22
+ match: /(^|[^a-z])e5[-_]|multilingual-e5/i,
23
+ query: "query: ",
24
+ document: "passage: ",
25
+ family: "e5",
26
+ },
27
+ ];
28
+ /** Prefixes for a model id, or undefined when none are known to apply. */
29
+ static forModel(modelId) {
30
+ const found = EmbeddingPrefixes.KNOWN.find((e) => e.match.test(modelId));
31
+ if (!found)
32
+ return undefined;
33
+ return {
34
+ query: found.query,
35
+ document: found.document,
36
+ family: found.family,
37
+ };
38
+ }
39
+ }
40
+ //# sourceMappingURL=EmbeddingPrefixes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmbeddingPrefixes.js","sourceRoot":"","sources":["../../../src/infrastructure/ai/EmbeddingPrefixes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,iBAAiB;IACrB,MAAM,CAAU,KAAK,GAKxB;QACJ;YACC,KAAK,EAAE,cAAc;YACrB,KAAK,EAAE,gBAAgB;YACvB,QAAQ,EAAE,mBAAmB;YAC7B,MAAM,EAAE,aAAa;SACrB;QACD;YACC,KAAK,EAAE,mCAAmC;YAC1C,KAAK,EAAE,SAAS;YAChB,QAAQ,EAAE,WAAW;YACrB,MAAM,EAAE,IAAI;SACZ;KACD,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,QAAQ,CACd,OAAe;QAEf,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACzE,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,OAAO;YACN,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,KAAK,CAAC,MAAM;SACpB,CAAC;IACH,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { DetectedRuntime, RuntimeProbe } from "./ModelRuntime.js";
2
+ /**
3
+ * Detects a local LM Studio server.
4
+ *
5
+ * LM Studio's native listing reports each model's type, so kinds come from the
6
+ * server rather than from guessing at names. Its OpenAI-compatible `/v1`
7
+ * surface is what the embedding calls actually use.
8
+ */
9
+ export declare class LmStudioProbe implements RuntimeProbe {
10
+ private static readonly CATALOG_URL;
11
+ static readonly BASE_URL = "http://localhost:1234/v1";
12
+ /** LM Studio speaks OpenAI's protocol, not one of its own. */
13
+ static readonly PROVIDER_PACKAGE = "@ai-sdk/openai-compatible";
14
+ private static readonly TIMEOUT_MS;
15
+ detect(): Promise<DetectedRuntime | undefined>;
16
+ /** `vlm` is a vision-capable chat model, and answers text prompts fine. */
17
+ private static kindOf;
18
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Detects a local LM Studio server.
3
+ *
4
+ * LM Studio's native listing reports each model's type, so kinds come from the
5
+ * server rather than from guessing at names. Its OpenAI-compatible `/v1`
6
+ * surface is what the embedding calls actually use.
7
+ */
8
+ export class LmStudioProbe {
9
+ static CATALOG_URL = "http://localhost:1234/api/v0/models";
10
+ static BASE_URL = "http://localhost:1234/v1";
11
+ /** LM Studio speaks OpenAI's protocol, not one of its own. */
12
+ static PROVIDER_PACKAGE = "@ai-sdk/openai-compatible";
13
+ static TIMEOUT_MS = 3000;
14
+ async detect() {
15
+ let payload;
16
+ try {
17
+ const res = await fetch(LmStudioProbe.CATALOG_URL, {
18
+ signal: AbortSignal.timeout(LmStudioProbe.TIMEOUT_MS),
19
+ });
20
+ if (!res.ok)
21
+ return undefined;
22
+ payload = (await res.json());
23
+ }
24
+ catch {
25
+ return undefined;
26
+ }
27
+ const models = (payload.data ?? []).map((m) => ({
28
+ id: m.id,
29
+ kind: LmStudioProbe.kindOf(m.type),
30
+ loaded: m.state === "loaded",
31
+ }));
32
+ return {
33
+ label: "LM Studio",
34
+ providerId: "lmstudio",
35
+ baseURL: LmStudioProbe.BASE_URL,
36
+ providerPackage: LmStudioProbe.PROVIDER_PACKAGE,
37
+ models,
38
+ };
39
+ }
40
+ /** `vlm` is a vision-capable chat model, and answers text prompts fine. */
41
+ static kindOf(type) {
42
+ if (type === "embeddings")
43
+ return "embedding";
44
+ if (type === "llm" || type === "vlm")
45
+ return "chat";
46
+ return "unknown";
47
+ }
48
+ }
49
+ //# sourceMappingURL=LmStudioProbe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LmStudioProbe.js","sourceRoot":"","sources":["../../../src/infrastructure/ai/LmStudioProbe.ts"],"names":[],"mappings":"AAOA;;;;;;GAMG;AACH,MAAM,OAAO,aAAa;IACjB,MAAM,CAAU,WAAW,GAAG,qCAAqC,CAAC;IAC5E,MAAM,CAAU,QAAQ,GAAG,0BAA0B,CAAC;IACtD,8DAA8D;IAC9D,MAAM,CAAU,gBAAgB,GAAG,2BAA2B,CAAC;IACvD,MAAM,CAAU,UAAU,GAAG,IAAI,CAAC;IAE1C,KAAK,CAAC,MAAM;QACX,IAAI,OAEH,CAAC;QACF,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,WAAW,EAAE;gBAClD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC;aACrD,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO,SAAS,CAAC;YAC9B,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAE1B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAqB,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjE,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;YAClC,MAAM,EAAE,CAAC,CAAC,KAAK,KAAK,QAAQ;SAC5B,CAAC,CAAC,CAAC;QAEJ,OAAO;YACN,KAAK,EAAE,WAAW;YAClB,UAAU,EAAE,UAAU;YACtB,OAAO,EAAE,aAAa,CAAC,QAAQ;YAC/B,eAAe,EAAE,aAAa,CAAC,gBAAgB;YAC/C,MAAM;SACN,CAAC;IACH,CAAC;IAED,2EAA2E;IACnE,MAAM,CAAC,MAAM,CAAC,IAAwB;QAC7C,IAAI,IAAI,KAAK,YAAY;YAAE,OAAO,WAAW,CAAC;QAC9C,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK;YAAE,OAAO,MAAM,CAAC;QACpD,OAAO,SAAS,CAAC;IAClB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { LmgrepConfig } from "../../domain/config/LmgrepConfig.js";
2
+ /**
3
+ * Unloads and reloads a model on a local inference server.
4
+ *
5
+ * A local server that has wedged or evicted the model is the common cause of a
6
+ * run of embedding failures, and it recovers on a reload — worth one automatic
7
+ * attempt before abandoning a long index run. Remote providers are never
8
+ * reloaded: the request would be meaningless and possibly billable.
9
+ */
10
+ export declare class LocalModelReloader {
11
+ private readonly config;
12
+ private static readonly LOOPBACK_HOSTS;
13
+ private static readonly UNLOAD_SETTLE_MS;
14
+ private static readonly DEFAULT_BASE_URL;
15
+ private static readonly DEFAULT_CONTEXT_LENGTH;
16
+ constructor(config: LmgrepConfig);
17
+ /** Whether the configured endpoint is a loopback address. */
18
+ get isLocal(): boolean;
19
+ /** Best-effort reload; false when the server does not cooperate. */
20
+ reload(): Promise<boolean>;
21
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Unloads and reloads a model on a local inference server.
3
+ *
4
+ * A local server that has wedged or evicted the model is the common cause of a
5
+ * run of embedding failures, and it recovers on a reload — worth one automatic
6
+ * attempt before abandoning a long index run. Remote providers are never
7
+ * reloaded: the request would be meaningless and possibly billable.
8
+ */
9
+ export class LocalModelReloader {
10
+ config;
11
+ static LOOPBACK_HOSTS = new Set([
12
+ "localhost",
13
+ "127.0.0.1",
14
+ "0.0.0.0",
15
+ ]);
16
+ static UNLOAD_SETTLE_MS = 2000;
17
+ static DEFAULT_BASE_URL = "http://localhost:1234";
18
+ static DEFAULT_CONTEXT_LENGTH = 8192;
19
+ constructor(config) {
20
+ this.config = config;
21
+ }
22
+ /** Whether the configured endpoint is a loopback address. */
23
+ get isLocal() {
24
+ if (!this.config.baseURL)
25
+ return false;
26
+ try {
27
+ return LocalModelReloader.LOOPBACK_HOSTS.has(new URL(this.config.baseURL).hostname);
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ }
33
+ /** Best-effort reload; false when the server does not cooperate. */
34
+ async reload() {
35
+ const modelId = this.config.model.split(":").slice(1).join(":");
36
+ const baseURL = this.config.baseURL ?? LocalModelReloader.DEFAULT_BASE_URL;
37
+ const apiBase = baseURL.replace(/\/v1\/?$/, "");
38
+ try {
39
+ await fetch(`${apiBase}/api/v1/models/unload`, {
40
+ method: "POST",
41
+ headers: { "Content-Type": "application/json" },
42
+ body: JSON.stringify({ instance_id: modelId }),
43
+ });
44
+ await new Promise((r) => setTimeout(r, LocalModelReloader.UNLOAD_SETTLE_MS));
45
+ const res = await fetch(`${apiBase}/api/v1/models/load`, {
46
+ method: "POST",
47
+ headers: { "Content-Type": "application/json" },
48
+ body: JSON.stringify({
49
+ model: modelId,
50
+ context_length: this.config.maxTokens ?? LocalModelReloader.DEFAULT_CONTEXT_LENGTH,
51
+ }),
52
+ });
53
+ await res.json();
54
+ return true;
55
+ }
56
+ catch {
57
+ return false;
58
+ }
59
+ }
60
+ }
61
+ //# sourceMappingURL=LocalModelReloader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalModelReloader.js","sourceRoot":"","sources":["../../../src/infrastructure/ai/LocalModelReloader.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,OAAO,kBAAkB;IAUD;IATrB,MAAM,CAAU,cAAc,GAAG,IAAI,GAAG,CAAC;QAChD,WAAW;QACX,WAAW;QACX,SAAS;KACT,CAAC,CAAC;IACK,MAAM,CAAU,gBAAgB,GAAG,IAAI,CAAC;IACxC,MAAM,CAAU,gBAAgB,GAAG,uBAAuB,CAAC;IAC3D,MAAM,CAAU,sBAAsB,GAAG,IAAI,CAAC;IAEtD,YAA6B,MAAoB;QAApB,WAAM,GAAN,MAAM,CAAc;IAAG,CAAC;IAErD,6DAA6D;IAC7D,IAAI,OAAO;QACV,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QACvC,IAAI,CAAC;YACJ,OAAO,kBAAkB,CAAC,cAAc,CAAC,GAAG,CAC3C,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CACrC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IAED,oEAAoE;IACpE,KAAK,CAAC,MAAM;QACX,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,kBAAkB,CAAC,gBAAgB,CAAC;QAC3E,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAEhD,IAAI,CAAC;YACJ,MAAM,KAAK,CAAC,GAAG,OAAO,uBAAuB,EAAE;gBAC9C,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;aAC9C,CAAC,CAAC;YACH,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CACvB,UAAU,CAAC,CAAC,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAClD,CAAC;YACF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,qBAAqB,EAAE;gBACxD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACpB,KAAK,EAAE,OAAO;oBACd,cAAc,EACb,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,kBAAkB,CAAC,sBAAsB;iBACnE,CAAC;aACF,CAAC,CAAC;YACH,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QACb,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { CatalogedModel, DetectedRuntime, RuntimeProbe } from "./ModelRuntime.js";
2
+ /**
3
+ * Finds whichever local inference server is running.
4
+ *
5
+ * Probes run concurrently and the first *useful* result wins — a server with
6
+ * models beats one that is merely listening, so a running-but-empty Ollama
7
+ * does not shadow a fully set up LM Studio.
8
+ */
9
+ export declare class LocalRuntimeDetector {
10
+ private readonly probes;
11
+ constructor(probes?: readonly RuntimeProbe[]);
12
+ detectAll(): Promise<DetectedRuntime[]>;
13
+ /** The best runtime to configure against, if any is usable. */
14
+ detectBest(): Promise<DetectedRuntime | undefined>;
15
+ /**
16
+ * Models the runtime says are embedders, best candidate first.
17
+ *
18
+ * A loaded model sorts ahead of the rest. Runtimes list models in an order
19
+ * of their own — LM Studio appears to use recency — and picking by position
20
+ * means the choice silently changes depending on what was used last.
21
+ * Load state is an explicit signal instead of an incidental one.
22
+ */
23
+ static embeddingModels(runtime: DetectedRuntime): CatalogedModel[];
24
+ /** Stable sort putting loaded models first, order otherwise preserved. */
25
+ private static loadedFirst;
26
+ /**
27
+ * Models usable for `ask`. Only taken when the runtime typed them: guessing
28
+ * an embedder is a chat model produces a confusing failure at answer time.
29
+ */
30
+ static chatModels(runtime: DetectedRuntime): CatalogedModel[];
31
+ /**
32
+ * Fallback for runtimes that do not type their models: anything not
33
+ * recognizable as an embedder.
34
+ */
35
+ static untypedModels(runtime: DetectedRuntime): CatalogedModel[];
36
+ }
@@ -0,0 +1,61 @@
1
+ import { LmStudioProbe } from "./LmStudioProbe.js";
2
+ import { OllamaProbe } from "./OllamaProbe.js";
3
+ /**
4
+ * Finds whichever local inference server is running.
5
+ *
6
+ * Probes run concurrently and the first *useful* result wins — a server with
7
+ * models beats one that is merely listening, so a running-but-empty Ollama
8
+ * does not shadow a fully set up LM Studio.
9
+ */
10
+ export class LocalRuntimeDetector {
11
+ probes;
12
+ constructor(probes = [
13
+ new LmStudioProbe(),
14
+ new OllamaProbe(),
15
+ ]) {
16
+ this.probes = probes;
17
+ }
18
+ async detectAll() {
19
+ const results = await Promise.all(this.probes.map((p) => p.detect().catch(() => undefined)));
20
+ return results.filter((r) => r !== undefined);
21
+ }
22
+ /** The best runtime to configure against, if any is usable. */
23
+ async detectBest() {
24
+ const found = await this.detectAll();
25
+ return (found.find((r) => LocalRuntimeDetector.embeddingModels(r).length > 0) ??
26
+ found[0]);
27
+ }
28
+ /**
29
+ * Models the runtime says are embedders, best candidate first.
30
+ *
31
+ * A loaded model sorts ahead of the rest. Runtimes list models in an order
32
+ * of their own — LM Studio appears to use recency — and picking by position
33
+ * means the choice silently changes depending on what was used last.
34
+ * Load state is an explicit signal instead of an incidental one.
35
+ */
36
+ static embeddingModels(runtime) {
37
+ return LocalRuntimeDetector.loadedFirst(runtime.models.filter((m) => m.kind === "embedding"));
38
+ }
39
+ /** Stable sort putting loaded models first, order otherwise preserved. */
40
+ static loadedFirst(models) {
41
+ return [
42
+ ...models.filter((m) => m.loaded),
43
+ ...models.filter((m) => !m.loaded),
44
+ ];
45
+ }
46
+ /**
47
+ * Models usable for `ask`. Only taken when the runtime typed them: guessing
48
+ * an embedder is a chat model produces a confusing failure at answer time.
49
+ */
50
+ static chatModels(runtime) {
51
+ return LocalRuntimeDetector.loadedFirst(runtime.models.filter((m) => m.kind === "chat"));
52
+ }
53
+ /**
54
+ * Fallback for runtimes that do not type their models: anything not
55
+ * recognizable as an embedder.
56
+ */
57
+ static untypedModels(runtime) {
58
+ return LocalRuntimeDetector.loadedFirst(runtime.models.filter((m) => m.kind === "unknown"));
59
+ }
60
+ }
61
+ //# sourceMappingURL=LocalRuntimeDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalRuntimeDetector.js","sourceRoot":"","sources":["../../../src/infrastructure/ai/LocalRuntimeDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMnD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C;;;;;;GAMG;AACH,MAAM,OAAO,oBAAoB;IAEd;IADlB,YACkB,SAAkC;QAClD,IAAI,aAAa,EAAE;QACnB,IAAI,WAAW,EAAE;KACjB;QAHgB,WAAM,GAAN,MAAM,CAGtB;IACC,CAAC;IAEJ,KAAK,CAAC,SAAS;QACd,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CACzD,CAAC;QACF,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAwB,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;IACrE,CAAC;IAED,+DAA+D;IAC/D,KAAK,CAAC,UAAU;QACf,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACrC,OAAO,CACN,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YACrE,KAAK,CAAC,CAAC,CAAC,CACR,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,eAAe,CAAC,OAAwB;QAC9C,OAAO,oBAAoB,CAAC,WAAW,CACtC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CACpD,CAAC;IACH,CAAC;IAED,0EAA0E;IAClE,MAAM,CAAC,WAAW,CAAC,MAAwB;QAClD,OAAO;YACN,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YACjC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;SAClC,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,UAAU,CAAC,OAAwB;QACzC,OAAO,oBAAoB,CAAC,WAAW,CACtC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAC/C,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,aAAa,CAAC,OAAwB;QAC5C,OAAO,oBAAoB,CAAC,WAAW,CACtC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAClD,CAAC;IACH,CAAC;CACD"}