@wanshi-kg/wanshi 0.1.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 +21 -0
- package/README.md +458 -0
- package/dist/__tests__/helpers.js +27 -0
- package/dist/__tests__/helpers.js.map +1 -0
- package/dist/cli/commands/export.command.js +99 -0
- package/dist/cli/commands/export.command.js.map +1 -0
- package/dist/cli/commands/index.js +22 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/inspectMerges.command.js +84 -0
- package/dist/cli/commands/inspectMerges.command.js.map +1 -0
- package/dist/cli/commands/metrics.command.js +196 -0
- package/dist/cli/commands/metrics.command.js.map +1 -0
- package/dist/cli/commands/process.command.js +82 -0
- package/dist/cli/commands/process.command.js.map +1 -0
- package/dist/cli/commands/watch.command.js +91 -0
- package/dist/cli/commands/watch.command.js.map +1 -0
- package/dist/cli/index.js +269 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/optionsToConfig.js +160 -0
- package/dist/cli/optionsToConfig.js.map +1 -0
- package/dist/config/index.js +59 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/legacyHints.js +113 -0
- package/dist/config/legacyHints.js.map +1 -0
- package/dist/config/schema.js +803 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/ui.js +221 -0
- package/dist/config/ui.js.map +1 -0
- package/dist/core/DirectoryProcessor.js +725 -0
- package/dist/core/DirectoryProcessor.js.map +1 -0
- package/dist/core/adapters/IStructuredAdapter.js +3 -0
- package/dist/core/adapters/IStructuredAdapter.js.map +1 -0
- package/dist/core/adapters/SqliteAdapter.js +267 -0
- package/dist/core/adapters/SqliteAdapter.js.map +1 -0
- package/dist/core/adapters/StructuredAdapterRegistry.js +31 -0
- package/dist/core/adapters/StructuredAdapterRegistry.js.map +1 -0
- package/dist/core/adapters/index.js +20 -0
- package/dist/core/adapters/index.js.map +1 -0
- package/dist/core/checkpoint/CheckpointService.js +188 -0
- package/dist/core/checkpoint/CheckpointService.js.map +1 -0
- package/dist/core/checkpoint/index.js +18 -0
- package/dist/core/checkpoint/index.js.map +1 -0
- package/dist/core/corpus/CorpusAnalyzer.js +266 -0
- package/dist/core/corpus/CorpusAnalyzer.js.map +1 -0
- package/dist/core/corpus/CorpusProfileStore.js +92 -0
- package/dist/core/corpus/CorpusProfileStore.js.map +1 -0
- package/dist/core/corpus/index.js +21 -0
- package/dist/core/corpus/index.js.map +1 -0
- package/dist/core/corpus/normalizeGlossary.js +60 -0
- package/dist/core/corpus/normalizeGlossary.js.map +1 -0
- package/dist/core/corpus/relPath.js +52 -0
- package/dist/core/corpus/relPath.js.map +1 -0
- package/dist/core/corpus/termFrequency.js +86 -0
- package/dist/core/corpus/termFrequency.js.map +1 -0
- package/dist/core/cost/CostMeter.js +235 -0
- package/dist/core/cost/CostMeter.js.map +1 -0
- package/dist/core/cost/index.js +19 -0
- package/dist/core/cost/index.js.map +1 -0
- package/dist/core/cost/prices.js +38 -0
- package/dist/core/cost/prices.js.map +1 -0
- package/dist/core/cv/ObjectDetectionService.js +119 -0
- package/dist/core/cv/ObjectDetectionService.js.map +1 -0
- package/dist/core/di/ContainerFactory.js +670 -0
- package/dist/core/di/ContainerFactory.js.map +1 -0
- package/dist/core/di/DIContainer.js +103 -0
- package/dist/core/di/DIContainer.js.map +1 -0
- package/dist/core/di/index.js +19 -0
- package/dist/core/di/index.js.map +1 -0
- package/dist/core/errors/CustomErrors.js +342 -0
- package/dist/core/errors/CustomErrors.js.map +1 -0
- package/dist/core/errors/index.js +18 -0
- package/dist/core/errors/index.js.map +1 -0
- package/dist/core/export/KnowledgeGraphExportService.js +56 -0
- package/dist/core/export/KnowledgeGraphExportService.js.map +1 -0
- package/dist/core/export/index.js +19 -0
- package/dist/core/export/index.js.map +1 -0
- package/dist/core/export/strategies/GraphitiExportStrategy.js +115 -0
- package/dist/core/export/strategies/GraphitiExportStrategy.js.map +1 -0
- package/dist/core/export/strategies/GraphvizDotExportStrategy.js +331 -0
- package/dist/core/export/strategies/GraphvizDotExportStrategy.js.map +1 -0
- package/dist/core/export/strategies/IExportStrategy.js +3 -0
- package/dist/core/export/strategies/IExportStrategy.js.map +1 -0
- package/dist/core/export/strategies/JsonExportStrategy.js +19 -0
- package/dist/core/export/strategies/JsonExportStrategy.js.map +1 -0
- package/dist/core/export/strategies/JsonlExportStrategy.js +69 -0
- package/dist/core/export/strategies/JsonlExportStrategy.js.map +1 -0
- package/dist/core/export/strategies/KblamExportStrategy.js +36 -0
- package/dist/core/export/strategies/KblamExportStrategy.js.map +1 -0
- package/dist/core/export/strategies/LoraExportStrategy.js +46 -0
- package/dist/core/export/strategies/LoraExportStrategy.js.map +1 -0
- package/dist/core/export/strategies/McpExportStrategy.js +67 -0
- package/dist/core/export/strategies/McpExportStrategy.js.map +1 -0
- package/dist/core/export/strategies/index.js +25 -0
- package/dist/core/export/strategies/index.js.map +1 -0
- package/dist/core/export/strategies/kbTriples.js +60 -0
- package/dist/core/export/strategies/kbTriples.js.map +1 -0
- package/dist/core/index.js +22 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/knowledge/KnowledgeGraphBuilder.js +627 -0
- package/dist/core/knowledge/KnowledgeGraphBuilder.js.map +1 -0
- package/dist/core/knowledge/MergeRecord.js +3 -0
- package/dist/core/knowledge/MergeRecord.js.map +1 -0
- package/dist/core/knowledge/canon/Canonicalizer.js +414 -0
- package/dist/core/knowledge/canon/Canonicalizer.js.map +1 -0
- package/dist/core/knowledge/canon/index.js +18 -0
- package/dist/core/knowledge/canon/index.js.map +1 -0
- package/dist/core/knowledge/contradiction/HeuristicContradictionChecker.js +92 -0
- package/dist/core/knowledge/contradiction/HeuristicContradictionChecker.js.map +1 -0
- package/dist/core/knowledge/contradiction/LlmContradictionChecker.js +52 -0
- package/dist/core/knowledge/contradiction/LlmContradictionChecker.js.map +1 -0
- package/dist/core/knowledge/contradiction/index.js +19 -0
- package/dist/core/knowledge/contradiction/index.js.map +1 -0
- package/dist/core/knowledge/grounding/KeywordGroundingChecker.js +33 -0
- package/dist/core/knowledge/grounding/KeywordGroundingChecker.js.map +1 -0
- package/dist/core/knowledge/grounding/MiniCheckGroundingChecker.js +82 -0
- package/dist/core/knowledge/grounding/MiniCheckGroundingChecker.js.map +1 -0
- package/dist/core/knowledge/grounding/index.js +20 -0
- package/dist/core/knowledge/grounding/index.js.map +1 -0
- package/dist/core/knowledge/grounding/verbalize.js +38 -0
- package/dist/core/knowledge/grounding/verbalize.js.map +1 -0
- package/dist/core/knowledge/images/imageMetaGraph.js +136 -0
- package/dist/core/knowledge/images/imageMetaGraph.js.map +1 -0
- package/dist/core/knowledge/index.js +20 -0
- package/dist/core/knowledge/index.js.map +1 -0
- package/dist/core/knowledge/merging/KnowledgeMerger.js +624 -0
- package/dist/core/knowledge/merging/KnowledgeMerger.js.map +1 -0
- package/dist/core/knowledge/references/ReferenceResolver.js +184 -0
- package/dist/core/knowledge/references/ReferenceResolver.js.map +1 -0
- package/dist/core/knowledge/references/citations/CitationEvidenceProcessor.js +401 -0
- package/dist/core/knowledge/references/citations/CitationEvidenceProcessor.js.map +1 -0
- package/dist/core/knowledge/references/citations/CitationResolver.js +95 -0
- package/dist/core/knowledge/references/citations/CitationResolver.js.map +1 -0
- package/dist/core/knowledge/references/citations/GrobidClient.js +143 -0
- package/dist/core/knowledge/references/citations/GrobidClient.js.map +1 -0
- package/dist/core/knowledge/references/citations/TitleIdResolver.js +101 -0
- package/dist/core/knowledge/references/citations/TitleIdResolver.js.map +1 -0
- package/dist/core/knowledge/references/web/FetchCacheService.js +114 -0
- package/dist/core/knowledge/references/web/FetchCacheService.js.map +1 -0
- package/dist/core/knowledge/references/web/GatedFetcher.js +228 -0
- package/dist/core/knowledge/references/web/GatedFetcher.js.map +1 -0
- package/dist/core/knowledge/references/web/WebReferenceProcessor.js +164 -0
- package/dist/core/knowledge/references/web/WebReferenceProcessor.js.map +1 -0
- package/dist/core/knowledge/search/KnowledgeGraphSearch.js +261 -0
- package/dist/core/knowledge/search/KnowledgeGraphSearch.js.map +1 -0
- package/dist/core/knowledge/vocabulary.js +162 -0
- package/dist/core/knowledge/vocabulary.js.map +1 -0
- package/dist/core/llm/EmbeddingService.js +113 -0
- package/dist/core/llm/EmbeddingService.js.map +1 -0
- package/dist/core/llm/OllamaService.js +146 -0
- package/dist/core/llm/OllamaService.js.map +1 -0
- package/dist/core/llm/OpenAICompatibleService.js +190 -0
- package/dist/core/llm/OpenAICompatibleService.js.map +1 -0
- package/dist/core/llm/OpenAIEmbeddingService.js +129 -0
- package/dist/core/llm/OpenAIEmbeddingService.js.map +1 -0
- package/dist/core/llm/embeddingUtils.js +25 -0
- package/dist/core/llm/embeddingUtils.js.map +1 -0
- package/dist/core/llm/index.js +23 -0
- package/dist/core/llm/index.js.map +1 -0
- package/dist/core/llm/prompts/PromptManager.js +388 -0
- package/dist/core/llm/prompts/PromptManager.js.map +1 -0
- package/dist/core/llm/prompts/PromptTemplateEngine.js +257 -0
- package/dist/core/llm/prompts/PromptTemplateEngine.js.map +1 -0
- package/dist/core/llm/prompts/templates/partials/examples/EXAMPLE_STYLE_GUIDE.md +84 -0
- package/dist/core/llm/prompts/templates/partials/examples/article.md +187 -0
- package/dist/core/llm/prompts/templates/partials/examples/code.md +229 -0
- package/dist/core/llm/prompts/templates/partials/examples/communication.md +205 -0
- package/dist/core/llm/prompts/templates/partials/examples/documentation.md +262 -0
- package/dist/core/llm/prompts/templates/partials/examples/financial.md +157 -0
- package/dist/core/llm/prompts/templates/partials/examples/legal.md +153 -0
- package/dist/core/llm/prompts/templates/partials/examples/logs.md +127 -0
- package/dist/core/llm/prompts/templates/partials/examples/medical.md +218 -0
- package/dist/core/llm/prompts/templates/partials/examples/notes.md +201 -0
- package/dist/core/llm/prompts/templates/partials/examples/research.md +208 -0
- package/dist/core/llm/prompts/templates/partials/examples/tabular.md +178 -0
- package/dist/core/llm/prompts/templates/partials/examples/transcript.md +204 -0
- package/dist/core/llm/prompts/templates/partials/retrieved-context.hbs +18 -0
- package/dist/core/llm/prompts/templates/v1/system.hbs +371 -0
- package/dist/core/llm/prompts/templates/v1/user.hbs +20 -0
- package/dist/core/llm/prompts/templates/v2/system.hbs +573 -0
- package/dist/core/llm/prompts/templates/v2/user.hbs +20 -0
- package/dist/core/llm/prompts/templates/v3/system.hbs +861 -0
- package/dist/core/llm/prompts/templates/v3/user.hbs +16 -0
- package/dist/core/llm/prompts/templates/v4/system.hbs +800 -0
- package/dist/core/llm/prompts/templates/v4/user.hbs +40 -0
- package/dist/core/llm/prompts/templates/v4.5/system.hbs +71 -0
- package/dist/core/llm/prompts/templates/v4.5/user.hbs +46 -0
- package/dist/core/llm/prompts/templates/v5/glossary/system.hbs +40 -0
- package/dist/core/llm/prompts/templates/v5/glossary/user.hbs +11 -0
- package/dist/core/llm/prompts/templates/v5/system.hbs +163 -0
- package/dist/core/llm/prompts/templates/v5/user.hbs +55 -0
- package/dist/core/pipeline/GroundingTransform.js +52 -0
- package/dist/core/pipeline/GroundingTransform.js.map +1 -0
- package/dist/core/pipeline/PipelineRunner.js +51 -0
- package/dist/core/pipeline/PipelineRunner.js.map +1 -0
- package/dist/core/pipeline/RelationFilterTransform.js +72 -0
- package/dist/core/pipeline/RelationFilterTransform.js.map +1 -0
- package/dist/core/pipeline/index.js +20 -0
- package/dist/core/pipeline/index.js.map +1 -0
- package/dist/core/processor/FileProcessor.js +184 -0
- package/dist/core/processor/FileProcessor.js.map +1 -0
- package/dist/core/processor/ProcessedRegistry.js +38 -0
- package/dist/core/processor/ProcessedRegistry.js.map +1 -0
- package/dist/core/processor/ast/AstSeedService.js +0 -0
- package/dist/core/processor/ast/AstSeedService.js.map +1 -0
- package/dist/core/processor/ast/AstSymbolStore.js +110 -0
- package/dist/core/processor/ast/AstSymbolStore.js.map +1 -0
- package/dist/core/processor/ast/index.js +19 -0
- package/dist/core/processor/ast/index.js.map +1 -0
- package/dist/core/processor/chunking/TextChunker.js +98 -0
- package/dist/core/processor/chunking/TextChunker.js.map +1 -0
- package/dist/core/processor/chunking/index.js +18 -0
- package/dist/core/processor/chunking/index.js.map +1 -0
- package/dist/core/processor/classifier/CONTENT_CLASSES.js +294 -0
- package/dist/core/processor/classifier/CONTENT_CLASSES.js.map +1 -0
- package/dist/core/processor/classifier/CascadeContentClassifier.js +107 -0
- package/dist/core/processor/classifier/CascadeContentClassifier.js.map +1 -0
- package/dist/core/processor/classifier/HeuristicContentClassifier.js +113 -0
- package/dist/core/processor/classifier/HeuristicContentClassifier.js.map +1 -0
- package/dist/core/processor/classifier/IContentTypeClassifier.js +3 -0
- package/dist/core/processor/classifier/IContentTypeClassifier.js.map +1 -0
- package/dist/core/processor/classifier/LlmContentClassifier.js +107 -0
- package/dist/core/processor/classifier/LlmContentClassifier.js.map +1 -0
- package/dist/core/processor/classifier/NER_DOMAIN_EXAMPLES.js +498 -0
- package/dist/core/processor/classifier/NER_DOMAIN_EXAMPLES.js.map +1 -0
- package/dist/core/processor/classifier/index.js +21 -0
- package/dist/core/processor/classifier/index.js.map +1 -0
- package/dist/core/processor/classifier/mergeClassifications.js +32 -0
- package/dist/core/processor/classifier/mergeClassifications.js.map +1 -0
- package/dist/core/processor/index.js +20 -0
- package/dist/core/processor/index.js.map +1 -0
- package/dist/core/processor/readers/AudioReader.js +462 -0
- package/dist/core/processor/readers/AudioReader.js.map +1 -0
- package/dist/core/processor/readers/BinaryReader.js +90 -0
- package/dist/core/processor/readers/BinaryReader.js.map +1 -0
- package/dist/core/processor/readers/ChandraPdfReader.js +187 -0
- package/dist/core/processor/readers/ChandraPdfReader.js.map +1 -0
- package/dist/core/processor/readers/ChatExportReader.js +365 -0
- package/dist/core/processor/readers/ChatExportReader.js.map +1 -0
- package/dist/core/processor/readers/DoclingReader.js +445 -0
- package/dist/core/processor/readers/DoclingReader.js.map +1 -0
- package/dist/core/processor/readers/EmailReader.js +259 -0
- package/dist/core/processor/readers/EmailReader.js.map +1 -0
- package/dist/core/processor/readers/EpubReader.js +175 -0
- package/dist/core/processor/readers/EpubReader.js.map +1 -0
- package/dist/core/processor/readers/FileReader.js +90 -0
- package/dist/core/processor/readers/FileReader.js.map +1 -0
- package/dist/core/processor/readers/FileReaderFactory.js +49 -0
- package/dist/core/processor/readers/FileReaderFactory.js.map +1 -0
- package/dist/core/processor/readers/HtmlReader.js +371 -0
- package/dist/core/processor/readers/HtmlReader.js.map +1 -0
- package/dist/core/processor/readers/ImageReader.js +162 -0
- package/dist/core/processor/readers/ImageReader.js.map +1 -0
- package/dist/core/processor/readers/JsonFileReader.js +232 -0
- package/dist/core/processor/readers/JsonFileReader.js.map +1 -0
- package/dist/core/processor/readers/JupyterReader.js +178 -0
- package/dist/core/processor/readers/JupyterReader.js.map +1 -0
- package/dist/core/processor/readers/LatexReader.js +176 -0
- package/dist/core/processor/readers/LatexReader.js.map +1 -0
- package/dist/core/processor/readers/MarkdownReader.js +289 -0
- package/dist/core/processor/readers/MarkdownReader.js.map +1 -0
- package/dist/core/processor/readers/MarkerPdfReader.js +193 -0
- package/dist/core/processor/readers/MarkerPdfReader.js.map +1 -0
- package/dist/core/processor/readers/MistralOcrReader.js +198 -0
- package/dist/core/processor/readers/MistralOcrReader.js.map +1 -0
- package/dist/core/processor/readers/OfficeReader.js +174 -0
- package/dist/core/processor/readers/OfficeReader.js.map +1 -0
- package/dist/core/processor/readers/PdfReader.js +116 -0
- package/dist/core/processor/readers/PdfReader.js.map +1 -0
- package/dist/core/processor/readers/RtfReader.js +107 -0
- package/dist/core/processor/readers/RtfReader.js.map +1 -0
- package/dist/core/processor/readers/SubtitleReader.js +145 -0
- package/dist/core/processor/readers/SubtitleReader.js.map +1 -0
- package/dist/core/processor/readers/TesseractPdfReader.js +183 -0
- package/dist/core/processor/readers/TesseractPdfReader.js.map +1 -0
- package/dist/core/processor/readers/TextReader.js +129 -0
- package/dist/core/processor/readers/TextReader.js.map +1 -0
- package/dist/core/processor/readers/TranscriptReader.js +234 -0
- package/dist/core/processor/readers/TranscriptReader.js.map +1 -0
- package/dist/core/processor/readers/image/imageMetadata.js +155 -0
- package/dist/core/processor/readers/image/imageMetadata.js.map +1 -0
- package/dist/core/processor/readers/index.js +41 -0
- package/dist/core/processor/readers/index.js.map +1 -0
- package/dist/core/processor/readers/referenceExtraction.js +198 -0
- package/dist/core/processor/readers/referenceExtraction.js.map +1 -0
- package/dist/core/processor/readers/stripReferences.js +59 -0
- package/dist/core/processor/readers/stripReferences.js.map +1 -0
- package/dist/core/processor/readers/transcript/turnPacking.js +81 -0
- package/dist/core/processor/readers/transcript/turnPacking.js.map +1 -0
- package/dist/core/progress/NdjsonProgressEmitter.js +30 -0
- package/dist/core/progress/NdjsonProgressEmitter.js.map +1 -0
- package/dist/core/progress/NoopProgressEmitter.js +15 -0
- package/dist/core/progress/NoopProgressEmitter.js.map +1 -0
- package/dist/core/progress/index.js +19 -0
- package/dist/core/progress/index.js.map +1 -0
- package/dist/core/trace/TraceWriter.js +100 -0
- package/dist/core/trace/TraceWriter.js.map +1 -0
- package/dist/core/trace/events.js +13 -0
- package/dist/core/trace/events.js.map +1 -0
- package/dist/core/trace/index.js +20 -0
- package/dist/core/trace/index.js.map +1 -0
- package/dist/core/trace/lineage.js +97 -0
- package/dist/core/trace/lineage.js.map +1 -0
- package/dist/evaluation/BenchmarkRunner.js +171 -0
- package/dist/evaluation/BenchmarkRunner.js.map +1 -0
- package/dist/evaluation/classifier/ClassifierAccuracy.js +185 -0
- package/dist/evaluation/classifier/ClassifierAccuracy.js.map +1 -0
- package/dist/evaluation/classifier/labeledSamples.js +379 -0
- package/dist/evaluation/classifier/labeledSamples.js.map +1 -0
- package/dist/evaluation/compare/goldCompare.js +126 -0
- package/dist/evaluation/compare/goldCompare.js.map +1 -0
- package/dist/evaluation/crossre/compareScoring.js +30 -0
- package/dist/evaluation/crossre/compareScoring.js.map +1 -0
- package/dist/evaluation/datasets/CrossREDataset.js +170 -0
- package/dist/evaluation/datasets/CrossREDataset.js.map +1 -0
- package/dist/evaluation/datasets/IDataset.js +3 -0
- package/dist/evaluation/datasets/IDataset.js.map +1 -0
- package/dist/evaluation/datasets/RebelDataset.js +117 -0
- package/dist/evaluation/datasets/RebelDataset.js.map +1 -0
- package/dist/evaluation/datasets/RedocredDataset.js +218 -0
- package/dist/evaluation/datasets/RedocredDataset.js.map +1 -0
- package/dist/evaluation/datasets/SemEval2010Dataset.js +150 -0
- package/dist/evaluation/datasets/SemEval2010Dataset.js.map +1 -0
- package/dist/evaluation/index.js +33 -0
- package/dist/evaluation/index.js.map +1 -0
- package/dist/evaluation/matching/ExactMatcher.js +75 -0
- package/dist/evaluation/matching/ExactMatcher.js.map +1 -0
- package/dist/evaluation/matching/SemanticMatcher.js +143 -0
- package/dist/evaluation/matching/SemanticMatcher.js.map +1 -0
- package/dist/evaluation/metrics/TripleMetrics.js +64 -0
- package/dist/evaluation/metrics/TripleMetrics.js.map +1 -0
- package/dist/evaluation/mine/MineCheckpoint.js +114 -0
- package/dist/evaluation/mine/MineCheckpoint.js.map +1 -0
- package/dist/evaluation/mine/MineDataset.js +208 -0
- package/dist/evaluation/mine/MineDataset.js.map +1 -0
- package/dist/evaluation/mine/MineReporter.js +98 -0
- package/dist/evaluation/mine/MineReporter.js.map +1 -0
- package/dist/evaluation/mine/MineRunner.js +148 -0
- package/dist/evaluation/mine/MineRunner.js.map +1 -0
- package/dist/evaluation/mine/MineScorer.js +127 -0
- package/dist/evaluation/mine/MineScorer.js.map +1 -0
- package/dist/evaluation/mine/types.js +12 -0
- package/dist/evaluation/mine/types.js.map +1 -0
- package/dist/evaluation/reporters/ConsoleReporter.js +55 -0
- package/dist/evaluation/reporters/ConsoleReporter.js.map +1 -0
- package/dist/evaluation/reporters/JsonReporter.js +50 -0
- package/dist/evaluation/reporters/JsonReporter.js.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/quality/CompositeScore.js +61 -0
- package/dist/quality/CompositeScore.js.map +1 -0
- package/dist/quality/ConsistencyMetrics.js +70 -0
- package/dist/quality/ConsistencyMetrics.js.map +1 -0
- package/dist/quality/FactualMetrics.js +76 -0
- package/dist/quality/FactualMetrics.js.map +1 -0
- package/dist/quality/GraphHealthMetrics.js +68 -0
- package/dist/quality/GraphHealthMetrics.js.map +1 -0
- package/dist/quality/SemanticMetrics.js +102 -0
- package/dist/quality/SemanticMetrics.js.map +1 -0
- package/dist/quality/StructuralMetrics.js +60 -0
- package/dist/quality/StructuralMetrics.js.map +1 -0
- package/dist/quality/index.js +23 -0
- package/dist/quality/index.js.map +1 -0
- package/dist/shared/index.js +20 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/logger/Logger.js +3 -0
- package/dist/shared/logger/Logger.js.map +1 -0
- package/dist/shared/logger/LoggerFactory.js +75 -0
- package/dist/shared/logger/LoggerFactory.js.map +1 -0
- package/dist/shared/logger/index.js +19 -0
- package/dist/shared/logger/index.js.map +1 -0
- package/dist/shared/shutdown.js +30 -0
- package/dist/shared/shutdown.js.map +1 -0
- package/dist/shared/utils/agglomerativeCluster.js +269 -0
- package/dist/shared/utils/agglomerativeCluster.js.map +1 -0
- package/dist/shared/utils/astSymbols.js +69 -0
- package/dist/shared/utils/astSymbols.js.map +1 -0
- package/dist/shared/utils/cosineSimilarity.js +18 -0
- package/dist/shared/utils/cosineSimilarity.js.map +1 -0
- package/dist/shared/utils/directoryTree.js +184 -0
- package/dist/shared/utils/directoryTree.js.map +1 -0
- package/dist/shared/utils/documentOutline.js +74 -0
- package/dist/shared/utils/documentOutline.js.map +1 -0
- package/dist/shared/utils/index.js +24 -0
- package/dist/shared/utils/index.js.map +1 -0
- package/dist/shared/utils/jaroWinklerSimilarity.js +60 -0
- package/dist/shared/utils/jaroWinklerSimilarity.js.map +1 -0
- package/dist/shared/utils/parseJsonLenient.js +27 -0
- package/dist/shared/utils/parseJsonLenient.js.map +1 -0
- package/dist/shared/utils/readConfig.js +42 -0
- package/dist/shared/utils/readConfig.js.map +1 -0
- package/dist/shared/utils/readRtf.js +216 -0
- package/dist/shared/utils/readRtf.js.map +1 -0
- package/dist/shared/utils/softmax.js +26 -0
- package/dist/shared/utils/softmax.js.map +1 -0
- package/dist/types/ContentClass.js +3 -0
- package/dist/types/ContentClass.js.map +1 -0
- package/dist/types/CorpusProfile.js +3 -0
- package/dist/types/CorpusProfile.js.map +1 -0
- package/dist/types/IContradictionChecker.js +3 -0
- package/dist/types/IContradictionChecker.js.map +1 -0
- package/dist/types/ICorpusAnalyzer.js +3 -0
- package/dist/types/ICorpusAnalyzer.js.map +1 -0
- package/dist/types/IDirectoryProcessor.js +3 -0
- package/dist/types/IDirectoryProcessor.js.map +1 -0
- package/dist/types/IEmbeddingProvider.js +3 -0
- package/dist/types/IEmbeddingProvider.js.map +1 -0
- package/dist/types/IEmbeddingService.js +6 -0
- package/dist/types/IEmbeddingService.js.map +1 -0
- package/dist/types/IFileProcessor.js +3 -0
- package/dist/types/IFileProcessor.js.map +1 -0
- package/dist/types/IGroundingChecker.js +3 -0
- package/dist/types/IGroundingChecker.js.map +1 -0
- package/dist/types/IKnowledgeGraphBuilder.js +3 -0
- package/dist/types/IKnowledgeGraphBuilder.js.map +1 -0
- package/dist/types/IKnowledgeGraphExporter.js +3 -0
- package/dist/types/IKnowledgeGraphExporter.js.map +1 -0
- package/dist/types/IKnowledgeGraphMerger.js +3 -0
- package/dist/types/IKnowledgeGraphMerger.js.map +1 -0
- package/dist/types/IKnowledgeGraphSearch.js +3 -0
- package/dist/types/IKnowledgeGraphSearch.js.map +1 -0
- package/dist/types/ILLMProvider.js +3 -0
- package/dist/types/ILLMProvider.js.map +1 -0
- package/dist/types/ILLMService.js +3 -0
- package/dist/types/ILLMService.js.map +1 -0
- package/dist/types/IObjectDetector.js +3 -0
- package/dist/types/IObjectDetector.js.map +1 -0
- package/dist/types/IProcessingService.js +3 -0
- package/dist/types/IProcessingService.js.map +1 -0
- package/dist/types/IProgressEmitter.js +3 -0
- package/dist/types/IProgressEmitter.js.map +1 -0
- package/dist/types/IPromptManager.js +3 -0
- package/dist/types/IPromptManager.js.map +1 -0
- package/dist/types/KnowledgeGraph.js +3 -0
- package/dist/types/KnowledgeGraph.js.map +1 -0
- package/dist/types/MCPKnowledgeGraph.js +3 -0
- package/dist/types/MCPKnowledgeGraph.js.map +1 -0
- package/dist/types/Observation.js +21 -0
- package/dist/types/Observation.js.map +1 -0
- package/dist/types/ProcessingOptions.js +3 -0
- package/dist/types/ProcessingOptions.js.map +1 -0
- package/dist/types/index.js +40 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +122 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alex Sabaka
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
# wanshi
|
|
2
|
+
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/readme-banner-dark.png">
|
|
5
|
+
<source media="(prefers-color-scheme: light)" srcset="docs/assets/readme-banner-light.png">
|
|
6
|
+
<img alt="wanshi" src="docs/assets/readme-banner-light.png">
|
|
7
|
+
</picture>
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
> A local-first CLI that reads ten thousand things — code, docs, PDFs, audio, transcripts — and builds one knowledge graph that remembers where every fact came from.
|
|
11
|
+
|
|
12
|
+
`wanshi` extracts entities and relations from a file tree and merges them into a single graph. It runs on local models via [Ollama](https://ollama.ai) by default, or any OpenAI-compatible endpoint. Facts carry provenance and a bi-temporal axis, an inline grounding gate filters ungrounded claims, and the graph is a drop-in producer for the MCP memory server, Graphiti, and KBLaM/LoRA training exports.
|
|
13
|
+
|
|
14
|
+
It's a working CLI and a research platform in equal measure — the long game is domain-tuned extraction feeding knowledge injection into small local models.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
> **Command shorthand:** examples below write `wanshi` for the run command. Until the npm package ships, that's `npx ts-node ./src/index.ts` (dev) or `node ./dist/index.js` (built). Once published, it's literally `wanshi`.
|
|
19
|
+
|
|
20
|
+
## What's distinctive
|
|
21
|
+
|
|
22
|
+
Most text→KG tools stop at "extract triples." `wanshi` is built around the parts that come after:
|
|
23
|
+
|
|
24
|
+
- **Provenance, not just facts.** Every observation records its `source`/`speaker` and a Graphiti-style bi-temporal axis (`validAt`/`invalidAt` for world-time, `createdAt`/`expiredAt` for system-time). The same fact from two speakers stays as two attributed observations, never one flattened string.
|
|
25
|
+
- **A grounding gate.** Each extracted fact is scored against its source chunk and can be flagged or dropped before it reaches the output — keyword overlap as a cheap pre-filter, with an optional local NLI checker (MiniCheck) for the uncertain cases. It won't record what it can't verify against the source.
|
|
26
|
+
- **Closed-vocabulary extraction.** An optional corpus pre-pass builds a glossary of canonical entity/relation types, which then *constrains* extraction — so a large corpus doesn't fragment into hundreds of one-off types.
|
|
27
|
+
- **Transcript-aware ingestion.** Speaker-labeled transcripts and chat exports are split into speaker-pure chunks, so a speaker becomes per-fact provenance rather than a polluting entity.
|
|
28
|
+
- **Memory-store interop.** `mcp-jsonl` output is byte-compatible with the official [MCP memory server](https://github.com/modelcontextprotocol/servers/tree/main/src/memory) — point it at the file and query your graph from Claude Code/Desktop. No store to build.
|
|
29
|
+
- **Training-data exports.** Emit KBLaM `(entity, property, value)` triples or quality-filtered LoRA/SFT chat examples straight from a graph.
|
|
30
|
+
- **Resumable runs.** Per-chunk checkpoints survive interrupts and exhausted API credits; re-run the same command to continue.
|
|
31
|
+
|
|
32
|
+
## Supported inputs
|
|
33
|
+
|
|
34
|
+
| Format | Extensions | Handling |
|
|
35
|
+
| ------ | ---------- | -------- |
|
|
36
|
+
| Text / source code | `.txt`, `.ts`, `.js`, `.py`, `.go`, `.rs`, … | Direct / code-aware extraction |
|
|
37
|
+
| Markdown | `.md` | Markdown-aware parsing |
|
|
38
|
+
| Transcripts | speaker-labeled `*.parakeet.txt`/`*.whisper.txt`, transcript/turn JSON, Claude/ChatGPT exports | Speaker-pure chunks with per-fact `speaker`/`occurredAt` |
|
|
39
|
+
| JSON | `.json`, `.jsonl`, `.geojson` | Structure-aware chunking (splits on JSON structure, never mid-object) |
|
|
40
|
+
| PDF | `.pdf` | Page text (`pdf2json`), or a richer engine via `--pdf-engine docling\|marker\|mistral` |
|
|
41
|
+
| Office | `.docx`, `.xlsx`, `.pptx` | Via officeparser |
|
|
42
|
+
| HTML / RTF | `.html`, `.htm`, `.rtf` | cheerio / RTF parsing |
|
|
43
|
+
| Images | `.jpg`, `.png`, `.gif`, `.webp`, `.tiff`, `.heic`, `.avif` | Vision model required |
|
|
44
|
+
| Audio / Video | `.mp3`, `.wav`, `.m4a`, `.flac`, `.mp4`, `.mkv`, `.webm`, … | Whisper transcription, or `--asr-engine dual` (VAD + dual-STT + diarization) |
|
|
45
|
+
|
|
46
|
+
## Install
|
|
47
|
+
|
|
48
|
+
Requires **Node.js 18+** and **[Ollama](https://ollama.ai)** running locally (needed for the default local generation + embeddings path; optional only if you point *both* at an OpenAI-compatible provider).
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
git clone https://github.com/wanshi-kg/wanshi
|
|
52
|
+
cd wanshi
|
|
53
|
+
npm install
|
|
54
|
+
|
|
55
|
+
# Default local models
|
|
56
|
+
ollama pull llama3.2 # generation
|
|
57
|
+
ollama pull nomic-embed-text # embeddings
|
|
58
|
+
|
|
59
|
+
npm run build # optional; ts-node works directly
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Quick start
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Process a directory with defaults
|
|
66
|
+
wanshi -i ./my-project -o knowledge-graph.json
|
|
67
|
+
|
|
68
|
+
# Pick a model and output format
|
|
69
|
+
wanshi -i ./src -m qwen3:8b --export-format jsonl -o kg.jsonl
|
|
70
|
+
|
|
71
|
+
# Config file (recommended for anything non-trivial)
|
|
72
|
+
wanshi --config config.yaml
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Configuration
|
|
76
|
+
|
|
77
|
+
The config file uses a **nested** shape (the source of truth is the Zod schema in `src/config/`); CLI flags stay flat. Run `wanshi schema` to print the full JSON Schema.
|
|
78
|
+
|
|
79
|
+
```yaml
|
|
80
|
+
input: ./my-project
|
|
81
|
+
filter: ["**/*.ts", "**/*.md"]
|
|
82
|
+
exclude: ["**/node_modules/**", "**/dist/**"]
|
|
83
|
+
output: knowledge-graph.jsonl
|
|
84
|
+
description: "TypeScript project source code"
|
|
85
|
+
|
|
86
|
+
llm:
|
|
87
|
+
provider: ollama # ollama | openai (OpenAI-compatible)
|
|
88
|
+
model: gemma3:4b
|
|
89
|
+
host: http://localhost:11434
|
|
90
|
+
contextLength: 12000
|
|
91
|
+
temperature: 0.1
|
|
92
|
+
|
|
93
|
+
embeddings: # independent from generation — keep local & free
|
|
94
|
+
provider: ollama
|
|
95
|
+
model: nomic-embed-text
|
|
96
|
+
host: http://localhost:11434
|
|
97
|
+
|
|
98
|
+
chunking: { mode: enabled, size: 4000, overlap: 100 }
|
|
99
|
+
retrieval: { mode: enabled, limit: 3 }
|
|
100
|
+
|
|
101
|
+
merging:
|
|
102
|
+
enableSimilarityMerging: true
|
|
103
|
+
entitySimilarityThreshold: 0.9
|
|
104
|
+
observationSimilarityThreshold: 0.7
|
|
105
|
+
|
|
106
|
+
export: { format: jsonl }
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Cloud generation + resume
|
|
110
|
+
|
|
111
|
+
Point generation at any OpenAI-compatible endpoint (`provider: openai`, `host` = base URL), keep embeddings local so dedup/merge stays free, and enable `resume` so an interrupted run continues without reprocessing.
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
llm:
|
|
115
|
+
provider: openai
|
|
116
|
+
host: https://openrouter.ai/api/v1
|
|
117
|
+
apiKey: sk-or-... # or $OPENAI_API_KEY / $WANSHI_API_KEY
|
|
118
|
+
model: google/gemma-3-27b-it
|
|
119
|
+
embeddings:
|
|
120
|
+
provider: ollama
|
|
121
|
+
model: nomic-embed-text
|
|
122
|
+
resume:
|
|
123
|
+
enabled: true # writes <output>.checkpoint.jsonl
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
If the run dies mid-way, just run the same command again — finished chunks are skipped. **Ctrl+C once** finishes the in-flight chunk, checkpoints it, and writes the partial graph before exiting; press again to force-quit.
|
|
127
|
+
|
|
128
|
+
A chunk is reused only when its **file content, chunk size/overlap, model, and prompt version** all match — these are folded into the checkpoint key. Files are keyed by path *relative to `--input`*, so relocating the whole tree keeps checkpoints valid; only editing a file re-runs it.
|
|
129
|
+
|
|
130
|
+
### Other modes
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# Watch: update the graph as files change
|
|
134
|
+
wanshi --config config.yaml --watch
|
|
135
|
+
|
|
136
|
+
# Multimedia (images + audio transcription)
|
|
137
|
+
wanshi -i ./media --images enabled --asr enabled --whisper-model medium -m llava:7b
|
|
138
|
+
|
|
139
|
+
# GraphViz DOT for visualization
|
|
140
|
+
wanshi -i ./src --export-format dot -o graph.dot && dot -Tsvg graph.dot -o graph.svg
|
|
141
|
+
|
|
142
|
+
# Re-export an existing graph (no LLM calls)
|
|
143
|
+
wanshi --export-only -i ./knowledge-graph.json --export-format kblam -o ./kb.jsonl
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## CLI reference
|
|
147
|
+
|
|
148
|
+
### Core
|
|
149
|
+
|
|
150
|
+
| Option | Default | Description |
|
|
151
|
+
| ------ | ------- | ----------- |
|
|
152
|
+
| `-i, --input <path>` | `.` | Input directory |
|
|
153
|
+
| `-f, --filter <glob>` | `**/*` | Include pattern |
|
|
154
|
+
| `-e, --exclude <glob...>` | — | Exclude patterns |
|
|
155
|
+
| `-o, --output <path>` | `knowledge-graph.json` | Output file |
|
|
156
|
+
| `-d, --description <text>` | — | Content description for LLM context |
|
|
157
|
+
| `--config <file>` | — | YAML/JSON config file |
|
|
158
|
+
|
|
159
|
+
### LLM
|
|
160
|
+
|
|
161
|
+
| Option | Default | Description |
|
|
162
|
+
| ------ | ------- | ----------- |
|
|
163
|
+
| `--provider <name>` | `ollama` | `ollama` or `openai` (any OpenAI-compatible endpoint) |
|
|
164
|
+
| `-m, --model <name>` | `llama3.2` | Ollama tag or provider model id |
|
|
165
|
+
| `-h, --host <url>` | `http://localhost:11434` | Ollama host, or OpenAI-compatible base URL |
|
|
166
|
+
| `--api-key <key>` | — | Falls back to `$OPENAI_API_KEY` / `$WANSHI_API_KEY` |
|
|
167
|
+
| `--temperature <n>` | `0.1` | Sampling temperature |
|
|
168
|
+
| `--repeat-penalty <n>` | `1.1` | Ollama only (>1.0 discourages repetition) |
|
|
169
|
+
| `--context-length <n>` | `8192` | Context window (Ollama only) |
|
|
170
|
+
| `--max-tokens <n>` | provider default | Raise (or lower `--chunk-size`) if graph JSON truncates mid-output |
|
|
171
|
+
| `--seed <n>` | — | Reproducibility seed (Ollama only) |
|
|
172
|
+
| `-s, --system <prompt\|path>` | — | Custom system prompt or template path |
|
|
173
|
+
|
|
174
|
+
### Embeddings (independent from generation)
|
|
175
|
+
|
|
176
|
+
| Option | Default | Description |
|
|
177
|
+
| ------ | ------- | ----------- |
|
|
178
|
+
| `--embeddings-provider <name>` | `ollama` | `ollama` or `openai` |
|
|
179
|
+
| `--embeddings-model <name>` | `nomic-embed-text` | Embeddings model |
|
|
180
|
+
| `--embeddings-host <url>` | `http://localhost:11434` | Host / base URL |
|
|
181
|
+
| `--embeddings-max-input-chars <n>` | `1024` | Truncate embedding inputs (safe for 512-token models; raise for cloud) |
|
|
182
|
+
|
|
183
|
+
### Processing & retrieval
|
|
184
|
+
|
|
185
|
+
| Option | Default | Description |
|
|
186
|
+
| ------ | ------- | ----------- |
|
|
187
|
+
| `--chunking <mode>` | `enabled` | `enabled\|disabled\|auto` |
|
|
188
|
+
| `-c, --chunk-size <n>` | `2000` | Max chunk size (chars) |
|
|
189
|
+
| `--overlap-size <n>` | `100` | Chunk overlap |
|
|
190
|
+
| `--retrieval <mode>` | `enabled` | `enabled\|disabled\|auto` |
|
|
191
|
+
| `--retrieval-limit <n>` | `3` | Retrieved context entities per chunk |
|
|
192
|
+
| `--retrieval-scope <mode>` | `chunk` | `chunk` (per-chunk) or `file` (once, reused) |
|
|
193
|
+
| `--json-strategy <mode>` | `structural` | `structural` (split on JSON structure) or `raw` |
|
|
194
|
+
|
|
195
|
+
### Media & classification
|
|
196
|
+
|
|
197
|
+
| Option | Default | Description |
|
|
198
|
+
| ------ | ------- | ----------- |
|
|
199
|
+
| `--asr <mode>` | `enabled` | `enabled\|disabled\|auto` |
|
|
200
|
+
| `--whisper-model <name>` | `medium` | `tiny\|base\|small\|medium\|large` |
|
|
201
|
+
| `--language <lang>` | `auto` | Language code or `auto` |
|
|
202
|
+
| `--translate` | `false` | Translate audio to English |
|
|
203
|
+
| `--images <mode>` | `auto` | `enabled\|disabled\|auto` (vision model required) |
|
|
204
|
+
| `--pdf-engine <engine>` | `pdf2json` | `pdf2json\|docling\|marker\|mistral` — PDF reading engine (non-default engines degrade to `pdf2json` on failure) |
|
|
205
|
+
| `--asr-engine <engine>` | `whisper` | `whisper\|dual` — `dual` = vendored Python VAD + Parakeet/Whisper dual-STT + diarization (Apple-Silicon) |
|
|
206
|
+
| `--classifier <mode>` | `disabled` | `disabled\|heuristic\|llm\|cascade` — drives domain prompt hints and scopes `entityType` to a per-domain enum *(experimental)* |
|
|
207
|
+
| `--trace` | `false` | Emit a structured decision run-trace to `<output>.trace.jsonl` *(debug/observability)* |
|
|
208
|
+
|
|
209
|
+
### Merging, grounding, corpus glossary
|
|
210
|
+
|
|
211
|
+
| Option | Default | Description |
|
|
212
|
+
| ------ | ------- | ----------- |
|
|
213
|
+
| `--entity-similarity-threshold <n>` | `0.9` | Jaro-Winkler entity dedup (0–1) |
|
|
214
|
+
| `--observation-similarity-threshold <n>` | `0.9` | Embedding similarity (0–1) |
|
|
215
|
+
| `--enable-similarity-merging` | `true` | Enable entity deduplication |
|
|
216
|
+
| `--grounding <mode>` | `disabled` | `disabled` · `flag` (annotate `grounded`/`groundingScore`) · `drop` (remove below threshold) |
|
|
217
|
+
| `--grounding-min-score <n>` | `0.5` | Min grounding score; also gates which facts the `lora` export keeps |
|
|
218
|
+
| `--corpus-profiling <mode>` | `disabled` | Pre-pass that builds an authoritative corpus glossary (closed vocab under v5) *(experimental)* |
|
|
219
|
+
| `--prompt-version <version>` | `v5` | `v5` (closed-vocab + topology hygiene) or `v4.5` (legacy) |
|
|
220
|
+
|
|
221
|
+
### Export, resume, logging
|
|
222
|
+
|
|
223
|
+
| Option | Default | Description |
|
|
224
|
+
| ------ | ------- | ----------- |
|
|
225
|
+
| `--export-format <format>` | `json` | `json\|jsonl\|mcp-jsonl\|dot\|kblam\|lora\|graphiti` |
|
|
226
|
+
| `--export-only` | `false` | Convert an existing graph (`--input`) to `--export-format` — no extraction |
|
|
227
|
+
| `--resume` | `false` | Checkpoint chunks; skip done ones on re-run |
|
|
228
|
+
| `--checkpoint <path>` | `<output>.checkpoint.jsonl` | Checkpoint sidecar |
|
|
229
|
+
| `-L, --log-level <level>` | `info` | `debug\|info\|warning\|error` |
|
|
230
|
+
| `-l, --log-file <path>` | — | Write logs to file |
|
|
231
|
+
| `-w, --watch` | `false` | Watch mode |
|
|
232
|
+
|
|
233
|
+
> Document-outline injection (`readers.outline`) and DOT styling (`export.dot`) are config-only (no CLI flags) — see the config schema.
|
|
234
|
+
|
|
235
|
+
## Output formats
|
|
236
|
+
|
|
237
|
+
### JSON (`json`)
|
|
238
|
+
|
|
239
|
+
Observations are **objects**, not bare strings — each carries provenance and the bi-temporal axis. The LLM emits plain text; `wanshi` stamps the metadata deterministically from what it knows about the chunk. Unknown fields are omitted; legacy string-observation graphs still load.
|
|
240
|
+
|
|
241
|
+
```json
|
|
242
|
+
{
|
|
243
|
+
"entities": [
|
|
244
|
+
{
|
|
245
|
+
"name": "knowledge_graph_builder",
|
|
246
|
+
"entityType": "class",
|
|
247
|
+
"observations": [
|
|
248
|
+
{
|
|
249
|
+
"text": "Extracts entities and relations from file content using an LLM",
|
|
250
|
+
"source": "src/core/knowledge/KnowledgeGraphBuilder.ts",
|
|
251
|
+
"createdAt": "2026-06-05T15:57:59.856Z"
|
|
252
|
+
}
|
|
253
|
+
],
|
|
254
|
+
"files": ["src/core/knowledge/KnowledgeGraphBuilder.ts"]
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"name": "SPEAKER_01",
|
|
258
|
+
"entityType": "person",
|
|
259
|
+
"observations": [
|
|
260
|
+
{
|
|
261
|
+
"text": "Explains that a Naïve Bayes classifier assumes word independence",
|
|
262
|
+
"speaker": "SPEAKER_01",
|
|
263
|
+
"source": "Olga Lesson P.parakeet.txt",
|
|
264
|
+
"validAt": "2026-05-28T00:00:00Z",
|
|
265
|
+
"createdAt": "2026-06-05T15:57:59.856Z"
|
|
266
|
+
}
|
|
267
|
+
],
|
|
268
|
+
"files": ["Olga Lesson P.parakeet.txt"]
|
|
269
|
+
}
|
|
270
|
+
],
|
|
271
|
+
"relations": [
|
|
272
|
+
{ "from": "knowledge_graph_builder", "to": "ollama_service", "relationType": ["uses", "depends_on"] }
|
|
273
|
+
]
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### MCP-compatible JSONL (`mcp-jsonl`)
|
|
278
|
+
|
|
279
|
+
```jsonl
|
|
280
|
+
{"type":"entity","name":"knowledge_graph_builder","entityType":"class","observations":["Extracts entities and relations from file content using an LLM"]}
|
|
281
|
+
{"type":"relation","from":"knowledge_graph_builder","to":"ollama_service","relationType":"uses,depends_on"}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### GraphViz DOT (`dot`)
|
|
285
|
+
|
|
286
|
+
Styled, colored graph (one node per entity, colored edges per relation type, legend, config summary). Render with `dot -Tsvg graph.dot -o graph.svg` (or `neato`/`fdp`/`sfdp`/`circo`/`twopi`). Styling is config-only under `export.dot:` — layout, `rankdir`, `colorScheme` (`default\|scientific\|code\|minimal`), clustering by type or file, etc.
|
|
287
|
+
|
|
288
|
+
### KBLaM triples (`kblam`)
|
|
289
|
+
|
|
290
|
+
JSONL in the shape Microsoft [KBLaM](https://github.com/microsoft/KBLaM)'s `dataset_generation` ingests — **one `(entity, property, value)` per line**, each with the derived `Q`/`A`/`key_string` it encodes into a knowledge token. Property names are distinct per entity (relations contribute their predicate as the property), and keys are unique per `(name, property)` so rectangular-attention lookup is unambiguous.
|
|
291
|
+
|
|
292
|
+
```jsonl
|
|
293
|
+
{"name":"Recursion","property":"definition","value":"a function that calls itself","Q":"What is the definition of Recursion?","A":"The definition of Recursion is a function that calls itself.","key_string":"the definition of Recursion"}
|
|
294
|
+
{"name":"Recursion","property":"terminates_at","value":"BaseCase","Q":"What is the terminates_at of Recursion?","A":"The terminates_at of Recursion is BaseCase.","key_string":"the terminates_at of Recursion"}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### LoRA / SFT (`lora`)
|
|
298
|
+
|
|
299
|
+
Chat-format instruction examples derived from the same triples, **quality-filtered**: observations whose grounding score is below `--grounding-min-score` are dropped, so only grounded facts become training data.
|
|
300
|
+
|
|
301
|
+
```jsonl
|
|
302
|
+
{"messages":[{"role":"user","content":"What is the definition of Recursion?"},{"role":"assistant","content":"The definition of Recursion is a function that calls itself."}]}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Graphiti (`graphiti`)
|
|
306
|
+
|
|
307
|
+
`add_triplet`-shaped `{ nodes, edges }` for ingestion into a [Graphiti](https://github.com/getzep/graphiti) temporal graph — entities → nodes (summary from observations), relations → `UPPER_SNAKE` edges with stable uuids. Per-fact valid-time rides along in the `json`/`kblam` exports.
|
|
308
|
+
|
|
309
|
+
## Local model guidance
|
|
310
|
+
|
|
311
|
+
Quality/speed trade-off for local selection. For measured numbers see the benchmark below.
|
|
312
|
+
|
|
313
|
+
| Model | Params | Quality | Speed | Notes |
|
|
314
|
+
| ----- | ------ | ------- | ----- | ----- |
|
|
315
|
+
| `qwen3:8b` | 8B | ★★★★★ | slower | highest extraction quality |
|
|
316
|
+
| `gemma3:4b` | 4B | ★★★★ | medium | best quality/speed balance |
|
|
317
|
+
| `qwen2.5-coder:1.5b` | 1.5B | ★★★ | fast | strong on source code |
|
|
318
|
+
| `qwen3:1.7b` | 1.7B | ★★★ | fast | good general purpose |
|
|
319
|
+
| `gemma3:1b` | 1B | ★★ | very fast | minimal resources |
|
|
320
|
+
|
|
321
|
+
Default embeddings: `nomic-embed-text`.
|
|
322
|
+
|
|
323
|
+
The table above is qualitative guidance. For measured, comparative numbers (wanshi vs KGGen on gold-labeled datasets) see **[Benchmarks](#benchmarks)** below — note those run on **cloud** models; local-model benchmarks are planned.
|
|
324
|
+
|
|
325
|
+
## Benchmarks
|
|
326
|
+
|
|
327
|
+
> **Scope & honesty (read first).** Every number here is **cloud inference via OpenRouter** —
|
|
328
|
+
> **local-model (offline-first) benchmarks are planned and not yet run** (see [What's not yet
|
|
329
|
+
> measured](#whats-not-yet-measured)). Comparative baselines are **re-scored under one identical
|
|
330
|
+
> harness, not the published figures**. The document-level result rests on **one dataset** so far.
|
|
331
|
+
> **MINE** is a recall-only, LLM-judge-mediated axis, reported as *context*, not a load-bearing claim.
|
|
332
|
+
|
|
333
|
+
wanshi vs **KGGen** (its real Python package), **same model for both tools**, on gold-labeled datasets.
|
|
334
|
+
The fair cross-tool metric is **entity-capture F1** (did the tool recover the gold entities) — both
|
|
335
|
+
tools emit free predicates, so typed relation-F1 understates uniformly *except* in the schema-aware
|
|
336
|
+
mode below. Embeddings for matching run locally (`nomic-embed-text`), semantic threshold 0.80.
|
|
337
|
+
|
|
338
|
+
**Entity capture across granularity** (deepseek-v4-pro):
|
|
339
|
+
|
|
340
|
+
| Dataset | Level | N | wanshi F1 | KGGen F1 |
|
|
341
|
+
| ------- | ----- | - | --------- | -------- |
|
|
342
|
+
| SemEval-2010 T8 | sentence | 300 | 0.422 | **0.453** |
|
|
343
|
+
| CrossRE | sentence | 300 | 0.786 | **0.824** |
|
|
344
|
+
| Re-DocRED | document | 100 | **0.677** | 0.643 |
|
|
345
|
+
|
|
346
|
+
Same shape everywhere: KGGen edges **recall**, wanshi wins **precision**. The net **flips with document
|
|
347
|
+
length** — on long documents KGGen over-extracts and its precision collapses, so wanshi's discipline wins.
|
|
348
|
+
|
|
349
|
+
**Claim (a) — the precision advantage grows with document length *and* model capability.** Re-DocRED
|
|
350
|
+
two-way (node entity-capture F1) across the model ladder:
|
|
351
|
+
|
|
352
|
+
| Model | wanshi | KGGen | wanshi win | KGGen precision | KGGen ent/doc |
|
|
353
|
+
| ----- | ------ | ----- | ---------- | --------------- | ------------- |
|
|
354
|
+
| deepseek-v4-pro | 0.677 | 0.643 | +3.4 pt | 0.530 | 21.6 |
|
|
355
|
+
| claude-sonnet-4.6 | 0.721 | 0.620 | +10.1 pt | 0.489 | 24.2 |
|
|
356
|
+
| gpt-5.4 | 0.735 | 0.561 | **+17.4 pt** | 0.402 | 32.1 |
|
|
357
|
+
|
|
358
|
+
Stronger models extract *more* (KGGen 21.6 → 32.1 entities/doc); on long docs that craters precision
|
|
359
|
+
(0.53 → 0.40) faster than it helps recall, while wanshi stays disciplined — so the win **widens at the
|
|
360
|
+
frontier**. *Confirmed across three models; rests on one document-level dataset (a second, SciERC/BioRED,
|
|
361
|
+
is planned).*
|
|
362
|
+
|
|
363
|
+
**Claim (b) — schema-aware typed extraction (a mode KGGen lacks).** When the **target relation schema is
|
|
364
|
+
known**, wanshi extracts typed relations natively via a closed vocabulary (`--relation-vocab`). Re-DocRED
|
|
365
|
+
triple-F1, free predicates → strict gold schema (96 Wikidata properties):
|
|
366
|
+
|
|
367
|
+
| Model | wanshi free → strict | Ign-F1 | KGGen (free) | × KGGen |
|
|
368
|
+
| ----- | -------------------- | ------ | ------------ | ------- |
|
|
369
|
+
| deepseek-v4-pro | 0.012 → 0.107 | 0.111 | 0.025 | 4× |
|
|
370
|
+
| claude-sonnet-4.6 | 0.016 → 0.112 | 0.116 | 0.019 | 6× |
|
|
371
|
+
| gpt-5.4 | 0.015 → **0.145** | 0.148 | 0.014 | **10×** |
|
|
372
|
+
|
|
373
|
+
**Ign-F1 ≈ triple-F1** on every model (Ign-F1 excludes triples seen in training) → the gains are
|
|
374
|
+
**generalization, not memorized facts**. KGGen has no closed-vocab mode, so it can't consume a known
|
|
375
|
+
ontology. *This is "schema-aware typed extraction," not "wanshi beats KGGen at relation extraction."*
|
|
376
|
+
|
|
377
|
+
**MINE (context only).** On the recall-only, judge-mediated MINE benchmark KGGen's denser extraction wins
|
|
378
|
+
(re-scored ~64% vs wanshi's best ~28%). MINE rewards raw triple coverage and is blind to precision, and
|
|
379
|
+
its judge performs fact-verification (a known-soft measurement) — so the gold-labeled results above carry
|
|
380
|
+
the comparative claims; MINE is reported as context, not a verdict.
|
|
381
|
+
|
|
382
|
+
**Cost & reproducibility.** Generation = cloud OpenRouter; **embeddings = local Ollama (free)**.
|
|
383
|
+
Representative spend (measured live via the OpenRouter credits API; wanshi extraction tokens shown, the
|
|
384
|
+
$ also covers the KGGen baseline):
|
|
385
|
+
|
|
386
|
+
| Cell (Re-DocRED, two-way + H4, N=100) | tokens in | tokens out | cost |
|
|
387
|
+
| ------------------------------------- | --------- | ---------- | ---- |
|
|
388
|
+
| claude-sonnet-4.6 | ~0.57 M | ~0.16 M | $6.00 |
|
|
389
|
+
| gpt-5.4 | ~0.43 M | ~0.19 M | $5.60 |
|
|
390
|
+
|
|
391
|
+
(OpenRouter rates at run time, ≈ $3 / $15 per Mtok in/out for the Claude tier.) Reproduce a cell with the
|
|
392
|
+
one harness — wanshi inline, KGGen cached, same sample list for both:
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
npx ts-node scripts/gold-compare.ts --dataset redocred --limit 100 \
|
|
396
|
+
--model deepseek/deepseek-v4-pro --provider openai --host https://openrouter.ai/api/v1
|
|
397
|
+
.venv-kggen/bin/python scripts/kggen-crossre.py --model deepseek/deepseek-v4-pro \
|
|
398
|
+
--samples data/redocred/compare/samples.jsonl --out data/redocred/compare/kggen.jsonl
|
|
399
|
+
# add --relation-vocab @data/redocred/compare/relation-vocab.txt for the schema-aware (H4) cell
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### What's not yet measured
|
|
403
|
+
|
|
404
|
+
- **Local-model (offline-first) benchmarks** — the deployment-target floor (`gemma3:4b`-class) is *owed*;
|
|
405
|
+
every number above is cloud inference. This is the next benchmark priority. *(An earlier indicative
|
|
406
|
+
n=20 single-domain run hinted small `gemma3:4b` ≈ larger Gemmas on entity extraction — to be confirmed
|
|
407
|
+
in the local arm.)*
|
|
408
|
+
- **A second document-level dataset** (SciERC / BioRED) to close the single-dataset caveat on claim (a).
|
|
409
|
+
|
|
410
|
+
## Quality metrics
|
|
411
|
+
|
|
412
|
+
Importable evaluators in `src/quality/` (also wired into `npm run benchmark`): **structural** (counts, density, type distribution), **semantic** (name quality, observation specificity, coverage), **factual** (grounding, hallucination, contradiction — this one also backs the inline grounding gate), and **consistency** (cross-file naming, type coherence), rolled into a 0–100 composite that can gate which graphs are harvested for `kblam`/`lora` training data.
|
|
413
|
+
|
|
414
|
+
## Architecture
|
|
415
|
+
|
|
416
|
+
```text
|
|
417
|
+
src/
|
|
418
|
+
├── cli/ # Commander.js CLI (process/watch/export; --export-only)
|
|
419
|
+
├── core/
|
|
420
|
+
│ ├── di/ # Async DI container + service registrations
|
|
421
|
+
│ ├── processor/ # File readers (transcript, JSON, PDF, Office, audio, …) + chunking + classifiers
|
|
422
|
+
│ ├── checkpoint/# Per-chunk resume sidecar
|
|
423
|
+
│ ├── llm/ # Ollama / OpenAI-compatible providers, embeddings, Handlebars prompts
|
|
424
|
+
│ ├── knowledge/ # KG building (LLM+Zod, provenance + grounding gate), 3-level merge, vector search
|
|
425
|
+
│ └── export/ # Strategy pattern: json, jsonl, mcp-jsonl, dot, kblam, lora, graphiti
|
|
426
|
+
├── quality/ # Importable metrics (structural, semantic, factual, consistency, composite)
|
|
427
|
+
├── evaluation/ # Benchmark harness (CrossRE / REBEL / RE-DocRED)
|
|
428
|
+
├── types/ # Interfaces and data models
|
|
429
|
+
└── shared/ # Logger, graceful shutdown, utilities (Jaro-Winkler, cosine, config)
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
Tests use Jest (`npm test`); mock the LLM via `ILLMProvider` for network-free unit tests.
|
|
433
|
+
|
|
434
|
+
## Development
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
git clone https://github.com/wanshi-kg/wanshi && cd wanshi && npm install
|
|
438
|
+
npx ts-node ./src/index.ts --config config.yaml # run directly
|
|
439
|
+
npm run build && node ./dist/index.js --config config.yaml # or build first
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
See `examples/kg-mail-assistant/` for a full integration (Gmail OAuth + Telegram bot + continuous email→KG pipeline) and programmatic usage via `ContainerFactory`.
|
|
443
|
+
|
|
444
|
+
## Acknowledgments
|
|
445
|
+
|
|
446
|
+
- **[Ollama](https://ollama.ai)** — local LLM runtime and embeddings
|
|
447
|
+
- **[LangChain](https://github.com/langchain-ai/langchainjs)** — text-splitting utilities
|
|
448
|
+
- **[OpenAI Whisper](https://github.com/openai/whisper)** (via `nodejs-whisper`) — audio transcription
|
|
449
|
+
- **Anthropic** — the MCP protocol, and Claude as a build partner (Cheetah 🐆 on the code, Dove 🕊️ on the audits)
|
|
450
|
+
- **[KBLaM](https://github.com/microsoft/KBLaM)** and **[Graphiti](https://github.com/getzep/graphiti)** — prior work this project's training exports and temporal model lean on
|
|
451
|
+
|
|
452
|
+
## License
|
|
453
|
+
|
|
454
|
+
MIT — see [LICENSE](LICENSE).
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
*Knows ten thousand things; keeps only the ones it can source.*
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeConfig = makeConfig;
|
|
4
|
+
exports.stubLogger = stubLogger;
|
|
5
|
+
const config_1 = require("../config");
|
|
6
|
+
/**
|
|
7
|
+
* Build a fully-defaulted, validated config from a nested partial (the new
|
|
8
|
+
* config shape). Use this instead of hand-rolling flat `{ model, chunkSize }`
|
|
9
|
+
* fixtures — it deep-applies schema defaults so consumers reading
|
|
10
|
+
* `options.llm.model` / `options.chunking.size` don't hit undefined.
|
|
11
|
+
*/
|
|
12
|
+
function makeConfig(partial = {}) {
|
|
13
|
+
return (0, config_1.parseConfig)(partial);
|
|
14
|
+
}
|
|
15
|
+
/** Minimal no-op Logger for unit tests (avoids tslog/file side effects). */
|
|
16
|
+
function stubLogger() {
|
|
17
|
+
const noop = () => undefined;
|
|
18
|
+
return {
|
|
19
|
+
trace: noop,
|
|
20
|
+
debug: noop,
|
|
21
|
+
info: noop,
|
|
22
|
+
warn: noop,
|
|
23
|
+
error: noop,
|
|
24
|
+
fatal: noop,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/__tests__/helpers.ts"],"names":[],"mappings":";;AASA,gCAEC;AAGD,gCAUC;AAvBD,sCAA2D;AAE3D;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,UAAmC,EAAE;IAC9D,OAAO,IAAA,oBAAW,EAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED,4EAA4E;AAC5E,SAAgB,UAAU;IACxB,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC;IAC7B,OAAO;QACL,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,IAAI;KACS,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.exportCommand = exportCommand;
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const di_1 = require("../../core/di");
|
|
48
|
+
/**
|
|
49
|
+
* Export command — convert an existing knowledge-graph JSON file (`--input`)
|
|
50
|
+
* into another export format (`--export-format`), written to `--output`.
|
|
51
|
+
* Reuses the same `KnowledgeGraphExportService` strategies as the main pipeline.
|
|
52
|
+
*/
|
|
53
|
+
function exportCommand(container) {
|
|
54
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
var _a;
|
|
56
|
+
const logger = yield container.resolve(di_1.TYPES.Logger);
|
|
57
|
+
const options = yield container.resolve(di_1.TYPES.ProcessingOptions);
|
|
58
|
+
try {
|
|
59
|
+
const sourcePath = options.input;
|
|
60
|
+
if (!sourcePath ||
|
|
61
|
+
!fs.existsSync(sourcePath) ||
|
|
62
|
+
fs.statSync(sourcePath).isDirectory()) {
|
|
63
|
+
throw new Error(`In export mode, --input must point to an existing knowledge-graph JSON file (got: ${sourcePath})`);
|
|
64
|
+
}
|
|
65
|
+
const parsed = JSON.parse(fs.readFileSync(sourcePath, "utf-8"));
|
|
66
|
+
// Tolerate both a single merged graph object and a legacy array of graphs.
|
|
67
|
+
const graph = Array.isArray(parsed)
|
|
68
|
+
? flattenGraphs(parsed)
|
|
69
|
+
: parsed;
|
|
70
|
+
if (!graph || !Array.isArray(graph.entities)) {
|
|
71
|
+
throw new Error(`--input does not contain a knowledge graph ({ entities, relations }): ${sourcePath}`);
|
|
72
|
+
}
|
|
73
|
+
(_a = graph.relations) !== null && _a !== void 0 ? _a : (graph.relations = []);
|
|
74
|
+
const exporter = yield container.resolve(di_1.TYPES.KnowledgeGraphExportService);
|
|
75
|
+
const format = options.export.format;
|
|
76
|
+
if (!exporter.isFormatSupported(format)) {
|
|
77
|
+
throw new Error(`Unsupported export format: ${format}. Supported: ${exporter
|
|
78
|
+
.getSupportedFormats()
|
|
79
|
+
.join(", ")}`);
|
|
80
|
+
}
|
|
81
|
+
const content = exporter.export(graph, format, options);
|
|
82
|
+
yield fs.promises.writeFile(options.output, content);
|
|
83
|
+
logger.info(`Exported knowledge graph from ${sourcePath} to ${options.output} (${format}): ` +
|
|
84
|
+
`${graph.entities.length} entities, ${graph.relations.length} relations`);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
logger.error(`Export command failed: ${error}`);
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/** Concatenate a legacy array of per-file graphs into one graph. */
|
|
93
|
+
function flattenGraphs(graphs) {
|
|
94
|
+
return {
|
|
95
|
+
entities: graphs.flatMap((g) => { var _a; return (_a = g.entities) !== null && _a !== void 0 ? _a : []; }),
|
|
96
|
+
relations: graphs.flatMap((g) => { var _a; return (_a = g.relations) !== null && _a !== void 0 ? _a : []; }),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=export.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.command.js","sourceRoot":"","sources":["../../../src/cli/commands/export.command.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,sCAsDC;AApED,uCAAyB;AACzB,sCAAmD;AAQnD;;;;GAIG;AACH,SAAsB,aAAa,CAAC,SAAsB;;;QACxD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAS,UAAK,CAAC,MAAM,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,OAAO,CACrC,UAAK,CAAC,iBAAiB,CACxB,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC;YACjC,IACE,CAAC,UAAU;gBACX,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;gBAC1B,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,EACrC,CAAC;gBACD,MAAM,IAAI,KAAK,CACb,qFAAqF,UAAU,GAAG,CACnG,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;YAChE,2EAA2E;YAC3E,MAAM,KAAK,GAAmB,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBACjD,CAAC,CAAC,aAAa,CAAC,MAA0B,CAAC;gBAC3C,CAAC,CAAE,MAAyB,CAAC;YAE/B,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7C,MAAM,IAAI,KAAK,CACb,yEAAyE,UAAU,EAAE,CACtF,CAAC;YACJ,CAAC;YACD,MAAA,KAAK,CAAC,SAAS,oCAAf,KAAK,CAAC,SAAS,GAAK,EAAE,EAAC;YAEvB,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,OAAO,CACtC,UAAK,CAAC,2BAA2B,CAClC,CAAC;YACF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;YACrC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxC,MAAM,IAAI,KAAK,CACb,8BAA8B,MAAM,gBAAgB,QAAQ;qBACzD,mBAAmB,EAAE;qBACrB,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAC;YACJ,CAAC;YAED,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YACxD,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAErD,MAAM,CAAC,IAAI,CACT,iCAAiC,UAAU,OAAO,OAAO,CAAC,MAAM,KAAK,MAAM,KAAK;gBAC9E,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,cAAc,KAAK,CAAC,SAAS,CAAC,MAAM,YAAY,CAC3E,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;YAChD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CAAA;AAED,oEAAoE;AACpE,SAAS,aAAa,CAAC,MAAwB;IAC7C,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,WAAC,OAAA,MAAA,CAAC,CAAC,QAAQ,mCAAI,EAAE,CAAA,EAAA,CAAC;QACjD,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,WAAC,OAAA,MAAA,CAAC,CAAC,SAAS,mCAAI,EAAE,CAAA,EAAA,CAAC;KACpD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./process.command"), exports);
|
|
18
|
+
__exportStar(require("./watch.command"), exports);
|
|
19
|
+
__exportStar(require("./export.command"), exports);
|
|
20
|
+
__exportStar(require("./metrics.command"), exports);
|
|
21
|
+
__exportStar(require("./inspectMerges.command"), exports);
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/commands/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oDAAkC;AAClC,kDAAgC;AAChC,mDAAiC;AACjC,oDAAkC;AAClC,0DAAwC"}
|