llm-content-creator 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/README.md +309 -0
- package/dist/application/workflow/SyncExecutor.d.ts +75 -0
- package/dist/application/workflow/SyncExecutor.d.ts.map +1 -0
- package/dist/application/workflow/SyncExecutor.js +370 -0
- package/dist/application/workflow/SyncExecutor.js.map +1 -0
- package/dist/application/workflow/types.d.ts +46 -0
- package/dist/application/workflow/types.d.ts.map +1 -0
- package/dist/application/workflow/types.js +7 -0
- package/dist/application/workflow/types.js.map +1 -0
- package/dist/config/index.d.ts +173 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +288 -0
- package/dist/config/index.js.map +1 -0
- package/dist/domain/entities/QualityCheck.d.ts +181 -0
- package/dist/domain/entities/QualityCheck.d.ts.map +1 -0
- package/dist/domain/entities/QualityCheck.js +39 -0
- package/dist/domain/entities/QualityCheck.js.map +1 -0
- package/dist/domain/entities/Result.d.ts +103 -0
- package/dist/domain/entities/Result.d.ts.map +1 -0
- package/dist/domain/entities/Result.js +15 -0
- package/dist/domain/entities/Result.js.map +1 -0
- package/dist/domain/entities/Task.d.ts +130 -0
- package/dist/domain/entities/Task.d.ts.map +1 -0
- package/dist/domain/entities/Task.js +64 -0
- package/dist/domain/entities/Task.js.map +1 -0
- package/dist/domain/entities/TaskStep.d.ts +160 -0
- package/dist/domain/entities/TaskStep.d.ts.map +1 -0
- package/dist/domain/entities/TaskStep.js +30 -0
- package/dist/domain/entities/TaskStep.js.map +1 -0
- package/dist/domain/entities/TokenUsage.d.ts +70 -0
- package/dist/domain/entities/TokenUsage.d.ts.map +1 -0
- package/dist/domain/entities/TokenUsage.js +42 -0
- package/dist/domain/entities/TokenUsage.js.map +1 -0
- package/dist/domain/entities/index.d.ts +11 -0
- package/dist/domain/entities/index.d.ts.map +1 -0
- package/dist/domain/entities/index.js +16 -0
- package/dist/domain/entities/index.js.map +1 -0
- package/dist/domain/repositories/QualityCheckRepository.d.ts +49 -0
- package/dist/domain/repositories/QualityCheckRepository.d.ts.map +1 -0
- package/dist/domain/repositories/QualityCheckRepository.js +5 -0
- package/dist/domain/repositories/QualityCheckRepository.js.map +1 -0
- package/dist/domain/repositories/ResultRepository.d.ts +43 -0
- package/dist/domain/repositories/ResultRepository.d.ts.map +1 -0
- package/dist/domain/repositories/ResultRepository.js +5 -0
- package/dist/domain/repositories/ResultRepository.js.map +1 -0
- package/dist/domain/repositories/TaskRepository.d.ts +240 -0
- package/dist/domain/repositories/TaskRepository.d.ts.map +1 -0
- package/dist/domain/repositories/TaskRepository.js +7 -0
- package/dist/domain/repositories/TaskRepository.js.map +1 -0
- package/dist/domain/workflow/CheckpointManager.d.ts +94 -0
- package/dist/domain/workflow/CheckpointManager.d.ts.map +1 -0
- package/dist/domain/workflow/CheckpointManager.js +224 -0
- package/dist/domain/workflow/CheckpointManager.js.map +1 -0
- package/dist/domain/workflow/ContentCreatorGraph.d.ts +17 -0
- package/dist/domain/workflow/ContentCreatorGraph.d.ts.map +1 -0
- package/dist/domain/workflow/ContentCreatorGraph.js +381 -0
- package/dist/domain/workflow/ContentCreatorGraph.js.map +1 -0
- package/dist/domain/workflow/State.d.ts +172 -0
- package/dist/domain/workflow/State.d.ts.map +1 -0
- package/dist/domain/workflow/State.js +184 -0
- package/dist/domain/workflow/State.js.map +1 -0
- package/dist/domain/workflow/index.d.ts +11 -0
- package/dist/domain/workflow/index.d.ts.map +1 -0
- package/dist/domain/workflow/index.js +15 -0
- package/dist/domain/workflow/index.js.map +1 -0
- package/dist/domain/workflow/nodes/BaseNode.d.ts +134 -0
- package/dist/domain/workflow/nodes/BaseNode.d.ts.map +1 -0
- package/dist/domain/workflow/nodes/BaseNode.js +253 -0
- package/dist/domain/workflow/nodes/BaseNode.js.map +1 -0
- package/dist/domain/workflow/nodes/CheckImageNode.d.ts +43 -0
- package/dist/domain/workflow/nodes/CheckImageNode.d.ts.map +1 -0
- package/dist/domain/workflow/nodes/CheckImageNode.js +254 -0
- package/dist/domain/workflow/nodes/CheckImageNode.js.map +1 -0
- package/dist/domain/workflow/nodes/CheckTextNode.d.ts +66 -0
- package/dist/domain/workflow/nodes/CheckTextNode.d.ts.map +1 -0
- package/dist/domain/workflow/nodes/CheckTextNode.js +530 -0
- package/dist/domain/workflow/nodes/CheckTextNode.js.map +1 -0
- package/dist/domain/workflow/nodes/GenerateImageNode.d.ts +44 -0
- package/dist/domain/workflow/nodes/GenerateImageNode.d.ts.map +1 -0
- package/dist/domain/workflow/nodes/GenerateImageNode.js +272 -0
- package/dist/domain/workflow/nodes/GenerateImageNode.js.map +1 -0
- package/dist/domain/workflow/nodes/OrganizeNode.d.ts +49 -0
- package/dist/domain/workflow/nodes/OrganizeNode.d.ts.map +1 -0
- package/dist/domain/workflow/nodes/OrganizeNode.js +241 -0
- package/dist/domain/workflow/nodes/OrganizeNode.js.map +1 -0
- package/dist/domain/workflow/nodes/SearchNode.d.ts +48 -0
- package/dist/domain/workflow/nodes/SearchNode.d.ts.map +1 -0
- package/dist/domain/workflow/nodes/SearchNode.js +151 -0
- package/dist/domain/workflow/nodes/SearchNode.js.map +1 -0
- package/dist/domain/workflow/nodes/WriteNode.d.ts +68 -0
- package/dist/domain/workflow/nodes/WriteNode.d.ts.map +1 -0
- package/dist/domain/workflow/nodes/WriteNode.js +431 -0
- package/dist/domain/workflow/nodes/WriteNode.js.map +1 -0
- package/dist/domain/workflow/nodes/config/index.js +287 -0
- package/dist/domain/workflow/nodes/domain/entities/Task.js +68 -0
- package/dist/domain/workflow/nodes/domain/workflow/State.js +200 -0
- package/dist/domain/workflow/nodes/domain/workflow/nodes/BaseNode.js +328 -0
- package/dist/domain/workflow/nodes/domain/workflow/nodes/CheckTextNode.js +500 -0
- package/dist/domain/workflow/nodes/index.d.ts +13 -0
- package/dist/domain/workflow/nodes/index.d.ts.map +1 -0
- package/dist/domain/workflow/nodes/index.js +13 -0
- package/dist/domain/workflow/nodes/index.js.map +1 -0
- package/dist/domain/workflow/nodes/infrastructure/logging/logger.js +275 -0
- package/dist/domain/workflow/nodes/services/llm/EnhancedLLMService.js +559 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/cache/CacheService.d.ts +139 -0
- package/dist/infrastructure/cache/CacheService.d.ts.map +1 -0
- package/dist/infrastructure/cache/CacheService.js +419 -0
- package/dist/infrastructure/cache/CacheService.js.map +1 -0
- package/dist/infrastructure/cache/index.d.ts +5 -0
- package/dist/infrastructure/cache/index.d.ts.map +1 -0
- package/dist/infrastructure/cache/index.js +6 -0
- package/dist/infrastructure/cache/index.js.map +1 -0
- package/dist/infrastructure/database/BaseRepository.d.ts +98 -0
- package/dist/infrastructure/database/BaseRepository.d.ts.map +1 -0
- package/dist/infrastructure/database/BaseRepository.js +178 -0
- package/dist/infrastructure/database/BaseRepository.js.map +1 -0
- package/dist/infrastructure/database/MemoryTaskRepository.d.ts +77 -0
- package/dist/infrastructure/database/MemoryTaskRepository.d.ts.map +1 -0
- package/dist/infrastructure/database/MemoryTaskRepository.js +309 -0
- package/dist/infrastructure/database/MemoryTaskRepository.js.map +1 -0
- package/dist/infrastructure/database/PostgresQualityCheckRepository.d.ts +36 -0
- package/dist/infrastructure/database/PostgresQualityCheckRepository.d.ts.map +1 -0
- package/dist/infrastructure/database/PostgresQualityCheckRepository.js +89 -0
- package/dist/infrastructure/database/PostgresQualityCheckRepository.js.map +1 -0
- package/dist/infrastructure/database/PostgresTaskRepository.d.ts +94 -0
- package/dist/infrastructure/database/PostgresTaskRepository.d.ts.map +1 -0
- package/dist/infrastructure/database/PostgresTaskRepository.js +364 -0
- package/dist/infrastructure/database/PostgresTaskRepository.js.map +1 -0
- package/dist/infrastructure/database/ResultRepository.d.ts +41 -0
- package/dist/infrastructure/database/ResultRepository.d.ts.map +1 -0
- package/dist/infrastructure/database/ResultRepository.js +86 -0
- package/dist/infrastructure/database/ResultRepository.js.map +1 -0
- package/dist/infrastructure/database/SQLiteTaskRepository.d.ts +101 -0
- package/dist/infrastructure/database/SQLiteTaskRepository.d.ts.map +1 -0
- package/dist/infrastructure/database/SQLiteTaskRepository.js +548 -0
- package/dist/infrastructure/database/SQLiteTaskRepository.js.map +1 -0
- package/dist/infrastructure/database/index.d.ts +32 -0
- package/dist/infrastructure/database/index.d.ts.map +1 -0
- package/dist/infrastructure/database/index.js +72 -0
- package/dist/infrastructure/database/index.js.map +1 -0
- package/dist/infrastructure/logging/logger.d.ts +69 -0
- package/dist/infrastructure/logging/logger.d.ts.map +1 -0
- package/dist/infrastructure/logging/logger.js +169 -0
- package/dist/infrastructure/logging/logger.js.map +1 -0
- package/dist/infrastructure/monitoring/LoggingService.d.ts +109 -0
- package/dist/infrastructure/monitoring/LoggingService.d.ts.map +1 -0
- package/dist/infrastructure/monitoring/LoggingService.js +198 -0
- package/dist/infrastructure/monitoring/LoggingService.js.map +1 -0
- package/dist/infrastructure/monitoring/MetricsService.d.ts +112 -0
- package/dist/infrastructure/monitoring/MetricsService.d.ts.map +1 -0
- package/dist/infrastructure/monitoring/MetricsService.js +362 -0
- package/dist/infrastructure/monitoring/MetricsService.js.map +1 -0
- package/dist/infrastructure/monitoring/SentryService.d.ts +108 -0
- package/dist/infrastructure/monitoring/SentryService.d.ts.map +1 -0
- package/dist/infrastructure/monitoring/SentryService.js +282 -0
- package/dist/infrastructure/monitoring/SentryService.js.map +1 -0
- package/dist/infrastructure/monitoring/index.d.ts +7 -0
- package/dist/infrastructure/monitoring/index.d.ts.map +1 -0
- package/dist/infrastructure/monitoring/index.js +10 -0
- package/dist/infrastructure/monitoring/index.js.map +1 -0
- package/dist/infrastructure/queue/TaskQueue.d.ts +110 -0
- package/dist/infrastructure/queue/TaskQueue.d.ts.map +1 -0
- package/dist/infrastructure/queue/TaskQueue.js +363 -0
- package/dist/infrastructure/queue/TaskQueue.js.map +1 -0
- package/dist/infrastructure/queue/index.d.ts +5 -0
- package/dist/infrastructure/queue/index.d.ts.map +1 -0
- package/dist/infrastructure/queue/index.js +5 -0
- package/dist/infrastructure/queue/index.js.map +1 -0
- package/dist/infrastructure/redis/connection.d.ts +61 -0
- package/dist/infrastructure/redis/connection.d.ts.map +1 -0
- package/dist/infrastructure/redis/connection.js +184 -0
- package/dist/infrastructure/redis/connection.js.map +1 -0
- package/dist/infrastructure/redis/index.d.ts +5 -0
- package/dist/infrastructure/redis/index.d.ts.map +1 -0
- package/dist/infrastructure/redis/index.js +5 -0
- package/dist/infrastructure/redis/index.js.map +1 -0
- package/dist/infrastructure/security/ApiKeyService.d.ts +103 -0
- package/dist/infrastructure/security/ApiKeyService.d.ts.map +1 -0
- package/dist/infrastructure/security/ApiKeyService.js +250 -0
- package/dist/infrastructure/security/ApiKeyService.js.map +1 -0
- package/dist/infrastructure/security/QuotaService.d.ts +87 -0
- package/dist/infrastructure/security/QuotaService.d.ts.map +1 -0
- package/dist/infrastructure/security/QuotaService.js +303 -0
- package/dist/infrastructure/security/QuotaService.js.map +1 -0
- package/dist/infrastructure/security/RateLimiter.d.ts +104 -0
- package/dist/infrastructure/security/RateLimiter.d.ts.map +1 -0
- package/dist/infrastructure/security/RateLimiter.js +331 -0
- package/dist/infrastructure/security/RateLimiter.js.map +1 -0
- package/dist/infrastructure/security/index.d.ts +7 -0
- package/dist/infrastructure/security/index.d.ts.map +1 -0
- package/dist/infrastructure/security/index.js +10 -0
- package/dist/infrastructure/security/index.js.map +1 -0
- package/dist/monitoring/index.d.ts +5 -0
- package/dist/monitoring/index.d.ts.map +1 -0
- package/dist/monitoring/index.js +5 -0
- package/dist/monitoring/index.js.map +1 -0
- package/dist/monitoring/server.d.ts +14 -0
- package/dist/monitoring/server.d.ts.map +1 -0
- package/dist/monitoring/server.js +99 -0
- package/dist/monitoring/server.js.map +1 -0
- package/dist/presentation/cli/commands/cancel.d.ts +8 -0
- package/dist/presentation/cli/commands/cancel.d.ts.map +1 -0
- package/dist/presentation/cli/commands/cancel.js +57 -0
- package/dist/presentation/cli/commands/cancel.js.map +1 -0
- package/dist/presentation/cli/commands/create.d.ts +8 -0
- package/dist/presentation/cli/commands/create.d.ts.map +1 -0
- package/dist/presentation/cli/commands/create.js +368 -0
- package/dist/presentation/cli/commands/create.js.map +1 -0
- package/dist/presentation/cli/commands/result.d.ts +8 -0
- package/dist/presentation/cli/commands/result.d.ts.map +1 -0
- package/dist/presentation/cli/commands/result.js +121 -0
- package/dist/presentation/cli/commands/result.js.map +1 -0
- package/dist/presentation/cli/commands/status.d.ts +8 -0
- package/dist/presentation/cli/commands/status.d.ts.map +1 -0
- package/dist/presentation/cli/commands/status.js +92 -0
- package/dist/presentation/cli/commands/status.js.map +1 -0
- package/dist/presentation/cli/index.d.ts +8 -0
- package/dist/presentation/cli/index.d.ts.map +1 -0
- package/dist/presentation/cli/index.js +32 -0
- package/dist/presentation/cli/index.js.map +1 -0
- package/dist/presentation/cli/utils/cleanup.d.ts +14 -0
- package/dist/presentation/cli/utils/cleanup.d.ts.map +1 -0
- package/dist/presentation/cli/utils/cleanup.js +62 -0
- package/dist/presentation/cli/utils/cleanup.js.map +1 -0
- package/dist/presentation/cli/utils/formatter.d.ts +28 -0
- package/dist/presentation/cli/utils/formatter.d.ts.map +1 -0
- package/dist/presentation/cli/utils/formatter.js +68 -0
- package/dist/presentation/cli/utils/formatter.js.map +1 -0
- package/dist/presentation/cli.d.ts +7 -0
- package/dist/presentation/cli.d.ts.map +1 -0
- package/dist/presentation/cli.js +8 -0
- package/dist/presentation/cli.js.map +1 -0
- package/dist/presentation/monitor-cli.d.ts +8 -0
- package/dist/presentation/monitor-cli.d.ts.map +1 -0
- package/dist/presentation/monitor-cli.js +44 -0
- package/dist/presentation/monitor-cli.js.map +1 -0
- package/dist/presentation/worker-cli.d.ts +8 -0
- package/dist/presentation/worker-cli.d.ts.map +1 -0
- package/dist/presentation/worker-cli.js +51 -0
- package/dist/presentation/worker-cli.js.map +1 -0
- package/dist/schedulers/TaskScheduler.d.ts +99 -0
- package/dist/schedulers/TaskScheduler.d.ts.map +1 -0
- package/dist/schedulers/TaskScheduler.js +233 -0
- package/dist/schedulers/TaskScheduler.js.map +1 -0
- package/dist/schedulers/index.d.ts +5 -0
- package/dist/schedulers/index.d.ts.map +1 -0
- package/dist/schedulers/index.js +5 -0
- package/dist/schedulers/index.js.map +1 -0
- package/dist/services/image/ImageService.d.ts +68 -0
- package/dist/services/image/ImageService.d.ts.map +1 -0
- package/dist/services/image/ImageService.js +166 -0
- package/dist/services/image/ImageService.js.map +1 -0
- package/dist/services/index.d.ts +8 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +12 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/llm/EnhancedLLMService.d.ts +148 -0
- package/dist/services/llm/EnhancedLLMService.d.ts.map +1 -0
- package/dist/services/llm/EnhancedLLMService.js +425 -0
- package/dist/services/llm/EnhancedLLMService.js.map +1 -0
- package/dist/services/llm/LLMService.d.ts +103 -0
- package/dist/services/llm/LLMService.d.ts.map +1 -0
- package/dist/services/llm/LLMService.js +212 -0
- package/dist/services/llm/LLMService.js.map +1 -0
- package/dist/services/quality/HardRuleChecker.d.ts +143 -0
- package/dist/services/quality/HardRuleChecker.d.ts.map +1 -0
- package/dist/services/quality/HardRuleChecker.js +353 -0
- package/dist/services/quality/HardRuleChecker.js.map +1 -0
- package/dist/services/quality/LLMEvaluator.d.ts +105 -0
- package/dist/services/quality/LLMEvaluator.d.ts.map +1 -0
- package/dist/services/quality/LLMEvaluator.js +312 -0
- package/dist/services/quality/LLMEvaluator.js.map +1 -0
- package/dist/services/quality/QualityCheckService.d.ts +112 -0
- package/dist/services/quality/QualityCheckService.d.ts.map +1 -0
- package/dist/services/quality/QualityCheckService.js +342 -0
- package/dist/services/quality/QualityCheckService.js.map +1 -0
- package/dist/services/quality/QualityService.d.ts +75 -0
- package/dist/services/quality/QualityService.d.ts.map +1 -0
- package/dist/services/quality/QualityService.js +360 -0
- package/dist/services/quality/QualityService.js.map +1 -0
- package/dist/services/quality/index.d.ts +7 -0
- package/dist/services/quality/index.d.ts.map +1 -0
- package/dist/services/quality/index.js +10 -0
- package/dist/services/quality/index.js.map +1 -0
- package/dist/services/search/SearchService.d.ts +79 -0
- package/dist/services/search/SearchService.d.ts.map +1 -0
- package/dist/services/search/SearchService.js +193 -0
- package/dist/services/search/SearchService.js.map +1 -0
- package/dist/workers/TaskWorker.d.ts +61 -0
- package/dist/workers/TaskWorker.d.ts.map +1 -0
- package/dist/workers/TaskWorker.js +256 -0
- package/dist/workers/TaskWorker.js.map +1 -0
- package/dist/workers/index.d.ts +5 -0
- package/dist/workers/index.d.ts.map +1 -0
- package/dist/workers/index.js +5 -0
- package/dist/workers/index.js.map +1 -0
- package/docs/DOCUMENTATION-ANALYSIS.md +190 -0
- package/docs/README.md +145 -0
- package/docs/SOURCE-CODE-ANALYSIS.md +1107 -0
- package/docs/architecture-complete.md +5524 -0
- package/docs/archive/implementation/implementation-analysis/README.md +244 -0
- package/docs/archive/implementation/implementation-analysis/implementation-analysis-context.md +483 -0
- package/docs/archive/implementation/implementation-analysis/implementation-analysis-plan.md +1242 -0
- package/docs/archive/implementation/implementation-analysis/implementation-analysis-tasks.md +777 -0
- package/docs/archive/phases/phase-1/phase-1-completion-summary.md +284 -0
- package/docs/archive/phases/phase-1/phase-1-implementation-guide.md +1380 -0
- package/docs/archive/phases/phase-2/phase-2a/phase-2a-completion-summary.md +443 -0
- package/docs/archive/phases/phase-2/phase-2b/phase-2b-completion-report.md +430 -0
- package/docs/archive/phases/phase-2/phase-2b/phase-2b-completion-summary.md +592 -0
- package/docs/archive/phases/phase-2/phase-2b/phase-2b-final-summary.md +371 -0
- package/docs/archive/phases/phase-2/phase-2b/phase-2b-preparation-complete.md +343 -0
- package/docs/archive/phases/phase-2/phase-2b/phase-2b-preparation.md +945 -0
- package/docs/archive/phases/phase-2/phase-2b/phase-2b-progress-update.md +366 -0
- package/docs/archive/phases/phase-3/phase-3-completion-summary.md +354 -0
- package/docs/archive/phases/phase-3/phase-3-development-plan.md +878 -0
- package/docs/archive/phases/phase-3/phase-3-quick-start.md +324 -0
- package/docs/archive/phases/phase-4/phase-4-completion-summary.md +708 -0
- package/docs/archive/phases/phase-4/phase-4-development-plan.md +740 -0
- package/docs/archive/phases/phase-4/phase-4-quick-start.md +632 -0
- package/docs/archive/phases/phase-4/phase-4-session-3-security-testing.md +484 -0
- package/docs/archive/phases/phase-4/phase-4-session-4-unit-tests.md +550 -0
- package/docs/archive/phases/phase-4/phase-4-session-5-security-tests.md +564 -0
- package/docs/archive/phases/phase-4/phase-4-session-6-cache-integration.md +456 -0
- package/docs/archive/phases/phase-4/phase-4-session-7-test-fixes.md +348 -0
- package/docs/archive/phases/phase-4/phase-4-session-8-taskqueue-fixes.md +323 -0
- package/docs/archive/phases/phase-4/phase-4-session-summary-continued.md +373 -0
- package/docs/archive/phases/phase-4/phase-4-session-summary.md +595 -0
- package/docs/archive/reports/progress-reports/PHASE_0_PROGRESS.md +242 -0
- package/docs/archive/reports/progress-reports/PHASE_0_SUMMARY.md +262 -0
- package/docs/archive/reports/progress-reports/PHASE_1_2_ISSUES.md +399 -0
- package/docs/archive/reports/progress-reports/PHASE_1_PROGRESS.md +388 -0
- package/docs/archive/reports/progress-reports/PHASE_3_PREPARATION.md +574 -0
- package/docs/archive/reports/progress-reports/current-progress-update.md +294 -0
- package/docs/archive/reports/progress-reports/final-summary.md +215 -0
- package/docs/archive/reports/progress-reports/implementation-summary.md +287 -0
- package/docs/archive/reports/progress-reports/project-progress-report.md +440 -0
- package/docs/archive/reports/progress-reports/project-progress.md +386 -0
- package/docs/archive/reports/test-reports/TEST-COVERAGE-REPORT.md +441 -0
- package/docs/archive/reports/test-reports/e2e-test-report.md +293 -0
- package/docs/archive/reports/test-reports/final-test-report.md +367 -0
- package/docs/archive/reports/test-reports/real-env-test-report.md +391 -0
- package/docs/archive/reports/test-reports/test-completion-summary.md +356 -0
- package/docs/archive/reports/test-reports/test-report.md +371 -0
- package/docs/archive/sessions/session-2-summary.md +429 -0
- package/docs/archive/sessions/session-3-summary.md +395 -0
- package/docs/archive/sessions/session-summary.md +370 -0
- package/docs/config-system-update.md +239 -0
- package/docs/database-refactoring-PLAN.md +199 -0
- package/docs/database-refactoring-SUMMARY.md +384 -0
- package/docs/quality-check-architecture.md +1030 -0
- package/docs/quick-start.md +388 -0
- package/docs/references/bullmq-quick-reference.md +525 -0
- package/docs/references/monitoring-optimization-guide.md +871 -0
- package/docs/references/performance-optimization-guide.md +933 -0
- package/docs/storage-guide.md +612 -0
- package/docs/test-implementation-PLAN.md +223 -0
- package/docs/test-implementation-SUMMARY.md +194 -0
- package/docs/user-guide.md +719 -0
- package/docs/workflow-architecture.md +549 -0
- package/package.json +126 -0
- package/src/application/workflow/SyncExecutor.ts +444 -0
- package/src/application/workflow/types.ts +57 -0
- package/src/config/index.ts +352 -0
- package/src/domain/entities/QualityCheck.ts +202 -0
- package/src/domain/entities/Result.ts +130 -0
- package/src/domain/entities/Task.ts +178 -0
- package/src/domain/entities/TaskStep.ts +188 -0
- package/src/domain/entities/TokenUsage.ts +119 -0
- package/src/domain/entities/index.ts +20 -0
- package/src/domain/repositories/QualityCheckRepository.ts +52 -0
- package/src/domain/repositories/ResultRepository.ts +47 -0
- package/src/domain/repositories/TaskRepository.ts +271 -0
- package/src/domain/workflow/CheckpointManager.ts +283 -0
- package/src/domain/workflow/ContentCreatorGraph.ts +446 -0
- package/src/domain/workflow/State.ts +321 -0
- package/src/domain/workflow/index.ts +18 -0
- package/src/domain/workflow/nodes/BaseNode.ts +325 -0
- package/src/domain/workflow/nodes/CheckImageNode.ts +325 -0
- package/src/domain/workflow/nodes/CheckTextNode.ts +709 -0
- package/src/domain/workflow/nodes/GenerateImageNode.ts +342 -0
- package/src/domain/workflow/nodes/OrganizeNode.ts +304 -0
- package/src/domain/workflow/nodes/SearchNode.ts +192 -0
- package/src/domain/workflow/nodes/WriteNode.ts +505 -0
- package/src/domain/workflow/nodes/index.ts +13 -0
- package/src/index.ts +43 -0
- package/src/infrastructure/cache/CacheService.ts +483 -0
- package/src/infrastructure/cache/index.ts +6 -0
- package/src/infrastructure/database/BaseRepository.ts +214 -0
- package/src/infrastructure/database/MemoryTaskRepository.ts +377 -0
- package/src/infrastructure/database/PostgresQualityCheckRepository.ts +115 -0
- package/src/infrastructure/database/PostgresTaskRepository.ts +424 -0
- package/src/infrastructure/database/ResultRepository.ts +113 -0
- package/src/infrastructure/database/SQLiteTaskRepository.ts +651 -0
- package/src/infrastructure/database/index.ts +83 -0
- package/src/infrastructure/logging/logger.ts +231 -0
- package/src/infrastructure/monitoring/LoggingService.ts +292 -0
- package/src/infrastructure/monitoring/MetricsService.ts +468 -0
- package/src/infrastructure/monitoring/SentryService.ts +345 -0
- package/src/infrastructure/monitoring/index.ts +12 -0
- package/src/infrastructure/queue/TaskQueue.ts +429 -0
- package/src/infrastructure/queue/index.ts +5 -0
- package/src/infrastructure/redis/connection.ts +215 -0
- package/src/infrastructure/redis/index.ts +5 -0
- package/src/infrastructure/security/ApiKeyService.ts +340 -0
- package/src/infrastructure/security/QuotaService.ts +411 -0
- package/src/infrastructure/security/RateLimiter.ts +417 -0
- package/src/infrastructure/security/index.ts +12 -0
- package/src/monitoring/index.ts +5 -0
- package/src/monitoring/server.ts +109 -0
- package/src/presentation/cli/commands/cancel.ts +64 -0
- package/src/presentation/cli/commands/create.ts +400 -0
- package/src/presentation/cli/commands/result.ts +136 -0
- package/src/presentation/cli/commands/status.ts +102 -0
- package/src/presentation/cli/index.ts +39 -0
- package/src/presentation/cli/utils/cleanup.ts +65 -0
- package/src/presentation/cli/utils/formatter.ts +74 -0
- package/src/presentation/cli.ts +8 -0
- package/src/presentation/monitor-cli.ts +52 -0
- package/src/presentation/worker-cli.ts +62 -0
- package/src/schedulers/TaskScheduler.ts +314 -0
- package/src/schedulers/index.ts +11 -0
- package/src/services/image/ImageService.ts +221 -0
- package/src/services/index.ts +15 -0
- package/src/services/llm/EnhancedLLMService.ts +596 -0
- package/src/services/llm/LLMService.ts +310 -0
- package/src/services/quality/HardRuleChecker.ts +509 -0
- package/src/services/quality/LLMEvaluator.ts +400 -0
- package/src/services/quality/QualityCheckService.ts +473 -0
- package/src/services/quality/QualityService.ts +445 -0
- package/src/services/quality/index.ts +12 -0
- package/src/services/search/SearchService.ts +266 -0
- package/src/types/global.d.ts +17 -0
- package/src/workers/TaskWorker.ts +320 -0
- package/src/workers/index.ts +5 -0
|
@@ -0,0 +1,651 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite Task Repository
|
|
3
|
+
*
|
|
4
|
+
* 使用 better-sqlite3 实现的轻量级数据库访问层
|
|
5
|
+
* 适合开发和测试环境
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import Database from 'better-sqlite3';
|
|
9
|
+
import { createLogger } from '../../infrastructure/logging/logger.js';
|
|
10
|
+
import type {
|
|
11
|
+
Task,
|
|
12
|
+
TaskCreateParams,
|
|
13
|
+
TaskUpdateParams,
|
|
14
|
+
TaskListFilters,
|
|
15
|
+
PaginatedResult,
|
|
16
|
+
} from '../../domain/repositories/TaskRepository.js';
|
|
17
|
+
import { TaskStatus } from '../../domain/entities/Task.js';
|
|
18
|
+
|
|
19
|
+
const logger = createLogger('SQLite:TaskRepository');
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* SQLite Task Repository 实现
|
|
23
|
+
*/
|
|
24
|
+
export class SQLiteTaskRepository {
|
|
25
|
+
private db: Database.Database;
|
|
26
|
+
private dbPath: string;
|
|
27
|
+
|
|
28
|
+
constructor(dbPath?: string) {
|
|
29
|
+
this.dbPath = dbPath || './data/content-creator.db';
|
|
30
|
+
this.db = new Database(this.dbPath);
|
|
31
|
+
|
|
32
|
+
// 启用 WAL 模式(更好的并发性能)
|
|
33
|
+
this.db.pragma('journal_mode = WAL');
|
|
34
|
+
|
|
35
|
+
// 初始化数据库表
|
|
36
|
+
this.initializeTables();
|
|
37
|
+
|
|
38
|
+
logger.info('SQLite database connected', { dbPath: this.dbPath });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 初始化数据库表
|
|
43
|
+
*/
|
|
44
|
+
private initializeTables(): void {
|
|
45
|
+
this.db.exec(`
|
|
46
|
+
CREATE TABLE IF NOT EXISTS tasks (
|
|
47
|
+
id TEXT PRIMARY KEY,
|
|
48
|
+
trace_id TEXT,
|
|
49
|
+
mode TEXT NOT NULL,
|
|
50
|
+
type TEXT NOT NULL,
|
|
51
|
+
topic TEXT NOT NULL,
|
|
52
|
+
requirements TEXT NOT NULL,
|
|
53
|
+
hard_constraints TEXT,
|
|
54
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
55
|
+
current_step TEXT,
|
|
56
|
+
error_message TEXT,
|
|
57
|
+
retry_count INTEGER DEFAULT 0,
|
|
58
|
+
max_retries INTEGER DEFAULT 3,
|
|
59
|
+
priority INTEGER DEFAULT 0,
|
|
60
|
+
version INTEGER DEFAULT 1,
|
|
61
|
+
worker_id TEXT,
|
|
62
|
+
started_at TEXT,
|
|
63
|
+
completed_at TEXT,
|
|
64
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
65
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
CREATE TABLE IF NOT EXISTS task_steps (
|
|
69
|
+
id TEXT PRIMARY KEY,
|
|
70
|
+
task_id TEXT NOT NULL,
|
|
71
|
+
step_type TEXT NOT NULL,
|
|
72
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
73
|
+
input_data TEXT,
|
|
74
|
+
output_data TEXT,
|
|
75
|
+
error_message TEXT,
|
|
76
|
+
started_at TEXT,
|
|
77
|
+
completed_at TEXT,
|
|
78
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
79
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
80
|
+
FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
CREATE TABLE IF NOT EXISTS quality_checks (
|
|
84
|
+
id TEXT PRIMARY KEY,
|
|
85
|
+
task_id TEXT NOT NULL,
|
|
86
|
+
check_category TEXT NOT NULL,
|
|
87
|
+
score REAL,
|
|
88
|
+
passed BOOLEAN NOT NULL DEFAULT 0,
|
|
89
|
+
details TEXT,
|
|
90
|
+
fix_suggestions TEXT,
|
|
91
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
92
|
+
FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
CREATE TABLE IF NOT EXISTS results (
|
|
96
|
+
id TEXT PRIMARY KEY,
|
|
97
|
+
task_id TEXT NOT NULL,
|
|
98
|
+
result_type TEXT NOT NULL,
|
|
99
|
+
content TEXT,
|
|
100
|
+
metadata TEXT,
|
|
101
|
+
quality_score REAL,
|
|
102
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
103
|
+
FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
|
|
107
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_worker_id ON tasks(worker_id);
|
|
108
|
+
CREATE INDEX IF NOT EXISTS idx_task_steps_task_id ON task_steps(task_id);
|
|
109
|
+
CREATE INDEX IF NOT EXISTS idx_quality_checks_task_id ON quality_checks(task_id);
|
|
110
|
+
CREATE INDEX IF NOT EXISTS idx_results_task_id ON results(task_id);
|
|
111
|
+
`);
|
|
112
|
+
|
|
113
|
+
logger.debug('Database tables initialized');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* 创建任务
|
|
118
|
+
*/
|
|
119
|
+
async create(params: TaskCreateParams): Promise<Task> {
|
|
120
|
+
const now = new Date().toISOString();
|
|
121
|
+
const stmt = this.db.prepare(`
|
|
122
|
+
INSERT INTO tasks (
|
|
123
|
+
id, trace_id, mode, type, topic, requirements,
|
|
124
|
+
hard_constraints, status, priority, version,
|
|
125
|
+
created_at, updated_at
|
|
126
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
127
|
+
`);
|
|
128
|
+
|
|
129
|
+
const hardConstraints = params.hardConstraints
|
|
130
|
+
? JSON.stringify(params.hardConstraints)
|
|
131
|
+
: null;
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
stmt.run(
|
|
135
|
+
params.id,
|
|
136
|
+
params.traceId || null,
|
|
137
|
+
params.mode,
|
|
138
|
+
params.type,
|
|
139
|
+
params.topic,
|
|
140
|
+
params.requirements,
|
|
141
|
+
hardConstraints,
|
|
142
|
+
TaskStatus.PENDING,
|
|
143
|
+
params.priority || 0,
|
|
144
|
+
1,
|
|
145
|
+
now,
|
|
146
|
+
now
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
const task = await this.findById(params.id);
|
|
150
|
+
if (!task) {
|
|
151
|
+
throw new Error('Failed to create task');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
logger.info('Task created', { taskId: params.id, topic: params.topic });
|
|
155
|
+
return task;
|
|
156
|
+
} catch (error) {
|
|
157
|
+
logger.error('Failed to create task', { error: error as any, params });
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* 根据 ID 查找任务
|
|
164
|
+
*/
|
|
165
|
+
async findById(id: string): Promise<Task | null> {
|
|
166
|
+
const stmt = this.db.prepare('SELECT * FROM tasks WHERE id = ?');
|
|
167
|
+
const row = stmt.get(id) as any;
|
|
168
|
+
|
|
169
|
+
if (!row) {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return this.mapRowToTask(row);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* 更新任务
|
|
178
|
+
*/
|
|
179
|
+
async update(id: string, params: TaskUpdateParams): Promise<Task> {
|
|
180
|
+
const now = new Date().toISOString();
|
|
181
|
+
const updates: string[] = [];
|
|
182
|
+
const values: any[] = [];
|
|
183
|
+
|
|
184
|
+
if (params.status !== undefined) {
|
|
185
|
+
updates.push('status = ?');
|
|
186
|
+
values.push(params.status);
|
|
187
|
+
}
|
|
188
|
+
if (params.currentStep !== undefined) {
|
|
189
|
+
updates.push('current_step = ?');
|
|
190
|
+
values.push(params.currentStep);
|
|
191
|
+
}
|
|
192
|
+
if (params.errorMessage !== undefined) {
|
|
193
|
+
updates.push('error_message = ?');
|
|
194
|
+
values.push(params.errorMessage);
|
|
195
|
+
}
|
|
196
|
+
if (params.retryCount !== undefined) {
|
|
197
|
+
updates.push('retry_count = ?');
|
|
198
|
+
values.push(params.retryCount);
|
|
199
|
+
}
|
|
200
|
+
if (params.workerId !== undefined) {
|
|
201
|
+
updates.push('worker_id = ?');
|
|
202
|
+
values.push(params.workerId);
|
|
203
|
+
}
|
|
204
|
+
if (params.startedAt !== undefined) {
|
|
205
|
+
updates.push('started_at = ?');
|
|
206
|
+
values.push(params.startedAt);
|
|
207
|
+
}
|
|
208
|
+
if (params.completedAt !== undefined) {
|
|
209
|
+
updates.push('completed_at = ?');
|
|
210
|
+
values.push(params.completedAt);
|
|
211
|
+
}
|
|
212
|
+
if (params.version !== undefined) {
|
|
213
|
+
updates.push('version = ?');
|
|
214
|
+
values.push(params.version);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
updates.push('updated_at = ?');
|
|
218
|
+
values.push(now);
|
|
219
|
+
values.push(id);
|
|
220
|
+
|
|
221
|
+
const stmt = this.db.prepare(`
|
|
222
|
+
UPDATE tasks SET ${updates.join(', ')} WHERE id = ?
|
|
223
|
+
`);
|
|
224
|
+
|
|
225
|
+
try {
|
|
226
|
+
stmt.run(...values);
|
|
227
|
+
const task = await this.findById(id);
|
|
228
|
+
if (!task) {
|
|
229
|
+
throw new Error('Task not found after update');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
logger.debug('Task updated', { taskId: id, updates: Object.keys(params) });
|
|
233
|
+
return task;
|
|
234
|
+
} catch (error) {
|
|
235
|
+
logger.error('Failed to update task', { error: error as any, taskId: id, params });
|
|
236
|
+
throw error;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* 抢占任务(Worker 抢占机制)
|
|
242
|
+
*/
|
|
243
|
+
async claimForProcessing(
|
|
244
|
+
workerId: string,
|
|
245
|
+
limit: number = 1
|
|
246
|
+
): Promise<Task[]> {
|
|
247
|
+
const now = new Date().toISOString();
|
|
248
|
+
|
|
249
|
+
// 使用事务确保原子性
|
|
250
|
+
const claimStmt = this.db.prepare(`
|
|
251
|
+
UPDATE tasks
|
|
252
|
+
SET status = ?,
|
|
253
|
+
worker_id = ?,
|
|
254
|
+
started_at = ?,
|
|
255
|
+
updated_at = ?,
|
|
256
|
+
version = version + 1
|
|
257
|
+
WHERE id IN (
|
|
258
|
+
SELECT id FROM tasks
|
|
259
|
+
WHERE status = 'pending'
|
|
260
|
+
OR (status = 'waiting' AND datetime(updated_at) < datetime('now', '-5 minutes'))
|
|
261
|
+
ORDER BY priority DESC, created_at ASC
|
|
262
|
+
LIMIT ?
|
|
263
|
+
)
|
|
264
|
+
RETURNING *
|
|
265
|
+
`);
|
|
266
|
+
|
|
267
|
+
try {
|
|
268
|
+
const rows = claimStmt.all(
|
|
269
|
+
TaskStatus.RUNNING,
|
|
270
|
+
workerId,
|
|
271
|
+
now,
|
|
272
|
+
now,
|
|
273
|
+
limit
|
|
274
|
+
) as any[];
|
|
275
|
+
|
|
276
|
+
const tasks = rows.map((row) => this.mapRowToTask(row));
|
|
277
|
+
|
|
278
|
+
if (tasks.length > 0) {
|
|
279
|
+
logger.info('Tasks claimed for processing', {
|
|
280
|
+
workerId,
|
|
281
|
+
count: tasks.length,
|
|
282
|
+
taskIds: tasks.map((t) => t.id),
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return tasks;
|
|
287
|
+
} catch (error) {
|
|
288
|
+
logger.error('Failed to claim tasks', { error: error as any, workerId });
|
|
289
|
+
throw error;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* 列出任务(带过滤和分页)
|
|
295
|
+
*/
|
|
296
|
+
async list(filters: TaskListFilters = {}): Promise<PaginatedResult<Task>> {
|
|
297
|
+
const {
|
|
298
|
+
status,
|
|
299
|
+
workerId,
|
|
300
|
+
type,
|
|
301
|
+
limit = 50,
|
|
302
|
+
offset = 0,
|
|
303
|
+
sortBy = 'created_at',
|
|
304
|
+
sortOrder = 'DESC',
|
|
305
|
+
} = filters;
|
|
306
|
+
|
|
307
|
+
const conditions: string[] = [];
|
|
308
|
+
const values: any[] = [];
|
|
309
|
+
|
|
310
|
+
if (status) {
|
|
311
|
+
conditions.push('status = ?');
|
|
312
|
+
values.push(status);
|
|
313
|
+
}
|
|
314
|
+
if (workerId) {
|
|
315
|
+
conditions.push('worker_id = ?');
|
|
316
|
+
values.push(workerId);
|
|
317
|
+
}
|
|
318
|
+
if (type) {
|
|
319
|
+
conditions.push('type = ?');
|
|
320
|
+
values.push(type);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const whereClause = conditions.length > 0
|
|
324
|
+
? 'WHERE ' + conditions.join(' AND ')
|
|
325
|
+
: '';
|
|
326
|
+
|
|
327
|
+
// 获取总数
|
|
328
|
+
const countStmt = this.db.prepare(
|
|
329
|
+
`SELECT COUNT(*) as count FROM tasks ${whereClause}`
|
|
330
|
+
);
|
|
331
|
+
const countResult = countStmt.get(...values) as { count: number };
|
|
332
|
+
const total = countResult.count;
|
|
333
|
+
|
|
334
|
+
// 获取分页数据
|
|
335
|
+
const dataStmt = this.db.prepare(`
|
|
336
|
+
SELECT * FROM tasks
|
|
337
|
+
${whereClause}
|
|
338
|
+
ORDER BY ${sortBy} ${sortOrder}
|
|
339
|
+
LIMIT ? OFFSET ?
|
|
340
|
+
`);
|
|
341
|
+
|
|
342
|
+
const rows = dataStmt.all(...values, limit, offset) as any[];
|
|
343
|
+
const tasks = rows.map((row) => this.mapRowToTask(row));
|
|
344
|
+
|
|
345
|
+
return {
|
|
346
|
+
data: tasks,
|
|
347
|
+
total,
|
|
348
|
+
limit,
|
|
349
|
+
offset,
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* 更新任务状态(带乐观锁)
|
|
355
|
+
*/
|
|
356
|
+
async updateStatus(taskId: string, status: TaskStatus, version: number): Promise<boolean> {
|
|
357
|
+
const now = new Date().toISOString();
|
|
358
|
+
const stmt = this.db.prepare(`
|
|
359
|
+
UPDATE tasks
|
|
360
|
+
SET status = ?,
|
|
361
|
+
version = version + 1,
|
|
362
|
+
updated_at = ?
|
|
363
|
+
WHERE id = ? AND version = ?
|
|
364
|
+
`);
|
|
365
|
+
|
|
366
|
+
const result = stmt.run(status, now, taskId, version);
|
|
367
|
+
const updated = result.changes > 0;
|
|
368
|
+
|
|
369
|
+
if (updated) {
|
|
370
|
+
logger.debug('Task status updated', { taskId, status });
|
|
371
|
+
} else {
|
|
372
|
+
logger.warn('Task status update failed (version mismatch)', { taskId, expectedVersion: version });
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
return updated;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* 更新当前步骤(带乐观锁)
|
|
380
|
+
*/
|
|
381
|
+
async updateCurrentStep(taskId: string, step: string, version: number): Promise<boolean> {
|
|
382
|
+
const now = new Date().toISOString();
|
|
383
|
+
const stmt = this.db.prepare(`
|
|
384
|
+
UPDATE tasks
|
|
385
|
+
SET current_step = ?,
|
|
386
|
+
version = version + 1,
|
|
387
|
+
updated_at = ?
|
|
388
|
+
WHERE id = ? AND version = ?
|
|
389
|
+
`);
|
|
390
|
+
|
|
391
|
+
const result = stmt.run(step, now, taskId, version);
|
|
392
|
+
const updated = result.changes > 0;
|
|
393
|
+
|
|
394
|
+
if (updated) {
|
|
395
|
+
logger.debug('Task current step updated', { taskId, step });
|
|
396
|
+
} else {
|
|
397
|
+
logger.warn('Task current step update failed (version mismatch)', { taskId, expectedVersion: version });
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
return updated;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* 抢占任务(Worker 抢占机制)
|
|
405
|
+
*/
|
|
406
|
+
async claimTask(taskId: string, workerId: string, version: number): Promise<boolean> {
|
|
407
|
+
const now = new Date().toISOString();
|
|
408
|
+
const stmt = this.db.prepare(`
|
|
409
|
+
UPDATE tasks
|
|
410
|
+
SET status = ?,
|
|
411
|
+
worker_id = ?,
|
|
412
|
+
started_at = ?,
|
|
413
|
+
version = version + 1,
|
|
414
|
+
updated_at = ?
|
|
415
|
+
WHERE id = ? AND version = ? AND status = ?
|
|
416
|
+
`);
|
|
417
|
+
|
|
418
|
+
const result = stmt.run(TaskStatus.RUNNING, workerId, now, taskId, version, TaskStatus.PENDING);
|
|
419
|
+
const claimed = result.changes > 0;
|
|
420
|
+
|
|
421
|
+
if (claimed) {
|
|
422
|
+
logger.info('Task claimed', { taskId, workerId });
|
|
423
|
+
} else {
|
|
424
|
+
logger.warn('Task claim failed (version mismatch or not pending)', { taskId, workerId, expectedVersion: version });
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
return claimed;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* 增加重试计数(带乐观锁)
|
|
432
|
+
*/
|
|
433
|
+
async incrementRetryCount(taskId: string, type: 'text' | 'image', version: number): Promise<boolean> {
|
|
434
|
+
const now = new Date().toISOString();
|
|
435
|
+
const stmt = this.db.prepare(`
|
|
436
|
+
UPDATE tasks
|
|
437
|
+
SET retry_count = retry_count + 1,
|
|
438
|
+
version = version + 1,
|
|
439
|
+
updated_at = ?
|
|
440
|
+
WHERE id = ? AND version = ?
|
|
441
|
+
`);
|
|
442
|
+
|
|
443
|
+
const result = stmt.run(now, taskId, version);
|
|
444
|
+
const updated = result.changes > 0;
|
|
445
|
+
|
|
446
|
+
if (updated) {
|
|
447
|
+
logger.debug('Task retry count incremented', { taskId, type });
|
|
448
|
+
} else {
|
|
449
|
+
logger.warn('Task retry count increment failed (version mismatch)', { taskId, type, expectedVersion: version });
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
return updated;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* 保存状态快照(带乐观锁)
|
|
457
|
+
*/
|
|
458
|
+
async saveStateSnapshot(taskId: string, snapshot: object, _version: number): Promise<boolean> {
|
|
459
|
+
const now = new Date().toISOString();
|
|
460
|
+
const stmt = this.db.prepare(`
|
|
461
|
+
INSERT OR REPLACE INTO task_steps (id, task_id, step_type, status, output_data, created_at, updated_at)
|
|
462
|
+
VALUES (?, ?, ?, 'completed', ?, ?, ?)
|
|
463
|
+
`);
|
|
464
|
+
|
|
465
|
+
try {
|
|
466
|
+
stmt.run(`${taskId}_${Date.now()}`, taskId, 'state', JSON.stringify(snapshot), now, now);
|
|
467
|
+
logger.debug('State snapshot saved', { taskId });
|
|
468
|
+
return true;
|
|
469
|
+
} catch (error) {
|
|
470
|
+
logger.error('Failed to save state snapshot', { error: error as any, taskId });
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* 标记任务完成(带乐观锁)
|
|
477
|
+
*/
|
|
478
|
+
async markAsCompleted(taskId: string, version: number): Promise<boolean> {
|
|
479
|
+
const now = new Date().toISOString();
|
|
480
|
+
const stmt = this.db.prepare(`
|
|
481
|
+
UPDATE tasks
|
|
482
|
+
SET status = ?,
|
|
483
|
+
completed_at = ?,
|
|
484
|
+
version = version + 1,
|
|
485
|
+
updated_at = ?
|
|
486
|
+
WHERE id = ? AND version = ?
|
|
487
|
+
`);
|
|
488
|
+
|
|
489
|
+
const result = stmt.run(TaskStatus.COMPLETED, now, now, taskId, version);
|
|
490
|
+
const updated = result.changes > 0;
|
|
491
|
+
|
|
492
|
+
if (updated) {
|
|
493
|
+
logger.info('Task marked as completed', { taskId });
|
|
494
|
+
} else {
|
|
495
|
+
logger.warn('Task mark as completed failed (version mismatch)', { taskId, expectedVersion: version });
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return updated;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* 标记任务失败(带乐观锁)
|
|
503
|
+
*/
|
|
504
|
+
async markAsFailed(taskId: string, errorMessage: string, version: number): Promise<boolean> {
|
|
505
|
+
const now = new Date().toISOString();
|
|
506
|
+
const stmt = this.db.prepare(`
|
|
507
|
+
UPDATE tasks
|
|
508
|
+
SET status = ?,
|
|
509
|
+
error_message = ?,
|
|
510
|
+
completed_at = ?,
|
|
511
|
+
version = version + 1,
|
|
512
|
+
updated_at = ?
|
|
513
|
+
WHERE id = ? AND version = ?
|
|
514
|
+
`);
|
|
515
|
+
|
|
516
|
+
const result = stmt.run(TaskStatus.FAILED, errorMessage, now, now, taskId, version);
|
|
517
|
+
const updated = result.changes > 0;
|
|
518
|
+
|
|
519
|
+
if (updated) {
|
|
520
|
+
logger.info('Task marked as failed', { taskId, errorMessage });
|
|
521
|
+
} else {
|
|
522
|
+
logger.warn('Task mark as failed failed (version mismatch)', { taskId, expectedVersion: version });
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
return updated;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* 释放 Worker 占用(用于任务崩溃时)
|
|
530
|
+
*/
|
|
531
|
+
async releaseWorker(taskId: string, workerId: string, version: number): Promise<boolean> {
|
|
532
|
+
const now = new Date().toISOString();
|
|
533
|
+
const stmt = this.db.prepare(`
|
|
534
|
+
UPDATE tasks
|
|
535
|
+
SET status = ?,
|
|
536
|
+
worker_id = NULL,
|
|
537
|
+
version = version + 1,
|
|
538
|
+
updated_at = ?
|
|
539
|
+
WHERE id = ? AND version = ? AND worker_id = ?
|
|
540
|
+
`);
|
|
541
|
+
|
|
542
|
+
const result = stmt.run(TaskStatus.PENDING, now, taskId, version, workerId);
|
|
543
|
+
const released = result.changes > 0;
|
|
544
|
+
|
|
545
|
+
if (released) {
|
|
546
|
+
logger.info('Task worker released', { taskId, workerId });
|
|
547
|
+
} else {
|
|
548
|
+
logger.warn('Task worker release failed', { taskId, workerId, expectedVersion: version });
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
return released;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* 软删除任务
|
|
556
|
+
*/
|
|
557
|
+
async softDelete(taskId: string): Promise<boolean> {
|
|
558
|
+
// SQLite 不支持软删除,直接删除
|
|
559
|
+
return this.delete(taskId);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* 永久删除任务
|
|
564
|
+
*/
|
|
565
|
+
async delete(taskId: string): Promise<boolean> {
|
|
566
|
+
const stmt = this.db.prepare('DELETE FROM tasks WHERE id = ?');
|
|
567
|
+
const result = stmt.run(taskId);
|
|
568
|
+
|
|
569
|
+
return result.changes > 0;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* 获取待处理任务队列(用于 Worker 获取任务)
|
|
574
|
+
*/
|
|
575
|
+
async getPendingTasks(limit: number = 10): Promise<Task[]> {
|
|
576
|
+
const stmt = this.db.prepare(`
|
|
577
|
+
SELECT * FROM tasks
|
|
578
|
+
WHERE status = ?
|
|
579
|
+
ORDER BY priority DESC, created_at ASC
|
|
580
|
+
LIMIT ?
|
|
581
|
+
`);
|
|
582
|
+
|
|
583
|
+
const rows = stmt.all(TaskStatus.PENDING, limit) as any[];
|
|
584
|
+
return rows.map((row) => this.mapRowToTask(row));
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* 获取 Worker 的活跃任务
|
|
589
|
+
*/
|
|
590
|
+
async getActiveTasksByWorker(workerId: string): Promise<Task[]> {
|
|
591
|
+
const stmt = this.db.prepare(`
|
|
592
|
+
SELECT * FROM tasks
|
|
593
|
+
WHERE status = ? AND worker_id = ?
|
|
594
|
+
`);
|
|
595
|
+
|
|
596
|
+
const rows = stmt.all(TaskStatus.RUNNING, workerId) as any[];
|
|
597
|
+
return rows.map((row) => this.mapRowToTask(row));
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* 健康检查
|
|
602
|
+
*/
|
|
603
|
+
async healthCheck(): Promise<boolean> {
|
|
604
|
+
try {
|
|
605
|
+
const stmt = this.db.prepare('SELECT 1');
|
|
606
|
+
stmt.get();
|
|
607
|
+
return true;
|
|
608
|
+
} catch (error) {
|
|
609
|
+
logger.error('Database health check failed', { error: error as any });
|
|
610
|
+
return false;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* 关闭数据库连接
|
|
616
|
+
*/
|
|
617
|
+
close(): void {
|
|
618
|
+
this.db.close();
|
|
619
|
+
logger.info('SQLite database connection closed');
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/**
|
|
623
|
+
* 将数据库行映射为 Task 对象
|
|
624
|
+
*/
|
|
625
|
+
private mapRowToTask(row: any): Task {
|
|
626
|
+
return {
|
|
627
|
+
id: row.id,
|
|
628
|
+
taskId: row.id,
|
|
629
|
+
mode: row.mode as any,
|
|
630
|
+
type: row.type as any,
|
|
631
|
+
topic: row.topic,
|
|
632
|
+
requirements: row.requirements,
|
|
633
|
+
hardConstraints: row.hard_constraints
|
|
634
|
+
? JSON.parse(row.hard_constraints)
|
|
635
|
+
: undefined,
|
|
636
|
+
status: row.status,
|
|
637
|
+
priority: row.priority || 2,
|
|
638
|
+
version: row.version || 1,
|
|
639
|
+
textRetryCount: row.retry_count || 0,
|
|
640
|
+
imageRetryCount: 0,
|
|
641
|
+
targetAudience: 'general',
|
|
642
|
+
currentStep: row.current_step,
|
|
643
|
+
errorMessage: row.error_message,
|
|
644
|
+
workerId: row.worker_id,
|
|
645
|
+
startedAt: row.started_at ? new Date(row.started_at) : undefined,
|
|
646
|
+
completedAt: row.completed_at ? new Date(row.completed_at) : undefined,
|
|
647
|
+
createdAt: new Date(row.created_at),
|
|
648
|
+
updatedAt: new Date(row.updated_at),
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
}
|