@path58/n8n-mcp 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/AGENT_INSTALL.md +223 -0
- package/CHANGELOG.md +38 -0
- package/LICENSE +21 -0
- package/README.md +187 -0
- package/dist/autofix/suggestion-fixers/deprecated-node-fixer.js +465 -0
- package/dist/autofix/suggestion-fixers/deprecated-node-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/fixer-registry.js +495 -0
- package/dist/autofix/suggestion-fixers/fixer-registry.js.map +1 -0
- package/dist/autofix/suggestion-fixers/l1-structure-fixer.js +639 -0
- package/dist/autofix/suggestion-fixers/l1-structure-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/l4-connection-fixer.js +449 -0
- package/dist/autofix/suggestion-fixers/l4-connection-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/l5-parameter-fixer.js +575 -0
- package/dist/autofix/suggestion-fixers/l5-parameter-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/l5-typeversion-fixer.js +431 -0
- package/dist/autofix/suggestion-fixers/l5-typeversion-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/l5-webhook-path-fixer.js +356 -0
- package/dist/autofix/suggestion-fixers/l5-webhook-path-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/l6-ai-tool-variant-fixer.js +618 -0
- package/dist/autofix/suggestion-fixers/l6-ai-tool-variant-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/l6-pattern-fixer.js +1475 -0
- package/dist/autofix/suggestion-fixers/l6-pattern-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/llm-fixer.js +716 -0
- package/dist/autofix/suggestion-fixers/llm-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/missing-credential-fixer.js +336 -0
- package/dist/autofix/suggestion-fixers/missing-credential-fixer.js.map +1 -0
- package/dist/autofix/suggestion-fixers/types.js +29 -0
- package/dist/autofix/suggestion-fixers/types.js.map +1 -0
- package/dist/autofix/suggestion-fixers/typo-fixer.js +197 -0
- package/dist/autofix/suggestion-fixers/typo-fixer.js.map +1 -0
- package/dist/classification/certification-engine.js +208 -0
- package/dist/classification/certification-engine.js.map +1 -0
- package/dist/classification/feedback-collector.js +516 -0
- package/dist/classification/feedback-collector.js.map +1 -0
- package/dist/classification/l5-parameter-analyzer.js +670 -0
- package/dist/classification/l5-parameter-analyzer.js.map +1 -0
- package/dist/classification/l6-graph-analyzer.js +613 -0
- package/dist/classification/l6-graph-analyzer.js.map +1 -0
- package/dist/classification/severity-classifier.js +237 -0
- package/dist/classification/severity-classifier.js.map +1 -0
- package/dist/config/env.js +280 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/env.schema.js +234 -0
- package/dist/config/env.schema.js.map +1 -0
- package/dist/config/scraperEnv.js +55 -0
- package/dist/config/scraperEnv.js.map +1 -0
- package/dist/db/postgresClient.js +38 -0
- package/dist/db/postgresClient.js.map +1 -0
- package/dist/db/scraperDb.js +6 -0
- package/dist/db/scraperDb.js.map +1 -0
- package/dist/db/scraperPostgresClient.js +118 -0
- package/dist/db/scraperPostgresClient.js.map +1 -0
- package/dist/db/validationRepository.js +55 -0
- package/dist/db/validationRepository.js.map +1 -0
- package/dist/db/validatorPostgresClient.js +248 -0
- package/dist/db/validatorPostgresClient.js.map +1 -0
- package/dist/db/workflowInstanceMappingRepository.js +128 -0
- package/dist/db/workflowInstanceMappingRepository.js.map +1 -0
- package/dist/errors/AppError.js +156 -0
- package/dist/errors/AppError.js.map +1 -0
- package/dist/errors/index.js +7 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/factory/error-to-problem-mappers.js +385 -0
- package/dist/factory/error-to-problem-mappers.js.map +1 -0
- package/dist/factory/gap-recorder.js +260 -0
- package/dist/factory/gap-recorder.js.map +1 -0
- package/dist/factory/problem-recorder.js +94 -0
- package/dist/factory/problem-recorder.js.map +1 -0
- package/dist/factory/warning-to-gap-mappers.js +493 -0
- package/dist/factory/warning-to-gap-mappers.js.map +1 -0
- package/dist/factory/workflow-normalizer.js +247 -0
- package/dist/factory/workflow-normalizer.js.map +1 -0
- package/dist/mcp/adapters/catalog.js +13 -0
- package/dist/mcp/adapters/catalog.js.map +1 -0
- package/dist/mcp/adapters/index.js +36 -0
- package/dist/mcp/adapters/index.js.map +1 -0
- package/dist/mcp/adapters/supabase-catalog.js +467 -0
- package/dist/mcp/adapters/supabase-catalog.js.map +1 -0
- package/dist/mcp/adapters/test-catalog-adapter.js +100 -0
- package/dist/mcp/adapters/test-catalog-adapter.js.map +1 -0
- package/dist/mcp/adapters/validation.js +258 -0
- package/dist/mcp/adapters/validation.js.map +1 -0
- package/dist/mcp/build-email-workflow.js +113 -0
- package/dist/mcp/build-email-workflow.js.map +1 -0
- package/dist/mcp/config.js +22 -0
- package/dist/mcp/config.js.map +1 -0
- package/dist/mcp/formatters/errors.js +217 -0
- package/dist/mcp/formatters/errors.js.map +1 -0
- package/dist/mcp/formatters/index.js +12 -0
- package/dist/mcp/formatters/index.js.map +1 -0
- package/dist/mcp/formatters/response.js +141 -0
- package/dist/mcp/formatters/response.js.map +1 -0
- package/dist/mcp/quick-test.js +33 -0
- package/dist/mcp/quick-test.js.map +1 -0
- package/dist/mcp/server.js +70 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/test-mcp-error.js +81 -0
- package/dist/mcp/test-mcp-error.js.map +1 -0
- package/dist/mcp/test-mcp.js +80 -0
- package/dist/mcp/test-mcp.js.map +1 -0
- package/dist/mcp/tools/fixes/expression-fixes.js +166 -0
- package/dist/mcp/tools/fixes/expression-fixes.js.map +1 -0
- package/dist/mcp/tools/fixes/flow-fixes.js +155 -0
- package/dist/mcp/tools/fixes/flow-fixes.js.map +1 -0
- package/dist/mcp/tools/fixes/index.js +91 -0
- package/dist/mcp/tools/fixes/index.js.map +1 -0
- package/dist/mcp/tools/fixes/node-fixes.js +233 -0
- package/dist/mcp/tools/fixes/node-fixes.js.map +1 -0
- package/dist/mcp/tools/fixes/parameter-fixes.js +277 -0
- package/dist/mcp/tools/fixes/parameter-fixes.js.map +1 -0
- package/dist/mcp/tools/fixes/types.js +10 -0
- package/dist/mcp/tools/fixes/types.js.map +1 -0
- package/dist/mcp/tools/handlers/check-parameter.js +300 -0
- package/dist/mcp/tools/handlers/check-parameter.js.map +1 -0
- package/dist/mcp/tools/handlers/find-similar-pattern.js +121 -0
- package/dist/mcp/tools/handlers/find-similar-pattern.js.map +1 -0
- package/dist/mcp/tools/handlers/get-node-info.js +131 -0
- package/dist/mcp/tools/handlers/get-node-info.js.map +1 -0
- package/dist/mcp/tools/handlers/get-operation-schema.js +141 -0
- package/dist/mcp/tools/handlers/get-operation-schema.js.map +1 -0
- package/dist/mcp/tools/handlers/list-nodes.js +126 -0
- package/dist/mcp/tools/handlers/list-nodes.js.map +1 -0
- package/dist/mcp/tools/handlers/list-operations.js +138 -0
- package/dist/mcp/tools/handlers/list-operations.js.map +1 -0
- package/dist/mcp/tools/handlers/suggest-fix.js +120 -0
- package/dist/mcp/tools/handlers/suggest-fix.js.map +1 -0
- package/dist/mcp/tools/handlers/validate-workflow.js +92 -0
- package/dist/mcp/tools/handlers/validate-workflow.js.map +1 -0
- package/dist/mcp/tools/index.js +190 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/schemas.js +195 -0
- package/dist/mcp/tools/schemas.js.map +1 -0
- package/dist/mcp/tools/validate.js +95 -0
- package/dist/mcp/tools/validate.js.map +1 -0
- package/dist/mcp/types/mcp.js +7 -0
- package/dist/mcp/types/mcp.js.map +1 -0
- package/dist/mcp/utils/timeout.js +78 -0
- package/dist/mcp/utils/timeout.js.map +1 -0
- package/dist/services/BatchProcessor.js +433 -0
- package/dist/services/BatchProcessor.js.map +1 -0
- package/dist/services/CheckpointManager.js +281 -0
- package/dist/services/CheckpointManager.js.map +1 -0
- package/dist/services/CostCalculator.js +211 -0
- package/dist/services/CostCalculator.js.map +1 -0
- package/dist/services/EmbeddingCache.js +68 -0
- package/dist/services/EmbeddingCache.js.map +1 -0
- package/dist/services/EmbeddingService.js +143 -0
- package/dist/services/EmbeddingService.js.map +1 -0
- package/dist/services/RankingService.js +81 -0
- package/dist/services/RankingService.js.map +1 -0
- package/dist/services/RedisCache.js +376 -0
- package/dist/services/RedisCache.js.map +1 -0
- package/dist/services/RedisCatalogCache.js +680 -0
- package/dist/services/RedisCatalogCache.js.map +1 -0
- package/dist/services/ResumeManager.js +252 -0
- package/dist/services/ResumeManager.js.map +1 -0
- package/dist/services/SearchService.js +282 -0
- package/dist/services/SearchService.js.map +1 -0
- package/dist/services/SemanticCatalogSearch.js +405 -0
- package/dist/services/SemanticCatalogSearch.js.map +1 -0
- package/dist/services/ValidationCache.js +157 -0
- package/dist/services/ValidationCache.js.map +1 -0
- package/dist/services/WorkflowPipelineService.js +1997 -0
- package/dist/services/WorkflowPipelineService.js.map +1 -0
- package/dist/services/catalog/index.js +34 -0
- package/dist/services/catalog/index.js.map +1 -0
- package/dist/services/catalog/interfaces.js +17 -0
- package/dist/services/catalog/interfaces.js.map +1 -0
- package/dist/services/catalog/loaders.js +169 -0
- package/dist/services/catalog/loaders.js.map +1 -0
- package/dist/services/catalog/types.js +138 -0
- package/dist/services/catalog/types.js.map +1 -0
- package/dist/services/documentation-normalization/docUrlUtils.js +88 -0
- package/dist/services/documentation-normalization/docUrlUtils.js.map +1 -0
- package/dist/services/error-quality/ErrorQualityService.js +262 -0
- package/dist/services/error-quality/ErrorQualityService.js.map +1 -0
- package/dist/services/error-quality/analyzers/CredentialAnalyzer.js +260 -0
- package/dist/services/error-quality/analyzers/CredentialAnalyzer.js.map +1 -0
- package/dist/services/error-quality/analyzers/IssuePredictor.js +380 -0
- package/dist/services/error-quality/analyzers/IssuePredictor.js.map +1 -0
- package/dist/services/error-quality/analyzers/MockCoverageAnalyzer.js +267 -0
- package/dist/services/error-quality/analyzers/MockCoverageAnalyzer.js.map +1 -0
- package/dist/services/error-quality/data/ErrorPatternSeeder.js +963 -0
- package/dist/services/error-quality/data/ErrorPatternSeeder.js.map +1 -0
- package/dist/services/error-quality/index.js +25 -0
- package/dist/services/error-quality/index.js.map +1 -0
- package/dist/services/error-quality/reports/ReportGenerator.js +343 -0
- package/dist/services/error-quality/reports/ReportGenerator.js.map +1 -0
- package/dist/services/error-quality/taxonomy/ErrorTaxonomy.js +698 -0
- package/dist/services/error-quality/taxonomy/ErrorTaxonomy.js.map +1 -0
- package/dist/services/error-quality/types.js +11 -0
- package/dist/services/error-quality/types.js.map +1 -0
- package/dist/services/progress/ProgressTracker.js +288 -0
- package/dist/services/progress/ProgressTracker.js.map +1 -0
- package/dist/services/progress/formatters.js +122 -0
- package/dist/services/progress/formatters.js.map +1 -0
- package/dist/services/progress/index.js +36 -0
- package/dist/services/progress/index.js.map +1 -0
- package/dist/services/progress/types.js +7 -0
- package/dist/services/progress/types.js.map +1 -0
- package/dist/services/search/embeddingGenerator.js +112 -0
- package/dist/services/search/embeddingGenerator.js.map +1 -0
- package/dist/types/aiCapabilities.js +7 -0
- package/dist/types/aiCapabilities.js.map +1 -0
- package/dist/types/aiConfigSchema.js +7 -0
- package/dist/types/aiConfigSchema.js.map +1 -0
- package/dist/utils/bannerLogger.js +186 -0
- package/dist/utils/bannerLogger.js.map +1 -0
- package/dist/utils/bannerService.js +23 -0
- package/dist/utils/bannerService.js.map +1 -0
- package/dist/utils/bannerServiceAdapter.js +54 -0
- package/dist/utils/bannerServiceAdapter.js.map +1 -0
- package/dist/utils/batchLogger.js +171 -0
- package/dist/utils/batchLogger.js.map +1 -0
- package/dist/utils/bottomStickyBanner.js +239 -0
- package/dist/utils/bottomStickyBanner.js.map +1 -0
- package/dist/utils/credentialMatcher.js +206 -0
- package/dist/utils/credentialMatcher.js.map +1 -0
- package/dist/utils/credentialNormalizer.js +442 -0
- package/dist/utils/credentialNormalizer.js.map +1 -0
- package/dist/utils/integratedBannerLogger.js +59 -0
- package/dist/utils/integratedBannerLogger.js.map +1 -0
- package/dist/utils/n8nSourceGit.js +195 -0
- package/dist/utils/n8nSourceGit.js.map +1 -0
- package/dist/utils/nodeTypeNormalizer.js +131 -0
- package/dist/utils/nodeTypeNormalizer.js.map +1 -0
- package/dist/utils/openaiClient.js +397 -0
- package/dist/utils/openaiClient.js.map +1 -0
- package/dist/utils/productionLogger.js +16 -0
- package/dist/utils/productionLogger.js.map +1 -0
- package/dist/utils/progressBarBanner.js +132 -0
- package/dist/utils/progressBarBanner.js.map +1 -0
- package/dist/utils/scriptHeartbeat.js +117 -0
- package/dist/utils/scriptHeartbeat.js.map +1 -0
- package/dist/utils/scriptLogger.js +125 -0
- package/dist/utils/scriptLogger.js.map +1 -0
- package/dist/utils/scriptRunner.js +95 -0
- package/dist/utils/scriptRunner.js.map +1 -0
- package/dist/utils/scriptTimeout.js +128 -0
- package/dist/utils/scriptTimeout.js.map +1 -0
- package/dist/utils/scriptWrapper.js +219 -0
- package/dist/utils/scriptWrapper.js.map +1 -0
- package/dist/utils/stickyBanner.js +226 -0
- package/dist/utils/stickyBanner.js.map +1 -0
- package/dist/utils/terminalSpinner.js +97 -0
- package/dist/utils/terminalSpinner.js.map +1 -0
- package/dist/utils/threeLineBanner.js +427 -0
- package/dist/utils/threeLineBanner.js.map +1 -0
- package/dist/utils/validatorCheckpointManager.js +170 -0
- package/dist/utils/validatorCheckpointManager.js.map +1 -0
- package/dist/utils/validatorConnectionManager.js +124 -0
- package/dist/utils/validatorConnectionManager.js.map +1 -0
- package/dist/validation/catalog.js +56 -0
- package/dist/validation/catalog.js.map +1 -0
- package/dist/validation/config/deprecated-nodes.js +234 -0
- package/dist/validation/config/deprecated-nodes.js.map +1 -0
- package/dist/validation/config/l6-severity.js +227 -0
- package/dist/validation/config/l6-severity.js.map +1 -0
- package/dist/validation/config/terminal-nodes.js +132 -0
- package/dist/validation/config/terminal-nodes.js.map +1 -0
- package/dist/validation/config/unreachable-nodes.js +67 -0
- package/dist/validation/config/unreachable-nodes.js.map +1 -0
- package/dist/validation/core.js +47 -0
- package/dist/validation/core.js.map +1 -0
- package/dist/validation/docExtraction.js +12 -0
- package/dist/validation/docExtraction.js.map +1 -0
- package/dist/validation/dryRunMockRunner.js +128 -0
- package/dist/validation/dryRunMockRunner.js.map +1 -0
- package/dist/validation/fixtureEngine.js +61 -0
- package/dist/validation/fixtureEngine.js.map +1 -0
- package/dist/validation/index.js +15 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/k-levels/k2-blockers.js +222 -0
- package/dist/validation/k-levels/k2-blockers.js.map +1 -0
- package/dist/validation/l1-structure.js +296 -0
- package/dist/validation/l1-structure.js.map +1 -0
- package/dist/validation/l2-nodes.js +282 -0
- package/dist/validation/l2-nodes.js.map +1 -0
- package/dist/validation/l3-credentials.js +322 -0
- package/dist/validation/l3-credentials.js.map +1 -0
- package/dist/validation/l4-connections.js +698 -0
- package/dist/validation/l4-connections.js.map +1 -0
- package/dist/validation/l5-parameters.js +803 -0
- package/dist/validation/l5-parameters.js.map +1 -0
- package/dist/validation/l6-checks/ai-tool-variants.js +407 -0
- package/dist/validation/l6-checks/ai-tool-variants.js.map +1 -0
- package/dist/validation/l6-checks/catalog-checks.js +260 -0
- package/dist/validation/l6-checks/catalog-checks.js.map +1 -0
- package/dist/validation/l6-checks/data-contracts.js +197 -0
- package/dist/validation/l6-checks/data-contracts.js.map +1 -0
- package/dist/validation/l6-checks/deprecation.js +133 -0
- package/dist/validation/l6-checks/deprecation.js.map +1 -0
- package/dist/validation/l6-checks/error-handling.js +193 -0
- package/dist/validation/l6-checks/error-handling.js.map +1 -0
- package/dist/validation/l6-checks/expression-syntax.js +387 -0
- package/dist/validation/l6-checks/expression-syntax.js.map +1 -0
- package/dist/validation/l6-checks/flow-integrity.js +504 -0
- package/dist/validation/l6-checks/flow-integrity.js.map +1 -0
- package/dist/validation/l6-checks/index.js +106 -0
- package/dist/validation/l6-checks/index.js.map +1 -0
- package/dist/validation/l6-checks/loops.js +370 -0
- package/dist/validation/l6-checks/loops.js.map +1 -0
- package/dist/validation/l6-checks/performance.js +182 -0
- package/dist/validation/l6-checks/performance.js.map +1 -0
- package/dist/validation/l6-checks/security.js +273 -0
- package/dist/validation/l6-checks/security.js.map +1 -0
- package/dist/validation/l6-patterns.js +472 -0
- package/dist/validation/l6-patterns.js.map +1 -0
- package/dist/validation/mockLevelResolver.js +95 -0
- package/dist/validation/mockLevelResolver.js.map +1 -0
- package/dist/validation/n8nApiClient.js +21 -0
- package/dist/validation/n8nApiClient.js.map +1 -0
- package/dist/validation/n8nCli.js +87 -0
- package/dist/validation/n8nCli.js.map +1 -0
- package/dist/validation/types.js +8 -0
- package/dist/validation/types.js.map +1 -0
- package/dist/validation/usageStats.js +82 -0
- package/dist/validation/usageStats.js.map +1 -0
- package/package.json +274 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkpoint Manager Service
|
|
3
|
+
*
|
|
4
|
+
* Enhanced checkpoint/resume capability for long-running pipeline operations.
|
|
5
|
+
* Saves full state to database for reliable resume after interruptions.
|
|
6
|
+
*
|
|
7
|
+
* **Extends shared-utilities patterns:**
|
|
8
|
+
* - Follows shared-utilities CheckpointManager concepts
|
|
9
|
+
* - Enhanced for pipeline operations with full state tracking
|
|
10
|
+
* - Supports arrays of processed/failed items (not just last ID)
|
|
11
|
+
* - Detailed progress metrics (not just counts)
|
|
12
|
+
* - Full state restoration for complex operations
|
|
13
|
+
*
|
|
14
|
+
* **Integration:**
|
|
15
|
+
* - Integrates with banner service for progress display
|
|
16
|
+
* - Works with script runner for automatic checkpoint management
|
|
17
|
+
* - Reports checkpoint progress to banner service when provided
|
|
18
|
+
*
|
|
19
|
+
* Features:
|
|
20
|
+
* - Save checkpoint state to database
|
|
21
|
+
* - Load checkpoint state
|
|
22
|
+
* - Update checkpoint progress
|
|
23
|
+
* - Clear checkpoints
|
|
24
|
+
* - List checkpoints
|
|
25
|
+
* - Automatic state persistence
|
|
26
|
+
* - Banner service integration (optional)
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const checkpointManager = new CheckpointManager();
|
|
31
|
+
*
|
|
32
|
+
* // Save checkpoint
|
|
33
|
+
* await checkpointManager.saveCheckpoint({
|
|
34
|
+
* key: 'node-embeddings-v1',
|
|
35
|
+
* pipelineType: 'embedding',
|
|
36
|
+
* state: { processed: 100, success: 95, failed: 5 },
|
|
37
|
+
* processedItems: ['node1', 'node2'],
|
|
38
|
+
* failedItems: ['node3'],
|
|
39
|
+
* progress: { total: 1000, processed: 100 }
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* // Load checkpoint
|
|
43
|
+
* const checkpoint = await checkpointManager.loadCheckpoint('node-embeddings-v1');
|
|
44
|
+
* if (checkpoint) {
|
|
45
|
+
* console.log(`Resuming from checkpoint: ${checkpoint.progress.processed} items processed`);
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
import { validatorQuery } from '../db/validatorPostgresClient.js';
|
|
50
|
+
export class CheckpointManager {
|
|
51
|
+
bannerService;
|
|
52
|
+
/**
|
|
53
|
+
* Create a new CheckpointManager
|
|
54
|
+
*
|
|
55
|
+
* @param bannerService Optional banner service for progress display
|
|
56
|
+
*/
|
|
57
|
+
constructor(bannerService) {
|
|
58
|
+
this.bannerService = bannerService;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Set banner service for progress reporting
|
|
62
|
+
*
|
|
63
|
+
* @param bannerService Banner service instance
|
|
64
|
+
*/
|
|
65
|
+
setBannerService(bannerService) {
|
|
66
|
+
this.bannerService = bannerService;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Save a checkpoint to the database
|
|
70
|
+
*
|
|
71
|
+
* Creates a new checkpoint or updates existing one with same key.
|
|
72
|
+
* Reports progress to banner service if provided.
|
|
73
|
+
*
|
|
74
|
+
* @param data Checkpoint data to save
|
|
75
|
+
* @returns Saved checkpoint
|
|
76
|
+
*/
|
|
77
|
+
async saveCheckpoint(data) {
|
|
78
|
+
const { key, pipelineType, state, processedItems = [], failedItems = [], progress = {} } = data;
|
|
79
|
+
const result = await validatorQuery(`
|
|
80
|
+
INSERT INTO validator.pipeline_checkpoints (
|
|
81
|
+
checkpoint_key,
|
|
82
|
+
pipeline_type,
|
|
83
|
+
state,
|
|
84
|
+
processed_items,
|
|
85
|
+
failed_items,
|
|
86
|
+
progress
|
|
87
|
+
)
|
|
88
|
+
VALUES ($1, $2, $3::jsonb, $4, $5, $6::jsonb)
|
|
89
|
+
ON CONFLICT (checkpoint_key) DO UPDATE SET
|
|
90
|
+
pipeline_type = EXCLUDED.pipeline_type,
|
|
91
|
+
state = EXCLUDED.state,
|
|
92
|
+
processed_items = EXCLUDED.processed_items,
|
|
93
|
+
failed_items = EXCLUDED.failed_items,
|
|
94
|
+
progress = EXCLUDED.progress,
|
|
95
|
+
updated_at = NOW()
|
|
96
|
+
RETURNING
|
|
97
|
+
id::text,
|
|
98
|
+
checkpoint_key as key,
|
|
99
|
+
pipeline_type as "pipelineType",
|
|
100
|
+
state,
|
|
101
|
+
processed_items as "processedItems",
|
|
102
|
+
failed_items as "failedItems",
|
|
103
|
+
progress,
|
|
104
|
+
created_at as "createdAt",
|
|
105
|
+
updated_at as "updatedAt"
|
|
106
|
+
`, [key, pipelineType, JSON.stringify(state), processedItems, failedItems, JSON.stringify(progress)]);
|
|
107
|
+
const row = Array.isArray(result) ? result[0] : result.rows[0];
|
|
108
|
+
const saved = {
|
|
109
|
+
id: row.id,
|
|
110
|
+
key: row.key,
|
|
111
|
+
pipelineType: row.pipelineType,
|
|
112
|
+
state: row.state,
|
|
113
|
+
processedItems: row.processedItems || [],
|
|
114
|
+
failedItems: row.failedItems || [],
|
|
115
|
+
progress: row.progress || {},
|
|
116
|
+
createdAt: row.createdAt,
|
|
117
|
+
updatedAt: row.updatedAt,
|
|
118
|
+
};
|
|
119
|
+
// Report checkpoint progress to banner service if available
|
|
120
|
+
if (this.bannerService && saved.progress) {
|
|
121
|
+
const processed = saved.progress.processed || (saved.processedItems || []).length;
|
|
122
|
+
this.bannerService.setCheckpoint(processed);
|
|
123
|
+
}
|
|
124
|
+
return saved;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Load a checkpoint from the database
|
|
128
|
+
*
|
|
129
|
+
* @param key Checkpoint key
|
|
130
|
+
* @returns Checkpoint if found, null otherwise
|
|
131
|
+
*/
|
|
132
|
+
async loadCheckpoint(key) {
|
|
133
|
+
const result = await validatorQuery(`
|
|
134
|
+
SELECT
|
|
135
|
+
id::text,
|
|
136
|
+
checkpoint_key as key,
|
|
137
|
+
pipeline_type as "pipelineType",
|
|
138
|
+
state,
|
|
139
|
+
processed_items as "processedItems",
|
|
140
|
+
failed_items as "failedItems",
|
|
141
|
+
progress,
|
|
142
|
+
created_at as "createdAt",
|
|
143
|
+
updated_at as "updatedAt"
|
|
144
|
+
FROM validator.pipeline_checkpoints
|
|
145
|
+
WHERE checkpoint_key = $1
|
|
146
|
+
`, [key]);
|
|
147
|
+
const rows = Array.isArray(result) ? result : result.rows;
|
|
148
|
+
if (rows.length === 0) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
const row = rows[0];
|
|
152
|
+
return {
|
|
153
|
+
id: row.id,
|
|
154
|
+
key: row.key,
|
|
155
|
+
pipelineType: row.pipelineType,
|
|
156
|
+
state: row.state,
|
|
157
|
+
processedItems: row.processedItems || [],
|
|
158
|
+
failedItems: row.failedItems || [],
|
|
159
|
+
progress: row.progress || {},
|
|
160
|
+
createdAt: row.createdAt,
|
|
161
|
+
updatedAt: row.updatedAt,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Update checkpoint progress without changing state
|
|
166
|
+
*
|
|
167
|
+
* Useful for updating progress metrics during processing.
|
|
168
|
+
* Reports progress to banner service if provided.
|
|
169
|
+
*
|
|
170
|
+
* @param key Checkpoint key
|
|
171
|
+
* @param progress Progress metrics to update
|
|
172
|
+
*/
|
|
173
|
+
async updateProgress(key, progress) {
|
|
174
|
+
await validatorQuery(`
|
|
175
|
+
UPDATE validator.pipeline_checkpoints
|
|
176
|
+
SET progress = COALESCE(progress, '{}'::jsonb) || $1::jsonb,
|
|
177
|
+
updated_at = NOW()
|
|
178
|
+
WHERE checkpoint_key = $2
|
|
179
|
+
`, [JSON.stringify(progress), key]);
|
|
180
|
+
// Report checkpoint progress to banner service if available
|
|
181
|
+
if (this.bannerService && progress.processed !== undefined) {
|
|
182
|
+
this.bannerService.setCheckpoint(progress.processed);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Add processed items to checkpoint
|
|
187
|
+
*
|
|
188
|
+
* @param key Checkpoint key
|
|
189
|
+
* @param itemIds Item IDs to add
|
|
190
|
+
*/
|
|
191
|
+
async addProcessedItems(key, itemIds) {
|
|
192
|
+
await validatorQuery(`
|
|
193
|
+
UPDATE validator.pipeline_checkpoints
|
|
194
|
+
SET processed_items = array_cat(COALESCE(processed_items, '{}'), $1),
|
|
195
|
+
updated_at = NOW()
|
|
196
|
+
WHERE checkpoint_key = $2
|
|
197
|
+
`, [itemIds, key]);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Add failed items to checkpoint
|
|
201
|
+
*
|
|
202
|
+
* @param key Checkpoint key
|
|
203
|
+
* @param itemIds Item IDs to add
|
|
204
|
+
*/
|
|
205
|
+
async addFailedItems(key, itemIds) {
|
|
206
|
+
await validatorQuery(`
|
|
207
|
+
UPDATE validator.pipeline_checkpoints
|
|
208
|
+
SET failed_items = array_cat(COALESCE(failed_items, '{}'), $1),
|
|
209
|
+
updated_at = NOW()
|
|
210
|
+
WHERE checkpoint_key = $2
|
|
211
|
+
`, [itemIds, key]);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Clear a checkpoint
|
|
215
|
+
*
|
|
216
|
+
* @param key Checkpoint key
|
|
217
|
+
*/
|
|
218
|
+
async clearCheckpoint(key) {
|
|
219
|
+
await validatorQuery(`
|
|
220
|
+
DELETE FROM validator.pipeline_checkpoints
|
|
221
|
+
WHERE checkpoint_key = $1
|
|
222
|
+
`, [key]);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* List all checkpoints
|
|
226
|
+
*
|
|
227
|
+
* @param pipelineType Optional filter by pipeline type
|
|
228
|
+
* @returns Array of checkpoints
|
|
229
|
+
*/
|
|
230
|
+
async listCheckpoints(pipelineType) {
|
|
231
|
+
let query = `
|
|
232
|
+
SELECT
|
|
233
|
+
id::text,
|
|
234
|
+
checkpoint_key as key,
|
|
235
|
+
pipeline_type as "pipelineType",
|
|
236
|
+
state,
|
|
237
|
+
processed_items as "processedItems",
|
|
238
|
+
failed_items as "failedItems",
|
|
239
|
+
progress,
|
|
240
|
+
created_at as "createdAt",
|
|
241
|
+
updated_at as "updatedAt"
|
|
242
|
+
FROM validator.pipeline_checkpoints
|
|
243
|
+
`;
|
|
244
|
+
const params = [];
|
|
245
|
+
if (pipelineType) {
|
|
246
|
+
query += ` WHERE pipeline_type = $1`;
|
|
247
|
+
params.push(pipelineType);
|
|
248
|
+
}
|
|
249
|
+
query += ` ORDER BY updated_at DESC`;
|
|
250
|
+
const result = await validatorQuery(query, params);
|
|
251
|
+
const rows = Array.isArray(result) ? result : result.rows;
|
|
252
|
+
return rows.map((row) => ({
|
|
253
|
+
id: row.id,
|
|
254
|
+
key: row.key,
|
|
255
|
+
pipelineType: row.pipelineType,
|
|
256
|
+
state: row.state,
|
|
257
|
+
processedItems: row.processedItems || [],
|
|
258
|
+
failedItems: row.failedItems || [],
|
|
259
|
+
progress: row.progress || {},
|
|
260
|
+
createdAt: row.createdAt,
|
|
261
|
+
updatedAt: row.updatedAt,
|
|
262
|
+
}));
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Check if a checkpoint exists
|
|
266
|
+
*
|
|
267
|
+
* @param key Checkpoint key
|
|
268
|
+
* @returns True if checkpoint exists
|
|
269
|
+
*/
|
|
270
|
+
async checkpointExists(key) {
|
|
271
|
+
const result = await validatorQuery(`
|
|
272
|
+
SELECT EXISTS(
|
|
273
|
+
SELECT 1 FROM validator.pipeline_checkpoints
|
|
274
|
+
WHERE checkpoint_key = $1
|
|
275
|
+
) as exists
|
|
276
|
+
`, [key]);
|
|
277
|
+
const row = Array.isArray(result) ? result[0] : result.rows[0];
|
|
278
|
+
return row.exists;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=CheckpointManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CheckpointManager.js","sourceRoot":"","sources":["../../src/services/CheckpointManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cost Calculator Service
|
|
3
|
+
*
|
|
4
|
+
* Unified cost calculation for embedding generation scripts.
|
|
5
|
+
* Replaces duplicate cost tracking code across multiple files.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Accurate token estimation
|
|
9
|
+
* - Cost calculation for OpenAI API
|
|
10
|
+
* - Support for different models/pricing
|
|
11
|
+
* - Formatted cost output
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const calculator = new CostCalculator();
|
|
16
|
+
*
|
|
17
|
+
* // Estimate tokens before API call
|
|
18
|
+
* const estimatedTokens = calculator.estimateTokens(text);
|
|
19
|
+
* logger.info('Estimated cost', { cost: calculator.estimateCost(estimatedTokens) });
|
|
20
|
+
*
|
|
21
|
+
* // Track actual usage after API call
|
|
22
|
+
* calculator.addTokens(response.usage.total_tokens);
|
|
23
|
+
*
|
|
24
|
+
* // Get totals
|
|
25
|
+
* logger.info('Cost summary', {
|
|
26
|
+
* total_tokens: calculator.getTotalTokens(),
|
|
27
|
+
* total_cost: calculator.getTotalCost(),
|
|
28
|
+
* formatted: calculator.getFormattedCost(),
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
import { logger } from '@tsvika58/shared-utilities/logging';
|
|
33
|
+
/**
|
|
34
|
+
* OpenAI API Pricing (as of 2024)
|
|
35
|
+
*/
|
|
36
|
+
export const OPENAI_PRICING = {
|
|
37
|
+
// Embedding models
|
|
38
|
+
'text-embedding-3-small': 0.00002, // $0.02 per 1M tokens
|
|
39
|
+
'text-embedding-3-large': 0.00013, // $0.13 per 1M tokens
|
|
40
|
+
'text-embedding-ada-002': 0.00010, // $0.10 per 1M tokens
|
|
41
|
+
// GPT models (for reference)
|
|
42
|
+
'gpt-4-turbo': 0.01, // $10 per 1M input tokens
|
|
43
|
+
'gpt-4': 0.03, // $30 per 1M input tokens
|
|
44
|
+
'gpt-3.5-turbo': 0.0005, // $0.50 per 1M input tokens
|
|
45
|
+
};
|
|
46
|
+
export class CostCalculator {
|
|
47
|
+
totalTokens = 0;
|
|
48
|
+
itemsProcessed = 0;
|
|
49
|
+
costPer1K;
|
|
50
|
+
model;
|
|
51
|
+
constructor(config = {}) {
|
|
52
|
+
this.model = config.model || 'text-embedding-3-small';
|
|
53
|
+
this.costPer1K = config.costPer1K || OPENAI_PRICING[this.model] || 0.00002;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Add tokens to the total count
|
|
57
|
+
*
|
|
58
|
+
* @param tokenCount Number of tokens used
|
|
59
|
+
*/
|
|
60
|
+
addTokens(tokenCount) {
|
|
61
|
+
this.totalTokens += tokenCount;
|
|
62
|
+
this.itemsProcessed++;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Estimate tokens for a text string
|
|
66
|
+
*
|
|
67
|
+
* Uses a simple heuristic: ~4 characters per token for English text
|
|
68
|
+
* This is a rough estimate - actual tokenization may vary
|
|
69
|
+
*
|
|
70
|
+
* @param text Text to estimate
|
|
71
|
+
* @returns Estimated token count
|
|
72
|
+
*/
|
|
73
|
+
estimateTokens(text) {
|
|
74
|
+
// Average: ~4 characters per token for English
|
|
75
|
+
// Add 10% buffer for safety
|
|
76
|
+
const estimate = Math.ceil((text.length / 4) * 1.1);
|
|
77
|
+
return Math.max(estimate, 1); // Minimum 1 token
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Estimate cost for a given token count
|
|
81
|
+
*
|
|
82
|
+
* @param tokenCount Number of tokens
|
|
83
|
+
* @returns Estimated cost in dollars
|
|
84
|
+
*/
|
|
85
|
+
estimateCost(tokenCount) {
|
|
86
|
+
return (tokenCount / 1000) * this.costPer1K;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Estimate cost for a text string
|
|
90
|
+
*
|
|
91
|
+
* @param text Text to estimate
|
|
92
|
+
* @returns Estimated cost in dollars
|
|
93
|
+
*/
|
|
94
|
+
estimateTextCost(text) {
|
|
95
|
+
const tokens = this.estimateTokens(text);
|
|
96
|
+
return this.estimateCost(tokens);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get total tokens used
|
|
100
|
+
*
|
|
101
|
+
* @returns Total token count
|
|
102
|
+
*/
|
|
103
|
+
getTotalTokens() {
|
|
104
|
+
return this.totalTokens;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get total cost
|
|
108
|
+
*
|
|
109
|
+
* @returns Total cost in dollars
|
|
110
|
+
*/
|
|
111
|
+
getTotalCost() {
|
|
112
|
+
return (this.totalTokens / 1000) * this.costPer1K;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get formatted cost string
|
|
116
|
+
*
|
|
117
|
+
* @param decimals Number of decimal places (default: 4)
|
|
118
|
+
* @returns Formatted cost (e.g., "$0.0025")
|
|
119
|
+
*/
|
|
120
|
+
getFormattedCost(decimals = 4) {
|
|
121
|
+
return `$${this.getTotalCost().toFixed(decimals)}`;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get formatted token count with thousands separators
|
|
125
|
+
*
|
|
126
|
+
* @returns Formatted token count (e.g., "125,000")
|
|
127
|
+
*/
|
|
128
|
+
getFormattedTokens() {
|
|
129
|
+
return this.totalTokens.toLocaleString();
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get average tokens per item
|
|
133
|
+
*
|
|
134
|
+
* @returns Average tokens
|
|
135
|
+
*/
|
|
136
|
+
getAvgTokensPerItem() {
|
|
137
|
+
if (this.itemsProcessed === 0)
|
|
138
|
+
return 0;
|
|
139
|
+
return this.totalTokens / this.itemsProcessed;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get average cost per item
|
|
143
|
+
*
|
|
144
|
+
* @returns Average cost in dollars
|
|
145
|
+
*/
|
|
146
|
+
getAvgCostPerItem() {
|
|
147
|
+
if (this.itemsProcessed === 0)
|
|
148
|
+
return 0;
|
|
149
|
+
return this.getTotalCost() / this.itemsProcessed;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Get number of items processed
|
|
153
|
+
*
|
|
154
|
+
* @returns Item count
|
|
155
|
+
*/
|
|
156
|
+
getItemsProcessed() {
|
|
157
|
+
return this.itemsProcessed;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get complete cost summary
|
|
161
|
+
*
|
|
162
|
+
* @returns Cost summary object
|
|
163
|
+
*/
|
|
164
|
+
getSummary() {
|
|
165
|
+
return {
|
|
166
|
+
totalTokens: this.totalTokens,
|
|
167
|
+
totalCost: this.getTotalCost(),
|
|
168
|
+
avgTokensPerItem: this.getAvgTokensPerItem(),
|
|
169
|
+
avgCostPerItem: this.getAvgCostPerItem(),
|
|
170
|
+
itemsProcessed: this.itemsProcessed,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Reset all counters
|
|
175
|
+
*/
|
|
176
|
+
reset() {
|
|
177
|
+
this.totalTokens = 0;
|
|
178
|
+
this.itemsProcessed = 0;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Get model name
|
|
182
|
+
*
|
|
183
|
+
* @returns Model name
|
|
184
|
+
*/
|
|
185
|
+
getModel() {
|
|
186
|
+
return this.model;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Get cost per 1K tokens
|
|
190
|
+
*
|
|
191
|
+
* @returns Cost rate
|
|
192
|
+
*/
|
|
193
|
+
getCostPer1K() {
|
|
194
|
+
return this.costPer1K;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Print cost summary to console
|
|
198
|
+
*/
|
|
199
|
+
printSummary() {
|
|
200
|
+
const summary = this.getSummary();
|
|
201
|
+
logger.info('Cost Summary', {
|
|
202
|
+
model: this.model,
|
|
203
|
+
total_tokens: this.getFormattedTokens(),
|
|
204
|
+
total_cost: this.getFormattedCost(),
|
|
205
|
+
items_processed: summary.itemsProcessed > 0 ? summary.itemsProcessed.toLocaleString() : undefined,
|
|
206
|
+
avg_tokens_per_item: summary.itemsProcessed > 0 ? Math.round(summary.avgTokensPerItem).toLocaleString() : undefined,
|
|
207
|
+
avg_cost_per_item: summary.itemsProcessed > 0 ? `$${summary.avgCostPerItem.toFixed(6)}` : undefined,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=CostCalculator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CostCalculator.js","sourceRoot":"","sources":["../../src/services/CostCalculator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedding Cache Service
|
|
3
|
+
*
|
|
4
|
+
* Caches query embeddings to avoid regenerating them for repeated queries.
|
|
5
|
+
* Reduces API calls and improves latency for common queries.
|
|
6
|
+
*/
|
|
7
|
+
import NodeCache from 'node-cache';
|
|
8
|
+
export class EmbeddingCache {
|
|
9
|
+
cache;
|
|
10
|
+
constructor() {
|
|
11
|
+
const ttl = process.env.EMBEDDING_CACHE_TTL
|
|
12
|
+
? Number(process.env.EMBEDDING_CACHE_TTL)
|
|
13
|
+
: 604800; // Default: 7 days (query embeddings are deterministic, database is static)
|
|
14
|
+
const maxKeys = process.env.EMBEDDING_CACHE_MAX_SIZE
|
|
15
|
+
? Number(process.env.EMBEDDING_CACHE_MAX_SIZE)
|
|
16
|
+
: 1000; // Default: 1000 queries
|
|
17
|
+
this.cache = new NodeCache({
|
|
18
|
+
stdTTL: ttl,
|
|
19
|
+
checkperiod: 600, // Check for expired keys every 10 minutes
|
|
20
|
+
useClones: false, // Don't clone arrays (faster, but be careful with mutations)
|
|
21
|
+
maxKeys: maxKeys,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get cached embedding for a query
|
|
26
|
+
*/
|
|
27
|
+
get(query) {
|
|
28
|
+
const key = this.getKey(query);
|
|
29
|
+
return this.cache.get(key);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Cache an embedding for a query
|
|
33
|
+
*/
|
|
34
|
+
set(query, embedding) {
|
|
35
|
+
const key = this.getKey(query);
|
|
36
|
+
this.cache.set(key, embedding);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check if a query is cached
|
|
40
|
+
*/
|
|
41
|
+
has(query) {
|
|
42
|
+
const key = this.getKey(query);
|
|
43
|
+
return this.cache.has(key);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get cache statistics
|
|
47
|
+
*/
|
|
48
|
+
stats() {
|
|
49
|
+
return this.cache.getStats();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Clear all cached embeddings
|
|
53
|
+
*/
|
|
54
|
+
flush() {
|
|
55
|
+
this.cache.flushAll();
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Generate cache key from query
|
|
59
|
+
*/
|
|
60
|
+
getKey(query) {
|
|
61
|
+
// Normalize query: lowercase, trim, remove extra whitespace
|
|
62
|
+
const normalized = query.toLowerCase().trim().replace(/\s+/g, ' ');
|
|
63
|
+
return `embedding:${normalized}`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Singleton instance
|
|
67
|
+
export const embeddingCache = new EmbeddingCache();
|
|
68
|
+
//# sourceMappingURL=EmbeddingCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmbeddingCache.js","sourceRoot":"","sources":["../../src/services/EmbeddingCache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,SAAS,MAAM,YAAY,CAAC;AAEnC,MAAM,OAAO,cAAc;IACjB,KAAK,CAAY;IAEzB;QACE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB;YACzC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;YACzC,CAAC,CAAC,MAAM,CAAC,CAAC,2EAA2E;QAEvF,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB;YAClD,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;YAC9C,CAAC,CAAC,IAAI,CAAC,CAAC,wBAAwB;QAElC,IAAI,CAAC,KAAK,GAAG,IAAI,SAAS,CAAC;YACzB,MAAM,EAAE,GAAG;YACX,WAAW,EAAE,GAAG,EAAE,0CAA0C;YAC5D,SAAS,EAAE,KAAK,EAAE,6DAA6D;YAC/E,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,KAAa;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAW,GAAG,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,KAAa,EAAE,SAAmB;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,KAAa;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAED;;OAEG;IACK,MAAM,CAAC,KAAa;QAC1B,4DAA4D;QAC5D,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACnE,OAAO,aAAa,UAAU,EAAE,CAAC;IACnC,CAAC;CACF;AAED,qBAAqB;AACrB,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC"}
|