causantic 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/LICENSE +19 -0
- package/README.md +332 -0
- package/config.schema.json +254 -0
- package/dist/cli/commands/archive.d.ts +4 -0
- package/dist/cli/commands/archive.d.ts.map +1 -0
- package/dist/cli/commands/archive.js +76 -0
- package/dist/cli/commands/archive.js.map +1 -0
- package/dist/cli/commands/benchmark-collection.d.ts +8 -0
- package/dist/cli/commands/benchmark-collection.d.ts.map +1 -0
- package/dist/cli/commands/benchmark-collection.js +146 -0
- package/dist/cli/commands/benchmark-collection.js.map +1 -0
- package/dist/cli/commands/config.d.ts +3 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +69 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/dashboard.d.ts +3 -0
- package/dist/cli/commands/dashboard.d.ts.map +1 -0
- package/dist/cli/commands/dashboard.js +12 -0
- package/dist/cli/commands/dashboard.js.map +1 -0
- package/dist/cli/commands/encryption.d.ts +3 -0
- package/dist/cli/commands/encryption.d.ts.map +1 -0
- package/dist/cli/commands/encryption.js +207 -0
- package/dist/cli/commands/encryption.js.map +1 -0
- package/dist/cli/commands/hook.d.ts +3 -0
- package/dist/cli/commands/hook.d.ts.map +1 -0
- package/dist/cli/commands/hook.js +35 -0
- package/dist/cli/commands/hook.js.map +1 -0
- package/dist/cli/commands/ingest.d.ts +4 -0
- package/dist/cli/commands/ingest.d.ts.map +1 -0
- package/dist/cli/commands/ingest.js +31 -0
- package/dist/cli/commands/ingest.js.map +1 -0
- package/dist/cli/commands/init.d.ts +3 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +680 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/maintenance.d.ts +3 -0
- package/dist/cli/commands/maintenance.d.ts.map +1 -0
- package/dist/cli/commands/maintenance.js +67 -0
- package/dist/cli/commands/maintenance.js.map +1 -0
- package/dist/cli/commands/search.d.ts +3 -0
- package/dist/cli/commands/search.d.ts.map +1 -0
- package/dist/cli/commands/search.js +16 -0
- package/dist/cli/commands/search.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +3 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +19 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +4 -0
- package/dist/cli/commands/stats.d.ts.map +1 -0
- package/dist/cli/commands/stats.js +49 -0
- package/dist/cli/commands/stats.js.map +1 -0
- package/dist/cli/commands/uninstall.d.ts +3 -0
- package/dist/cli/commands/uninstall.d.ts.map +1 -0
- package/dist/cli/commands/uninstall.js +10 -0
- package/dist/cli/commands/uninstall.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +86 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/skill-templates.d.ts +19 -0
- package/dist/cli/skill-templates.d.ts.map +1 -0
- package/dist/cli/skill-templates.js +1128 -0
- package/dist/cli/skill-templates.js.map +1 -0
- package/dist/cli/types.d.ts +10 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +5 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli/uninstall.d.ts +66 -0
- package/dist/cli/uninstall.d.ts.map +1 -0
- package/dist/cli/uninstall.js +490 -0
- package/dist/cli/uninstall.js.map +1 -0
- package/dist/cli/utils.d.ts +26 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/utils.js +105 -0
- package/dist/cli/utils.js.map +1 -0
- package/dist/clusters/cluster-manager.d.ts +96 -0
- package/dist/clusters/cluster-manager.d.ts.map +1 -0
- package/dist/clusters/cluster-manager.js +321 -0
- package/dist/clusters/cluster-manager.js.map +1 -0
- package/dist/clusters/cluster-refresh.d.ts +56 -0
- package/dist/clusters/cluster-refresh.d.ts.map +1 -0
- package/dist/clusters/cluster-refresh.js +187 -0
- package/dist/clusters/cluster-refresh.js.map +1 -0
- package/dist/clusters/hdbscan/cluster-extraction.d.ts +26 -0
- package/dist/clusters/hdbscan/cluster-extraction.d.ts.map +1 -0
- package/dist/clusters/hdbscan/cluster-extraction.js +232 -0
- package/dist/clusters/hdbscan/cluster-extraction.js.map +1 -0
- package/dist/clusters/hdbscan/core-distance-worker.d.ts +6 -0
- package/dist/clusters/hdbscan/core-distance-worker.d.ts.map +1 -0
- package/dist/clusters/hdbscan/core-distance-worker.js +54 -0
- package/dist/clusters/hdbscan/core-distance-worker.js.map +1 -0
- package/dist/clusters/hdbscan/core-distance.d.ts +26 -0
- package/dist/clusters/hdbscan/core-distance.d.ts.map +1 -0
- package/dist/clusters/hdbscan/core-distance.js +94 -0
- package/dist/clusters/hdbscan/core-distance.js.map +1 -0
- package/dist/clusters/hdbscan/distance-cache.d.ts +46 -0
- package/dist/clusters/hdbscan/distance-cache.d.ts.map +1 -0
- package/dist/clusters/hdbscan/distance-cache.js +84 -0
- package/dist/clusters/hdbscan/distance-cache.js.map +1 -0
- package/dist/clusters/hdbscan/hierarchy.d.ts +34 -0
- package/dist/clusters/hdbscan/hierarchy.d.ts.map +1 -0
- package/dist/clusters/hdbscan/hierarchy.js +442 -0
- package/dist/clusters/hdbscan/hierarchy.js.map +1 -0
- package/dist/clusters/hdbscan/incremental.d.ts +30 -0
- package/dist/clusters/hdbscan/incremental.d.ts.map +1 -0
- package/dist/clusters/hdbscan/incremental.js +130 -0
- package/dist/clusters/hdbscan/incremental.js.map +1 -0
- package/dist/clusters/hdbscan/kd-tree.d.ts +51 -0
- package/dist/clusters/hdbscan/kd-tree.d.ts.map +1 -0
- package/dist/clusters/hdbscan/kd-tree.js +130 -0
- package/dist/clusters/hdbscan/kd-tree.js.map +1 -0
- package/dist/clusters/hdbscan/min-heap.d.ts +62 -0
- package/dist/clusters/hdbscan/min-heap.d.ts.map +1 -0
- package/dist/clusters/hdbscan/min-heap.js +139 -0
- package/dist/clusters/hdbscan/min-heap.js.map +1 -0
- package/dist/clusters/hdbscan/mst.d.ts +20 -0
- package/dist/clusters/hdbscan/mst.d.ts.map +1 -0
- package/dist/clusters/hdbscan/mst.js +77 -0
- package/dist/clusters/hdbscan/mst.js.map +1 -0
- package/dist/clusters/hdbscan/probabilities.d.ts +37 -0
- package/dist/clusters/hdbscan/probabilities.d.ts.map +1 -0
- package/dist/clusters/hdbscan/probabilities.js +149 -0
- package/dist/clusters/hdbscan/probabilities.js.map +1 -0
- package/dist/clusters/hdbscan/types.d.ts +123 -0
- package/dist/clusters/hdbscan/types.d.ts.map +1 -0
- package/dist/clusters/hdbscan/types.js +5 -0
- package/dist/clusters/hdbscan/types.js.map +1 -0
- package/dist/clusters/hdbscan/union-find.d.ts +51 -0
- package/dist/clusters/hdbscan/union-find.d.ts.map +1 -0
- package/dist/clusters/hdbscan/union-find.js +115 -0
- package/dist/clusters/hdbscan/union-find.js.map +1 -0
- package/dist/clusters/hdbscan.d.ts +71 -0
- package/dist/clusters/hdbscan.d.ts.map +1 -0
- package/dist/clusters/hdbscan.js +283 -0
- package/dist/clusters/hdbscan.js.map +1 -0
- package/dist/clusters/index.d.ts +8 -0
- package/dist/clusters/index.d.ts.map +1 -0
- package/dist/clusters/index.js +8 -0
- package/dist/clusters/index.js.map +1 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +6 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +105 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +339 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/memory-config.d.ts +109 -0
- package/dist/config/memory-config.d.ts.map +1 -0
- package/dist/config/memory-config.js +182 -0
- package/dist/config/memory-config.js.map +1 -0
- package/dist/core/benchmark-types.d.ts +62 -0
- package/dist/core/benchmark-types.d.ts.map +1 -0
- package/dist/core/benchmark-types.js +11 -0
- package/dist/core/benchmark-types.js.map +1 -0
- package/dist/core/decay-types.d.ts +111 -0
- package/dist/core/decay-types.d.ts.map +1 -0
- package/dist/core/decay-types.js +30 -0
- package/dist/core/decay-types.js.map +1 -0
- package/dist/core/index.d.ts +11 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/lexical-features.d.ts +34 -0
- package/dist/core/lexical-features.d.ts.map +1 -0
- package/dist/core/lexical-features.js +155 -0
- package/dist/core/lexical-features.js.map +1 -0
- package/dist/dashboard/client/assets/index-CMUKy4f9.css +1 -0
- package/dist/dashboard/client/assets/index-esv8TpCN.js +168 -0
- package/dist/dashboard/client/index.html +14 -0
- package/dist/dashboard/middleware/async-handler.d.ts +11 -0
- package/dist/dashboard/middleware/async-handler.d.ts.map +1 -0
- package/dist/dashboard/middleware/async-handler.js +12 -0
- package/dist/dashboard/middleware/async-handler.js.map +1 -0
- package/dist/dashboard/middleware/error-handler.d.ts +9 -0
- package/dist/dashboard/middleware/error-handler.d.ts.map +1 -0
- package/dist/dashboard/middleware/error-handler.js +14 -0
- package/dist/dashboard/middleware/error-handler.js.map +1 -0
- package/dist/dashboard/routes/benchmark-collection.d.ts +11 -0
- package/dist/dashboard/routes/benchmark-collection.d.ts.map +1 -0
- package/dist/dashboard/routes/benchmark-collection.js +49 -0
- package/dist/dashboard/routes/benchmark-collection.js.map +1 -0
- package/dist/dashboard/routes/chunks.d.ts +3 -0
- package/dist/dashboard/routes/chunks.d.ts.map +1 -0
- package/dist/dashboard/routes/chunks.js +25 -0
- package/dist/dashboard/routes/chunks.js.map +1 -0
- package/dist/dashboard/routes/clusters.d.ts +3 -0
- package/dist/dashboard/routes/clusters.d.ts.map +1 -0
- package/dist/dashboard/routes/clusters.js +28 -0
- package/dist/dashboard/routes/clusters.js.map +1 -0
- package/dist/dashboard/routes/edges.d.ts +3 -0
- package/dist/dashboard/routes/edges.d.ts.map +1 -0
- package/dist/dashboard/routes/edges.js +32 -0
- package/dist/dashboard/routes/edges.js.map +1 -0
- package/dist/dashboard/routes/graph.d.ts +3 -0
- package/dist/dashboard/routes/graph.d.ts.map +1 -0
- package/dist/dashboard/routes/graph.js +158 -0
- package/dist/dashboard/routes/graph.js.map +1 -0
- package/dist/dashboard/routes/projects.d.ts +3 -0
- package/dist/dashboard/routes/projects.d.ts.map +1 -0
- package/dist/dashboard/routes/projects.js +9 -0
- package/dist/dashboard/routes/projects.js.map +1 -0
- package/dist/dashboard/routes/search.d.ts +3 -0
- package/dist/dashboard/routes/search.d.ts.map +1 -0
- package/dist/dashboard/routes/search.js +105 -0
- package/dist/dashboard/routes/search.js.map +1 -0
- package/dist/dashboard/routes/sessions.d.ts +3 -0
- package/dist/dashboard/routes/sessions.d.ts.map +1 -0
- package/dist/dashboard/routes/sessions.js +16 -0
- package/dist/dashboard/routes/sessions.js.map +1 -0
- package/dist/dashboard/routes/stats.d.ts +3 -0
- package/dist/dashboard/routes/stats.d.ts.map +1 -0
- package/dist/dashboard/routes/stats.js +38 -0
- package/dist/dashboard/routes/stats.js.map +1 -0
- package/dist/dashboard/server.d.ts +3 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +85 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/eval/annotation-schema.d.ts +41 -0
- package/dist/eval/annotation-schema.d.ts.map +1 -0
- package/dist/eval/annotation-schema.js +171 -0
- package/dist/eval/annotation-schema.js.map +1 -0
- package/dist/eval/benchmark-runner.d.ts +15 -0
- package/dist/eval/benchmark-runner.d.ts.map +1 -0
- package/dist/eval/benchmark-runner.js +93 -0
- package/dist/eval/benchmark-runner.js.map +1 -0
- package/dist/eval/cluster-evaluator.d.ts +39 -0
- package/dist/eval/cluster-evaluator.d.ts.map +1 -0
- package/dist/eval/cluster-evaluator.js +51 -0
- package/dist/eval/cluster-evaluator.js.map +1 -0
- package/dist/eval/code-nl-alignment.d.ts +25 -0
- package/dist/eval/code-nl-alignment.d.ts.map +1 -0
- package/dist/eval/code-nl-alignment.js +49 -0
- package/dist/eval/code-nl-alignment.js.map +1 -0
- package/dist/eval/collection-benchmark/graph-value.d.ts +16 -0
- package/dist/eval/collection-benchmark/graph-value.d.ts.map +1 -0
- package/dist/eval/collection-benchmark/graph-value.js +162 -0
- package/dist/eval/collection-benchmark/graph-value.js.map +1 -0
- package/dist/eval/collection-benchmark/health.d.ts +12 -0
- package/dist/eval/collection-benchmark/health.d.ts.map +1 -0
- package/dist/eval/collection-benchmark/health.js +246 -0
- package/dist/eval/collection-benchmark/health.js.map +1 -0
- package/dist/eval/collection-benchmark/history.d.ts +27 -0
- package/dist/eval/collection-benchmark/history.d.ts.map +1 -0
- package/dist/eval/collection-benchmark/history.js +134 -0
- package/dist/eval/collection-benchmark/history.js.map +1 -0
- package/dist/eval/collection-benchmark/latency.d.ts +16 -0
- package/dist/eval/collection-benchmark/latency.d.ts.map +1 -0
- package/dist/eval/collection-benchmark/latency.js +115 -0
- package/dist/eval/collection-benchmark/latency.js.map +1 -0
- package/dist/eval/collection-benchmark/reporter.d.ts +18 -0
- package/dist/eval/collection-benchmark/reporter.d.ts.map +1 -0
- package/dist/eval/collection-benchmark/reporter.js +244 -0
- package/dist/eval/collection-benchmark/reporter.js.map +1 -0
- package/dist/eval/collection-benchmark/retrieval.d.ts +15 -0
- package/dist/eval/collection-benchmark/retrieval.d.ts.map +1 -0
- package/dist/eval/collection-benchmark/retrieval.js +203 -0
- package/dist/eval/collection-benchmark/retrieval.js.map +1 -0
- package/dist/eval/collection-benchmark/runner.d.ts +20 -0
- package/dist/eval/collection-benchmark/runner.d.ts.map +1 -0
- package/dist/eval/collection-benchmark/runner.js +189 -0
- package/dist/eval/collection-benchmark/runner.js.map +1 -0
- package/dist/eval/collection-benchmark/sampler.d.ts +18 -0
- package/dist/eval/collection-benchmark/sampler.d.ts.map +1 -0
- package/dist/eval/collection-benchmark/sampler.js +186 -0
- package/dist/eval/collection-benchmark/sampler.js.map +1 -0
- package/dist/eval/collection-benchmark/tuning.d.ts +12 -0
- package/dist/eval/collection-benchmark/tuning.d.ts.map +1 -0
- package/dist/eval/collection-benchmark/tuning.js +222 -0
- package/dist/eval/collection-benchmark/tuning.js.map +1 -0
- package/dist/eval/collection-benchmark/types.d.ts +183 -0
- package/dist/eval/collection-benchmark/types.d.ts.map +1 -0
- package/dist/eval/collection-benchmark/types.js +7 -0
- package/dist/eval/collection-benchmark/types.js.map +1 -0
- package/dist/eval/context-window-test.d.ts +34 -0
- package/dist/eval/context-window-test.d.ts.map +1 -0
- package/dist/eval/context-window-test.js +59 -0
- package/dist/eval/context-window-test.js.map +1 -0
- package/dist/eval/corpus-builder.d.ts +33 -0
- package/dist/eval/corpus-builder.d.ts.map +1 -0
- package/dist/eval/corpus-builder.js +88 -0
- package/dist/eval/corpus-builder.js.map +1 -0
- package/dist/eval/experiments/boilerplate-filter.d.ts +26 -0
- package/dist/eval/experiments/boilerplate-filter.d.ts.map +1 -0
- package/dist/eval/experiments/boilerplate-filter.js +95 -0
- package/dist/eval/experiments/boilerplate-filter.js.map +1 -0
- package/dist/eval/experiments/cluster-threshold/index.d.ts +6 -0
- package/dist/eval/experiments/cluster-threshold/index.d.ts.map +1 -0
- package/dist/eval/experiments/cluster-threshold/index.js +5 -0
- package/dist/eval/experiments/cluster-threshold/index.js.map +1 -0
- package/dist/eval/experiments/cluster-threshold/run-threshold-sweep.d.ts +58 -0
- package/dist/eval/experiments/cluster-threshold/run-threshold-sweep.d.ts.map +1 -0
- package/dist/eval/experiments/cluster-threshold/run-threshold-sweep.js +246 -0
- package/dist/eval/experiments/cluster-threshold/run-threshold-sweep.js.map +1 -0
- package/dist/eval/experiments/code-focused-mode.d.ts +20 -0
- package/dist/eval/experiments/code-focused-mode.d.ts.map +1 -0
- package/dist/eval/experiments/code-focused-mode.js +66 -0
- package/dist/eval/experiments/code-focused-mode.js.map +1 -0
- package/dist/eval/experiments/edge-decay/decay-curves.d.ts +59 -0
- package/dist/eval/experiments/edge-decay/decay-curves.d.ts.map +1 -0
- package/dist/eval/experiments/edge-decay/decay-curves.js +124 -0
- package/dist/eval/experiments/edge-decay/decay-curves.js.map +1 -0
- package/dist/eval/experiments/edge-decay/index.d.ts +13 -0
- package/dist/eval/experiments/edge-decay/index.d.ts.map +1 -0
- package/dist/eval/experiments/edge-decay/index.js +16 -0
- package/dist/eval/experiments/edge-decay/index.js.map +1 -0
- package/dist/eval/experiments/edge-decay/presets.d.ts +52 -0
- package/dist/eval/experiments/edge-decay/presets.d.ts.map +1 -0
- package/dist/eval/experiments/edge-decay/presets.js +234 -0
- package/dist/eval/experiments/edge-decay/presets.js.map +1 -0
- package/dist/eval/experiments/edge-decay/reference-extractor.d.ts +34 -0
- package/dist/eval/experiments/edge-decay/reference-extractor.d.ts.map +1 -0
- package/dist/eval/experiments/edge-decay/reference-extractor.js +353 -0
- package/dist/eval/experiments/edge-decay/reference-extractor.js.map +1 -0
- package/dist/eval/experiments/edge-decay/reference-types.d.ts +131 -0
- package/dist/eval/experiments/edge-decay/reference-types.d.ts.map +1 -0
- package/dist/eval/experiments/edge-decay/reference-types.js +5 -0
- package/dist/eval/experiments/edge-decay/reference-types.js.map +1 -0
- package/dist/eval/experiments/edge-decay/retrieval-ranking.d.ts +64 -0
- package/dist/eval/experiments/edge-decay/retrieval-ranking.d.ts.map +1 -0
- package/dist/eval/experiments/edge-decay/retrieval-ranking.js +565 -0
- package/dist/eval/experiments/edge-decay/retrieval-ranking.js.map +1 -0
- package/dist/eval/experiments/edge-decay/run-experiments.d.ts +25 -0
- package/dist/eval/experiments/edge-decay/run-experiments.d.ts.map +1 -0
- package/dist/eval/experiments/edge-decay/run-experiments.js +229 -0
- package/dist/eval/experiments/edge-decay/run-experiments.js.map +1 -0
- package/dist/eval/experiments/edge-decay/simulate.d.ts +42 -0
- package/dist/eval/experiments/edge-decay/simulate.d.ts.map +1 -0
- package/dist/eval/experiments/edge-decay/simulate.js +232 -0
- package/dist/eval/experiments/edge-decay/simulate.js.map +1 -0
- package/dist/eval/experiments/edge-decay/types.d.ts +10 -0
- package/dist/eval/experiments/edge-decay/types.d.ts.map +1 -0
- package/dist/eval/experiments/edge-decay/types.js +9 -0
- package/dist/eval/experiments/edge-decay/types.js.map +1 -0
- package/dist/eval/experiments/hdbscan-sweep.d.ts +19 -0
- package/dist/eval/experiments/hdbscan-sweep.d.ts.map +1 -0
- package/dist/eval/experiments/hdbscan-sweep.js +71 -0
- package/dist/eval/experiments/hdbscan-sweep.js.map +1 -0
- package/dist/eval/experiments/single-model-run.d.ts +54 -0
- package/dist/eval/experiments/single-model-run.d.ts.map +1 -0
- package/dist/eval/experiments/single-model-run.js +120 -0
- package/dist/eval/experiments/single-model-run.js.map +1 -0
- package/dist/eval/experiments/thinking-ablation.d.ts +21 -0
- package/dist/eval/experiments/thinking-ablation.d.ts.map +1 -0
- package/dist/eval/experiments/thinking-ablation.js +68 -0
- package/dist/eval/experiments/thinking-ablation.js.map +1 -0
- package/dist/eval/experiments/topic-continuity/embedding-classifier.d.ts +55 -0
- package/dist/eval/experiments/topic-continuity/embedding-classifier.d.ts.map +1 -0
- package/dist/eval/experiments/topic-continuity/embedding-classifier.js +126 -0
- package/dist/eval/experiments/topic-continuity/embedding-classifier.js.map +1 -0
- package/dist/eval/experiments/topic-continuity/hybrid-classifier.d.ts +68 -0
- package/dist/eval/experiments/topic-continuity/hybrid-classifier.d.ts.map +1 -0
- package/dist/eval/experiments/topic-continuity/hybrid-classifier.js +175 -0
- package/dist/eval/experiments/topic-continuity/hybrid-classifier.js.map +1 -0
- package/dist/eval/experiments/topic-continuity/index.d.ts +13 -0
- package/dist/eval/experiments/topic-continuity/index.d.ts.map +1 -0
- package/dist/eval/experiments/topic-continuity/index.js +17 -0
- package/dist/eval/experiments/topic-continuity/index.js.map +1 -0
- package/dist/eval/experiments/topic-continuity/labeler.d.ts +42 -0
- package/dist/eval/experiments/topic-continuity/labeler.d.ts.map +1 -0
- package/dist/eval/experiments/topic-continuity/labeler.js +253 -0
- package/dist/eval/experiments/topic-continuity/labeler.js.map +1 -0
- package/dist/eval/experiments/topic-continuity/lexical-features.d.ts +26 -0
- package/dist/eval/experiments/topic-continuity/lexical-features.d.ts.map +1 -0
- package/dist/eval/experiments/topic-continuity/lexical-features.js +58 -0
- package/dist/eval/experiments/topic-continuity/lexical-features.js.map +1 -0
- package/dist/eval/experiments/topic-continuity/run-experiment.d.ts +40 -0
- package/dist/eval/experiments/topic-continuity/run-experiment.d.ts.map +1 -0
- package/dist/eval/experiments/topic-continuity/run-experiment.js +379 -0
- package/dist/eval/experiments/topic-continuity/run-experiment.js.map +1 -0
- package/dist/eval/experiments/topic-continuity/types.d.ts +146 -0
- package/dist/eval/experiments/topic-continuity/types.d.ts.map +1 -0
- package/dist/eval/experiments/topic-continuity/types.js +9 -0
- package/dist/eval/experiments/topic-continuity/types.js.map +1 -0
- package/dist/eval/experiments/truncation.d.ts +21 -0
- package/dist/eval/experiments/truncation.d.ts.map +1 -0
- package/dist/eval/experiments/truncation.js +59 -0
- package/dist/eval/experiments/truncation.js.map +1 -0
- package/dist/eval/experiments/types.d.ts +37 -0
- package/dist/eval/experiments/types.d.ts.map +1 -0
- package/dist/eval/experiments/types.js +13 -0
- package/dist/eval/experiments/types.js.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/curve-shapes-experiment.d.ts +10 -0
- package/dist/eval/experiments/vector-decay-shapes/curve-shapes-experiment.d.ts.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/curve-shapes-experiment.js +229 -0
- package/dist/eval/experiments/vector-decay-shapes/curve-shapes-experiment.js.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/graph-range-experiment.d.ts +12 -0
- package/dist/eval/experiments/vector-decay-shapes/graph-range-experiment.d.ts.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/graph-range-experiment.js +316 -0
- package/dist/eval/experiments/vector-decay-shapes/graph-range-experiment.js.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/hop-decay.d.ts +19 -0
- package/dist/eval/experiments/vector-decay-shapes/hop-decay.d.ts.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/hop-decay.js +127 -0
- package/dist/eval/experiments/vector-decay-shapes/hop-decay.js.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/index.d.ts +11 -0
- package/dist/eval/experiments/vector-decay-shapes/index.d.ts.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/index.js +11 -0
- package/dist/eval/experiments/vector-decay-shapes/index.js.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/path-traversal-experiment.d.ts +14 -0
- package/dist/eval/experiments/vector-decay-shapes/path-traversal-experiment.d.ts.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/path-traversal-experiment.js +274 -0
- package/dist/eval/experiments/vector-decay-shapes/path-traversal-experiment.js.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/presets.d.ts +36 -0
- package/dist/eval/experiments/vector-decay-shapes/presets.d.ts.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/presets.js +157 -0
- package/dist/eval/experiments/vector-decay-shapes/presets.js.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/run-experiment.d.ts +20 -0
- package/dist/eval/experiments/vector-decay-shapes/run-experiment.d.ts.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/run-experiment.js +504 -0
- package/dist/eval/experiments/vector-decay-shapes/run-experiment.js.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/types.d.ts +111 -0
- package/dist/eval/experiments/vector-decay-shapes/types.d.ts.map +1 -0
- package/dist/eval/experiments/vector-decay-shapes/types.js +15 -0
- package/dist/eval/experiments/vector-decay-shapes/types.js.map +1 -0
- package/dist/eval/experiments/vector-decay-sweep/index.d.ts +7 -0
- package/dist/eval/experiments/vector-decay-sweep/index.d.ts.map +1 -0
- package/dist/eval/experiments/vector-decay-sweep/index.js +7 -0
- package/dist/eval/experiments/vector-decay-sweep/index.js.map +1 -0
- package/dist/eval/experiments/vector-decay-sweep/run-sweep.d.ts +30 -0
- package/dist/eval/experiments/vector-decay-sweep/run-sweep.d.ts.map +1 -0
- package/dist/eval/experiments/vector-decay-sweep/run-sweep.js +378 -0
- package/dist/eval/experiments/vector-decay-sweep/run-sweep.js.map +1 -0
- package/dist/eval/experiments/vector-decay-sweep/types.d.ts +109 -0
- package/dist/eval/experiments/vector-decay-sweep/types.d.ts.map +1 -0
- package/dist/eval/experiments/vector-decay-sweep/types.js +16 -0
- package/dist/eval/experiments/vector-decay-sweep/types.js.map +1 -0
- package/dist/eval/metrics.d.ts +45 -0
- package/dist/eval/metrics.d.ts.map +1 -0
- package/dist/eval/metrics.js +134 -0
- package/dist/eval/metrics.js.map +1 -0
- package/dist/hooks/claudemd-generator.d.ts +62 -0
- package/dist/hooks/claudemd-generator.d.ts.map +1 -0
- package/dist/hooks/claudemd-generator.js +220 -0
- package/dist/hooks/claudemd-generator.js.map +1 -0
- package/dist/hooks/hook-utils.d.ts +84 -0
- package/dist/hooks/hook-utils.d.ts.map +1 -0
- package/dist/hooks/hook-utils.js +187 -0
- package/dist/hooks/hook-utils.js.map +1 -0
- package/dist/hooks/index.d.ts +12 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +12 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/pre-compact.d.ts +58 -0
- package/dist/hooks/pre-compact.d.ts.map +1 -0
- package/dist/hooks/pre-compact.js +127 -0
- package/dist/hooks/pre-compact.js.map +1 -0
- package/dist/hooks/session-start.d.ts +62 -0
- package/dist/hooks/session-start.d.ts.map +1 -0
- package/dist/hooks/session-start.js +249 -0
- package/dist/hooks/session-start.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest/batch-ingest.d.ts +94 -0
- package/dist/ingest/batch-ingest.d.ts.map +1 -0
- package/dist/ingest/batch-ingest.js +167 -0
- package/dist/ingest/batch-ingest.js.map +1 -0
- package/dist/ingest/brief-debrief-detector.d.ts +74 -0
- package/dist/ingest/brief-debrief-detector.d.ts.map +1 -0
- package/dist/ingest/brief-debrief-detector.js +253 -0
- package/dist/ingest/brief-debrief-detector.js.map +1 -0
- package/dist/ingest/cross-session-linker.d.ts +39 -0
- package/dist/ingest/cross-session-linker.d.ts.map +1 -0
- package/dist/ingest/cross-session-linker.js +103 -0
- package/dist/ingest/cross-session-linker.js.map +1 -0
- package/dist/ingest/edge-creator.d.ts +62 -0
- package/dist/ingest/edge-creator.d.ts.map +1 -0
- package/dist/ingest/edge-creator.js +186 -0
- package/dist/ingest/edge-creator.js.map +1 -0
- package/dist/ingest/edge-detector.d.ts +37 -0
- package/dist/ingest/edge-detector.d.ts.map +1 -0
- package/dist/ingest/edge-detector.js +234 -0
- package/dist/ingest/edge-detector.js.map +1 -0
- package/dist/ingest/index.d.ts +14 -0
- package/dist/ingest/index.d.ts.map +1 -0
- package/dist/ingest/index.js +14 -0
- package/dist/ingest/index.js.map +1 -0
- package/dist/ingest/ingest-session.d.ts +83 -0
- package/dist/ingest/ingest-session.d.ts.map +1 -0
- package/dist/ingest/ingest-session.js +415 -0
- package/dist/ingest/ingest-session.js.map +1 -0
- package/dist/maintenance/index.d.ts +5 -0
- package/dist/maintenance/index.d.ts.map +1 -0
- package/dist/maintenance/index.js +5 -0
- package/dist/maintenance/index.js.map +1 -0
- package/dist/maintenance/scheduler.d.ts +79 -0
- package/dist/maintenance/scheduler.d.ts.map +1 -0
- package/dist/maintenance/scheduler.js +362 -0
- package/dist/maintenance/scheduler.js.map +1 -0
- package/dist/maintenance/tasks/cleanup-vectors.d.ts +10 -0
- package/dist/maintenance/tasks/cleanup-vectors.d.ts.map +1 -0
- package/dist/maintenance/tasks/cleanup-vectors.js +23 -0
- package/dist/maintenance/tasks/cleanup-vectors.js.map +1 -0
- package/dist/maintenance/tasks/index.d.ts +9 -0
- package/dist/maintenance/tasks/index.d.ts.map +1 -0
- package/dist/maintenance/tasks/index.js +9 -0
- package/dist/maintenance/tasks/index.js.map +1 -0
- package/dist/maintenance/tasks/prune-graph.d.ts +12 -0
- package/dist/maintenance/tasks/prune-graph.d.ts.map +1 -0
- package/dist/maintenance/tasks/prune-graph.js +23 -0
- package/dist/maintenance/tasks/prune-graph.js.map +1 -0
- package/dist/maintenance/tasks/scan-projects.d.ts +12 -0
- package/dist/maintenance/tasks/scan-projects.d.ts.map +1 -0
- package/dist/maintenance/tasks/scan-projects.js +31 -0
- package/dist/maintenance/tasks/scan-projects.js.map +1 -0
- package/dist/maintenance/tasks/update-clusters.d.ts +12 -0
- package/dist/maintenance/tasks/update-clusters.d.ts.map +1 -0
- package/dist/maintenance/tasks/update-clusters.js +41 -0
- package/dist/maintenance/tasks/update-clusters.js.map +1 -0
- package/dist/maintenance/tasks/vacuum.d.ts +10 -0
- package/dist/maintenance/tasks/vacuum.d.ts.map +1 -0
- package/dist/maintenance/tasks/vacuum.js +23 -0
- package/dist/maintenance/tasks/vacuum.js.map +1 -0
- package/dist/mcp/index.d.ts +7 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +8 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +90 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +395 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +52 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +292 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/models/device-detector.d.ts +32 -0
- package/dist/models/device-detector.d.ts.map +1 -0
- package/dist/models/device-detector.js +123 -0
- package/dist/models/device-detector.js.map +1 -0
- package/dist/models/embedder.d.ts +60 -0
- package/dist/models/embedder.d.ts.map +1 -0
- package/dist/models/embedder.js +171 -0
- package/dist/models/embedder.js.map +1 -0
- package/dist/models/model-registry.d.ts +25 -0
- package/dist/models/model-registry.d.ts.map +1 -0
- package/dist/models/model-registry.js +56 -0
- package/dist/models/model-registry.js.map +1 -0
- package/dist/parser/chunker.d.ts +74 -0
- package/dist/parser/chunker.d.ts.map +1 -0
- package/dist/parser/chunker.js +330 -0
- package/dist/parser/chunker.js.map +1 -0
- package/dist/parser/session-reader.d.ts +75 -0
- package/dist/parser/session-reader.d.ts.map +1 -0
- package/dist/parser/session-reader.js +198 -0
- package/dist/parser/session-reader.js.map +1 -0
- package/dist/parser/turn-assembler.d.ts +18 -0
- package/dist/parser/turn-assembler.d.ts.map +1 -0
- package/dist/parser/turn-assembler.js +150 -0
- package/dist/parser/turn-assembler.js.map +1 -0
- package/dist/parser/types.d.ts +124 -0
- package/dist/parser/types.d.ts.map +1 -0
- package/dist/parser/types.js +8 -0
- package/dist/parser/types.js.map +1 -0
- package/dist/report/reporter.d.ts +18 -0
- package/dist/report/reporter.d.ts.map +1 -0
- package/dist/report/reporter.js +121 -0
- package/dist/report/reporter.js.map +1 -0
- package/dist/retrieval/cluster-expander.d.ts +30 -0
- package/dist/retrieval/cluster-expander.d.ts.map +1 -0
- package/dist/retrieval/cluster-expander.js +87 -0
- package/dist/retrieval/cluster-expander.js.map +1 -0
- package/dist/retrieval/context-assembler.d.ts +89 -0
- package/dist/retrieval/context-assembler.d.ts.map +1 -0
- package/dist/retrieval/context-assembler.js +313 -0
- package/dist/retrieval/context-assembler.js.map +1 -0
- package/dist/retrieval/index.d.ts +12 -0
- package/dist/retrieval/index.d.ts.map +1 -0
- package/dist/retrieval/index.js +12 -0
- package/dist/retrieval/index.js.map +1 -0
- package/dist/retrieval/rrf.d.ts +25 -0
- package/dist/retrieval/rrf.d.ts.map +1 -0
- package/dist/retrieval/rrf.js +56 -0
- package/dist/retrieval/rrf.js.map +1 -0
- package/dist/retrieval/session-reconstructor.d.ts +79 -0
- package/dist/retrieval/session-reconstructor.d.ts.map +1 -0
- package/dist/retrieval/session-reconstructor.js +173 -0
- package/dist/retrieval/session-reconstructor.js.map +1 -0
- package/dist/retrieval/traverser.d.ts +66 -0
- package/dist/retrieval/traverser.d.ts.map +1 -0
- package/dist/retrieval/traverser.js +160 -0
- package/dist/retrieval/traverser.js.map +1 -0
- package/dist/storage/archive.d.ts +81 -0
- package/dist/storage/archive.d.ts.map +1 -0
- package/dist/storage/archive.js +204 -0
- package/dist/storage/archive.js.map +1 -0
- package/dist/storage/audit-log.d.ts +29 -0
- package/dist/storage/audit-log.d.ts.map +1 -0
- package/dist/storage/audit-log.js +69 -0
- package/dist/storage/audit-log.js.map +1 -0
- package/dist/storage/checkpoint-store.d.ts +38 -0
- package/dist/storage/checkpoint-store.d.ts.map +1 -0
- package/dist/storage/checkpoint-store.js +76 -0
- package/dist/storage/checkpoint-store.js.map +1 -0
- package/dist/storage/chunk-store.d.ts +111 -0
- package/dist/storage/chunk-store.d.ts.map +1 -0
- package/dist/storage/chunk-store.js +298 -0
- package/dist/storage/chunk-store.js.map +1 -0
- package/dist/storage/clock-store.d.ts +80 -0
- package/dist/storage/clock-store.d.ts.map +1 -0
- package/dist/storage/clock-store.js +155 -0
- package/dist/storage/clock-store.js.map +1 -0
- package/dist/storage/cluster-store.d.ts +63 -0
- package/dist/storage/cluster-store.d.ts.map +1 -0
- package/dist/storage/cluster-store.js +219 -0
- package/dist/storage/cluster-store.js.map +1 -0
- package/dist/storage/db.d.ts +57 -0
- package/dist/storage/db.d.ts.map +1 -0
- package/dist/storage/db.js +249 -0
- package/dist/storage/db.js.map +1 -0
- package/dist/storage/decay.d.ts +125 -0
- package/dist/storage/decay.d.ts.map +1 -0
- package/dist/storage/decay.js +276 -0
- package/dist/storage/decay.js.map +1 -0
- package/dist/storage/edge-store.d.ts +75 -0
- package/dist/storage/edge-store.d.ts.map +1 -0
- package/dist/storage/edge-store.js +259 -0
- package/dist/storage/edge-store.js.map +1 -0
- package/dist/storage/embedding-cache.d.ts +51 -0
- package/dist/storage/embedding-cache.d.ts.map +1 -0
- package/dist/storage/embedding-cache.js +155 -0
- package/dist/storage/embedding-cache.js.map +1 -0
- package/dist/storage/encryption.d.ts +55 -0
- package/dist/storage/encryption.d.ts.map +1 -0
- package/dist/storage/encryption.js +130 -0
- package/dist/storage/encryption.js.map +1 -0
- package/dist/storage/index.d.ts +15 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +20 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/keyword-store.d.ts +25 -0
- package/dist/storage/keyword-store.d.ts.map +1 -0
- package/dist/storage/keyword-store.js +104 -0
- package/dist/storage/keyword-store.js.map +1 -0
- package/dist/storage/migrations.d.ts +12 -0
- package/dist/storage/migrations.d.ts.map +1 -0
- package/dist/storage/migrations.js +345 -0
- package/dist/storage/migrations.js.map +1 -0
- package/dist/storage/pruner.d.ts +111 -0
- package/dist/storage/pruner.d.ts.map +1 -0
- package/dist/storage/pruner.js +280 -0
- package/dist/storage/pruner.js.map +1 -0
- package/dist/storage/schema-loader.d.ts +18 -0
- package/dist/storage/schema-loader.d.ts.map +1 -0
- package/dist/storage/schema-loader.js +62 -0
- package/dist/storage/schema-loader.js.map +1 -0
- package/dist/storage/schema.sql +133 -0
- package/dist/storage/types.d.ts +278 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +14 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/storage/vector-store.d.ts +213 -0
- package/dist/storage/vector-store.d.ts.map +1 -0
- package/dist/storage/vector-store.js +440 -0
- package/dist/storage/vector-store.js.map +1 -0
- package/dist/temporal/clock-compactor.d.ts +65 -0
- package/dist/temporal/clock-compactor.d.ts.map +1 -0
- package/dist/temporal/clock-compactor.js +157 -0
- package/dist/temporal/clock-compactor.js.map +1 -0
- package/dist/temporal/index.d.ts +6 -0
- package/dist/temporal/index.d.ts.map +1 -0
- package/dist/temporal/index.js +6 -0
- package/dist/temporal/index.js.map +1 -0
- package/dist/temporal/vector-clock.d.ts +143 -0
- package/dist/temporal/vector-clock.d.ts.map +1 -0
- package/dist/temporal/vector-clock.js +231 -0
- package/dist/temporal/vector-clock.js.map +1 -0
- package/dist/utils/angular-distance.d.ts +31 -0
- package/dist/utils/angular-distance.d.ts.map +1 -0
- package/dist/utils/angular-distance.js +61 -0
- package/dist/utils/angular-distance.js.map +1 -0
- package/dist/utils/array-utils.d.ts +28 -0
- package/dist/utils/array-utils.d.ts.map +1 -0
- package/dist/utils/array-utils.js +67 -0
- package/dist/utils/array-utils.js.map +1 -0
- package/dist/utils/embedding-utils.d.ts +25 -0
- package/dist/utils/embedding-utils.d.ts.map +1 -0
- package/dist/utils/embedding-utils.js +30 -0
- package/dist/utils/embedding-utils.js.map +1 -0
- package/dist/utils/errors.d.ts +143 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +220 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/keychain.d.ts +43 -0
- package/dist/utils/keychain.d.ts.map +1 -0
- package/dist/utils/keychain.js +82 -0
- package/dist/utils/keychain.js.map +1 -0
- package/dist/utils/logger.d.ts +50 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +104 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/secret-store.d.ts +110 -0
- package/dist/utils/secret-store.d.ts.map +1 -0
- package/dist/utils/secret-store.js +340 -0
- package/dist/utils/secret-store.js.map +1 -0
- package/dist/utils/secure-buffer.d.ts +66 -0
- package/dist/utils/secure-buffer.d.ts.map +1 -0
- package/dist/utils/secure-buffer.js +104 -0
- package/dist/utils/secure-buffer.js.map +1 -0
- package/dist/utils/token-counter.d.ts +13 -0
- package/dist/utils/token-counter.d.ts.map +1 -0
- package/dist/utils/token-counter.js +18 -0
- package/dist/utils/token-counter.js.map +1 -0
- package/package.json +110 -0
- package/src/dashboard/client/package-lock.json +3045 -0
- package/src/dashboard/client/package.json +30 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM-based cluster description refresh.
|
|
3
|
+
* Uses Claude API to generate human-readable descriptions for clusters.
|
|
4
|
+
*/
|
|
5
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
6
|
+
import { getConfig } from '../config/memory-config.js';
|
|
7
|
+
import { getClusterById, upsertCluster, getStaleClusters } from '../storage/cluster-store.js';
|
|
8
|
+
import { getChunksByIds } from '../storage/chunk-store.js';
|
|
9
|
+
import { createLogger } from '../utils/logger.js';
|
|
10
|
+
import { createSecretStore } from '../utils/secret-store.js';
|
|
11
|
+
const log = createLogger('cluster-refresh');
|
|
12
|
+
/**
|
|
13
|
+
* Rate limiter for API calls.
|
|
14
|
+
*/
|
|
15
|
+
class RateLimiter {
|
|
16
|
+
lastCall = 0;
|
|
17
|
+
minIntervalMs;
|
|
18
|
+
constructor(callsPerMinute) {
|
|
19
|
+
this.minIntervalMs = (60 * 1000) / callsPerMinute;
|
|
20
|
+
}
|
|
21
|
+
async wait() {
|
|
22
|
+
const now = Date.now();
|
|
23
|
+
const elapsed = now - this.lastCall;
|
|
24
|
+
if (elapsed < this.minIntervalMs) {
|
|
25
|
+
await new Promise((resolve) => setTimeout(resolve, this.minIntervalMs - elapsed));
|
|
26
|
+
}
|
|
27
|
+
this.lastCall = Date.now();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Cluster refresher for generating descriptions using Claude.
|
|
32
|
+
*/
|
|
33
|
+
export class ClusterRefresher {
|
|
34
|
+
client = null;
|
|
35
|
+
rateLimiter;
|
|
36
|
+
config = getConfig();
|
|
37
|
+
constructor() {
|
|
38
|
+
this.rateLimiter = new RateLimiter(this.config.refreshRateLimitPerMin);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Initialize the Anthropic client.
|
|
42
|
+
* Checks keychain for API key if not set in environment.
|
|
43
|
+
*/
|
|
44
|
+
async getClient() {
|
|
45
|
+
if (!this.client) {
|
|
46
|
+
// Check if API key is in environment
|
|
47
|
+
if (!process.env.ANTHROPIC_API_KEY) {
|
|
48
|
+
// Try to load from keychain
|
|
49
|
+
const store = createSecretStore();
|
|
50
|
+
const storedKey = await store.get('anthropic-api-key');
|
|
51
|
+
if (storedKey) {
|
|
52
|
+
process.env.ANTHROPIC_API_KEY = storedKey;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (!process.env.ANTHROPIC_API_KEY) {
|
|
56
|
+
throw new Error('No Anthropic API key found. Set ANTHROPIC_API_KEY environment variable ' +
|
|
57
|
+
'or run "causantic config set-key anthropic-api-key" to store in keychain.');
|
|
58
|
+
}
|
|
59
|
+
this.client = new Anthropic();
|
|
60
|
+
}
|
|
61
|
+
return this.client;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Refresh a single cluster's description.
|
|
65
|
+
*/
|
|
66
|
+
async refreshCluster(clusterId, options = {}) {
|
|
67
|
+
const startTime = Date.now();
|
|
68
|
+
const { model = this.config.clusterRefreshModel, maxExemplars = 3, maxTokensPerChunk = 500 } = options;
|
|
69
|
+
const cluster = getClusterById(clusterId);
|
|
70
|
+
if (!cluster) {
|
|
71
|
+
throw new Error(`Cluster not found: ${clusterId}`);
|
|
72
|
+
}
|
|
73
|
+
// Get exemplar chunks
|
|
74
|
+
const exemplarIds = cluster.exemplarIds.slice(0, maxExemplars);
|
|
75
|
+
const exemplars = getChunksByIds(exemplarIds);
|
|
76
|
+
if (exemplars.length === 0) {
|
|
77
|
+
return {
|
|
78
|
+
clusterId,
|
|
79
|
+
name: cluster.name ?? 'Empty Cluster',
|
|
80
|
+
description: 'No exemplar chunks available.',
|
|
81
|
+
durationMs: Date.now() - startTime,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
// Build prompt
|
|
85
|
+
const prompt = buildRefreshPrompt(exemplars, maxTokensPerChunk);
|
|
86
|
+
// Rate limit
|
|
87
|
+
await this.rateLimiter.wait();
|
|
88
|
+
// Call Claude API
|
|
89
|
+
const client = await this.getClient();
|
|
90
|
+
const response = await client.messages.create({
|
|
91
|
+
model,
|
|
92
|
+
max_tokens: 200,
|
|
93
|
+
messages: [{ role: 'user', content: prompt }],
|
|
94
|
+
});
|
|
95
|
+
// Parse response
|
|
96
|
+
const text = response.content[0].type === 'text' ? response.content[0].text : '';
|
|
97
|
+
const { name, description } = parseRefreshResponse(text);
|
|
98
|
+
// Update cluster
|
|
99
|
+
upsertCluster({
|
|
100
|
+
id: clusterId,
|
|
101
|
+
name,
|
|
102
|
+
description,
|
|
103
|
+
});
|
|
104
|
+
return {
|
|
105
|
+
clusterId,
|
|
106
|
+
name,
|
|
107
|
+
description,
|
|
108
|
+
durationMs: Date.now() - startTime,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Refresh all stale clusters.
|
|
113
|
+
*/
|
|
114
|
+
async refreshStaleClusters(options = {}) {
|
|
115
|
+
const { maxAgeMs = 24 * 60 * 60 * 1000, onProgress } = options; // Default: 24 hours
|
|
116
|
+
const staleClusters = getStaleClusters(maxAgeMs);
|
|
117
|
+
const results = [];
|
|
118
|
+
for (const cluster of staleClusters) {
|
|
119
|
+
try {
|
|
120
|
+
const result = await this.refreshCluster(cluster.id, options);
|
|
121
|
+
results.push(result);
|
|
122
|
+
onProgress?.(results.length, staleClusters.length);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
log.error(`Failed to refresh cluster ${cluster.id}`, { error: error.message });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return results;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Refresh all clusters (force refresh).
|
|
132
|
+
*/
|
|
133
|
+
async refreshAllClusters(options = {}) {
|
|
134
|
+
const { onProgress } = options;
|
|
135
|
+
const staleClusters = getStaleClusters(0); // Get all
|
|
136
|
+
const results = [];
|
|
137
|
+
for (const cluster of staleClusters) {
|
|
138
|
+
try {
|
|
139
|
+
const result = await this.refreshCluster(cluster.id, options);
|
|
140
|
+
results.push(result);
|
|
141
|
+
onProgress?.(results.length, staleClusters.length);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
log.error(`Failed to refresh cluster ${cluster.id}`, { error: error.message });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return results;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Build prompt for cluster description generation.
|
|
152
|
+
*/
|
|
153
|
+
function buildRefreshPrompt(exemplars, maxTokensPerChunk) {
|
|
154
|
+
const truncatedExemplars = exemplars.map((e) => {
|
|
155
|
+
const content = e.content;
|
|
156
|
+
// Rough token estimate: 4 chars per token
|
|
157
|
+
const maxChars = maxTokensPerChunk * 4;
|
|
158
|
+
if (content.length > maxChars) {
|
|
159
|
+
return content.slice(0, maxChars) + '\n...[truncated]';
|
|
160
|
+
}
|
|
161
|
+
return content;
|
|
162
|
+
});
|
|
163
|
+
return `Analyze these conversation excerpts from the same topic cluster and generate:
|
|
164
|
+
1. A short name (2-5 words) that captures the main theme
|
|
165
|
+
2. A brief description (1-2 sentences) of what this cluster is about
|
|
166
|
+
|
|
167
|
+
Excerpts:
|
|
168
|
+
${truncatedExemplars.map((e, i) => `--- Excerpt ${i + 1} ---\n${e}`).join('\n\n')}
|
|
169
|
+
|
|
170
|
+
Respond in this exact format:
|
|
171
|
+
Name: [short name]
|
|
172
|
+
Description: [brief description]`;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Parse the LLM response to extract name and description.
|
|
176
|
+
*/
|
|
177
|
+
function parseRefreshResponse(text) {
|
|
178
|
+
const nameMatch = text.match(/Name:\s*(.+?)(?:\n|$)/i);
|
|
179
|
+
const descMatch = text.match(/Description:\s*(.+?)(?:\n\n|$)/is);
|
|
180
|
+
return {
|
|
181
|
+
name: nameMatch?.[1]?.trim() ?? 'Unnamed Cluster',
|
|
182
|
+
description: descMatch?.[1]?.trim() ?? text.trim(),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
// Singleton instance
|
|
186
|
+
export const clusterRefresher = new ClusterRefresher();
|
|
187
|
+
//# sourceMappingURL=cluster-refresh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cluster-refresh.js","sourceRoot":"","sources":["../../src/clusters/cluster-refresh.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cluster extraction from condensed tree.
|
|
3
|
+
* Supports EOM (Excess of Mass) and Leaf methods.
|
|
4
|
+
*/
|
|
5
|
+
import type { CondensedTree } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Extract clusters using the specified method.
|
|
8
|
+
*
|
|
9
|
+
* @param tree Condensed cluster tree.
|
|
10
|
+
* @param method Selection method: 'eom' (default) or 'leaf'.
|
|
11
|
+
* @returns Array of selected cluster IDs.
|
|
12
|
+
*/
|
|
13
|
+
export declare function extractClusters(tree: CondensedTree, method?: 'eom' | 'leaf'): number[];
|
|
14
|
+
/**
|
|
15
|
+
* Assign labels to points based on selected clusters.
|
|
16
|
+
*
|
|
17
|
+
* @param tree Condensed cluster tree.
|
|
18
|
+
* @param selectedClusters Selected cluster IDs.
|
|
19
|
+
* @returns Labels for each point (-1 = noise).
|
|
20
|
+
*/
|
|
21
|
+
export declare function assignLabels(tree: CondensedTree, selectedClusters: number[]): number[];
|
|
22
|
+
/**
|
|
23
|
+
* Get cluster stability scores.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getClusterStabilities(tree: CondensedTree): Map<number, number>;
|
|
26
|
+
//# sourceMappingURL=cluster-extraction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cluster-extraction.d.ts","sourceRoot":"","sources":["../../../src/clusters/hdbscan/cluster-extraction.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AAEnE;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,aAAa,EACnB,MAAM,GAAE,KAAK,GAAG,MAAc,GAC7B,MAAM,EAAE,CAyBV;AAgJD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,aAAa,EACnB,gBAAgB,EAAE,MAAM,EAAE,GACzB,MAAM,EAAE,CAwBV;AA2CD;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,aAAa,GAClB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAUrB"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cluster extraction from condensed tree.
|
|
3
|
+
* Supports EOM (Excess of Mass) and Leaf methods.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Extract clusters using the specified method.
|
|
7
|
+
*
|
|
8
|
+
* @param tree Condensed cluster tree.
|
|
9
|
+
* @param method Selection method: 'eom' (default) or 'leaf'.
|
|
10
|
+
* @returns Array of selected cluster IDs.
|
|
11
|
+
*/
|
|
12
|
+
export function extractClusters(tree, method = 'eom') {
|
|
13
|
+
if (tree.nodes.size === 0 || tree.root === -1) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
// Get all cluster nodes (id >= numPoints)
|
|
17
|
+
const clusterNodes = [];
|
|
18
|
+
for (const [id, node] of tree.nodes) {
|
|
19
|
+
if (node.isCluster && id >= tree.numPoints) {
|
|
20
|
+
clusterNodes.push(node);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (clusterNodes.length === 0) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
// Compute stability for all cluster nodes
|
|
27
|
+
computeStability(tree, clusterNodes);
|
|
28
|
+
if (method === 'leaf') {
|
|
29
|
+
return extractLeafClusters(clusterNodes);
|
|
30
|
+
}
|
|
31
|
+
return extractEOMClusters(tree, clusterNodes);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Compute stability for cluster nodes.
|
|
35
|
+
* Stability = sum over member points: (point_lambda_death - cluster_lambda_birth)
|
|
36
|
+
*
|
|
37
|
+
* For a cluster to have positive stability, points must "live" within it
|
|
38
|
+
* (join at lambdaBirth or later, persist until the cluster dies)
|
|
39
|
+
*/
|
|
40
|
+
function computeStability(tree, clusters) {
|
|
41
|
+
// First, for each leaf cluster, find its directly associated points
|
|
42
|
+
// A point belongs to a leaf cluster if its lambdaDeath equals the cluster's lambdaBirth
|
|
43
|
+
// Then for parent clusters, accumulate stability from children plus
|
|
44
|
+
// any points that joined directly (not via children)
|
|
45
|
+
// Build a map from cluster to its member points
|
|
46
|
+
const clusterToPoints = new Map();
|
|
47
|
+
for (const cluster of clusters) {
|
|
48
|
+
clusterToPoints.set(cluster.id, new Set());
|
|
49
|
+
}
|
|
50
|
+
// Assign each point to the deepest cluster it belongs to
|
|
51
|
+
// A point belongs to a cluster if its lambdaDeath is at or below the cluster's lambdaBirth
|
|
52
|
+
for (let i = 0; i < tree.numPoints; i++) {
|
|
53
|
+
const pointNode = tree.nodes.get(i);
|
|
54
|
+
if (!pointNode)
|
|
55
|
+
continue;
|
|
56
|
+
const pointLambda = pointNode.lambdaDeath;
|
|
57
|
+
if (pointLambda <= 0 || !isFinite(pointLambda))
|
|
58
|
+
continue;
|
|
59
|
+
// Find the cluster(s) this point belongs to
|
|
60
|
+
// It belongs to a cluster if it joined (lambdaDeath) at or after cluster's lambdaBirth
|
|
61
|
+
for (const cluster of clusters) {
|
|
62
|
+
// Point joined this cluster if it was born at this cluster's birth
|
|
63
|
+
// (i.e., the cluster formed from a component containing this point)
|
|
64
|
+
if (Math.abs(pointLambda - cluster.lambdaBirth) < 1e-10) {
|
|
65
|
+
clusterToPoints.get(cluster.id).add(i);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Compute stability for each cluster
|
|
70
|
+
for (const cluster of clusters) {
|
|
71
|
+
const points = clusterToPoints.get(cluster.id);
|
|
72
|
+
let stability = 0;
|
|
73
|
+
for (const pointId of points) {
|
|
74
|
+
const pointNode = tree.nodes.get(pointId);
|
|
75
|
+
// Stability contribution = lambda_death - lambda_birth of cluster
|
|
76
|
+
// But for these points, lambda_death === cluster.lambdaBirth
|
|
77
|
+
// So we need to think about this differently
|
|
78
|
+
// Actually, stability is about how long a point persists in a cluster
|
|
79
|
+
// A point joins at lambda = cluster.lambdaBirth
|
|
80
|
+
// It leaves when the cluster dies at cluster.lambdaDeath
|
|
81
|
+
// But we store point's lambdaDeath as when it joined a cluster
|
|
82
|
+
// The correct formula is:
|
|
83
|
+
// For each point in cluster: (min(lambdaDeath_cluster, lambda_point_left) - lambdaBirth_cluster) * 1
|
|
84
|
+
// Since we're dealing with lambdas (1/distance), higher lambda means closer/denser
|
|
85
|
+
// Let's use: stability = sum of (point's persistence in this cluster)
|
|
86
|
+
// A point persists from lambdaBirth to lambdaDeath of cluster (or until it left)
|
|
87
|
+
const clusterDeath = isFinite(cluster.lambdaDeath) ? cluster.lambdaDeath : 0;
|
|
88
|
+
const persistence = cluster.lambdaBirth - clusterDeath;
|
|
89
|
+
if (persistence > 0) {
|
|
90
|
+
stability += persistence;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
cluster.stability = stability;
|
|
94
|
+
}
|
|
95
|
+
// For non-leaf clusters, we might need to add stability from points that
|
|
96
|
+
// joined after children merged but before the cluster died
|
|
97
|
+
// This is handled above since we check all points against all clusters
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Extract clusters using Excess of Mass (EOM) method.
|
|
101
|
+
* Bottom-up selection: compare node stability vs children total.
|
|
102
|
+
*/
|
|
103
|
+
function extractEOMClusters(tree, clusters) {
|
|
104
|
+
// Sort by lambdaBirth descending (process children before parents)
|
|
105
|
+
const sorted = [...clusters].sort((a, b) => b.lambdaBirth - a.lambdaBirth);
|
|
106
|
+
// Track subtree stability (sum of selected children OR own stability)
|
|
107
|
+
const subtreeStability = new Map();
|
|
108
|
+
for (const cluster of sorted) {
|
|
109
|
+
if (cluster.children.length === 0) {
|
|
110
|
+
// Leaf cluster: select it
|
|
111
|
+
subtreeStability.set(cluster.id, cluster.stability);
|
|
112
|
+
cluster.selected = true;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// Non-leaf: compare own stability vs children's subtree stability
|
|
116
|
+
let childrenTotal = 0;
|
|
117
|
+
for (const childId of cluster.children) {
|
|
118
|
+
const childStability = subtreeStability.get(childId) ?? 0;
|
|
119
|
+
childrenTotal += childStability;
|
|
120
|
+
}
|
|
121
|
+
if (cluster.stability >= childrenTotal) {
|
|
122
|
+
// This cluster is more stable - select it, deselect children
|
|
123
|
+
subtreeStability.set(cluster.id, cluster.stability);
|
|
124
|
+
cluster.selected = true;
|
|
125
|
+
for (const childId of cluster.children) {
|
|
126
|
+
const child = tree.nodes.get(childId);
|
|
127
|
+
if (child)
|
|
128
|
+
child.selected = false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
// Children are more stable - keep them selected
|
|
133
|
+
subtreeStability.set(cluster.id, childrenTotal);
|
|
134
|
+
cluster.selected = false;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return clusters.filter((c) => c.selected).map((c) => c.id);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Extract clusters using Leaf method.
|
|
142
|
+
* Select only leaf nodes (finest granularity).
|
|
143
|
+
*/
|
|
144
|
+
function extractLeafClusters(clusters) {
|
|
145
|
+
const leaves = [];
|
|
146
|
+
for (const cluster of clusters) {
|
|
147
|
+
if (cluster.children.length === 0) {
|
|
148
|
+
leaves.push(cluster.id);
|
|
149
|
+
cluster.selected = true;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
cluster.selected = false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return leaves;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Assign labels to points based on selected clusters.
|
|
159
|
+
*
|
|
160
|
+
* @param tree Condensed cluster tree.
|
|
161
|
+
* @param selectedClusters Selected cluster IDs.
|
|
162
|
+
* @returns Labels for each point (-1 = noise).
|
|
163
|
+
*/
|
|
164
|
+
export function assignLabels(tree, selectedClusters) {
|
|
165
|
+
const labels = new Array(tree.numPoints).fill(-1);
|
|
166
|
+
if (selectedClusters.length === 0) {
|
|
167
|
+
return labels;
|
|
168
|
+
}
|
|
169
|
+
// For each selected cluster, find all points that belong to it
|
|
170
|
+
for (let clusterLabel = 0; clusterLabel < selectedClusters.length; clusterLabel++) {
|
|
171
|
+
const clusterId = selectedClusters[clusterLabel];
|
|
172
|
+
const clusterNode = tree.nodes.get(clusterId);
|
|
173
|
+
if (!clusterNode)
|
|
174
|
+
continue;
|
|
175
|
+
// Find all points in this cluster (recursively through children)
|
|
176
|
+
const points = getAllClusterPoints(tree, clusterId);
|
|
177
|
+
for (const pointId of points) {
|
|
178
|
+
if (labels[pointId] === -1) {
|
|
179
|
+
labels[pointId] = clusterLabel;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return labels;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Get all points that belong to a cluster (including via children).
|
|
187
|
+
*/
|
|
188
|
+
function getAllClusterPoints(tree, clusterId) {
|
|
189
|
+
const points = [];
|
|
190
|
+
const clusterNode = tree.nodes.get(clusterId);
|
|
191
|
+
if (!clusterNode || !clusterNode.isCluster) {
|
|
192
|
+
return points;
|
|
193
|
+
}
|
|
194
|
+
// Find all points with lambdaDeath matching this cluster or any ancestor
|
|
195
|
+
const clusterLambda = clusterNode.lambdaBirth;
|
|
196
|
+
for (let i = 0; i < tree.numPoints; i++) {
|
|
197
|
+
const pointNode = tree.nodes.get(i);
|
|
198
|
+
if (!pointNode)
|
|
199
|
+
continue;
|
|
200
|
+
// Point belongs to this cluster if:
|
|
201
|
+
// 1. Its lambdaDeath >= cluster's lambdaBirth (joined at or after cluster formed)
|
|
202
|
+
// 2. Its lambdaDeath <= cluster's lambdaDeath (left at or before cluster died)
|
|
203
|
+
const clusterDeath = clusterNode.lambdaDeath;
|
|
204
|
+
const pointLambda = pointNode.lambdaDeath;
|
|
205
|
+
if (pointLambda >= clusterDeath && pointLambda <= clusterLambda + 1e-10) {
|
|
206
|
+
points.push(i);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// Also recurse into children
|
|
210
|
+
for (const childId of clusterNode.children) {
|
|
211
|
+
const childPoints = getAllClusterPoints(tree, childId);
|
|
212
|
+
for (const p of childPoints) {
|
|
213
|
+
if (!points.includes(p)) {
|
|
214
|
+
points.push(p);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return points;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Get cluster stability scores.
|
|
222
|
+
*/
|
|
223
|
+
export function getClusterStabilities(tree) {
|
|
224
|
+
const stabilities = new Map();
|
|
225
|
+
for (const [id, node] of tree.nodes) {
|
|
226
|
+
if (node.isCluster && id >= tree.numPoints) {
|
|
227
|
+
stabilities.set(id, node.stability);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return stabilities;
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=cluster-extraction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cluster-extraction.js","sourceRoot":"","sources":["../../../src/clusters/hdbscan/cluster-extraction.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAmB,EACnB,SAAyB,KAAK;IAE9B,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC;QAC9C,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,0CAA0C;IAC1C,MAAM,YAAY,GAAwB,EAAE,CAAC;IAC7C,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,SAAS,IAAI,EAAE,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC3C,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,0CAA0C;IAC1C,gBAAgB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAErC,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,kBAAkB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gBAAgB,CAAC,IAAmB,EAAE,QAA6B;IAC1E,oEAAoE;IACpE,wFAAwF;IAExF,oEAAoE;IACpE,qDAAqD;IAErD,gDAAgD;IAChD,MAAM,eAAe,GAAG,IAAI,GAAG,EAAuB,CAAC;IAEvD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,yDAAyD;IACzD,2FAA2F;IAC3F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,SAAS;YAAE,SAAS;QAEzB,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC;QAC1C,IAAI,WAAW,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,SAAS;QAEzD,4CAA4C;QAC5C,uFAAuF;QACvF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,mEAAmE;YACnE,oEAAoE;YACpE,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,KAAK,EAAE,CAAC;gBACxD,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAE,CAAC;QAChD,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,KAAK,MAAM,OAAO,IAAI,MAAM,EAAE,CAAC;YAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC;YAC3C,kEAAkE;YAClE,6DAA6D;YAC7D,6CAA6C;YAE7C,sEAAsE;YACtE,gDAAgD;YAChD,yDAAyD;YACzD,+DAA+D;YAE/D,0BAA0B;YAC1B,qGAAqG;YACrG,mFAAmF;YAEnF,sEAAsE;YACtE,iFAAiF;YAEjF,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7E,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,GAAG,YAAY,CAAC;YACvD,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;gBACpB,SAAS,IAAI,WAAW,CAAC;YAC3B,CAAC;QACH,CAAC;QAED,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAChC,CAAC;IAED,yEAAyE;IACzE,2DAA2D;IAC3D,uEAAuE;AACzE,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CAAC,IAAmB,EAAE,QAA6B;IAC5E,mEAAmE;IACnE,MAAM,MAAM,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC;IAE3E,sEAAsE;IACtE,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEnD,KAAK,MAAM,OAAO,IAAI,MAAM,EAAE,CAAC;QAC7B,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,0BAA0B;YAC1B,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;YACpD,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,kEAAkE;YAClE,IAAI,aAAa,GAAG,CAAC,CAAC;YACtB,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACvC,MAAM,cAAc,GAAG,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBAC1D,aAAa,IAAI,cAAc,CAAC;YAClC,CAAC;YAED,IAAI,OAAO,CAAC,SAAS,IAAI,aAAa,EAAE,CAAC;gBACvC,6DAA6D;gBAC7D,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;gBACpD,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;gBAExB,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;oBACvC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBACtC,IAAI,KAAK;wBAAE,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC;gBACpC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,gDAAgD;gBAChD,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;gBAChD,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAAC,QAA6B;IACxD,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACxB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAmB,EACnB,gBAA0B;IAE1B,MAAM,MAAM,GAAG,IAAI,KAAK,CAAS,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAE1D,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,+DAA+D;IAC/D,KAAK,IAAI,YAAY,GAAG,CAAC,EAAE,YAAY,GAAG,gBAAgB,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,CAAC;QAClF,MAAM,SAAS,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAC;QACjD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,CAAC,WAAW;YAAE,SAAS;QAE3B,iEAAiE;QACjE,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAEpD,KAAK,MAAM,OAAO,IAAI,MAAM,EAAE,CAAC;YAC7B,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBAC3B,MAAM,CAAC,OAAO,CAAC,GAAG,YAAY,CAAC;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,IAAmB,EAAE,SAAiB;IACjE,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC9C,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;QAC3C,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,yEAAyE;IACzE,MAAM,aAAa,GAAG,WAAW,CAAC,WAAW,CAAC;IAE9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,SAAS;YAAE,SAAS;QAEzB,oCAAoC;QACpC,kFAAkF;QAClF,+EAA+E;QAC/E,MAAM,YAAY,GAAG,WAAW,CAAC,WAAW,CAAC;QAC7C,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC;QAE1C,IAAI,WAAW,IAAI,YAAY,IAAI,WAAW,IAAI,aAAa,GAAG,KAAK,EAAE,CAAC;YACxE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,KAAK,MAAM,OAAO,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;QAC3C,MAAM,WAAW,GAAG,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACvD,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxB,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAmB;IAEnB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE9C,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,SAAS,IAAI,EAAE,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC3C,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-distance-worker.d.ts","sourceRoot":"","sources":["../../../src/clusters/hdbscan/core-distance-worker.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker thread for parallel core distance computation.
|
|
3
|
+
* This file is loaded by worker_threads.
|
|
4
|
+
*/
|
|
5
|
+
import { parentPort, workerData } from 'worker_threads';
|
|
6
|
+
import { quickselect } from '../../utils/array-utils.js';
|
|
7
|
+
/**
|
|
8
|
+
* Compute Euclidean distance between two points.
|
|
9
|
+
*/
|
|
10
|
+
function euclideanDistance(a, b) {
|
|
11
|
+
let sum = 0;
|
|
12
|
+
for (let i = 0; i < a.length; i++) {
|
|
13
|
+
const diff = a[i] - b[i];
|
|
14
|
+
sum += diff * diff;
|
|
15
|
+
}
|
|
16
|
+
return Math.sqrt(sum);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Compute angular distance between two normalized vectors.
|
|
20
|
+
*/
|
|
21
|
+
function angularDistance(a, b) {
|
|
22
|
+
let dot = 0;
|
|
23
|
+
for (let i = 0; i < a.length; i++) {
|
|
24
|
+
dot += a[i] * b[i];
|
|
25
|
+
}
|
|
26
|
+
return 1 - dot;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Compute core distances for assigned indices.
|
|
30
|
+
*/
|
|
31
|
+
function computeChunk(data) {
|
|
32
|
+
const { indices, allPoints, k, metric } = data;
|
|
33
|
+
const distFn = metric === 'euclidean' ? euclideanDistance : angularDistance;
|
|
34
|
+
const n = allPoints.length;
|
|
35
|
+
const effectiveK = Math.min(k, n - 1);
|
|
36
|
+
const coreDistances = [];
|
|
37
|
+
for (const i of indices) {
|
|
38
|
+
const distances = [];
|
|
39
|
+
for (let j = 0; j < n; j++) {
|
|
40
|
+
if (i !== j) {
|
|
41
|
+
distances.push(distFn(allPoints[i], allPoints[j]));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const coreDistance = effectiveK > 0 ? quickselect(distances, effectiveK - 1) : 0;
|
|
45
|
+
coreDistances.push({ index: i, coreDistance });
|
|
46
|
+
}
|
|
47
|
+
return { coreDistances };
|
|
48
|
+
}
|
|
49
|
+
// Run computation and send result back
|
|
50
|
+
if (parentPort && workerData) {
|
|
51
|
+
const result = computeChunk(workerData);
|
|
52
|
+
parentPort.postMessage(result);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=core-distance-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-distance-worker.js","sourceRoot":"","sources":["../../../src/clusters/hdbscan/core-distance-worker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEzD;;GAEG;AACH,SAAS,iBAAiB,CAAC,CAAW,EAAE,CAAW;IACjD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACzB,GAAG,IAAI,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,CAAW,EAAE,CAAW;IAC/C,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,IAA4B;IAChD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC/C,MAAM,MAAM,GAAG,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,eAAe,CAAC;IAC5E,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC;IAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACtC,MAAM,aAAa,GAAmD,EAAE,CAAC;IAEzE,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACZ,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;QAED,MAAM,YAAY,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,aAAa,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,EAAE,aAAa,EAAE,CAAC;AAC3B,CAAC;AAED,uCAAuC;AACvC,IAAI,UAAU,IAAI,UAAU,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,YAAY,CAAC,UAAoC,CAAC,CAAC;IAClE,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core distance computation for HDBSCAN.
|
|
3
|
+
* Core distance = distance to k-th nearest neighbor.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Compute core distances for all points.
|
|
7
|
+
* Core distance is the distance to the k-th nearest neighbor.
|
|
8
|
+
*
|
|
9
|
+
* @param points All points (embeddings).
|
|
10
|
+
* @param k k value (typically minSamples).
|
|
11
|
+
* @param metric Distance metric.
|
|
12
|
+
* @param useKDTree Whether to use KD-tree for approximate k-NN.
|
|
13
|
+
*/
|
|
14
|
+
export declare function computeCoreDistances(points: number[][], k: number, metric?: 'euclidean' | 'angular', useKDTree?: boolean): number[];
|
|
15
|
+
/**
|
|
16
|
+
* Compute core distances for a chunk of indices (for parallel processing).
|
|
17
|
+
* @param indices Indices to process.
|
|
18
|
+
* @param allPoints All points.
|
|
19
|
+
* @param k k value.
|
|
20
|
+
* @param metric Distance metric.
|
|
21
|
+
*/
|
|
22
|
+
export declare function computeCoreDistancesChunk(indices: number[], allPoints: number[][], k: number, metric?: 'euclidean' | 'angular'): Array<{
|
|
23
|
+
index: number;
|
|
24
|
+
coreDistance: number;
|
|
25
|
+
}>;
|
|
26
|
+
//# sourceMappingURL=core-distance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-distance.d.ts","sourceRoot":"","sources":["../../../src/clusters/hdbscan/core-distance.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EAAE,EAAE,EAClB,CAAC,EAAE,MAAM,EACT,MAAM,GAAE,WAAW,GAAG,SAAuB,EAC7C,SAAS,GAAE,OAAe,GACzB,MAAM,EAAE,CAoBV;AAkDD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,EAAE,EAAE,EACrB,CAAC,EAAE,MAAM,EACT,MAAM,GAAE,WAAW,GAAG,SAAuB,GAC5C,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAmBhD"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core distance computation for HDBSCAN.
|
|
3
|
+
* Core distance = distance to k-th nearest neighbor.
|
|
4
|
+
*/
|
|
5
|
+
import { KDTree, euclideanDistance, angularDistance } from './kd-tree.js';
|
|
6
|
+
import { quickselect } from '../../utils/array-utils.js';
|
|
7
|
+
/**
|
|
8
|
+
* Compute core distances for all points.
|
|
9
|
+
* Core distance is the distance to the k-th nearest neighbor.
|
|
10
|
+
*
|
|
11
|
+
* @param points All points (embeddings).
|
|
12
|
+
* @param k k value (typically minSamples).
|
|
13
|
+
* @param metric Distance metric.
|
|
14
|
+
* @param useKDTree Whether to use KD-tree for approximate k-NN.
|
|
15
|
+
*/
|
|
16
|
+
export function computeCoreDistances(points, k, metric = 'euclidean', useKDTree = false) {
|
|
17
|
+
const n = points.length;
|
|
18
|
+
if (n === 0) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
// k must be at most n-1 (can't count self as neighbor)
|
|
22
|
+
const effectiveK = Math.min(k, n - 1);
|
|
23
|
+
if (effectiveK <= 0) {
|
|
24
|
+
// Only 1 point, core distance is 0
|
|
25
|
+
return new Array(n).fill(0);
|
|
26
|
+
}
|
|
27
|
+
if (useKDTree && metric === 'euclidean') {
|
|
28
|
+
return computeCoreDistancesKDTree(points, effectiveK);
|
|
29
|
+
}
|
|
30
|
+
return computeCoreDistancesBruteForce(points, effectiveK, metric);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Brute force core distance computation using quickselect.
|
|
34
|
+
*/
|
|
35
|
+
function computeCoreDistancesBruteForce(points, k, metric) {
|
|
36
|
+
const n = points.length;
|
|
37
|
+
const coreDistances = new Array(n);
|
|
38
|
+
const distFn = metric === 'euclidean' ? euclideanDistance : angularDistance;
|
|
39
|
+
for (let i = 0; i < n; i++) {
|
|
40
|
+
// Compute distances to all other points
|
|
41
|
+
const distances = [];
|
|
42
|
+
for (let j = 0; j < n; j++) {
|
|
43
|
+
if (i !== j) {
|
|
44
|
+
distances.push(distFn(points[i], points[j]));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Use quickselect to find k-th smallest distance
|
|
48
|
+
coreDistances[i] = quickselect(distances, k - 1);
|
|
49
|
+
}
|
|
50
|
+
return coreDistances;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* KD-tree based core distance computation.
|
|
54
|
+
*/
|
|
55
|
+
function computeCoreDistancesKDTree(points, k) {
|
|
56
|
+
const tree = new KDTree(points);
|
|
57
|
+
const coreDistances = new Array(points.length);
|
|
58
|
+
for (let i = 0; i < points.length; i++) {
|
|
59
|
+
const neighbors = tree.kNearest(points[i], k, i);
|
|
60
|
+
if (neighbors.length === k) {
|
|
61
|
+
coreDistances[i] = neighbors[k - 1].distance;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// Fewer than k neighbors, use max distance
|
|
65
|
+
coreDistances[i] = neighbors.length > 0 ? neighbors[neighbors.length - 1].distance : 0;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return coreDistances;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Compute core distances for a chunk of indices (for parallel processing).
|
|
72
|
+
* @param indices Indices to process.
|
|
73
|
+
* @param allPoints All points.
|
|
74
|
+
* @param k k value.
|
|
75
|
+
* @param metric Distance metric.
|
|
76
|
+
*/
|
|
77
|
+
export function computeCoreDistancesChunk(indices, allPoints, k, metric = 'euclidean') {
|
|
78
|
+
const distFn = metric === 'euclidean' ? euclideanDistance : angularDistance;
|
|
79
|
+
const n = allPoints.length;
|
|
80
|
+
const effectiveK = Math.min(k, n - 1);
|
|
81
|
+
const results = [];
|
|
82
|
+
for (const i of indices) {
|
|
83
|
+
const distances = [];
|
|
84
|
+
for (let j = 0; j < n; j++) {
|
|
85
|
+
if (i !== j) {
|
|
86
|
+
distances.push(distFn(allPoints[i], allPoints[j]));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const coreDistance = effectiveK > 0 ? quickselect(distances, effectiveK - 1) : 0;
|
|
90
|
+
results.push({ index: i, coreDistance });
|
|
91
|
+
}
|
|
92
|
+
return results;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=core-distance.js.map
|