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.
Files changed (438) hide show
  1. package/README.md +309 -0
  2. package/dist/application/workflow/SyncExecutor.d.ts +75 -0
  3. package/dist/application/workflow/SyncExecutor.d.ts.map +1 -0
  4. package/dist/application/workflow/SyncExecutor.js +370 -0
  5. package/dist/application/workflow/SyncExecutor.js.map +1 -0
  6. package/dist/application/workflow/types.d.ts +46 -0
  7. package/dist/application/workflow/types.d.ts.map +1 -0
  8. package/dist/application/workflow/types.js +7 -0
  9. package/dist/application/workflow/types.js.map +1 -0
  10. package/dist/config/index.d.ts +173 -0
  11. package/dist/config/index.d.ts.map +1 -0
  12. package/dist/config/index.js +288 -0
  13. package/dist/config/index.js.map +1 -0
  14. package/dist/domain/entities/QualityCheck.d.ts +181 -0
  15. package/dist/domain/entities/QualityCheck.d.ts.map +1 -0
  16. package/dist/domain/entities/QualityCheck.js +39 -0
  17. package/dist/domain/entities/QualityCheck.js.map +1 -0
  18. package/dist/domain/entities/Result.d.ts +103 -0
  19. package/dist/domain/entities/Result.d.ts.map +1 -0
  20. package/dist/domain/entities/Result.js +15 -0
  21. package/dist/domain/entities/Result.js.map +1 -0
  22. package/dist/domain/entities/Task.d.ts +130 -0
  23. package/dist/domain/entities/Task.d.ts.map +1 -0
  24. package/dist/domain/entities/Task.js +64 -0
  25. package/dist/domain/entities/Task.js.map +1 -0
  26. package/dist/domain/entities/TaskStep.d.ts +160 -0
  27. package/dist/domain/entities/TaskStep.d.ts.map +1 -0
  28. package/dist/domain/entities/TaskStep.js +30 -0
  29. package/dist/domain/entities/TaskStep.js.map +1 -0
  30. package/dist/domain/entities/TokenUsage.d.ts +70 -0
  31. package/dist/domain/entities/TokenUsage.d.ts.map +1 -0
  32. package/dist/domain/entities/TokenUsage.js +42 -0
  33. package/dist/domain/entities/TokenUsage.js.map +1 -0
  34. package/dist/domain/entities/index.d.ts +11 -0
  35. package/dist/domain/entities/index.d.ts.map +1 -0
  36. package/dist/domain/entities/index.js +16 -0
  37. package/dist/domain/entities/index.js.map +1 -0
  38. package/dist/domain/repositories/QualityCheckRepository.d.ts +49 -0
  39. package/dist/domain/repositories/QualityCheckRepository.d.ts.map +1 -0
  40. package/dist/domain/repositories/QualityCheckRepository.js +5 -0
  41. package/dist/domain/repositories/QualityCheckRepository.js.map +1 -0
  42. package/dist/domain/repositories/ResultRepository.d.ts +43 -0
  43. package/dist/domain/repositories/ResultRepository.d.ts.map +1 -0
  44. package/dist/domain/repositories/ResultRepository.js +5 -0
  45. package/dist/domain/repositories/ResultRepository.js.map +1 -0
  46. package/dist/domain/repositories/TaskRepository.d.ts +240 -0
  47. package/dist/domain/repositories/TaskRepository.d.ts.map +1 -0
  48. package/dist/domain/repositories/TaskRepository.js +7 -0
  49. package/dist/domain/repositories/TaskRepository.js.map +1 -0
  50. package/dist/domain/workflow/CheckpointManager.d.ts +94 -0
  51. package/dist/domain/workflow/CheckpointManager.d.ts.map +1 -0
  52. package/dist/domain/workflow/CheckpointManager.js +224 -0
  53. package/dist/domain/workflow/CheckpointManager.js.map +1 -0
  54. package/dist/domain/workflow/ContentCreatorGraph.d.ts +17 -0
  55. package/dist/domain/workflow/ContentCreatorGraph.d.ts.map +1 -0
  56. package/dist/domain/workflow/ContentCreatorGraph.js +381 -0
  57. package/dist/domain/workflow/ContentCreatorGraph.js.map +1 -0
  58. package/dist/domain/workflow/State.d.ts +172 -0
  59. package/dist/domain/workflow/State.d.ts.map +1 -0
  60. package/dist/domain/workflow/State.js +184 -0
  61. package/dist/domain/workflow/State.js.map +1 -0
  62. package/dist/domain/workflow/index.d.ts +11 -0
  63. package/dist/domain/workflow/index.d.ts.map +1 -0
  64. package/dist/domain/workflow/index.js +15 -0
  65. package/dist/domain/workflow/index.js.map +1 -0
  66. package/dist/domain/workflow/nodes/BaseNode.d.ts +134 -0
  67. package/dist/domain/workflow/nodes/BaseNode.d.ts.map +1 -0
  68. package/dist/domain/workflow/nodes/BaseNode.js +253 -0
  69. package/dist/domain/workflow/nodes/BaseNode.js.map +1 -0
  70. package/dist/domain/workflow/nodes/CheckImageNode.d.ts +43 -0
  71. package/dist/domain/workflow/nodes/CheckImageNode.d.ts.map +1 -0
  72. package/dist/domain/workflow/nodes/CheckImageNode.js +254 -0
  73. package/dist/domain/workflow/nodes/CheckImageNode.js.map +1 -0
  74. package/dist/domain/workflow/nodes/CheckTextNode.d.ts +66 -0
  75. package/dist/domain/workflow/nodes/CheckTextNode.d.ts.map +1 -0
  76. package/dist/domain/workflow/nodes/CheckTextNode.js +530 -0
  77. package/dist/domain/workflow/nodes/CheckTextNode.js.map +1 -0
  78. package/dist/domain/workflow/nodes/GenerateImageNode.d.ts +44 -0
  79. package/dist/domain/workflow/nodes/GenerateImageNode.d.ts.map +1 -0
  80. package/dist/domain/workflow/nodes/GenerateImageNode.js +272 -0
  81. package/dist/domain/workflow/nodes/GenerateImageNode.js.map +1 -0
  82. package/dist/domain/workflow/nodes/OrganizeNode.d.ts +49 -0
  83. package/dist/domain/workflow/nodes/OrganizeNode.d.ts.map +1 -0
  84. package/dist/domain/workflow/nodes/OrganizeNode.js +241 -0
  85. package/dist/domain/workflow/nodes/OrganizeNode.js.map +1 -0
  86. package/dist/domain/workflow/nodes/SearchNode.d.ts +48 -0
  87. package/dist/domain/workflow/nodes/SearchNode.d.ts.map +1 -0
  88. package/dist/domain/workflow/nodes/SearchNode.js +151 -0
  89. package/dist/domain/workflow/nodes/SearchNode.js.map +1 -0
  90. package/dist/domain/workflow/nodes/WriteNode.d.ts +68 -0
  91. package/dist/domain/workflow/nodes/WriteNode.d.ts.map +1 -0
  92. package/dist/domain/workflow/nodes/WriteNode.js +431 -0
  93. package/dist/domain/workflow/nodes/WriteNode.js.map +1 -0
  94. package/dist/domain/workflow/nodes/config/index.js +287 -0
  95. package/dist/domain/workflow/nodes/domain/entities/Task.js +68 -0
  96. package/dist/domain/workflow/nodes/domain/workflow/State.js +200 -0
  97. package/dist/domain/workflow/nodes/domain/workflow/nodes/BaseNode.js +328 -0
  98. package/dist/domain/workflow/nodes/domain/workflow/nodes/CheckTextNode.js +500 -0
  99. package/dist/domain/workflow/nodes/index.d.ts +13 -0
  100. package/dist/domain/workflow/nodes/index.d.ts.map +1 -0
  101. package/dist/domain/workflow/nodes/index.js +13 -0
  102. package/dist/domain/workflow/nodes/index.js.map +1 -0
  103. package/dist/domain/workflow/nodes/infrastructure/logging/logger.js +275 -0
  104. package/dist/domain/workflow/nodes/services/llm/EnhancedLLMService.js +559 -0
  105. package/dist/index.d.ts +24 -0
  106. package/dist/index.d.ts.map +1 -0
  107. package/dist/index.js +34 -0
  108. package/dist/index.js.map +1 -0
  109. package/dist/infrastructure/cache/CacheService.d.ts +139 -0
  110. package/dist/infrastructure/cache/CacheService.d.ts.map +1 -0
  111. package/dist/infrastructure/cache/CacheService.js +419 -0
  112. package/dist/infrastructure/cache/CacheService.js.map +1 -0
  113. package/dist/infrastructure/cache/index.d.ts +5 -0
  114. package/dist/infrastructure/cache/index.d.ts.map +1 -0
  115. package/dist/infrastructure/cache/index.js +6 -0
  116. package/dist/infrastructure/cache/index.js.map +1 -0
  117. package/dist/infrastructure/database/BaseRepository.d.ts +98 -0
  118. package/dist/infrastructure/database/BaseRepository.d.ts.map +1 -0
  119. package/dist/infrastructure/database/BaseRepository.js +178 -0
  120. package/dist/infrastructure/database/BaseRepository.js.map +1 -0
  121. package/dist/infrastructure/database/MemoryTaskRepository.d.ts +77 -0
  122. package/dist/infrastructure/database/MemoryTaskRepository.d.ts.map +1 -0
  123. package/dist/infrastructure/database/MemoryTaskRepository.js +309 -0
  124. package/dist/infrastructure/database/MemoryTaskRepository.js.map +1 -0
  125. package/dist/infrastructure/database/PostgresQualityCheckRepository.d.ts +36 -0
  126. package/dist/infrastructure/database/PostgresQualityCheckRepository.d.ts.map +1 -0
  127. package/dist/infrastructure/database/PostgresQualityCheckRepository.js +89 -0
  128. package/dist/infrastructure/database/PostgresQualityCheckRepository.js.map +1 -0
  129. package/dist/infrastructure/database/PostgresTaskRepository.d.ts +94 -0
  130. package/dist/infrastructure/database/PostgresTaskRepository.d.ts.map +1 -0
  131. package/dist/infrastructure/database/PostgresTaskRepository.js +364 -0
  132. package/dist/infrastructure/database/PostgresTaskRepository.js.map +1 -0
  133. package/dist/infrastructure/database/ResultRepository.d.ts +41 -0
  134. package/dist/infrastructure/database/ResultRepository.d.ts.map +1 -0
  135. package/dist/infrastructure/database/ResultRepository.js +86 -0
  136. package/dist/infrastructure/database/ResultRepository.js.map +1 -0
  137. package/dist/infrastructure/database/SQLiteTaskRepository.d.ts +101 -0
  138. package/dist/infrastructure/database/SQLiteTaskRepository.d.ts.map +1 -0
  139. package/dist/infrastructure/database/SQLiteTaskRepository.js +548 -0
  140. package/dist/infrastructure/database/SQLiteTaskRepository.js.map +1 -0
  141. package/dist/infrastructure/database/index.d.ts +32 -0
  142. package/dist/infrastructure/database/index.d.ts.map +1 -0
  143. package/dist/infrastructure/database/index.js +72 -0
  144. package/dist/infrastructure/database/index.js.map +1 -0
  145. package/dist/infrastructure/logging/logger.d.ts +69 -0
  146. package/dist/infrastructure/logging/logger.d.ts.map +1 -0
  147. package/dist/infrastructure/logging/logger.js +169 -0
  148. package/dist/infrastructure/logging/logger.js.map +1 -0
  149. package/dist/infrastructure/monitoring/LoggingService.d.ts +109 -0
  150. package/dist/infrastructure/monitoring/LoggingService.d.ts.map +1 -0
  151. package/dist/infrastructure/monitoring/LoggingService.js +198 -0
  152. package/dist/infrastructure/monitoring/LoggingService.js.map +1 -0
  153. package/dist/infrastructure/monitoring/MetricsService.d.ts +112 -0
  154. package/dist/infrastructure/monitoring/MetricsService.d.ts.map +1 -0
  155. package/dist/infrastructure/monitoring/MetricsService.js +362 -0
  156. package/dist/infrastructure/monitoring/MetricsService.js.map +1 -0
  157. package/dist/infrastructure/monitoring/SentryService.d.ts +108 -0
  158. package/dist/infrastructure/monitoring/SentryService.d.ts.map +1 -0
  159. package/dist/infrastructure/monitoring/SentryService.js +282 -0
  160. package/dist/infrastructure/monitoring/SentryService.js.map +1 -0
  161. package/dist/infrastructure/monitoring/index.d.ts +7 -0
  162. package/dist/infrastructure/monitoring/index.d.ts.map +1 -0
  163. package/dist/infrastructure/monitoring/index.js +10 -0
  164. package/dist/infrastructure/monitoring/index.js.map +1 -0
  165. package/dist/infrastructure/queue/TaskQueue.d.ts +110 -0
  166. package/dist/infrastructure/queue/TaskQueue.d.ts.map +1 -0
  167. package/dist/infrastructure/queue/TaskQueue.js +363 -0
  168. package/dist/infrastructure/queue/TaskQueue.js.map +1 -0
  169. package/dist/infrastructure/queue/index.d.ts +5 -0
  170. package/dist/infrastructure/queue/index.d.ts.map +1 -0
  171. package/dist/infrastructure/queue/index.js +5 -0
  172. package/dist/infrastructure/queue/index.js.map +1 -0
  173. package/dist/infrastructure/redis/connection.d.ts +61 -0
  174. package/dist/infrastructure/redis/connection.d.ts.map +1 -0
  175. package/dist/infrastructure/redis/connection.js +184 -0
  176. package/dist/infrastructure/redis/connection.js.map +1 -0
  177. package/dist/infrastructure/redis/index.d.ts +5 -0
  178. package/dist/infrastructure/redis/index.d.ts.map +1 -0
  179. package/dist/infrastructure/redis/index.js +5 -0
  180. package/dist/infrastructure/redis/index.js.map +1 -0
  181. package/dist/infrastructure/security/ApiKeyService.d.ts +103 -0
  182. package/dist/infrastructure/security/ApiKeyService.d.ts.map +1 -0
  183. package/dist/infrastructure/security/ApiKeyService.js +250 -0
  184. package/dist/infrastructure/security/ApiKeyService.js.map +1 -0
  185. package/dist/infrastructure/security/QuotaService.d.ts +87 -0
  186. package/dist/infrastructure/security/QuotaService.d.ts.map +1 -0
  187. package/dist/infrastructure/security/QuotaService.js +303 -0
  188. package/dist/infrastructure/security/QuotaService.js.map +1 -0
  189. package/dist/infrastructure/security/RateLimiter.d.ts +104 -0
  190. package/dist/infrastructure/security/RateLimiter.d.ts.map +1 -0
  191. package/dist/infrastructure/security/RateLimiter.js +331 -0
  192. package/dist/infrastructure/security/RateLimiter.js.map +1 -0
  193. package/dist/infrastructure/security/index.d.ts +7 -0
  194. package/dist/infrastructure/security/index.d.ts.map +1 -0
  195. package/dist/infrastructure/security/index.js +10 -0
  196. package/dist/infrastructure/security/index.js.map +1 -0
  197. package/dist/monitoring/index.d.ts +5 -0
  198. package/dist/monitoring/index.d.ts.map +1 -0
  199. package/dist/monitoring/index.js +5 -0
  200. package/dist/monitoring/index.js.map +1 -0
  201. package/dist/monitoring/server.d.ts +14 -0
  202. package/dist/monitoring/server.d.ts.map +1 -0
  203. package/dist/monitoring/server.js +99 -0
  204. package/dist/monitoring/server.js.map +1 -0
  205. package/dist/presentation/cli/commands/cancel.d.ts +8 -0
  206. package/dist/presentation/cli/commands/cancel.d.ts.map +1 -0
  207. package/dist/presentation/cli/commands/cancel.js +57 -0
  208. package/dist/presentation/cli/commands/cancel.js.map +1 -0
  209. package/dist/presentation/cli/commands/create.d.ts +8 -0
  210. package/dist/presentation/cli/commands/create.d.ts.map +1 -0
  211. package/dist/presentation/cli/commands/create.js +368 -0
  212. package/dist/presentation/cli/commands/create.js.map +1 -0
  213. package/dist/presentation/cli/commands/result.d.ts +8 -0
  214. package/dist/presentation/cli/commands/result.d.ts.map +1 -0
  215. package/dist/presentation/cli/commands/result.js +121 -0
  216. package/dist/presentation/cli/commands/result.js.map +1 -0
  217. package/dist/presentation/cli/commands/status.d.ts +8 -0
  218. package/dist/presentation/cli/commands/status.d.ts.map +1 -0
  219. package/dist/presentation/cli/commands/status.js +92 -0
  220. package/dist/presentation/cli/commands/status.js.map +1 -0
  221. package/dist/presentation/cli/index.d.ts +8 -0
  222. package/dist/presentation/cli/index.d.ts.map +1 -0
  223. package/dist/presentation/cli/index.js +32 -0
  224. package/dist/presentation/cli/index.js.map +1 -0
  225. package/dist/presentation/cli/utils/cleanup.d.ts +14 -0
  226. package/dist/presentation/cli/utils/cleanup.d.ts.map +1 -0
  227. package/dist/presentation/cli/utils/cleanup.js +62 -0
  228. package/dist/presentation/cli/utils/cleanup.js.map +1 -0
  229. package/dist/presentation/cli/utils/formatter.d.ts +28 -0
  230. package/dist/presentation/cli/utils/formatter.d.ts.map +1 -0
  231. package/dist/presentation/cli/utils/formatter.js +68 -0
  232. package/dist/presentation/cli/utils/formatter.js.map +1 -0
  233. package/dist/presentation/cli.d.ts +7 -0
  234. package/dist/presentation/cli.d.ts.map +1 -0
  235. package/dist/presentation/cli.js +8 -0
  236. package/dist/presentation/cli.js.map +1 -0
  237. package/dist/presentation/monitor-cli.d.ts +8 -0
  238. package/dist/presentation/monitor-cli.d.ts.map +1 -0
  239. package/dist/presentation/monitor-cli.js +44 -0
  240. package/dist/presentation/monitor-cli.js.map +1 -0
  241. package/dist/presentation/worker-cli.d.ts +8 -0
  242. package/dist/presentation/worker-cli.d.ts.map +1 -0
  243. package/dist/presentation/worker-cli.js +51 -0
  244. package/dist/presentation/worker-cli.js.map +1 -0
  245. package/dist/schedulers/TaskScheduler.d.ts +99 -0
  246. package/dist/schedulers/TaskScheduler.d.ts.map +1 -0
  247. package/dist/schedulers/TaskScheduler.js +233 -0
  248. package/dist/schedulers/TaskScheduler.js.map +1 -0
  249. package/dist/schedulers/index.d.ts +5 -0
  250. package/dist/schedulers/index.d.ts.map +1 -0
  251. package/dist/schedulers/index.js +5 -0
  252. package/dist/schedulers/index.js.map +1 -0
  253. package/dist/services/image/ImageService.d.ts +68 -0
  254. package/dist/services/image/ImageService.d.ts.map +1 -0
  255. package/dist/services/image/ImageService.js +166 -0
  256. package/dist/services/image/ImageService.js.map +1 -0
  257. package/dist/services/index.d.ts +8 -0
  258. package/dist/services/index.d.ts.map +1 -0
  259. package/dist/services/index.js +12 -0
  260. package/dist/services/index.js.map +1 -0
  261. package/dist/services/llm/EnhancedLLMService.d.ts +148 -0
  262. package/dist/services/llm/EnhancedLLMService.d.ts.map +1 -0
  263. package/dist/services/llm/EnhancedLLMService.js +425 -0
  264. package/dist/services/llm/EnhancedLLMService.js.map +1 -0
  265. package/dist/services/llm/LLMService.d.ts +103 -0
  266. package/dist/services/llm/LLMService.d.ts.map +1 -0
  267. package/dist/services/llm/LLMService.js +212 -0
  268. package/dist/services/llm/LLMService.js.map +1 -0
  269. package/dist/services/quality/HardRuleChecker.d.ts +143 -0
  270. package/dist/services/quality/HardRuleChecker.d.ts.map +1 -0
  271. package/dist/services/quality/HardRuleChecker.js +353 -0
  272. package/dist/services/quality/HardRuleChecker.js.map +1 -0
  273. package/dist/services/quality/LLMEvaluator.d.ts +105 -0
  274. package/dist/services/quality/LLMEvaluator.d.ts.map +1 -0
  275. package/dist/services/quality/LLMEvaluator.js +312 -0
  276. package/dist/services/quality/LLMEvaluator.js.map +1 -0
  277. package/dist/services/quality/QualityCheckService.d.ts +112 -0
  278. package/dist/services/quality/QualityCheckService.d.ts.map +1 -0
  279. package/dist/services/quality/QualityCheckService.js +342 -0
  280. package/dist/services/quality/QualityCheckService.js.map +1 -0
  281. package/dist/services/quality/QualityService.d.ts +75 -0
  282. package/dist/services/quality/QualityService.d.ts.map +1 -0
  283. package/dist/services/quality/QualityService.js +360 -0
  284. package/dist/services/quality/QualityService.js.map +1 -0
  285. package/dist/services/quality/index.d.ts +7 -0
  286. package/dist/services/quality/index.d.ts.map +1 -0
  287. package/dist/services/quality/index.js +10 -0
  288. package/dist/services/quality/index.js.map +1 -0
  289. package/dist/services/search/SearchService.d.ts +79 -0
  290. package/dist/services/search/SearchService.d.ts.map +1 -0
  291. package/dist/services/search/SearchService.js +193 -0
  292. package/dist/services/search/SearchService.js.map +1 -0
  293. package/dist/workers/TaskWorker.d.ts +61 -0
  294. package/dist/workers/TaskWorker.d.ts.map +1 -0
  295. package/dist/workers/TaskWorker.js +256 -0
  296. package/dist/workers/TaskWorker.js.map +1 -0
  297. package/dist/workers/index.d.ts +5 -0
  298. package/dist/workers/index.d.ts.map +1 -0
  299. package/dist/workers/index.js +5 -0
  300. package/dist/workers/index.js.map +1 -0
  301. package/docs/DOCUMENTATION-ANALYSIS.md +190 -0
  302. package/docs/README.md +145 -0
  303. package/docs/SOURCE-CODE-ANALYSIS.md +1107 -0
  304. package/docs/architecture-complete.md +5524 -0
  305. package/docs/archive/implementation/implementation-analysis/README.md +244 -0
  306. package/docs/archive/implementation/implementation-analysis/implementation-analysis-context.md +483 -0
  307. package/docs/archive/implementation/implementation-analysis/implementation-analysis-plan.md +1242 -0
  308. package/docs/archive/implementation/implementation-analysis/implementation-analysis-tasks.md +777 -0
  309. package/docs/archive/phases/phase-1/phase-1-completion-summary.md +284 -0
  310. package/docs/archive/phases/phase-1/phase-1-implementation-guide.md +1380 -0
  311. package/docs/archive/phases/phase-2/phase-2a/phase-2a-completion-summary.md +443 -0
  312. package/docs/archive/phases/phase-2/phase-2b/phase-2b-completion-report.md +430 -0
  313. package/docs/archive/phases/phase-2/phase-2b/phase-2b-completion-summary.md +592 -0
  314. package/docs/archive/phases/phase-2/phase-2b/phase-2b-final-summary.md +371 -0
  315. package/docs/archive/phases/phase-2/phase-2b/phase-2b-preparation-complete.md +343 -0
  316. package/docs/archive/phases/phase-2/phase-2b/phase-2b-preparation.md +945 -0
  317. package/docs/archive/phases/phase-2/phase-2b/phase-2b-progress-update.md +366 -0
  318. package/docs/archive/phases/phase-3/phase-3-completion-summary.md +354 -0
  319. package/docs/archive/phases/phase-3/phase-3-development-plan.md +878 -0
  320. package/docs/archive/phases/phase-3/phase-3-quick-start.md +324 -0
  321. package/docs/archive/phases/phase-4/phase-4-completion-summary.md +708 -0
  322. package/docs/archive/phases/phase-4/phase-4-development-plan.md +740 -0
  323. package/docs/archive/phases/phase-4/phase-4-quick-start.md +632 -0
  324. package/docs/archive/phases/phase-4/phase-4-session-3-security-testing.md +484 -0
  325. package/docs/archive/phases/phase-4/phase-4-session-4-unit-tests.md +550 -0
  326. package/docs/archive/phases/phase-4/phase-4-session-5-security-tests.md +564 -0
  327. package/docs/archive/phases/phase-4/phase-4-session-6-cache-integration.md +456 -0
  328. package/docs/archive/phases/phase-4/phase-4-session-7-test-fixes.md +348 -0
  329. package/docs/archive/phases/phase-4/phase-4-session-8-taskqueue-fixes.md +323 -0
  330. package/docs/archive/phases/phase-4/phase-4-session-summary-continued.md +373 -0
  331. package/docs/archive/phases/phase-4/phase-4-session-summary.md +595 -0
  332. package/docs/archive/reports/progress-reports/PHASE_0_PROGRESS.md +242 -0
  333. package/docs/archive/reports/progress-reports/PHASE_0_SUMMARY.md +262 -0
  334. package/docs/archive/reports/progress-reports/PHASE_1_2_ISSUES.md +399 -0
  335. package/docs/archive/reports/progress-reports/PHASE_1_PROGRESS.md +388 -0
  336. package/docs/archive/reports/progress-reports/PHASE_3_PREPARATION.md +574 -0
  337. package/docs/archive/reports/progress-reports/current-progress-update.md +294 -0
  338. package/docs/archive/reports/progress-reports/final-summary.md +215 -0
  339. package/docs/archive/reports/progress-reports/implementation-summary.md +287 -0
  340. package/docs/archive/reports/progress-reports/project-progress-report.md +440 -0
  341. package/docs/archive/reports/progress-reports/project-progress.md +386 -0
  342. package/docs/archive/reports/test-reports/TEST-COVERAGE-REPORT.md +441 -0
  343. package/docs/archive/reports/test-reports/e2e-test-report.md +293 -0
  344. package/docs/archive/reports/test-reports/final-test-report.md +367 -0
  345. package/docs/archive/reports/test-reports/real-env-test-report.md +391 -0
  346. package/docs/archive/reports/test-reports/test-completion-summary.md +356 -0
  347. package/docs/archive/reports/test-reports/test-report.md +371 -0
  348. package/docs/archive/sessions/session-2-summary.md +429 -0
  349. package/docs/archive/sessions/session-3-summary.md +395 -0
  350. package/docs/archive/sessions/session-summary.md +370 -0
  351. package/docs/config-system-update.md +239 -0
  352. package/docs/database-refactoring-PLAN.md +199 -0
  353. package/docs/database-refactoring-SUMMARY.md +384 -0
  354. package/docs/quality-check-architecture.md +1030 -0
  355. package/docs/quick-start.md +388 -0
  356. package/docs/references/bullmq-quick-reference.md +525 -0
  357. package/docs/references/monitoring-optimization-guide.md +871 -0
  358. package/docs/references/performance-optimization-guide.md +933 -0
  359. package/docs/storage-guide.md +612 -0
  360. package/docs/test-implementation-PLAN.md +223 -0
  361. package/docs/test-implementation-SUMMARY.md +194 -0
  362. package/docs/user-guide.md +719 -0
  363. package/docs/workflow-architecture.md +549 -0
  364. package/package.json +126 -0
  365. package/src/application/workflow/SyncExecutor.ts +444 -0
  366. package/src/application/workflow/types.ts +57 -0
  367. package/src/config/index.ts +352 -0
  368. package/src/domain/entities/QualityCheck.ts +202 -0
  369. package/src/domain/entities/Result.ts +130 -0
  370. package/src/domain/entities/Task.ts +178 -0
  371. package/src/domain/entities/TaskStep.ts +188 -0
  372. package/src/domain/entities/TokenUsage.ts +119 -0
  373. package/src/domain/entities/index.ts +20 -0
  374. package/src/domain/repositories/QualityCheckRepository.ts +52 -0
  375. package/src/domain/repositories/ResultRepository.ts +47 -0
  376. package/src/domain/repositories/TaskRepository.ts +271 -0
  377. package/src/domain/workflow/CheckpointManager.ts +283 -0
  378. package/src/domain/workflow/ContentCreatorGraph.ts +446 -0
  379. package/src/domain/workflow/State.ts +321 -0
  380. package/src/domain/workflow/index.ts +18 -0
  381. package/src/domain/workflow/nodes/BaseNode.ts +325 -0
  382. package/src/domain/workflow/nodes/CheckImageNode.ts +325 -0
  383. package/src/domain/workflow/nodes/CheckTextNode.ts +709 -0
  384. package/src/domain/workflow/nodes/GenerateImageNode.ts +342 -0
  385. package/src/domain/workflow/nodes/OrganizeNode.ts +304 -0
  386. package/src/domain/workflow/nodes/SearchNode.ts +192 -0
  387. package/src/domain/workflow/nodes/WriteNode.ts +505 -0
  388. package/src/domain/workflow/nodes/index.ts +13 -0
  389. package/src/index.ts +43 -0
  390. package/src/infrastructure/cache/CacheService.ts +483 -0
  391. package/src/infrastructure/cache/index.ts +6 -0
  392. package/src/infrastructure/database/BaseRepository.ts +214 -0
  393. package/src/infrastructure/database/MemoryTaskRepository.ts +377 -0
  394. package/src/infrastructure/database/PostgresQualityCheckRepository.ts +115 -0
  395. package/src/infrastructure/database/PostgresTaskRepository.ts +424 -0
  396. package/src/infrastructure/database/ResultRepository.ts +113 -0
  397. package/src/infrastructure/database/SQLiteTaskRepository.ts +651 -0
  398. package/src/infrastructure/database/index.ts +83 -0
  399. package/src/infrastructure/logging/logger.ts +231 -0
  400. package/src/infrastructure/monitoring/LoggingService.ts +292 -0
  401. package/src/infrastructure/monitoring/MetricsService.ts +468 -0
  402. package/src/infrastructure/monitoring/SentryService.ts +345 -0
  403. package/src/infrastructure/monitoring/index.ts +12 -0
  404. package/src/infrastructure/queue/TaskQueue.ts +429 -0
  405. package/src/infrastructure/queue/index.ts +5 -0
  406. package/src/infrastructure/redis/connection.ts +215 -0
  407. package/src/infrastructure/redis/index.ts +5 -0
  408. package/src/infrastructure/security/ApiKeyService.ts +340 -0
  409. package/src/infrastructure/security/QuotaService.ts +411 -0
  410. package/src/infrastructure/security/RateLimiter.ts +417 -0
  411. package/src/infrastructure/security/index.ts +12 -0
  412. package/src/monitoring/index.ts +5 -0
  413. package/src/monitoring/server.ts +109 -0
  414. package/src/presentation/cli/commands/cancel.ts +64 -0
  415. package/src/presentation/cli/commands/create.ts +400 -0
  416. package/src/presentation/cli/commands/result.ts +136 -0
  417. package/src/presentation/cli/commands/status.ts +102 -0
  418. package/src/presentation/cli/index.ts +39 -0
  419. package/src/presentation/cli/utils/cleanup.ts +65 -0
  420. package/src/presentation/cli/utils/formatter.ts +74 -0
  421. package/src/presentation/cli.ts +8 -0
  422. package/src/presentation/monitor-cli.ts +52 -0
  423. package/src/presentation/worker-cli.ts +62 -0
  424. package/src/schedulers/TaskScheduler.ts +314 -0
  425. package/src/schedulers/index.ts +11 -0
  426. package/src/services/image/ImageService.ts +221 -0
  427. package/src/services/index.ts +15 -0
  428. package/src/services/llm/EnhancedLLMService.ts +596 -0
  429. package/src/services/llm/LLMService.ts +310 -0
  430. package/src/services/quality/HardRuleChecker.ts +509 -0
  431. package/src/services/quality/LLMEvaluator.ts +400 -0
  432. package/src/services/quality/QualityCheckService.ts +473 -0
  433. package/src/services/quality/QualityService.ts +445 -0
  434. package/src/services/quality/index.ts +12 -0
  435. package/src/services/search/SearchService.ts +266 -0
  436. package/src/types/global.d.ts +17 -0
  437. package/src/workers/TaskWorker.ts +320 -0
  438. package/src/workers/index.ts +5 -0
@@ -0,0 +1,945 @@
1
+ # 阶段 2b 准备工作:LangGraph 工作流实现
2
+
3
+ **项目**: Content Creator (写作 Agent)
4
+ **阶段**: 2b - LangGraph 工作流实现
5
+ **准备日期**: 2025-01-18
6
+ **状态**: 准备中
7
+
8
+ ---
9
+
10
+ ## 📊 当前进度更新
11
+
12
+ ### 整体进度:**40%** 完成
13
+
14
+ ```
15
+ 阶段 1 [████████████████████] 100% ✅ (数据层)
16
+ 阶段 2a [████████████████████] 100% ✅ (基础设施)
17
+ 阶段 2b [░░░░░░░░░░░░░░░░░░░░] 0% ⏳ (工作流实现)
18
+ 阶段 3 [░░░░░░░░░░░░░░░░░░░░] 0% (待开始)
19
+ 阶段 4 [░░░░░░░░░░░░░░░░░░░░] 0% (待开始)
20
+ ```
21
+
22
+ ### 已完成工作总结
23
+
24
+ #### 阶段 1:核心数据层(100%)
25
+ - ✅ 5 个领域实体(Task, TaskStep, QualityCheck, Result, TokenUsage)
26
+ - ✅ Repository 层(BaseRepository, TaskRepository)
27
+ - ✅ 数据库迁移脚本(6 张表)
28
+ - ✅ 乐观锁并发控制
29
+ - ✅ Worker 抢占机制
30
+
31
+ **代码量**: ~2,130 行
32
+
33
+ #### 阶段 2a:LangGraph 基础设施(100%)
34
+ - ✅ LangGraph 依赖安装(@langchain/langgraph@0.0.26)
35
+ - ✅ Workflow State 定义(完整接口 + 工具类)
36
+ - ✅ BaseNode 基类(错误处理、重试、Token 记录)
37
+ - ✅ Enhanced LLM Service(重试机制、成本追踪)
38
+ - ✅ CheckpointManager(断点续传)
39
+
40
+ **代码量**: ~1,290 行
41
+
42
+ **总代码量**: ~3,420 行
43
+
44
+ ---
45
+
46
+ ## 🎯 阶段 2b 目标
47
+
48
+ ### 时间规划:7-11 天
49
+
50
+ #### 1. MCP Search 集成(2 天)
51
+ - 研究 MCP 协议和 Tavily API
52
+ - 创建 MCP Client 封装
53
+ - 实现搜索结果解析
54
+ - 实现搜索缓存(Redis)
55
+ - 编写集成测试
56
+
57
+ #### 2. Prompt 工程与优化(2 天)
58
+ - 设计 Write Node Prompt 模板
59
+ - 设计 CheckText Node Prompt 模板
60
+ - 设计 Organize Node Prompt 模板
61
+ - 实现 Prompt 版本管理
62
+ - A/B 测试不同 Prompt 变体
63
+
64
+ #### 3. 实现 6 个核心节点(4-6 天)
65
+ - Search Node(搜索)
66
+ - Organize Node(整理)
67
+ - Write Node(写作)
68
+ - CheckText Node(文本质检)
69
+ - GenerateImage Node(生成配图)
70
+ - CheckImage Node(配图质检)
71
+
72
+ #### 4. 构建工作流图(1 天)
73
+ - 创建 StateGraph 实例
74
+ - 添加所有节点
75
+ - 配置条件路由
76
+ - 配置循环(质检失败重试)
77
+
78
+ #### 5. 调试和测试(1-2 天)
79
+ - 端到端测试
80
+ - 质量检查重试测试
81
+ - 崩溃恢复测试
82
+
83
+ ---
84
+
85
+ ## 📚 节点实现详解
86
+
87
+ ### 节点 1:Search Node(搜索节点)
88
+
89
+ #### 职责
90
+ 根据选题搜索相关资料,为后续写作提供参考素材。
91
+
92
+ #### 输入
93
+ - `state.topic` - 选题关键词
94
+ - `state.requirements` - 写作要求
95
+ - `state.hardConstraints.keywords` - 必须包含的关键词
96
+
97
+ #### 输出
98
+ - `state.searchQuery` - 搜索关键词
99
+ - `state.searchResults` - 搜索结果列表
100
+
101
+ #### 实现要点
102
+
103
+ **1. 生成搜索查询**
104
+ ```typescript
105
+ // 根据选题生成搜索关键词
106
+ function generateSearchQuery(topic: string, keywords?: string[]): string {
107
+ const baseQuery = topic;
108
+
109
+ if (keywords && keywords.length > 0) {
110
+ // 组合关键词
111
+ return `${baseQuery} ${keywords.slice(0, 3).join(' ')}`;
112
+ }
113
+
114
+ return baseQuery;
115
+ }
116
+ ```
117
+
118
+ **2. 调用搜索 API**
119
+ ```typescript
120
+ // 使用 SearchService
121
+ const searchResponse = await searchService.searchWithAnswer(
122
+ state.searchQuery || generateSearchQuery(state.topic, state.hardConstraints.keywords),
123
+ 10 // 最多 10 条结果
124
+ );
125
+ ```
126
+
127
+ **3. 保存搜索结果**
128
+ ```typescript
129
+ return {
130
+ searchQuery: searchResponse.query,
131
+ searchResults: searchResponse.results.map(item => ({
132
+ title: item.title,
133
+ url: item.url,
134
+ content: item.content,
135
+ score: item.score,
136
+ publishedDate: item.publishedDate,
137
+ })),
138
+ };
139
+ ```
140
+
141
+ **4. Redis 缓存(优化)**
142
+ ```typescript
143
+ // 生成缓存键
144
+ const cacheKey = `search:${hashQuery(searchQuery)}`;
145
+
146
+ // 检查缓存
147
+ const cached = await redis.get(cacheKey);
148
+ if (cached) {
149
+ return JSON.parse(cached);
150
+ }
151
+
152
+ // 调用 API
153
+ const results = await searchService.search(...);
154
+
155
+ // 保存到缓存(24 小时)
156
+ await redis.setex(cacheKey, 86400, JSON.stringify(results));
157
+ ```
158
+
159
+ #### 验收标准
160
+ - ✅ 可以成功调用 Tavily API
161
+ - ✅ 搜索结果正确解析
162
+ - ✅ Redis 缓存正常工作
163
+ - ✅ 搜索失败时有降级策略
164
+
165
+ ---
166
+
167
+ ### 节点 2:Organize Node(整理节点)
168
+
169
+ #### 职责
170
+ 整理搜索结果,生成文章大纲和关键点。
171
+
172
+ #### 输入
173
+ - `state.searchResults` - 搜索结果列表
174
+ - `state.requirements` - 写作要求
175
+
176
+ #### 输出
177
+ - `state.organizedInfo.outline` - 文章大纲
178
+ - `state.organizedInfo.keyPoints` - 关键点列表
179
+ - `state.organizedInfo.summary` - 摘要
180
+
181
+ #### Prompt 模板
182
+
183
+ ```typescript
184
+ const ORGANIZE_PROMPT = `你是一位专业的内容策划。请根据以下搜索结果,整理出文章的大纲和关键点。
185
+
186
+ 【选题】{topic}
187
+
188
+ 【要求】{requirements}
189
+
190
+ 【搜索结果】
191
+ {searchResults}
192
+
193
+ 请按以下格式输出:
194
+
195
+ 1. **文章大纲**(Markdown 格式)
196
+ - 一级标题
197
+ - 二级标题
198
+ - 关键点
199
+
200
+ 2. **关键点列表**(3-5 个)
201
+ - 每个关键点 50-100 字
202
+
203
+ 3. **摘要**(100-150 字)
204
+ - 概括文章核心内容
205
+
206
+ 请以 JSON 格式返回:
207
+ {
208
+ "outline": "完整大纲(Markdown)",
209
+ "keyPoints": ["关键点1", "关键点2", ...],
210
+ "summary": "文章摘要"
211
+ }
212
+ `;
213
+ ```
214
+
215
+ #### 实现要点
216
+
217
+ **1. 准备搜索结果**
218
+ ```typescript
219
+ // 格式化搜索结果供 LLM 使用
220
+ const formattedResults = state.searchResults
221
+ .map((result, index) => `
222
+ ${index + 1}. ${result.title}
223
+ URL: ${result.url}
224
+ 内容: ${result.content.substring(0, 500)}...
225
+ `)
226
+ .join('\n\n');
227
+ ```
228
+
229
+ **2. 构建 Prompt**
230
+ ```typescript
231
+ const prompt = ORGANIZE_PROMPT
232
+ .replace('{topic}', state.topic)
233
+ .replace('{requirements}', state.requirements)
234
+ .replace('{searchResults}', formattedResults);
235
+ ```
236
+
237
+ **3. 调用 LLM**
238
+ ```typescript
239
+ const result = await enhancedLLMService.generateText(
240
+ prompt,
241
+ '你是一位专业的内容策划。请严格按照要求输出 JSON 格式。'
242
+ );
243
+
244
+ // 解析 JSON 响应
245
+ const organized = JSON.parse(result);
246
+ ```
247
+
248
+ **4. 验证输出**
249
+ ```typescript
250
+ // 验证必需字段
251
+ if (!organized.outline || !organized.keyPoints || !organized.summary) {
252
+ throw new Error('Organize output missing required fields');
253
+ }
254
+
255
+ // 验证关键点数量
256
+ if (organized.keyPoints.length < 3) {
257
+ throw new Error('At least 3 key points required');
258
+ }
259
+ ```
260
+
261
+ #### 验收标准
262
+ - ✅ 生成的大纲结构清晰
263
+ - ✅ 关键点数量 3-5 个
264
+ - ✅ 摘要长度 100-150 字
265
+ - ✅ LLM 输出正确解析为 JSON
266
+
267
+ ---
268
+
269
+ ### 节点 3:Write Node(写作节点)
270
+
271
+ #### 职责
272
+ 根据整理后的信息撰写文章内容。
273
+
274
+ #### 输入
275
+ - `state.organizedInfo` - 整理后的信息
276
+ - `state.searchResults` - 搜索结果
277
+ - `state.hardConstraints` - 硬性约束
278
+ - `state.previousContent` - 上一版内容(重写时)
279
+ - `state.textQualityReport.fixSuggestions` - 质检反馈(重写时)
280
+
281
+ #### 输出
282
+ - `state.articleContent` - 文章内容(Markdown)
283
+
284
+ #### Prompt 模板
285
+
286
+ **初始写作**:
287
+ ```typescript
288
+ const WRITE_PROMPT = `你是一位专业的内容创作者。根据以下信息撰写一篇文章:
289
+
290
+ 【主题】{topic}
291
+
292
+ 【要求】{requirements}
293
+
294
+ 【硬性约束】
295
+ - 字数:{minWords} - {maxWords} 字
296
+ - 必须包含关键词:{keywords}
297
+
298
+ 【参考资料】
299
+ 1. 搜索结果:
300
+ {searchResults}
301
+
302
+ 2. 文章大纲:
303
+ {outline}
304
+
305
+ 3. 关键点:
306
+ {keyPoints}
307
+
308
+ 请撰写一篇完整的文章,确保:
309
+ 1. 内容原创,不抄袭
310
+ 2. 逻辑清晰,条理分明
311
+ 3. 语言流畅,表达准确
312
+ 4. 严格遵守硬性约束要求
313
+ 5. 包含标题、导语、正文、结语
314
+
315
+ 以 Markdown 格式输出完整文章。
316
+ `;
317
+ ```
318
+
319
+ **重写模式**(有质检反馈时):
320
+ ```typescript
321
+ const REWRITE_PROMPT = `你是一位专业的内容创作者。根据以下质检反馈,修改上一版文章:
322
+
323
+ 【质检反馈】
324
+ {fixSuggestions}
325
+
326
+ 【要求】
327
+ 1. 只修改有问题的部分
328
+ 2. 保持已经合格的内容不变
329
+ 3. 确保修改后不引入新问题
330
+ 4. 严格遵守硬性约束要求
331
+
332
+ 【上一版文章】
333
+ {previousContent}
334
+
335
+ 请输出修改后的完整文章(Markdown 格式)。
336
+ `;
337
+ ```
338
+
339
+ #### 实现要点
340
+
341
+ **1. 判断是否为重写模式**
342
+ ```typescript
343
+ const isRewrite = !!(
344
+ state.previousContent &&
345
+ state.textQualityReport?.fixSuggestions
346
+ );
347
+ ```
348
+
349
+ **2. 选择合适的 Prompt**
350
+ ```typescript
351
+ const prompt = isRewrite
352
+ ? REWRITE_PROMPT
353
+ : WRITE_PROMPT;
354
+ ```
355
+
356
+ **3. 构建 Prompt 参数**
357
+ ```typescript
358
+ const promptParams = {
359
+ topic: state.topic,
360
+ requirements: state.requirements,
361
+ minWords: state.hardConstraints.minWords || 500,
362
+ maxWords: state.hardConstraints.maxWords || 1000,
363
+ keywords: state.hardConstraints.keywords?.join(', ') || '无',
364
+ searchResults: formatSearchResults(state.searchResults),
365
+ outline: state.organizedInfo?.outline || '',
366
+ keyPoints: state.organizedInfo?.keyPoints?.join('\n') || '',
367
+ previousContent: state.previousContent || '',
368
+ fixSuggestions: state.textQualityReport?.fixSuggestions?.join('\n') || '',
369
+ };
370
+ ```
371
+
372
+ **4. 调用 LLM 并记录 Token**
373
+ ```typescript
374
+ const result = await enhancedLLMService.chat({
375
+ messages: [
376
+ { role: 'system', content: '你是一位专业的内容创作者。' },
377
+ { role: 'user', content: prompt.replace(/\{(\w+)\}/g, (_, key) => promptParams[key]) },
378
+ ],
379
+ taskId: state.taskId,
380
+ stepName: 'write',
381
+ });
382
+
383
+ // Token 使用和成本已自动记录
384
+ ```
385
+
386
+ **5. 验证输出**
387
+ ```typescript
388
+ // 检查字数
389
+ const wordCount = result.content.length;
390
+ if (state.hardConstraints.minWords && wordCount < state.hardConstraints.minWords) {
391
+ throw new Error(`Word count insufficient: ${wordCount} < ${state.hardConstraints.minWords}`);
392
+ }
393
+
394
+ if (state.hardConstraints.maxWords && wordCount > state.hardConstraints.maxWords) {
395
+ throw new Error(`Word count exceeded: ${wordCount} > ${state.hardConstraints.maxWords}`);
396
+ }
397
+
398
+ // 检查关键词
399
+ if (state.hardConstraints.keywords) {
400
+ const missingKeywords = state.hardConstraints.keywords.filter(
401
+ keyword => !result.content.includes(keyword)
402
+ );
403
+
404
+ if (missingKeywords.length > 0) {
405
+ throw new Error(`Missing keywords: ${missingKeywords.join(', ')}`);
406
+ }
407
+ }
408
+ ```
409
+
410
+ #### 验收标准
411
+ - ✅ 生成文章符合要求
412
+ - ✅ 字数在范围内
413
+ - ✅ 包含所有关键词
414
+ - ✅ 结构完整(标题、导语、正文、结语)
415
+ - ✅ 重写模式下只修改有问题部分
416
+
417
+ ---
418
+
419
+ ### 节点 4:CheckText Node(文本质检节点)
420
+
421
+ #### 职责
422
+ 对文章进行质量检查,包括硬规则检查和 LLM 软评分。
423
+
424
+ #### 输入
425
+ - `state.articleContent` - 文章内容
426
+ - `state.hardConstraints` - 硬性约束
427
+ - `state.textRetryCount` - 当前重试次数
428
+
429
+ #### 输出
430
+ - `state.textQualityReport` - 质检报告
431
+
432
+ #### 质检流程
433
+
434
+ **1. 硬规则检查**
435
+ ```typescript
436
+ // 字数检查
437
+ const wordCount = state.articleContent.length;
438
+ const wordCountCheck = {
439
+ passed: true,
440
+ wordCount,
441
+ };
442
+
443
+ if (state.hardConstraints.minWords && wordCount < state.hardConstraints.minWords) {
444
+ wordCountCheck.passed = false;
445
+ }
446
+
447
+ if (state.hardConstraints.maxWords && wordCount > state.hardConstraints.maxWords) {
448
+ wordCountCheck.passed = false;
449
+ }
450
+
451
+ // 关键词检查
452
+ const keywordsCheck = {
453
+ passed: true,
454
+ found: [] as string[],
455
+ };
456
+
457
+ if (state.hardConstraints.keywords) {
458
+ keywordsCheck.found = state.hardConstraints.keywords.filter(keyword =>
459
+ state.articleContent.includes(keyword)
460
+ );
461
+
462
+ keywordsCheck.passed = keywordsCheck.found.length === state.hardConstraints.keywords.length;
463
+ }
464
+
465
+ // 结构检查
466
+ const structureCheck = {
467
+ passed: true,
468
+ checks: {
469
+ hasTitle: /^#\s+.+/.test(state.articleContent), // 有标题
470
+ hasIntro: /\n\n.+/.test(state.articleContent), // 有导语
471
+ hasBody: state.articleContent.split('\n\n').length >= 3, // 至少 3 段
472
+ hasConclusion: /(结语|总结|结论|最后)/.test(state.articleContent), // 有结语
473
+ },
474
+ };
475
+
476
+ structureCheck.passed = Object.values(structureCheck.checks).every(check => check);
477
+
478
+ // 硬规则总体通过
479
+ const hardRulesPassed = wordCountCheck.passed && keywordsCheck.passed && structureCheck.passed;
480
+ ```
481
+
482
+ **2. LLM 软评分**
483
+ ```typescript
484
+ const CHECK_PROMPT = `你是一位专业的内容审核专家。请对以下文章进行质量评估:
485
+
486
+ 【文章内容】
487
+ {articleContent}
488
+
489
+ 【硬性约束】
490
+ - 字数:{minWords} - {maxWords} 字
491
+ - 必须包含关键词:{keywords}
492
+
493
+ 请从以下维度评估(每项 1-10 分):
494
+ 1. **相关性**:内容是否切题
495
+ 2. **连贯性**:逻辑是否通顺
496
+ 3. **完整性**:结构是否完整
497
+ 4. **可读性**:语言是否流畅
498
+
499
+ 硬规则检查:
500
+ - 字数是否符合要求?
501
+ - 是否包含所有关键词?
502
+ - 是否有标题、导语、正文、结语?
503
+
504
+ 请以 JSON 格式返回:
505
+ {
506
+ "score": 8.5,
507
+ "passed": true,
508
+ "hardConstraintsPassed": true,
509
+ "details": {
510
+ "hardRules": {
511
+ "wordCount": { "passed": true, "wordCount": 1200 },
512
+ "keywords": { "passed": true, "found": ["AI", "技术", "发展"] },
513
+ "structure": { "passed": true, "checks": {...} }
514
+ },
515
+ "softScores": {
516
+ "relevance": { "score": 9, "reason": "内容完全切题" },
517
+ "coherence": { "score": 8, "reason": "逻辑基本通顺" },
518
+ "completeness": { "score": 8.5, "reason": "结构完整" },
519
+ "readability": { "score": 8, "reason": "语言流畅" }
520
+ }
521
+ },
522
+ "fixSuggestions": ["建议1", "建议2"]
523
+ }
524
+ `;
525
+ ```
526
+
527
+ **3. 计算总分和通过判断**
528
+ ```typescript
529
+ const softScore = (
530
+ result.details.softScores.relevance.score * 0.3 +
531
+ result.details.softScores.coherence.score * 0.3 +
532
+ result.details.softScores.completeness.score * 0.2 +
533
+ result.details.softScores.readability.score * 0.2
534
+ );
535
+
536
+ const passed = hardRulesPassed && softScore >= 7.0;
537
+ ```
538
+
539
+ **4. 生成改进建议**
540
+ ```typescript
541
+ const fixSuggestions: string[] = [];
542
+
543
+ // 硬规则问题
544
+ if (!wordCountCheck.passed) {
545
+ fixSuggestions.push(`字数${wordCountCheck.wordCount},需要在 ${state.hardConstraints.minWords}-${state.hardConstraints.maxWords} 范围内`);
546
+ }
547
+
548
+ if (!keywordsCheck.passed) {
549
+ const missing = state.hardConstraints.keywords!.filter(k => !keywordsCheck.found.includes(k));
550
+ fixSuggestions.push(`缺少关键词:${missing.join('、')}`);
551
+ }
552
+
553
+ if (!structureCheck.passed) {
554
+ if (!structureCheck.checks.hasTitle) fixSuggestions.push('缺少标题');
555
+ if (!structureCheck.checks.hasIntro) fixSuggestions.push('缺少导语段落');
556
+ if (!structureCheck.checks.hasBody) fixSuggestions.push('正文内容不足');
557
+ if (!structureCheck.checks.hasConclusion) fixSuggestions.push('缺少结语段落');
558
+ }
559
+
560
+ // LLM 软评分问题
561
+ if (softScore < 7) {
562
+ fixSuggestions.push(...(result.fixSuggestions || []));
563
+ }
564
+ ```
565
+
566
+ #### 验收标准
567
+ - ✅ 硬规则检查准确
568
+ - ✅ LLM 评分合理(1-10 分)
569
+ - ✅ 不合格内容返回改进建议
570
+ - ✅ 质检结果正确保存
571
+
572
+ ---
573
+
574
+ ### 节点 5:GenerateImage Node(生成配图节点)
575
+
576
+ #### 职责
577
+ 根据文章内容生成配图。
578
+
579
+ #### 输入
580
+ - `state.articleContent` - 文章内容
581
+ - `state.imagePrompts` - 配图提示词(可选)
582
+
583
+ #### 输出
584
+ - `state.images` - 生成的配图列表
585
+
586
+ #### 实现要点
587
+
588
+ **1. 生成图片提示词**
589
+ ```typescript
590
+ async function generateImagePrompts(articleContent: string): Promise<string[]> {
591
+ const prompt = `根据以下文章内容,生成 1-3 个配图提示词:
592
+
593
+ 【文章内容】
594
+ ${articleContent.substring(0, 1000)}
595
+
596
+ 要求:
597
+ 1. 描述图片的主题和风格
598
+ 2. 简洁明了(50 字以内)
599
+ 3. 适合 AI 图片生成
600
+
601
+ 请以 JSON 数组格式返回:["提示词1", "提示词2", "提示词3"]
602
+ `;
603
+
604
+ const result = await enhancedLLMService.generateText(
605
+ prompt,
606
+ '请严格按照 JSON 数组格式返回。'
607
+ );
608
+
609
+ return JSON.parse(result);
610
+ }
611
+ ```
612
+
613
+ **2. 调用 Doubao API**
614
+ ```typescript
615
+ // 注意:Doubao API 需要单独实现
616
+ const imagePrompts = state.imagePrompts || await generateImagePrompts(state.articleContent);
617
+
618
+ const images = await Promise.all(
619
+ imagePrompts.map(async (prompt) => {
620
+ // 调用 Doubao API
621
+ const imageUrl = await imageService.generateImage({
622
+ prompt,
623
+ // 其他参数...
624
+ });
625
+
626
+ return {
627
+ url: imageUrl,
628
+ prompt: prompt,
629
+ };
630
+ })
631
+ );
632
+ ```
633
+
634
+ **3. 保存结果**
635
+ ```typescript
636
+ return {
637
+ images: images,
638
+ };
639
+ ```
640
+
641
+ #### 验收标准
642
+ - ✅ 可以成功调用 Doubao API
643
+ - ✅ 图片提示词生成合理
644
+ - ✅ 图片 URL 有效
645
+ - ✅ 生成失败时有降级策略
646
+
647
+ ---
648
+
649
+ ### 节点 6:CheckImage Node(配图质检节点)
650
+
651
+ #### 职责
652
+ 对生成的配图进行质量检查。
653
+
654
+ #### 输入
655
+ - `state.images` - 生成的配图列表
656
+ - `state.imageRetryCount` - 当前重试次数
657
+
658
+ #### 输出
659
+ - `state.imageQualityReport` - 配图质检报告
660
+
661
+ #### 实现要点
662
+
663
+ **1. LLM 图片评估**
664
+ ```typescript
665
+ // 注意:需要支持图片输入的 LLM,或使用其他方案
666
+ const CHECK_IMAGE_PROMPT = `请评估以下配图的质量:
667
+
668
+ 【配图信息】
669
+ 图片 URL: {imageUrl}
670
+ 提示词: {prompt}
671
+
672
+ 请从以下维度评估(每项 1-10 分):
673
+ 1. **相关性**:图片与文章内容的相关性
674
+ 2. **美学质量**:构图、色彩、清晰度
675
+ 3. **提示词匹配**:是否符合提示词要求
676
+
677
+ 请以 JSON 格式返回:
678
+ {
679
+ "score": 8.0,
680
+ "passed": true,
681
+ "details": {
682
+ "relevanceScore": 8.5,
683
+ "aestheticScore": 7.5,
684
+ "promptMatch": 8.0
685
+ },
686
+ "fixSuggestions": ["建议1"]
687
+ }
688
+ `;
689
+ ```
690
+
691
+ **2. 评估所有图片**
692
+ ```typescript
693
+ const qualityReports = await Promise.all(
694
+ state.images.map(async (image) => {
695
+ const result = await enhancedLLMService.generateText(
696
+ CHECK_IMAGE_PROMPT
697
+ .replace('{imageUrl}', image.url)
698
+ .replace('{prompt}', image.prompt),
699
+ '请严格按照 JSON 格式返回。'
700
+ );
701
+
702
+ return JSON.parse(result);
703
+ })
704
+ );
705
+
706
+ // 计算平均分
707
+ const avgScore = qualityReports.reduce((sum, r) => sum + r.score, 0) / qualityReports.length;
708
+ const passed = avgScore >= 7.0;
709
+ ```
710
+
711
+ **3. 生成改进建议**
712
+ ```typescript
713
+ const fixSuggestions: string[] = [];
714
+
715
+ if (avgScore < 7) {
716
+ qualityReports.forEach((report, index) => {
717
+ if (report.score < 7) {
718
+ fixSuggestions.push(`图片 ${index + 1}: ${report.fixSuggestions?.[0] || '质量不达标'}`);
719
+ }
720
+ });
721
+ }
722
+ ```
723
+
724
+ #### 验收标准
725
+ - ✅ LLM 评分合理(1-10 分)
726
+ - ✅ 不合格内容返回改进建议
727
+ - ✅ 质检结果正确保存
728
+
729
+ ---
730
+
731
+ ## 🔀 工作流图构建
732
+
733
+ ### Graph 结构
734
+
735
+ ```typescript
736
+ import { StateGraph } from '@langchain/langgraph';
737
+ import { SearchNode } from './nodes/SearchNode.js';
738
+ import { OrganizeNode } from './nodes/OrganizeNode.js';
739
+ import { WriteNode } from './nodes/WriteNode.js';
740
+ import { CheckTextNode } from './nodes/CheckTextNode.js';
741
+ import { GenerateImageNode } from './nodes/GenerateImageNode.js';
742
+ import { CheckImageNode } from './nodes/CheckImageNode.js';
743
+ import { WorkflowState } from './State.js';
744
+
745
+ // 创建工作流图
746
+ export function createContentCreatorGraph(): StateGraph<WorkflowState> {
747
+ // 创建节点实例
748
+ const searchNode = new SearchNode();
749
+ const organizeNode = new OrganizeNode();
750
+ const writeNode = new WriteNode();
751
+ const checkTextNode = new CheckTextNode();
752
+ const generateImageNode = new GenerateImageNode();
753
+ const checkImageNode = new CheckImageNode();
754
+
755
+ // 创建 StateGraph
756
+ const graph = new StateGraph<WorkflowState>({
757
+ channels: {
758
+ // 定义 State 字段
759
+ taskId: {
760
+ value: (x: WorkflowState) => x.taskId,
761
+ default: () => '',
762
+ },
763
+ mode: {
764
+ value: (x: WorkflowState) => x.mode,
765
+ default: () => 'sync' as ExecutionMode,
766
+ },
767
+ topic: {
768
+ value: (x: WorkflowState) => x.topic,
769
+ default: () => '',
770
+ },
771
+ requirements: {
772
+ value: (x: WorkflowState) => x.requirements,
773
+ default: () => '',
774
+ },
775
+ // ... 其他字段
776
+ },
777
+ });
778
+
779
+ // 添加节点
780
+ graph.addNode('search', searchNode.toLangGraphNode());
781
+ graph.addNode('organize', organizeNode.toLangGraphNode());
782
+ graph.addNode('write', writeNode.toLangGraphNode());
783
+ graph.addNode('checkText', checkTextNode.toLangGraphNode());
784
+ graph.addNode('generateImage', generateImageNode.toLangGraphNode());
785
+ graph.addNode('checkImage', checkImageNode.toLangGraphNode());
786
+
787
+ // 添加边(线性流程)
788
+ graph.setEntryPoint('search');
789
+ graph.addEdge('search', 'organize');
790
+ graph.addEdge('organize', 'write');
791
+ graph.addEdge('write', 'checkText');
792
+
793
+ // 添加条件边(文本质检)
794
+ graph.addConditionalEdges(
795
+ 'checkText',
796
+ {
797
+ shouldRetry: (state: WorkflowState) => {
798
+ // 质检失败且重试次数 < 3
799
+ return !state.textQualityReport?.passed && state.textRetryCount < 3;
800
+ },
801
+ true: 'write', // 重试写作
802
+ false: 'generateImage', // 通过,生成配图
803
+ }
804
+ );
805
+
806
+ // 添加条件边(配图质检)
807
+ graph.addConditionalEdges(
808
+ 'checkImage',
809
+ {
810
+ shouldRetry: (state: WorkflowState) => {
811
+ // 质检失败且重试次数 < 2
812
+ return !state.imageQualityReport?.passed && state.imageRetryCount < 2;
813
+ },
814
+ true: 'generateImage', // 重试生成
815
+ false: '__end__', // 通过,结束
816
+ }
817
+ );
818
+
819
+ return graph.compile();
820
+ }
821
+ ```
822
+
823
+ ### 条件路由函数
824
+
825
+ ```typescript
826
+ // 文本质检路由
827
+ function routeAfterCheckText(state: WorkflowState): string {
828
+ if (state.textQualityReport?.passed) {
829
+ return 'generate_image';
830
+ }
831
+
832
+ if (state.textRetryCount < 3) {
833
+ return 'write'; // 重试
834
+ }
835
+
836
+ throw new Error('Text quality check failed after 3 attempts');
837
+ }
838
+
839
+ // 配图质检路由
840
+ function routeAfterCheckImage(state: WorkflowState): string {
841
+ if (state.imageQualityReport?.passed) {
842
+ return '__end__'; // 完成
843
+ }
844
+
845
+ if (state.imageRetryCount < 2) {
846
+ return 'generate_image'; // 重试
847
+ }
848
+
849
+ throw new Error('Image quality check failed after 2 attempts');
850
+ }
851
+ ```
852
+
853
+ ---
854
+
855
+ ## 🧪 测试策略
856
+
857
+ ### 单元测试
858
+
859
+ 每个节点独立测试:
860
+
861
+ ```typescript
862
+ describe('SearchNode', () => {
863
+ it('should search and return results', async () => {
864
+ const node = new SearchNode();
865
+ const state = createInitialState({...});
866
+
867
+ const result = await node.execute(state);
868
+
869
+ expect(result.success).toBe(true);
870
+ expect(result.stateUpdate.searchResults).toBeDefined();
871
+ });
872
+
873
+ it('should use cached results if available', async () => {
874
+ // 测试缓存逻辑
875
+ });
876
+ });
877
+ ```
878
+
879
+ ### 集成测试
880
+
881
+ 完整工作流测试:
882
+
883
+ ```typescript
884
+ describe('ContentCreator Workflow', () => {
885
+ it('should complete full workflow', async () => {
886
+ const graph = createContentCreatorGraph();
887
+ const initialState = createInitialState({...});
888
+
889
+ const result = await graph.invoke(initialState);
890
+
891
+ expect(result.articleContent).toBeDefined();
892
+ expect(result.images).toBeDefined();
893
+ expect(result.textQualityReport?.passed).toBe(true);
894
+ expect(result.imageQualityReport?.passed).toBe(true);
895
+ });
896
+
897
+ it('should retry write on quality check failure', async () => {
898
+ // 测试重试逻辑
899
+ });
900
+
901
+ it('should recover from checkpoint', async () => {
902
+ // 测试断点续传
903
+ });
904
+ });
905
+ ```
906
+
907
+ ---
908
+
909
+ ## 📝 待准备资源
910
+
911
+ ### 环境配置
912
+
913
+ - ✅ DeepSeek API Key(已有)
914
+ - ✅ Tavily API Key(已有)
915
+ - ⏳ **Doubao API Key**(需要申请)
916
+ - ⏳ **图片存储配置**(S3/OSS/本地)
917
+
918
+ ### 服务实现
919
+
920
+ - ✅ LLMService(增强版已实现)
921
+ - ✅ SearchService(已实现)
922
+ - ⏳ **ImageService**(待实现 Doubao API 封装)
923
+ - ⏳ **QualityService**(待实现)
924
+
925
+ ### 工具和库
926
+
927
+ - ✅ LangGraph(已安装)
928
+ - ✅ Redis 客户端(ioredis,已安装)
929
+ - ⏳ **图片生成库**(如需要)
930
+
931
+ ---
932
+
933
+ ## 🚀 立即可做
934
+
935
+ 1. **实现 ImageService**(Doubao API)
936
+ 2. **实现第一个节点**(SearchNode)
937
+ 3. **测试 Prompt 模板**
938
+ 4. **配置图片存储**
939
+
940
+ ---
941
+
942
+ **文档版本**: 1.0
943
+ **创建日期**: 2025-01-18
944
+ **最后更新**: 2025-01-18
945
+ **状态**: 准备完成,等待实施