ocr-provenance-mcp 1.0.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.
Potentially problematic release.
This version of ocr-provenance-mcp might be problematic. Click here for more details.
- package/.env.example +55 -0
- package/LICENSE +78 -0
- package/README.md +1154 -0
- package/dist/bin-http.d.ts +24 -0
- package/dist/bin-http.d.ts.map +1 -0
- package/dist/bin-http.js +275 -0
- package/dist/bin-http.js.map +1 -0
- package/dist/bin-setup.d.ts +11 -0
- package/dist/bin-setup.d.ts.map +1 -0
- package/dist/bin-setup.js +610 -0
- package/dist/bin-setup.js.map +1 -0
- package/dist/bin.d.ts +16 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +16 -0
- package/dist/bin.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +90 -0
- package/dist/index.js.map +1 -0
- package/dist/models/chunk.d.ts +136 -0
- package/dist/models/chunk.d.ts.map +1 -0
- package/dist/models/chunk.js +27 -0
- package/dist/models/chunk.js.map +1 -0
- package/dist/models/cluster.d.ts +79 -0
- package/dist/models/cluster.d.ts.map +1 -0
- package/dist/models/cluster.js +10 -0
- package/dist/models/cluster.js.map +1 -0
- package/dist/models/comparison.d.ts +62 -0
- package/dist/models/comparison.d.ts.map +1 -0
- package/dist/models/comparison.js +8 -0
- package/dist/models/comparison.js.map +1 -0
- package/dist/models/document.d.ts +104 -0
- package/dist/models/document.d.ts.map +1 -0
- package/dist/models/document.js +15 -0
- package/dist/models/document.js.map +1 -0
- package/dist/models/embedding.d.ts +87 -0
- package/dist/models/embedding.d.ts.map +1 -0
- package/dist/models/embedding.js +23 -0
- package/dist/models/embedding.js.map +1 -0
- package/dist/models/extraction.d.ts +15 -0
- package/dist/models/extraction.d.ts.map +1 -0
- package/dist/models/extraction.js +2 -0
- package/dist/models/extraction.js.map +1 -0
- package/dist/models/form-fill.d.ts +23 -0
- package/dist/models/form-fill.d.ts.map +1 -0
- package/dist/models/form-fill.js +2 -0
- package/dist/models/form-fill.js.map +1 -0
- package/dist/models/image.d.ts +177 -0
- package/dist/models/image.d.ts.map +1 -0
- package/dist/models/image.js +8 -0
- package/dist/models/image.js.map +1 -0
- package/dist/models/index.d.ts +14 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +22 -0
- package/dist/models/index.js.map +1 -0
- package/dist/models/provenance.d.ts +174 -0
- package/dist/models/provenance.d.ts.map +1 -0
- package/dist/models/provenance.js +53 -0
- package/dist/models/provenance.js.map +1 -0
- package/dist/models/uploaded-file.d.ts +20 -0
- package/dist/models/uploaded-file.d.ts.map +1 -0
- package/dist/models/uploaded-file.js +2 -0
- package/dist/models/uploaded-file.js.map +1 -0
- package/dist/server/errors.d.ts +93 -0
- package/dist/server/errors.d.ts.map +1 -0
- package/dist/server/errors.js +256 -0
- package/dist/server/errors.js.map +1 -0
- package/dist/server/events.d.ts +36 -0
- package/dist/server/events.d.ts.map +1 -0
- package/dist/server/events.js +48 -0
- package/dist/server/events.js.map +1 -0
- package/dist/server/permissions.d.ts +26 -0
- package/dist/server/permissions.d.ts.map +1 -0
- package/dist/server/permissions.js +194 -0
- package/dist/server/permissions.js.map +1 -0
- package/dist/server/register-tools.d.ts +25 -0
- package/dist/server/register-tools.d.ts.map +1 -0
- package/dist/server/register-tools.js +102 -0
- package/dist/server/register-tools.js.map +1 -0
- package/dist/server/startup.d.ts +16 -0
- package/dist/server/startup.d.ts.map +1 -0
- package/dist/server/startup.js +37 -0
- package/dist/server/startup.js.map +1 -0
- package/dist/server/state.d.ts +166 -0
- package/dist/server/state.d.ts.map +1 -0
- package/dist/server/state.js +424 -0
- package/dist/server/state.js.map +1 -0
- package/dist/server/transports/http-transport.d.ts +37 -0
- package/dist/server/transports/http-transport.d.ts.map +1 -0
- package/dist/server/transports/http-transport.js +204 -0
- package/dist/server/transports/http-transport.js.map +1 -0
- package/dist/server/transports/index.d.ts +9 -0
- package/dist/server/transports/index.d.ts.map +1 -0
- package/dist/server/transports/index.js +9 -0
- package/dist/server/transports/index.js.map +1 -0
- package/dist/server/transports/session-manager.d.ts +40 -0
- package/dist/server/transports/session-manager.d.ts.map +1 -0
- package/dist/server/transports/session-manager.js +74 -0
- package/dist/server/transports/session-manager.js.map +1 -0
- package/dist/server/types.d.ts +82 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +14 -0
- package/dist/server/types.js.map +1 -0
- package/dist/services/audit.d.ts +26 -0
- package/dist/services/audit.d.ts.map +1 -0
- package/dist/services/audit.js +43 -0
- package/dist/services/audit.js.map +1 -0
- package/dist/services/chunking/chunk-deduplicator.d.ts +33 -0
- package/dist/services/chunking/chunk-deduplicator.d.ts.map +1 -0
- package/dist/services/chunking/chunk-deduplicator.js +46 -0
- package/dist/services/chunking/chunk-deduplicator.js.map +1 -0
- package/dist/services/chunking/chunk-merger.d.ts +26 -0
- package/dist/services/chunking/chunk-merger.d.ts.map +1 -0
- package/dist/services/chunking/chunk-merger.js +94 -0
- package/dist/services/chunking/chunk-merger.js.map +1 -0
- package/dist/services/chunking/chunker.d.ts +62 -0
- package/dist/services/chunking/chunker.d.ts.map +1 -0
- package/dist/services/chunking/chunker.js +566 -0
- package/dist/services/chunking/chunker.js.map +1 -0
- package/dist/services/chunking/heading-normalizer.d.ts +33 -0
- package/dist/services/chunking/heading-normalizer.d.ts.map +1 -0
- package/dist/services/chunking/heading-normalizer.js +101 -0
- package/dist/services/chunking/heading-normalizer.js.map +1 -0
- package/dist/services/chunking/json-block-analyzer.d.ts +163 -0
- package/dist/services/chunking/json-block-analyzer.d.ts.map +1 -0
- package/dist/services/chunking/json-block-analyzer.js +1033 -0
- package/dist/services/chunking/json-block-analyzer.js.map +1 -0
- package/dist/services/chunking/markdown-parser.d.ts +75 -0
- package/dist/services/chunking/markdown-parser.d.ts.map +1 -0
- package/dist/services/chunking/markdown-parser.js +428 -0
- package/dist/services/chunking/markdown-parser.js.map +1 -0
- package/dist/services/chunking/text-normalizer.d.ts +20 -0
- package/dist/services/chunking/text-normalizer.d.ts.map +1 -0
- package/dist/services/chunking/text-normalizer.js +36 -0
- package/dist/services/chunking/text-normalizer.js.map +1 -0
- package/dist/services/clm/contract-schemas.d.ts +36 -0
- package/dist/services/clm/contract-schemas.d.ts.map +1 -0
- package/dist/services/clm/contract-schemas.js +92 -0
- package/dist/services/clm/contract-schemas.js.map +1 -0
- package/dist/services/clm/summarization.d.ts +46 -0
- package/dist/services/clm/summarization.d.ts.map +1 -0
- package/dist/services/clm/summarization.js +61 -0
- package/dist/services/clm/summarization.js.map +1 -0
- package/dist/services/clustering/clustering-service.d.ts +58 -0
- package/dist/services/clustering/clustering-service.d.ts.map +1 -0
- package/dist/services/clustering/clustering-service.js +467 -0
- package/dist/services/clustering/clustering-service.js.map +1 -0
- package/dist/services/comparison/diff-service.d.ts +41 -0
- package/dist/services/comparison/diff-service.d.ts.map +1 -0
- package/dist/services/comparison/diff-service.js +120 -0
- package/dist/services/comparison/diff-service.js.map +1 -0
- package/dist/services/embedding/embedder.d.ts +55 -0
- package/dist/services/embedding/embedder.d.ts.map +1 -0
- package/dist/services/embedding/embedder.js +202 -0
- package/dist/services/embedding/embedder.js.map +1 -0
- package/dist/services/embedding/nomic.d.ts +67 -0
- package/dist/services/embedding/nomic.d.ts.map +1 -0
- package/dist/services/embedding/nomic.js +280 -0
- package/dist/services/embedding/nomic.js.map +1 -0
- package/dist/services/gemini/circuit-breaker.d.ts +106 -0
- package/dist/services/gemini/circuit-breaker.d.ts.map +1 -0
- package/dist/services/gemini/circuit-breaker.js +237 -0
- package/dist/services/gemini/circuit-breaker.js.map +1 -0
- package/dist/services/gemini/client.d.ts +173 -0
- package/dist/services/gemini/client.d.ts.map +1 -0
- package/dist/services/gemini/client.js +483 -0
- package/dist/services/gemini/client.js.map +1 -0
- package/dist/services/gemini/config.d.ts +116 -0
- package/dist/services/gemini/config.d.ts.map +1 -0
- package/dist/services/gemini/config.js +118 -0
- package/dist/services/gemini/config.js.map +1 -0
- package/dist/services/gemini/index.d.ts +9 -0
- package/dist/services/gemini/index.d.ts.map +1 -0
- package/dist/services/gemini/index.js +13 -0
- package/dist/services/gemini/index.js.map +1 -0
- package/dist/services/gemini/rate-limiter.d.ts +62 -0
- package/dist/services/gemini/rate-limiter.d.ts.map +1 -0
- package/dist/services/gemini/rate-limiter.js +120 -0
- package/dist/services/gemini/rate-limiter.js.map +1 -0
- package/dist/services/images/extractor.d.ts +88 -0
- package/dist/services/images/extractor.d.ts.map +1 -0
- package/dist/services/images/extractor.js +340 -0
- package/dist/services/images/extractor.js.map +1 -0
- package/dist/services/images/optimizer.d.ts +130 -0
- package/dist/services/images/optimizer.d.ts.map +1 -0
- package/dist/services/images/optimizer.js +228 -0
- package/dist/services/images/optimizer.js.map +1 -0
- package/dist/services/ocr/datalab.d.ts +64 -0
- package/dist/services/ocr/datalab.d.ts.map +1 -0
- package/dist/services/ocr/datalab.js +425 -0
- package/dist/services/ocr/datalab.js.map +1 -0
- package/dist/services/ocr/errors.d.ts +38 -0
- package/dist/services/ocr/errors.d.ts.map +1 -0
- package/dist/services/ocr/errors.js +83 -0
- package/dist/services/ocr/errors.js.map +1 -0
- package/dist/services/ocr/file-manager.d.ts +76 -0
- package/dist/services/ocr/file-manager.d.ts.map +1 -0
- package/dist/services/ocr/file-manager.js +238 -0
- package/dist/services/ocr/file-manager.js.map +1 -0
- package/dist/services/ocr/form-fill.d.ts +48 -0
- package/dist/services/ocr/form-fill.d.ts.map +1 -0
- package/dist/services/ocr/form-fill.js +213 -0
- package/dist/services/ocr/form-fill.js.map +1 -0
- package/dist/services/ocr/processor.d.ts +95 -0
- package/dist/services/ocr/processor.d.ts.map +1 -0
- package/dist/services/ocr/processor.js +259 -0
- package/dist/services/ocr/processor.js.map +1 -0
- package/dist/services/provenance/agent-metadata.d.ts +82 -0
- package/dist/services/provenance/agent-metadata.d.ts.map +1 -0
- package/dist/services/provenance/agent-metadata.js +106 -0
- package/dist/services/provenance/agent-metadata.js.map +1 -0
- package/dist/services/provenance/chain-hash.d.ts +57 -0
- package/dist/services/provenance/chain-hash.d.ts.map +1 -0
- package/dist/services/provenance/chain-hash.js +131 -0
- package/dist/services/provenance/chain-hash.js.map +1 -0
- package/dist/services/provenance/exporter.d.ts +202 -0
- package/dist/services/provenance/exporter.d.ts.map +1 -0
- package/dist/services/provenance/exporter.js +457 -0
- package/dist/services/provenance/exporter.js.map +1 -0
- package/dist/services/provenance/index.d.ts +15 -0
- package/dist/services/provenance/index.d.ts.map +1 -0
- package/dist/services/provenance/index.js +17 -0
- package/dist/services/provenance/index.js.map +1 -0
- package/dist/services/provenance/tracker.d.ts +138 -0
- package/dist/services/provenance/tracker.d.ts.map +1 -0
- package/dist/services/provenance/tracker.js +293 -0
- package/dist/services/provenance/tracker.js.map +1 -0
- package/dist/services/provenance/verifier.d.ts +153 -0
- package/dist/services/provenance/verifier.d.ts.map +1 -0
- package/dist/services/provenance/verifier.js +536 -0
- package/dist/services/provenance/verifier.js.map +1 -0
- package/dist/services/python-pool.d.ts +70 -0
- package/dist/services/python-pool.d.ts.map +1 -0
- package/dist/services/python-pool.js +265 -0
- package/dist/services/python-pool.js.map +1 -0
- package/dist/services/search/bm25.d.ts +180 -0
- package/dist/services/search/bm25.d.ts.map +1 -0
- package/dist/services/search/bm25.js +656 -0
- package/dist/services/search/bm25.js.map +1 -0
- package/dist/services/search/fusion.d.ts +103 -0
- package/dist/services/search/fusion.d.ts.map +1 -0
- package/dist/services/search/fusion.js +122 -0
- package/dist/services/search/fusion.js.map +1 -0
- package/dist/services/search/local-reranker.d.ts +30 -0
- package/dist/services/search/local-reranker.d.ts.map +1 -0
- package/dist/services/search/local-reranker.js +123 -0
- package/dist/services/search/local-reranker.js.map +1 -0
- package/dist/services/search/quality.d.ts +11 -0
- package/dist/services/search/quality.d.ts.map +1 -0
- package/dist/services/search/quality.js +17 -0
- package/dist/services/search/quality.js.map +1 -0
- package/dist/services/search/query-classifier.d.ts +34 -0
- package/dist/services/search/query-classifier.d.ts.map +1 -0
- package/dist/services/search/query-classifier.js +114 -0
- package/dist/services/search/query-classifier.js.map +1 -0
- package/dist/services/search/query-expander.d.ts +73 -0
- package/dist/services/search/query-expander.d.ts.map +1 -0
- package/dist/services/search/query-expander.js +281 -0
- package/dist/services/search/query-expander.js.map +1 -0
- package/dist/services/search/reranker.d.ts +44 -0
- package/dist/services/search/reranker.d.ts.map +1 -0
- package/dist/services/search/reranker.js +101 -0
- package/dist/services/search/reranker.js.map +1 -0
- package/dist/services/storage/database/annotation-operations.d.ts +113 -0
- package/dist/services/storage/database/annotation-operations.d.ts.map +1 -0
- package/dist/services/storage/database/annotation-operations.js +177 -0
- package/dist/services/storage/database/annotation-operations.js.map +1 -0
- package/dist/services/storage/database/approval-operations.d.ts +132 -0
- package/dist/services/storage/database/approval-operations.d.ts.map +1 -0
- package/dist/services/storage/database/approval-operations.js +206 -0
- package/dist/services/storage/database/approval-operations.js.map +1 -0
- package/dist/services/storage/database/chunk-operations.d.ts +132 -0
- package/dist/services/storage/database/chunk-operations.d.ts.map +1 -0
- package/dist/services/storage/database/chunk-operations.js +306 -0
- package/dist/services/storage/database/chunk-operations.js.map +1 -0
- package/dist/services/storage/database/cluster-operations.d.ts +97 -0
- package/dist/services/storage/database/cluster-operations.d.ts.map +1 -0
- package/dist/services/storage/database/cluster-operations.js +258 -0
- package/dist/services/storage/database/cluster-operations.js.map +1 -0
- package/dist/services/storage/database/comparison-operations.d.ts +41 -0
- package/dist/services/storage/database/comparison-operations.d.ts.map +1 -0
- package/dist/services/storage/database/comparison-operations.js +65 -0
- package/dist/services/storage/database/comparison-operations.js.map +1 -0
- package/dist/services/storage/database/converters.d.ts +36 -0
- package/dist/services/storage/database/converters.d.ts.map +1 -0
- package/dist/services/storage/database/converters.js +244 -0
- package/dist/services/storage/database/converters.js.map +1 -0
- package/dist/services/storage/database/document-operations.d.ts +145 -0
- package/dist/services/storage/database/document-operations.d.ts.map +1 -0
- package/dist/services/storage/database/document-operations.js +498 -0
- package/dist/services/storage/database/document-operations.js.map +1 -0
- package/dist/services/storage/database/embedding-operations.d.ts +130 -0
- package/dist/services/storage/database/embedding-operations.d.ts.map +1 -0
- package/dist/services/storage/database/embedding-operations.js +315 -0
- package/dist/services/storage/database/embedding-operations.js.map +1 -0
- package/dist/services/storage/database/extraction-operations.d.ts +47 -0
- package/dist/services/storage/database/extraction-operations.d.ts.map +1 -0
- package/dist/services/storage/database/extraction-operations.js +85 -0
- package/dist/services/storage/database/extraction-operations.js.map +1 -0
- package/dist/services/storage/database/form-fill-operations.d.ts +58 -0
- package/dist/services/storage/database/form-fill-operations.d.ts.map +1 -0
- package/dist/services/storage/database/form-fill-operations.js +116 -0
- package/dist/services/storage/database/form-fill-operations.js.map +1 -0
- package/dist/services/storage/database/helpers.d.ts +29 -0
- package/dist/services/storage/database/helpers.d.ts.map +1 -0
- package/dist/services/storage/database/helpers.js +55 -0
- package/dist/services/storage/database/helpers.js.map +1 -0
- package/dist/services/storage/database/image-operations.d.ts +202 -0
- package/dist/services/storage/database/image-operations.d.ts.map +1 -0
- package/dist/services/storage/database/image-operations.js +484 -0
- package/dist/services/storage/database/image-operations.js.map +1 -0
- package/dist/services/storage/database/index.d.ts +13 -0
- package/dist/services/storage/database/index.d.ts.map +1 -0
- package/dist/services/storage/database/index.js +16 -0
- package/dist/services/storage/database/index.js.map +1 -0
- package/dist/services/storage/database/lock-operations.d.ts +59 -0
- package/dist/services/storage/database/lock-operations.d.ts.map +1 -0
- package/dist/services/storage/database/lock-operations.js +89 -0
- package/dist/services/storage/database/lock-operations.js.map +1 -0
- package/dist/services/storage/database/obligation-operations.d.ts +88 -0
- package/dist/services/storage/database/obligation-operations.d.ts.map +1 -0
- package/dist/services/storage/database/obligation-operations.js +206 -0
- package/dist/services/storage/database/obligation-operations.js.map +1 -0
- package/dist/services/storage/database/ocr-operations.d.ts +33 -0
- package/dist/services/storage/database/ocr-operations.d.ts.map +1 -0
- package/dist/services/storage/database/ocr-operations.js +70 -0
- package/dist/services/storage/database/ocr-operations.js.map +1 -0
- package/dist/services/storage/database/playbook-operations.d.ts +72 -0
- package/dist/services/storage/database/playbook-operations.d.ts.map +1 -0
- package/dist/services/storage/database/playbook-operations.js +247 -0
- package/dist/services/storage/database/playbook-operations.js.map +1 -0
- package/dist/services/storage/database/provenance-operations.d.ts +112 -0
- package/dist/services/storage/database/provenance-operations.d.ts.map +1 -0
- package/dist/services/storage/database/provenance-operations.js +251 -0
- package/dist/services/storage/database/provenance-operations.js.map +1 -0
- package/dist/services/storage/database/service.d.ts +142 -0
- package/dist/services/storage/database/service.d.ts.map +1 -0
- package/dist/services/storage/database/service.js +310 -0
- package/dist/services/storage/database/service.js.map +1 -0
- package/dist/services/storage/database/static-operations.d.ts +30 -0
- package/dist/services/storage/database/static-operations.d.ts.map +1 -0
- package/dist/services/storage/database/static-operations.js +218 -0
- package/dist/services/storage/database/static-operations.js.map +1 -0
- package/dist/services/storage/database/stats-operations.d.ts +101 -0
- package/dist/services/storage/database/stats-operations.d.ts.map +1 -0
- package/dist/services/storage/database/stats-operations.js +394 -0
- package/dist/services/storage/database/stats-operations.js.map +1 -0
- package/dist/services/storage/database/tag-operations.d.ts +76 -0
- package/dist/services/storage/database/tag-operations.d.ts.map +1 -0
- package/dist/services/storage/database/tag-operations.js +178 -0
- package/dist/services/storage/database/tag-operations.js.map +1 -0
- package/dist/services/storage/database/types.d.ts +286 -0
- package/dist/services/storage/database/types.d.ts.map +1 -0
- package/dist/services/storage/database/types.js +39 -0
- package/dist/services/storage/database/types.js.map +1 -0
- package/dist/services/storage/database/upload-operations.d.ts +71 -0
- package/dist/services/storage/database/upload-operations.d.ts.map +1 -0
- package/dist/services/storage/database/upload-operations.js +124 -0
- package/dist/services/storage/database/upload-operations.js.map +1 -0
- package/dist/services/storage/database/user-operations.d.ts +102 -0
- package/dist/services/storage/database/user-operations.d.ts.map +1 -0
- package/dist/services/storage/database/user-operations.js +151 -0
- package/dist/services/storage/database/user-operations.js.map +1 -0
- package/dist/services/storage/database/workflow-operations.d.ts +98 -0
- package/dist/services/storage/database/workflow-operations.d.ts.map +1 -0
- package/dist/services/storage/database/workflow-operations.js +157 -0
- package/dist/services/storage/database/workflow-operations.js.map +1 -0
- package/dist/services/storage/database.d.ts +16 -0
- package/dist/services/storage/database.d.ts.map +1 -0
- package/dist/services/storage/database.js +15 -0
- package/dist/services/storage/database.js.map +1 -0
- package/dist/services/storage/index.d.ts +10 -0
- package/dist/services/storage/index.d.ts.map +1 -0
- package/dist/services/storage/index.js +10 -0
- package/dist/services/storage/index.js.map +1 -0
- package/dist/services/storage/migrations/index.d.ts +16 -0
- package/dist/services/storage/migrations/index.d.ts.map +1 -0
- package/dist/services/storage/migrations/index.js +20 -0
- package/dist/services/storage/migrations/index.js.map +1 -0
- package/dist/services/storage/migrations/operations.d.ts +40 -0
- package/dist/services/storage/migrations/operations.d.ts.map +1 -0
- package/dist/services/storage/migrations/operations.js +2910 -0
- package/dist/services/storage/migrations/operations.js.map +1 -0
- package/dist/services/storage/migrations/schema-definitions.d.ts +306 -0
- package/dist/services/storage/migrations/schema-definitions.d.ts.map +1 -0
- package/dist/services/storage/migrations/schema-definitions.js +1006 -0
- package/dist/services/storage/migrations/schema-definitions.js.map +1 -0
- package/dist/services/storage/migrations/schema-helpers.d.ts +50 -0
- package/dist/services/storage/migrations/schema-helpers.d.ts.map +1 -0
- package/dist/services/storage/migrations/schema-helpers.js +176 -0
- package/dist/services/storage/migrations/schema-helpers.js.map +1 -0
- package/dist/services/storage/migrations/types.d.ts +15 -0
- package/dist/services/storage/migrations/types.d.ts.map +1 -0
- package/dist/services/storage/migrations/types.js +21 -0
- package/dist/services/storage/migrations/types.js.map +1 -0
- package/dist/services/storage/migrations/verification.d.ts +20 -0
- package/dist/services/storage/migrations/verification.d.ts.map +1 -0
- package/dist/services/storage/migrations/verification.js +78 -0
- package/dist/services/storage/migrations/verification.js.map +1 -0
- package/dist/services/storage/migrations.d.ts +16 -0
- package/dist/services/storage/migrations.d.ts.map +1 -0
- package/dist/services/storage/migrations.js +17 -0
- package/dist/services/storage/migrations.js.map +1 -0
- package/dist/services/storage/types.d.ts +12 -0
- package/dist/services/storage/types.d.ts.map +1 -0
- package/dist/services/storage/types.js +5 -0
- package/dist/services/storage/types.js.map +1 -0
- package/dist/services/storage/vector.d.ts +208 -0
- package/dist/services/storage/vector.d.ts.map +1 -0
- package/dist/services/storage/vector.js +526 -0
- package/dist/services/storage/vector.js.map +1 -0
- package/dist/services/vlm/pipeline.d.ts +194 -0
- package/dist/services/vlm/pipeline.d.ts.map +1 -0
- package/dist/services/vlm/pipeline.js +800 -0
- package/dist/services/vlm/pipeline.js.map +1 -0
- package/dist/services/vlm/prompts.d.ts +171 -0
- package/dist/services/vlm/prompts.d.ts.map +1 -0
- package/dist/services/vlm/prompts.js +229 -0
- package/dist/services/vlm/prompts.js.map +1 -0
- package/dist/services/vlm/service.d.ts +174 -0
- package/dist/services/vlm/service.d.ts.map +1 -0
- package/dist/services/vlm/service.js +256 -0
- package/dist/services/vlm/service.js.map +1 -0
- package/dist/services/webhook-delivery.d.ts +4 -0
- package/dist/services/webhook-delivery.d.ts.map +1 -0
- package/dist/services/webhook-delivery.js +140 -0
- package/dist/services/webhook-delivery.js.map +1 -0
- package/dist/tools/chunks.d.ts +19 -0
- package/dist/tools/chunks.d.ts.map +1 -0
- package/dist/tools/chunks.js +392 -0
- package/dist/tools/chunks.js.map +1 -0
- package/dist/tools/clm.d.ts +16 -0
- package/dist/tools/clm.d.ts.map +1 -0
- package/dist/tools/clm.js +668 -0
- package/dist/tools/clm.js.map +1 -0
- package/dist/tools/clustering.d.ts +13 -0
- package/dist/tools/clustering.d.ts.map +1 -0
- package/dist/tools/clustering.js +498 -0
- package/dist/tools/clustering.js.map +1 -0
- package/dist/tools/collaboration.d.ts +15 -0
- package/dist/tools/collaboration.d.ts.map +1 -0
- package/dist/tools/collaboration.js +516 -0
- package/dist/tools/collaboration.js.map +1 -0
- package/dist/tools/comparison.d.ts +13 -0
- package/dist/tools/comparison.d.ts.map +1 -0
- package/dist/tools/comparison.js +735 -0
- package/dist/tools/comparison.js.map +1 -0
- package/dist/tools/compliance.d.ts +15 -0
- package/dist/tools/compliance.d.ts.map +1 -0
- package/dist/tools/compliance.js +640 -0
- package/dist/tools/compliance.js.map +1 -0
- package/dist/tools/config.d.ts +19 -0
- package/dist/tools/config.d.ts.map +1 -0
- package/dist/tools/config.js +213 -0
- package/dist/tools/config.js.map +1 -0
- package/dist/tools/database.d.ts +62 -0
- package/dist/tools/database.d.ts.map +1 -0
- package/dist/tools/database.js +288 -0
- package/dist/tools/database.js.map +1 -0
- package/dist/tools/documents.d.ts +61 -0
- package/dist/tools/documents.d.ts.map +1 -0
- package/dist/tools/documents.js +1624 -0
- package/dist/tools/documents.js.map +1 -0
- package/dist/tools/embeddings.d.ts +14 -0
- package/dist/tools/embeddings.d.ts.map +1 -0
- package/dist/tools/embeddings.js +626 -0
- package/dist/tools/embeddings.js.map +1 -0
- package/dist/tools/evaluation.d.ts +25 -0
- package/dist/tools/evaluation.d.ts.map +1 -0
- package/dist/tools/evaluation.js +523 -0
- package/dist/tools/evaluation.js.map +1 -0
- package/dist/tools/events.d.ts +16 -0
- package/dist/tools/events.d.ts.map +1 -0
- package/dist/tools/events.js +493 -0
- package/dist/tools/events.js.map +1 -0
- package/dist/tools/extraction-structured.d.ts +13 -0
- package/dist/tools/extraction-structured.d.ts.map +1 -0
- package/dist/tools/extraction-structured.js +390 -0
- package/dist/tools/extraction-structured.js.map +1 -0
- package/dist/tools/extraction.d.ts +24 -0
- package/dist/tools/extraction.d.ts.map +1 -0
- package/dist/tools/extraction.js +424 -0
- package/dist/tools/extraction.js.map +1 -0
- package/dist/tools/file-management.d.ts +14 -0
- package/dist/tools/file-management.d.ts.map +1 -0
- package/dist/tools/file-management.js +523 -0
- package/dist/tools/file-management.js.map +1 -0
- package/dist/tools/form-fill.d.ts +13 -0
- package/dist/tools/form-fill.d.ts.map +1 -0
- package/dist/tools/form-fill.js +250 -0
- package/dist/tools/form-fill.js.map +1 -0
- package/dist/tools/health.d.ts +19 -0
- package/dist/tools/health.d.ts.map +1 -0
- package/dist/tools/health.js +229 -0
- package/dist/tools/health.js.map +1 -0
- package/dist/tools/images.d.ts +54 -0
- package/dist/tools/images.d.ts.map +1 -0
- package/dist/tools/images.js +787 -0
- package/dist/tools/images.js.map +1 -0
- package/dist/tools/ingestion.d.ts +94 -0
- package/dist/tools/ingestion.d.ts.map +1 -0
- package/dist/tools/ingestion.js +1659 -0
- package/dist/tools/ingestion.js.map +1 -0
- package/dist/tools/intelligence.d.ts +18 -0
- package/dist/tools/intelligence.d.ts.map +1 -0
- package/dist/tools/intelligence.js +1039 -0
- package/dist/tools/intelligence.js.map +1 -0
- package/dist/tools/provenance.d.ts +51 -0
- package/dist/tools/provenance.d.ts.map +1 -0
- package/dist/tools/provenance.js +691 -0
- package/dist/tools/provenance.js.map +1 -0
- package/dist/tools/reports.d.ts +41 -0
- package/dist/tools/reports.d.ts.map +1 -0
- package/dist/tools/reports.js +1394 -0
- package/dist/tools/reports.js.map +1 -0
- package/dist/tools/search.d.ts +35 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +2528 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/shared.d.ts +52 -0
- package/dist/tools/shared.d.ts.map +1 -0
- package/dist/tools/shared.js +54 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/tools/tags.d.ts +15 -0
- package/dist/tools/tags.d.ts.map +1 -0
- package/dist/tools/tags.js +287 -0
- package/dist/tools/tags.js.map +1 -0
- package/dist/tools/timeline.d.ts +15 -0
- package/dist/tools/timeline.d.ts.map +1 -0
- package/dist/tools/timeline.js +14 -0
- package/dist/tools/timeline.js.map +1 -0
- package/dist/tools/users.d.ts +14 -0
- package/dist/tools/users.d.ts.map +1 -0
- package/dist/tools/users.js +257 -0
- package/dist/tools/users.js.map +1 -0
- package/dist/tools/vlm.d.ts +40 -0
- package/dist/tools/vlm.d.ts.map +1 -0
- package/dist/tools/vlm.js +475 -0
- package/dist/tools/vlm.js.map +1 -0
- package/dist/tools/workflow.d.ts +16 -0
- package/dist/tools/workflow.d.ts.map +1 -0
- package/dist/tools/workflow.js +495 -0
- package/dist/tools/workflow.js.map +1 -0
- package/dist/utils/backoff.d.ts +53 -0
- package/dist/utils/backoff.d.ts.map +1 -0
- package/dist/utils/backoff.js +78 -0
- package/dist/utils/backoff.js.map +1 -0
- package/dist/utils/config-persistence.d.ts +33 -0
- package/dist/utils/config-persistence.d.ts.map +1 -0
- package/dist/utils/config-persistence.js +61 -0
- package/dist/utils/config-persistence.js.map +1 -0
- package/dist/utils/hash.d.ts +65 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +146 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/math.d.ts +21 -0
- package/dist/utils/math.d.ts.map +1 -0
- package/dist/utils/math.js +39 -0
- package/dist/utils/math.js.map +1 -0
- package/dist/utils/validation.d.ts +697 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +529 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +96 -0
- package/python/.gitkeep +0 -0
- package/python/__init__.py +104 -0
- package/python/clustering_worker.py +440 -0
- package/python/docx_image_extractor.py +524 -0
- package/python/embedding_worker.py +552 -0
- package/python/file_manager_worker.py +564 -0
- package/python/form_fill_worker.py +399 -0
- package/python/gpu_utils.py +582 -0
- package/python/image_extractor.py +317 -0
- package/python/image_optimizer.py +444 -0
- package/python/ocr_worker.py +712 -0
- package/python/pyproject.toml +76 -0
- package/python/requirements.txt +51 -0
- package/python/reranker_worker.py +87 -0
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
GPU Embedding Worker for OCR Provenance MCP System
|
|
4
|
+
|
|
5
|
+
Generates 768-dimensional embeddings using nomic-embed-text-v1.5.
|
|
6
|
+
Auto-detects best available device: CUDA > MPS > CPU.
|
|
7
|
+
|
|
8
|
+
CRITICAL CONSTRAINTS:
|
|
9
|
+
- CP-004: Local inference ONLY - NEVER fall back to cloud
|
|
10
|
+
- AP-008: NO Flash Attention
|
|
11
|
+
- Task prefixes: "search_document: " for chunks, "search_query: " for queries
|
|
12
|
+
|
|
13
|
+
Usage:
|
|
14
|
+
# Embed chunks (document mode)
|
|
15
|
+
python embedding_worker.py --chunks "text1" "text2" --json
|
|
16
|
+
|
|
17
|
+
# Embed query (search mode)
|
|
18
|
+
python embedding_worker.py --query "search text" --json
|
|
19
|
+
|
|
20
|
+
# From stdin (for large batches from TypeScript)
|
|
21
|
+
echo '["text1", "text2"]' | python embedding_worker.py --stdin --json
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
import argparse
|
|
27
|
+
import json
|
|
28
|
+
import logging
|
|
29
|
+
import os
|
|
30
|
+
import sys
|
|
31
|
+
import time
|
|
32
|
+
from dataclasses import asdict, dataclass
|
|
33
|
+
from pathlib import Path
|
|
34
|
+
|
|
35
|
+
import numpy as np
|
|
36
|
+
import torch
|
|
37
|
+
from sentence_transformers import SentenceTransformer
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
# When run as a script from python/ directory
|
|
41
|
+
from gpu_utils import EmbeddingModelError, GPUNotAvailableError, GPUOutOfMemoryError
|
|
42
|
+
except ImportError:
|
|
43
|
+
# When imported as part of python package
|
|
44
|
+
from .gpu_utils import EmbeddingModelError, GPUNotAvailableError, GPUOutOfMemoryError
|
|
45
|
+
|
|
46
|
+
# Configure logging
|
|
47
|
+
logging.basicConfig(
|
|
48
|
+
level=logging.INFO,
|
|
49
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
50
|
+
stream=sys.stderr,
|
|
51
|
+
)
|
|
52
|
+
logger = logging.getLogger(__name__)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# =============================================================================
|
|
56
|
+
# Constants - DO NOT CHANGE
|
|
57
|
+
# =============================================================================
|
|
58
|
+
|
|
59
|
+
def _resolve_model_path() -> Path:
|
|
60
|
+
"""Resolve embedding model path from env var or default locations."""
|
|
61
|
+
env_path = os.environ.get("EMBEDDING_MODEL_PATH")
|
|
62
|
+
if env_path:
|
|
63
|
+
return Path(env_path)
|
|
64
|
+
# Default: package-relative (works for dev and global npm install)
|
|
65
|
+
pkg_path = Path(__file__).resolve().parent.parent / "models" / "nomic-embed-text-v1.5"
|
|
66
|
+
if pkg_path.exists():
|
|
67
|
+
return pkg_path
|
|
68
|
+
# Fallback: user home directory
|
|
69
|
+
return Path.home() / ".ocr-provenance" / "models" / "nomic-embed-text-v1.5"
|
|
70
|
+
|
|
71
|
+
MODEL_PATH = _resolve_model_path()
|
|
72
|
+
EMBEDDING_DIM = 768
|
|
73
|
+
MODEL_NAME = "nomic-embed-text-v1.5"
|
|
74
|
+
MODEL_VERSION = "1.5.0"
|
|
75
|
+
|
|
76
|
+
# Task prefixes - REQUIRED by nomic model
|
|
77
|
+
PREFIX_DOCUMENT = "search_document: "
|
|
78
|
+
PREFIX_QUERY = "search_query: "
|
|
79
|
+
|
|
80
|
+
# Batch configuration
|
|
81
|
+
DEFAULT_BATCH_SIZE = 512
|
|
82
|
+
MIN_BATCH_SIZE = 1 # Must support single-item batches for VLM descriptions
|
|
83
|
+
|
|
84
|
+
# Device configuration
|
|
85
|
+
DEFAULT_DEVICE = "auto"
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
# =============================================================================
|
|
89
|
+
# Data Classes - MUST match TypeScript interfaces
|
|
90
|
+
# =============================================================================
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@dataclass
|
|
94
|
+
class EmbeddingResult:
|
|
95
|
+
"""
|
|
96
|
+
Result from batch embedding generation.
|
|
97
|
+
MUST match src/models/embedding.ts EmbeddingGenerationResult
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
success: bool
|
|
101
|
+
embeddings: list[list[float]] # (n, 768) as nested list for JSON
|
|
102
|
+
count: int
|
|
103
|
+
elapsed_ms: float
|
|
104
|
+
ms_per_chunk: float
|
|
105
|
+
device: str
|
|
106
|
+
batch_size: int
|
|
107
|
+
model: str = MODEL_NAME
|
|
108
|
+
model_version: str = MODEL_VERSION
|
|
109
|
+
vram_used_gb: float = 0.0
|
|
110
|
+
error: str | None = None
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@dataclass
|
|
114
|
+
class QueryEmbeddingResult:
|
|
115
|
+
"""Result from single query embedding."""
|
|
116
|
+
|
|
117
|
+
success: bool
|
|
118
|
+
embedding: list[float] # (768,) as list for JSON
|
|
119
|
+
elapsed_ms: float
|
|
120
|
+
device: str
|
|
121
|
+
model: str = MODEL_NAME
|
|
122
|
+
error: str | None = None
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# =============================================================================
|
|
126
|
+
# Global Model Singleton
|
|
127
|
+
# =============================================================================
|
|
128
|
+
|
|
129
|
+
_model: SentenceTransformer | None = None
|
|
130
|
+
_device: str | None = None
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
# =============================================================================
|
|
134
|
+
# Core Functions
|
|
135
|
+
# =============================================================================
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def resolve_device(requested: str = DEFAULT_DEVICE) -> str:
|
|
139
|
+
"""
|
|
140
|
+
Resolve the best available compute device.
|
|
141
|
+
|
|
142
|
+
Priority: CUDA > MPS (Apple Silicon) > CPU.
|
|
143
|
+
If a specific device is requested and available, use it.
|
|
144
|
+
If 'auto', detect the best available.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
requested: Requested device string ('auto', 'cuda', 'cuda:0', 'mps', 'cpu')
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
Resolved device string (e.g., 'cuda:0', 'mps', 'cpu')
|
|
151
|
+
"""
|
|
152
|
+
if requested == "auto":
|
|
153
|
+
if torch.cuda.is_available():
|
|
154
|
+
device = "cuda:0"
|
|
155
|
+
logger.info("Auto-detected device: %s (%s)", device, torch.cuda.get_device_name(0))
|
|
156
|
+
return device
|
|
157
|
+
if hasattr(torch.backends, "mps") and torch.backends.mps.is_available():
|
|
158
|
+
logger.info("Auto-detected device: mps (Apple Silicon)")
|
|
159
|
+
return "mps"
|
|
160
|
+
logger.info("Auto-detected device: cpu (no GPU available)")
|
|
161
|
+
return "cpu"
|
|
162
|
+
|
|
163
|
+
# Specific CUDA device requested
|
|
164
|
+
if requested.startswith("cuda"):
|
|
165
|
+
if torch.cuda.is_available():
|
|
166
|
+
return requested
|
|
167
|
+
logger.warning("Requested %s but CUDA unavailable, falling back to auto-detect", requested)
|
|
168
|
+
return resolve_device("auto")
|
|
169
|
+
|
|
170
|
+
# MPS requested
|
|
171
|
+
if requested == "mps":
|
|
172
|
+
if hasattr(torch.backends, "mps") and torch.backends.mps.is_available():
|
|
173
|
+
return "mps"
|
|
174
|
+
logger.warning("Requested mps but MPS unavailable, falling back to auto-detect")
|
|
175
|
+
return resolve_device("auto")
|
|
176
|
+
|
|
177
|
+
# CPU or unknown - use as-is
|
|
178
|
+
return requested
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def load_model(device: str = DEFAULT_DEVICE) -> SentenceTransformer:
|
|
182
|
+
"""
|
|
183
|
+
Load nomic-embed-text-v1.5 to the best available device.
|
|
184
|
+
|
|
185
|
+
Auto-detects device when 'auto' is specified: CUDA > MPS > CPU.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
device: Device string ('auto', 'cuda:0', 'mps', 'cpu')
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
Loaded SentenceTransformer model
|
|
192
|
+
|
|
193
|
+
Raises:
|
|
194
|
+
EmbeddingModelError: Model not found or failed to load
|
|
195
|
+
"""
|
|
196
|
+
global _model, _device
|
|
197
|
+
|
|
198
|
+
# Resolve 'auto' to actual device
|
|
199
|
+
device = resolve_device(device)
|
|
200
|
+
|
|
201
|
+
# Return cached model if same device
|
|
202
|
+
if _model is not None and _device == device:
|
|
203
|
+
return _model
|
|
204
|
+
|
|
205
|
+
logger.info("Loading embedding model to %s...", device)
|
|
206
|
+
|
|
207
|
+
if not MODEL_PATH.exists():
|
|
208
|
+
raise EmbeddingModelError(
|
|
209
|
+
f"Model not found at {MODEL_PATH}. Download with: "
|
|
210
|
+
"huggingface-cli download nomic-ai/nomic-embed-text-v1.5 "
|
|
211
|
+
"--local-dir models/nomic-embed-text-v1.5",
|
|
212
|
+
model_path=str(MODEL_PATH),
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
# Check required files
|
|
216
|
+
required = ["config.json", "model.safetensors", "tokenizer.json"]
|
|
217
|
+
missing = [f for f in required if not (MODEL_PATH / f).exists()]
|
|
218
|
+
if missing:
|
|
219
|
+
raise EmbeddingModelError(f"Missing model files: {missing}", model_path=str(MODEL_PATH))
|
|
220
|
+
|
|
221
|
+
try:
|
|
222
|
+
# Load model - trust_remote_code required for NomicBertModel
|
|
223
|
+
_model = SentenceTransformer(str(MODEL_PATH), device=device, trust_remote_code=True)
|
|
224
|
+
_device = device
|
|
225
|
+
|
|
226
|
+
# Verify dimensions
|
|
227
|
+
dim = _model.get_sentence_embedding_dimension()
|
|
228
|
+
if dim != EMBEDDING_DIM:
|
|
229
|
+
raise EmbeddingModelError(
|
|
230
|
+
f"Wrong embedding dimension: {dim}, expected {EMBEDDING_DIM}",
|
|
231
|
+
model_path=str(MODEL_PATH),
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
logger.info("Model loaded: %s, dim=%d, device=%s", MODEL_NAME, EMBEDDING_DIM, device)
|
|
235
|
+
return _model
|
|
236
|
+
|
|
237
|
+
except (GPUNotAvailableError, EmbeddingModelError):
|
|
238
|
+
raise
|
|
239
|
+
except Exception as e:
|
|
240
|
+
raise EmbeddingModelError(
|
|
241
|
+
f"Failed to load model: {e}", model_path=str(MODEL_PATH), cause=e
|
|
242
|
+
) from e
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def embed_chunks(
|
|
246
|
+
chunks: list[str], batch_size: int = DEFAULT_BATCH_SIZE, device: str = DEFAULT_DEVICE
|
|
247
|
+
) -> np.ndarray:
|
|
248
|
+
"""
|
|
249
|
+
Embed document chunks with "search_document: " prefix.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
chunks: Text chunks to embed
|
|
253
|
+
batch_size: GPU batch size (default 512)
|
|
254
|
+
device: CUDA device
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
np.ndarray of shape (n_chunks, 768), dtype float32
|
|
258
|
+
|
|
259
|
+
Raises:
|
|
260
|
+
GPUNotAvailableError: No GPU
|
|
261
|
+
EmbeddingModelError: Model error
|
|
262
|
+
"""
|
|
263
|
+
if not chunks:
|
|
264
|
+
return np.zeros((0, EMBEDDING_DIM), dtype=np.float32)
|
|
265
|
+
|
|
266
|
+
model = load_model(device)
|
|
267
|
+
resolved = resolve_device(device)
|
|
268
|
+
|
|
269
|
+
# Add task prefix - REQUIRED by nomic model
|
|
270
|
+
prefixed = [f"{PREFIX_DOCUMENT}{chunk}" for chunk in chunks]
|
|
271
|
+
|
|
272
|
+
# Generate embeddings
|
|
273
|
+
embeddings = model.encode(
|
|
274
|
+
prefixed,
|
|
275
|
+
batch_size=batch_size,
|
|
276
|
+
convert_to_numpy=True,
|
|
277
|
+
normalize_embeddings=True, # L2 normalize for cosine similarity
|
|
278
|
+
show_progress_bar=False,
|
|
279
|
+
device=resolved,
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
return embeddings.astype(np.float32)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def embed_query(query: str, device: str = DEFAULT_DEVICE) -> np.ndarray:
|
|
286
|
+
"""
|
|
287
|
+
Embed search query with "search_query: " prefix.
|
|
288
|
+
|
|
289
|
+
Args:
|
|
290
|
+
query: Search query text
|
|
291
|
+
device: Device string ('auto', 'cuda:0', 'mps', 'cpu')
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
np.ndarray of shape (768,), dtype float32
|
|
295
|
+
"""
|
|
296
|
+
model = load_model(device)
|
|
297
|
+
resolved = resolve_device(device)
|
|
298
|
+
|
|
299
|
+
# Add query task prefix
|
|
300
|
+
prefixed = f"{PREFIX_QUERY}{query}"
|
|
301
|
+
|
|
302
|
+
embedding = model.encode(
|
|
303
|
+
[prefixed],
|
|
304
|
+
convert_to_numpy=True,
|
|
305
|
+
normalize_embeddings=True,
|
|
306
|
+
show_progress_bar=False,
|
|
307
|
+
device=resolved,
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
return embedding[0].astype(np.float32)
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def embed_with_oom_recovery(
|
|
314
|
+
chunks: list[str],
|
|
315
|
+
initial_batch_size: int = DEFAULT_BATCH_SIZE,
|
|
316
|
+
device: str = DEFAULT_DEVICE,
|
|
317
|
+
) -> tuple[np.ndarray, int]:
|
|
318
|
+
"""
|
|
319
|
+
Embed with automatic OOM recovery via batch size reduction.
|
|
320
|
+
|
|
321
|
+
Halves batch size on OOM until MIN_BATCH_SIZE.
|
|
322
|
+
|
|
323
|
+
Args:
|
|
324
|
+
chunks: Text chunks to embed
|
|
325
|
+
initial_batch_size: Starting batch size
|
|
326
|
+
device: CUDA device
|
|
327
|
+
|
|
328
|
+
Returns:
|
|
329
|
+
Tuple of (embeddings, final_batch_size)
|
|
330
|
+
|
|
331
|
+
Raises:
|
|
332
|
+
GPUOutOfMemoryError: OOM at minimum batch size
|
|
333
|
+
"""
|
|
334
|
+
batch_size = initial_batch_size
|
|
335
|
+
is_cuda = resolve_device(device).startswith("cuda")
|
|
336
|
+
|
|
337
|
+
while batch_size >= MIN_BATCH_SIZE:
|
|
338
|
+
try:
|
|
339
|
+
if is_cuda:
|
|
340
|
+
torch.cuda.empty_cache()
|
|
341
|
+
embeddings = embed_chunks(chunks, batch_size, device)
|
|
342
|
+
return embeddings, batch_size
|
|
343
|
+
except (torch.cuda.OutOfMemoryError, MemoryError, RuntimeError) as e:
|
|
344
|
+
if isinstance(e, RuntimeError) and "out of memory" not in str(e).lower():
|
|
345
|
+
raise
|
|
346
|
+
if is_cuda:
|
|
347
|
+
torch.cuda.empty_cache()
|
|
348
|
+
batch_size //= 2
|
|
349
|
+
if batch_size >= MIN_BATCH_SIZE:
|
|
350
|
+
logger.warning("OOM: Reducing batch size to %d", batch_size)
|
|
351
|
+
|
|
352
|
+
raise GPUOutOfMemoryError(
|
|
353
|
+
f"OOM with {len(chunks)} chunks on {device}. "
|
|
354
|
+
f"Tried batch sizes {initial_batch_size} down to {MIN_BATCH_SIZE}.",
|
|
355
|
+
vram_required=None,
|
|
356
|
+
vram_available=None,
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def generate_embeddings(
|
|
361
|
+
chunks: list[str],
|
|
362
|
+
batch_size: int = DEFAULT_BATCH_SIZE,
|
|
363
|
+
device: str = DEFAULT_DEVICE,
|
|
364
|
+
) -> EmbeddingResult:
|
|
365
|
+
"""
|
|
366
|
+
Generate embeddings with full metrics for TypeScript bridge.
|
|
367
|
+
|
|
368
|
+
This is the main entry point for batch embedding.
|
|
369
|
+
|
|
370
|
+
Args:
|
|
371
|
+
chunks: Text chunks to embed
|
|
372
|
+
batch_size: Initial batch size
|
|
373
|
+
device: CUDA device
|
|
374
|
+
|
|
375
|
+
Returns:
|
|
376
|
+
EmbeddingResult with embeddings and metrics
|
|
377
|
+
"""
|
|
378
|
+
start_time = time.perf_counter()
|
|
379
|
+
resolved_device = resolve_device(device)
|
|
380
|
+
is_cuda = resolved_device.startswith("cuda")
|
|
381
|
+
|
|
382
|
+
# Reset VRAM tracking (CUDA only)
|
|
383
|
+
if is_cuda:
|
|
384
|
+
torch.cuda.reset_peak_memory_stats()
|
|
385
|
+
|
|
386
|
+
try:
|
|
387
|
+
embeddings_np, final_batch_size = embed_with_oom_recovery(chunks, batch_size, device)
|
|
388
|
+
|
|
389
|
+
elapsed_ms = (time.perf_counter() - start_time) * 1000
|
|
390
|
+
ms_per_chunk = elapsed_ms / len(chunks) if chunks else 0
|
|
391
|
+
vram_gb = torch.cuda.max_memory_allocated() / (1024**3) if is_cuda else 0.0
|
|
392
|
+
|
|
393
|
+
# H-8: Convert to list and delete numpy array to avoid ~7x memory overlap
|
|
394
|
+
# (numpy float32 ~1.5MB vs Python float64 list ~10.7MB for 500x768)
|
|
395
|
+
embeddings_list = embeddings_np.tolist()
|
|
396
|
+
del embeddings_np
|
|
397
|
+
|
|
398
|
+
return EmbeddingResult(
|
|
399
|
+
success=True,
|
|
400
|
+
embeddings=embeddings_list,
|
|
401
|
+
count=len(chunks),
|
|
402
|
+
elapsed_ms=round(elapsed_ms, 2),
|
|
403
|
+
ms_per_chunk=round(ms_per_chunk, 4),
|
|
404
|
+
device=resolved_device,
|
|
405
|
+
batch_size=final_batch_size,
|
|
406
|
+
vram_used_gb=round(vram_gb, 3),
|
|
407
|
+
error=None,
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
except Exception as e:
|
|
411
|
+
elapsed_ms = (time.perf_counter() - start_time) * 1000
|
|
412
|
+
logger.error("Embedding generation failed: %s", e)
|
|
413
|
+
return EmbeddingResult(
|
|
414
|
+
success=False,
|
|
415
|
+
embeddings=[],
|
|
416
|
+
count=0,
|
|
417
|
+
elapsed_ms=round(elapsed_ms, 2),
|
|
418
|
+
ms_per_chunk=0,
|
|
419
|
+
device=resolved_device,
|
|
420
|
+
batch_size=batch_size,
|
|
421
|
+
error=str(e),
|
|
422
|
+
)
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def generate_query_embedding(query: str, device: str = DEFAULT_DEVICE) -> QueryEmbeddingResult:
|
|
426
|
+
"""
|
|
427
|
+
Generate query embedding with metrics.
|
|
428
|
+
|
|
429
|
+
Args:
|
|
430
|
+
query: Search query text
|
|
431
|
+
device: CUDA device
|
|
432
|
+
|
|
433
|
+
Returns:
|
|
434
|
+
QueryEmbeddingResult with embedding and metrics
|
|
435
|
+
"""
|
|
436
|
+
start_time = time.perf_counter()
|
|
437
|
+
resolved_device = resolve_device(device)
|
|
438
|
+
|
|
439
|
+
try:
|
|
440
|
+
embedding = embed_query(query, device)
|
|
441
|
+
elapsed_ms = (time.perf_counter() - start_time) * 1000
|
|
442
|
+
|
|
443
|
+
return QueryEmbeddingResult(
|
|
444
|
+
success=True,
|
|
445
|
+
embedding=embedding.tolist(),
|
|
446
|
+
elapsed_ms=round(elapsed_ms, 2),
|
|
447
|
+
device=resolved_device,
|
|
448
|
+
error=None,
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
except Exception as e:
|
|
452
|
+
elapsed_ms = (time.perf_counter() - start_time) * 1000
|
|
453
|
+
logger.error("Query embedding failed: %s", e)
|
|
454
|
+
return QueryEmbeddingResult(
|
|
455
|
+
success=False,
|
|
456
|
+
embedding=[],
|
|
457
|
+
elapsed_ms=round(elapsed_ms, 2),
|
|
458
|
+
device=resolved_device,
|
|
459
|
+
error=str(e),
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
# =============================================================================
|
|
464
|
+
# CLI Entry Point
|
|
465
|
+
# =============================================================================
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
def main() -> None:
|
|
469
|
+
"""CLI entry point for embedding worker."""
|
|
470
|
+
parser = argparse.ArgumentParser(
|
|
471
|
+
description="GPU Embedding Worker - nomic-embed-text-v1.5",
|
|
472
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
473
|
+
epilog="""
|
|
474
|
+
Examples:
|
|
475
|
+
python embedding_worker.py --chunks "text1" "text2" --json
|
|
476
|
+
python embedding_worker.py --query "search text" --json
|
|
477
|
+
echo '["text1", "text2"]' | python embedding_worker.py --stdin --json
|
|
478
|
+
""",
|
|
479
|
+
)
|
|
480
|
+
|
|
481
|
+
# Input modes (mutually exclusive)
|
|
482
|
+
input_group = parser.add_mutually_exclusive_group(required=True)
|
|
483
|
+
input_group.add_argument("--chunks", nargs="+", help="Texts to embed")
|
|
484
|
+
input_group.add_argument("--query", help="Search query to embed")
|
|
485
|
+
input_group.add_argument("--stdin", action="store_true", help="Read JSON array from stdin")
|
|
486
|
+
|
|
487
|
+
# Configuration
|
|
488
|
+
parser.add_argument(
|
|
489
|
+
"--batch-size", type=int, default=DEFAULT_BATCH_SIZE, help="Batch size for GPU"
|
|
490
|
+
)
|
|
491
|
+
parser.add_argument("--device", default=DEFAULT_DEVICE, help="CUDA device")
|
|
492
|
+
parser.add_argument("--model-path", help="Path to embedding model directory")
|
|
493
|
+
parser.add_argument("--json", action="store_true", help="JSON output for TypeScript bridge")
|
|
494
|
+
|
|
495
|
+
args = parser.parse_args()
|
|
496
|
+
|
|
497
|
+
# Override model path if specified via CLI
|
|
498
|
+
if args.model_path:
|
|
499
|
+
global MODEL_PATH
|
|
500
|
+
MODEL_PATH = Path(args.model_path)
|
|
501
|
+
|
|
502
|
+
try:
|
|
503
|
+
if args.query:
|
|
504
|
+
# Query mode
|
|
505
|
+
result = generate_query_embedding(args.query, args.device)
|
|
506
|
+
|
|
507
|
+
else:
|
|
508
|
+
# Chunk mode
|
|
509
|
+
if args.stdin:
|
|
510
|
+
chunks = json.load(sys.stdin)
|
|
511
|
+
if not isinstance(chunks, list):
|
|
512
|
+
raise ValueError("stdin must be a JSON array of strings")
|
|
513
|
+
else:
|
|
514
|
+
chunks = args.chunks
|
|
515
|
+
|
|
516
|
+
result = generate_embeddings(chunks, args.batch_size, args.device)
|
|
517
|
+
|
|
518
|
+
if args.json:
|
|
519
|
+
print(json.dumps(asdict(result)))
|
|
520
|
+
else:
|
|
521
|
+
# Human readable output
|
|
522
|
+
if isinstance(result, EmbeddingResult):
|
|
523
|
+
if result.success:
|
|
524
|
+
throughput = 1000 / result.ms_per_chunk if result.ms_per_chunk > 0 else 0
|
|
525
|
+
print(f"Embedded {result.count} chunks in {result.elapsed_ms}ms")
|
|
526
|
+
print(f"Throughput: {throughput:.0f} chunks/sec")
|
|
527
|
+
print(f"VRAM used: {result.vram_used_gb:.3f} GB")
|
|
528
|
+
else:
|
|
529
|
+
print(f"ERROR: {result.error}", file=sys.stderr)
|
|
530
|
+
sys.exit(1)
|
|
531
|
+
else:
|
|
532
|
+
if result.success:
|
|
533
|
+
print(f"Query embedded in {result.elapsed_ms}ms")
|
|
534
|
+
else:
|
|
535
|
+
print(f"ERROR: {result.error}", file=sys.stderr)
|
|
536
|
+
sys.exit(1)
|
|
537
|
+
|
|
538
|
+
except Exception as e:
|
|
539
|
+
error_result = {
|
|
540
|
+
"success": False,
|
|
541
|
+
"error": str(e),
|
|
542
|
+
"error_type": type(e).__name__,
|
|
543
|
+
}
|
|
544
|
+
if args.json:
|
|
545
|
+
print(json.dumps(error_result))
|
|
546
|
+
else:
|
|
547
|
+
print(f"ERROR: {e}", file=sys.stderr)
|
|
548
|
+
sys.exit(1)
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
if __name__ == "__main__":
|
|
552
|
+
main()
|