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,342 @@
1
+ /**
2
+ * GenerateImage Node - 生成配图节点
3
+ *
4
+ * 根据文章内容生成配图
5
+ */
6
+
7
+ import { BaseNode } from './BaseNode.js';
8
+ import type { WorkflowState } from '../State.js';
9
+ import type { GeneratedImage } from '../State.js';
10
+ import { enhancedLLMService } from '../../../services/llm/EnhancedLLMService.js';
11
+ import { imageService } from '../../../services/image/ImageService.js';
12
+ import { createLogger } from '../../../infrastructure/logging/logger.js';
13
+
14
+ const logger = createLogger('GenerateImageNode');
15
+
16
+ /**
17
+ * 图片提示词生成请求
18
+ */
19
+ interface ImagePromptGenerationRequest {
20
+ articleContent: string;
21
+ topic: string;
22
+ maxPrompts?: number;
23
+ }
24
+
25
+ /**
26
+ * GenerateImage Node 配置
27
+ */
28
+ interface GenerateImageNodeConfig {
29
+ defaultImageCount?: number;
30
+ maxImageCount?: number;
31
+ useImageGeneration?: boolean; // 是否实际调用图片生成 API
32
+ }
33
+
34
+ /**
35
+ * 图片提示词生成 Prompt 模板
36
+ */
37
+ const GENERATE_IMAGE_PROMPTS_PROMPT = `你是一位专业的配图策划。根据以下文章内容,生成 {maxPrompts} 个配图提示词。
38
+
39
+ 【文章主题】{topic}
40
+
41
+ 【文章内容】
42
+ {articleContent}
43
+
44
+ 要求:
45
+ 1. 每个提示词描述一个独立的配图场景
46
+ 2. 简洁明了(50 字以内)
47
+ 3. 适合 AI 图片生成(描述视觉元素、风格、氛围)
48
+ 4. 与文章内容相关且美观
49
+ 5. 避免文字内容,只描述画面
50
+
51
+ 请以 JSON 数组格式返回:
52
+ ["提示词1", "提示词2", "提示词3"]
53
+
54
+ 注意:
55
+ 1. 只返回 JSON 数组,不要有其他内容
56
+ 2. 提示词数量必须是 {maxPrompts} 个
57
+ 3. 每个提示词 50 字以内
58
+ `;
59
+
60
+ /**
61
+ * GenerateImage Node 实现
62
+ */
63
+ export class GenerateImageNode extends BaseNode {
64
+ private config: GenerateImageNodeConfig;
65
+
66
+ constructor(config: GenerateImageNodeConfig = {}) {
67
+ super({
68
+ name: 'generateImage',
69
+ retryCount: 2,
70
+ timeout: 180000, // 3 分钟超时(图片生成可能很慢)
71
+ });
72
+
73
+ // 测试环境下禁用图片生成,避免API key问题
74
+ const isTestEnvironment = process.env.NODE_ENV === 'test';
75
+
76
+ this.config = {
77
+ defaultImageCount: 2,
78
+ maxImageCount: 5,
79
+ useImageGeneration: isTestEnvironment ? false : true, // 测试环境禁用图片生成
80
+ ...config,
81
+ };
82
+ }
83
+
84
+ /**
85
+ * 生成图片提示词
86
+ */
87
+ private async generateImagePrompts(
88
+ request: ImagePromptGenerationRequest
89
+ ): Promise<string[]> {
90
+ logger.debug('Generating image prompts', {
91
+ topic: request.topic,
92
+ contentLength: request.articleContent.length,
93
+ maxPrompts: request.maxPrompts || this.config.defaultImageCount,
94
+ });
95
+
96
+ try {
97
+ // 1. 构建 Prompt
98
+ const maxPrompts = request.maxPrompts || this.config.defaultImageCount;
99
+
100
+ // 限制文章内容长度,避免 Token 过多
101
+ const articleContent =
102
+ request.articleContent.length > 1000
103
+ ? request.articleContent.substring(0, 1000) + '...'
104
+ : request.articleContent;
105
+
106
+ const prompt = GENERATE_IMAGE_PROMPTS_PROMPT.replace(
107
+ '{topic}',
108
+ request.topic
109
+ )
110
+ .replace('{articleContent}', articleContent)
111
+ .replace('{maxPrompts}', String(maxPrompts));
112
+
113
+ // 2. 调用 LLM
114
+ const systemMessage =
115
+ '你是一位专业的配图策划。请严格按照 JSON 数组格式返回。';
116
+
117
+ const result = await enhancedLLMService.chat({
118
+ messages: [
119
+ { role: 'system', content: systemMessage },
120
+ { role: 'user', content: prompt },
121
+ ],
122
+ taskId: '', // 这里没有 taskId,使用空字符串
123
+ stepName: 'generateImagePrompts',
124
+ });
125
+
126
+ // 3. 解析 JSON 响应
127
+ let prompts: string[];
128
+ try {
129
+ let content = result.content.trim();
130
+ if (content.startsWith('```json')) {
131
+ content = content.slice(7);
132
+ }
133
+ if (content.startsWith('```')) {
134
+ content = content.slice(3);
135
+ }
136
+ if (content.endsWith('```')) {
137
+ content = content.slice(0, -3);
138
+ }
139
+ content = content.trim();
140
+
141
+ prompts = JSON.parse(content);
142
+ } catch (error) {
143
+ logger.error('Failed to parse LLM output as JSON', {
144
+ content: result.content.substring(0, 500),
145
+ error: error instanceof Error ? error.message : String(error),
146
+ });
147
+
148
+ throw new Error(
149
+ 'Failed to parse image prompts. LLM did not return valid JSON.'
150
+ );
151
+ }
152
+
153
+ // 4. 验证输出
154
+ if (!Array.isArray(prompts)) {
155
+ throw new Error('Image prompts must be an array');
156
+ }
157
+
158
+ if (prompts.length !== maxPrompts) {
159
+ logger.warn('Image prompts count mismatch', {
160
+ expected: maxPrompts,
161
+ actual: prompts.length,
162
+ });
163
+ }
164
+
165
+ if (prompts.length === 0) {
166
+ throw new Error('At least one image prompt is required');
167
+ }
168
+
169
+ logger.info('Image prompts generated successfully', {
170
+ count: prompts.length,
171
+ });
172
+
173
+ return prompts;
174
+ } catch (error) {
175
+ logger.error('Failed to generate image prompts', {
176
+ error: error instanceof Error ? error.message : String(error),
177
+ });
178
+
179
+ throw error;
180
+ }
181
+ }
182
+
183
+ /**
184
+ * 生成图片
185
+ */
186
+ private async generateImages(prompts: string[]): Promise<GeneratedImage[]> {
187
+ if (!this.config.useImageGeneration) {
188
+ const isTestEnvironment = process.env.NODE_ENV === 'test';
189
+ logger.info('Image generation is disabled, returning mock images', {
190
+ isTestEnvironment,
191
+ reason: isTestEnvironment ? 'Test environment detected' : 'Configuration disabled',
192
+ });
193
+ // 返回模拟图片
194
+ return prompts.map((prompt) => ({
195
+ url: `https://example.com/mock-image-${Date.now()}.png`,
196
+ prompt,
197
+ width: 1024,
198
+ height: 1024,
199
+ format: 'png',
200
+ }));
201
+ }
202
+
203
+ logger.info('Generating images', { count: prompts.length });
204
+
205
+ try {
206
+ // 并发生成所有图片
207
+ const images = await Promise.all(
208
+ prompts.map(async (prompt, index) => {
209
+ try {
210
+ logger.debug(`Generating image ${index + 1}/${prompts.length}`, {
211
+ prompt: prompt.substring(0, 50),
212
+ });
213
+
214
+ const result = await imageService.generateImage({
215
+ prompt,
216
+ size: '1920x1920', // Doubao 要求至少 3686400 像素
217
+ watermark: false,
218
+ });
219
+
220
+ logger.info(`Image ${index + 1} generated successfully`, {
221
+ imageUrl: result.imageUrl.substring(0, 50) + '...',
222
+ model: result.model,
223
+ });
224
+
225
+ return {
226
+ url: result.imageUrl,
227
+ prompt,
228
+ width: 1024,
229
+ height: 1024,
230
+ format: 'png',
231
+ };
232
+ } catch (error) {
233
+ logger.error(`Failed to generate image ${index + 1}`, {
234
+ prompt: prompt.substring(0, 50),
235
+ error: error instanceof Error ? error.message : String(error),
236
+ });
237
+
238
+ // 返回一个占位符图片,避免整个流程失败
239
+ return {
240
+ url: '',
241
+ prompt,
242
+ error: error instanceof Error ? error.message : String(error),
243
+ };
244
+ }
245
+ })
246
+ );
247
+
248
+ // 过滤掉生成失败的图片
249
+ const successfulImages = images.filter((img) => img.url);
250
+
251
+ logger.info('Image generation completed', {
252
+ total: prompts.length,
253
+ successful: successfulImages.length,
254
+ failed: prompts.length - successfulImages.length,
255
+ });
256
+
257
+ return successfulImages;
258
+ } catch (error) {
259
+ logger.error('Image generation failed', {
260
+ error: error instanceof Error ? error.message : String(error),
261
+ });
262
+
263
+ throw error;
264
+ }
265
+ }
266
+
267
+ /**
268
+ * 执行配图生成逻辑
269
+ */
270
+ protected async executeLogic(state: WorkflowState): Promise<Partial<WorkflowState>> {
271
+ logger.info('Starting image generation', {
272
+ taskId: state.taskId,
273
+ topic: state.topic,
274
+ });
275
+
276
+ try {
277
+ // 1. 检查是否已有图片提示词
278
+ let imagePrompts = state.imagePrompts;
279
+
280
+ if (!imagePrompts || imagePrompts.length === 0) {
281
+ // 2. 生成图片提示词
282
+ imagePrompts = await this.generateImagePrompts({
283
+ articleContent: state.articleContent!,
284
+ topic: state.topic,
285
+ maxPrompts: this.config.defaultImageCount,
286
+ });
287
+ }
288
+
289
+ // 3. 生成图片
290
+ const images = await this.generateImages(imagePrompts);
291
+
292
+ // 4. 检查是否至少有一张图片生成成功
293
+ if (images.length === 0) {
294
+ logger.warn('No images generated successfully', {
295
+ taskId: state.taskId,
296
+ });
297
+
298
+ // 返回空数组,允许工作流继续
299
+ return {
300
+ images: [],
301
+ };
302
+ }
303
+
304
+ logger.info('Image generation completed successfully', {
305
+ taskId: state.taskId,
306
+ imageCount: images.length,
307
+ });
308
+
309
+ return {
310
+ images,
311
+ };
312
+ } catch (error) {
313
+ logger.error('Image generation failed', {
314
+ taskId: state.taskId,
315
+ error: error instanceof Error ? error.message : String(error),
316
+ });
317
+
318
+ // 图片生成失败时,返回空数组而不是抛出错误
319
+ // 这样可以让工作流继续,文章没有配图也可以接受
320
+ logger.warn('Returning empty images array to allow workflow to continue');
321
+ return {
322
+ images: [],
323
+ };
324
+ }
325
+ }
326
+
327
+ /**
328
+ * 验证输入状态
329
+ */
330
+ protected validateState(state: WorkflowState): void {
331
+ super.validateState(state);
332
+
333
+ if (!state.articleContent || state.articleContent.trim().length === 0) {
334
+ throw new Error('Article content is required for image generation');
335
+ }
336
+ }
337
+ }
338
+
339
+ /**
340
+ * GenerateImage Node 单例导出(默认配置)
341
+ */
342
+ export const generateImageNode = new GenerateImageNode();
@@ -0,0 +1,304 @@
1
+ /**
2
+ * Organize Node - 整理节点
3
+ *
4
+ * 整理搜索结果,生成文章大纲和关键点
5
+ */
6
+
7
+ import { BaseNode } from './BaseNode.js';
8
+ import type { WorkflowState } from '../State.js';
9
+ import type { OrganizedInfo } from '../State.js';
10
+ import { enhancedLLMService } from '../../../services/llm/EnhancedLLMService.js';
11
+ import { createLogger } from '../../../infrastructure/logging/logger.js';
12
+
13
+ const logger = createLogger('OrganizeNode');
14
+
15
+ /**
16
+ * Organize 输出结构
17
+ */
18
+ interface OrganizeOutput {
19
+ outline: string;
20
+ keyPoints: string[];
21
+ summary: string;
22
+ }
23
+
24
+ /**
25
+ * Organize Node 配置
26
+ */
27
+ interface OrganizeNodeConfig {
28
+ maxKeyPoints?: number;
29
+ minKeyPoints?: number;
30
+ maxSummaryLength?: number;
31
+ minSummaryLength?: number;
32
+ }
33
+
34
+ /**
35
+ * Organize Node Prompt 模板
36
+ */
37
+ const ORGANIZE_PROMPT = `你是一位专业的内容策划。请根据以下搜索结果,整理出文章的大纲和关键点。
38
+
39
+ 【选题】{topic}
40
+
41
+ 【要求】{requirements}
42
+
43
+ 【搜索结果】
44
+ {searchResults}
45
+
46
+ 请按以下格式输出:
47
+
48
+ 1. **文章大纲**(Markdown 格式)
49
+ - 使用一级标题(#)作为主标题
50
+ - 使用二级标题(##)作为章节
51
+ - 使用三级标题(###)作为小节
52
+ - 每个章节下简要说明该部分要写的内容
53
+
54
+ 2. **关键点列表**({minKeyPoints}-{maxKeyPoints} 个)
55
+ - 每个关键点 50-100 字
56
+ - 提炼文章的核心观点
57
+ - 确保逻辑连贯
58
+
59
+ 3. **摘要**({minSummaryLength}-{maxSummaryLength} 字)
60
+ - 概括文章核心内容
61
+ - 包含文章的主要观点
62
+ - 语言简洁明了
63
+
64
+ 请以 JSON 格式返回:
65
+ {
66
+ "outline": "完整大纲(Markdown 格式)",
67
+ "keyPoints": ["关键点1", "关键点2", ...],
68
+ "summary": "文章摘要"
69
+ }
70
+
71
+ 注意:
72
+ 1. 大纲必须使用 Markdown 格式
73
+ 2. 关键点数量必须在 {minKeyPoints}-{maxKeyPoints} 之间
74
+ 3. 摘要长度必须在 {minSummaryLength}-{maxSummaryLength} 字之间
75
+ 4. 只返回 JSON,不要有其他内容
76
+ `;
77
+
78
+ /**
79
+ * Organize Node 实现
80
+ */
81
+ export class OrganizeNode extends BaseNode {
82
+ private config: OrganizeNodeConfig;
83
+
84
+ constructor(config: OrganizeNodeConfig = {}) {
85
+ super({
86
+ name: 'organize',
87
+ retryCount: 2,
88
+ timeout: 60000, // 60 秒超时(LLM 调用可能较慢)
89
+ });
90
+
91
+ this.config = {
92
+ maxKeyPoints: 5,
93
+ minKeyPoints: 3,
94
+ maxSummaryLength: 150,
95
+ minSummaryLength: 100,
96
+ ...config,
97
+ };
98
+ }
99
+
100
+ /**
101
+ * 格式化搜索结果供 LLM 使用
102
+ */
103
+ private formatSearchResults(searchResults: WorkflowState['searchResults']): string {
104
+ if (!searchResults || searchResults.length === 0) {
105
+ return '(无搜索结果)';
106
+ }
107
+
108
+ return searchResults
109
+ .map((result, index) => {
110
+ // 限制内容长度,避免 Token 过多
111
+ const content =
112
+ result.content.length > 500
113
+ ? result.content.substring(0, 500) + '...'
114
+ : result.content;
115
+
116
+ return `${index + 1}. ${result.title}
117
+ URL: ${result.url}
118
+ ${result.author ? `作者: ${result.author}` : ''}
119
+ ${result.publishedDate ? `日期: ${result.publishedDate}` : ''}
120
+ 内容: ${content}`;
121
+ })
122
+ .join('\n\n');
123
+ }
124
+
125
+ /**
126
+ * 调用 LLM 生成组织结构
127
+ */
128
+ private async callLLM(state: WorkflowState): Promise<OrganizeOutput> {
129
+ // 1. 构建 Prompt
130
+ const formattedResults = this.formatSearchResults(state.searchResults);
131
+
132
+ const prompt = ORGANIZE_PROMPT.replace('{topic}', state.topic)
133
+ .replace('{requirements}', state.requirements)
134
+ .replace('{searchResults}', formattedResults)
135
+ .replace('{minKeyPoints}', String(this.config.minKeyPoints))
136
+ .replace('{maxKeyPoints}', String(this.config.maxKeyPoints))
137
+ .replace('{minSummaryLength}', String(this.config.minSummaryLength))
138
+ .replace('{maxSummaryLength}', String(this.config.maxSummaryLength));
139
+
140
+ // 2. 调用 LLM
141
+ logger.debug('Calling LLM to organize content', {
142
+ taskId: state.taskId,
143
+ searchResultsCount: state.searchResults?.length || 0,
144
+ });
145
+
146
+ const systemMessage =
147
+ '你是一位专业的内容策划。请严格按照要求输出 JSON 格式,不要包含任何其他内容。';
148
+
149
+ const result = await enhancedLLMService.chat({
150
+ messages: [
151
+ { role: 'system', content: systemMessage },
152
+ { role: 'user', content: prompt },
153
+ ],
154
+ taskId: state.taskId,
155
+ stepName: 'organize',
156
+ });
157
+
158
+ // 3. 解析 JSON 响应
159
+ let output: OrganizeOutput;
160
+ try {
161
+ // 尝试提取 JSON(去除可能的 markdown 代码块标记)
162
+ let content = result.content.trim();
163
+ if (content.startsWith('```json')) {
164
+ content = content.slice(7);
165
+ }
166
+ if (content.startsWith('```')) {
167
+ content = content.slice(3);
168
+ }
169
+ if (content.endsWith('```')) {
170
+ content = content.slice(0, -3);
171
+ }
172
+ content = content.trim();
173
+
174
+ output = JSON.parse(content);
175
+ } catch (error) {
176
+ logger.error('Failed to parse LLM output as JSON', {
177
+ taskId: state.taskId,
178
+ content: result.content.substring(0, 500),
179
+ error: error instanceof Error ? error.message : String(error),
180
+ });
181
+
182
+ throw new Error(
183
+ 'Failed to parse organize output. LLM did not return valid JSON.'
184
+ );
185
+ }
186
+
187
+ // 4. 验证输出
188
+ this.validateOutput(output);
189
+
190
+ return output;
191
+ }
192
+
193
+ /**
194
+ * 验证 LLM 输出
195
+ */
196
+ private validateOutput(output: OrganizeOutput): void {
197
+ if (!output.outline || output.outline.trim().length === 0) {
198
+ throw new Error('Outline is empty');
199
+ }
200
+
201
+ if (
202
+ !output.keyPoints ||
203
+ output.keyPoints.length < (this.config.minKeyPoints || 3) ||
204
+ output.keyPoints.length > (this.config.maxKeyPoints || 5)
205
+ ) {
206
+ throw new Error(
207
+ `Key points count must be between ${this.config.minKeyPoints || 3} and ${this.config.maxKeyPoints || 5}`
208
+ );
209
+ }
210
+
211
+ if (!output.summary || output.summary.trim().length === 0) {
212
+ throw new Error('Summary is empty');
213
+ }
214
+
215
+ const summaryLength = output.summary.length;
216
+ if (
217
+ summaryLength < (this.config.minSummaryLength || 100) ||
218
+ summaryLength > (this.config.maxSummaryLength || 150)
219
+ ) {
220
+ logger.warn('Summary length is out of recommended range', {
221
+ length: summaryLength,
222
+ min: this.config.minSummaryLength,
223
+ max: this.config.maxSummaryLength,
224
+ });
225
+ // 不抛出错误,只是警告
226
+ }
227
+ }
228
+
229
+ /**
230
+ * 执行整理逻辑
231
+ */
232
+ protected async executeLogic(state: WorkflowState): Promise<Partial<WorkflowState>> {
233
+ logger.info('Starting organize', {
234
+ taskId: state.taskId,
235
+ topic: state.topic,
236
+ searchResultsCount: state.searchResults?.length || 0,
237
+ });
238
+
239
+ try {
240
+ // 1. 检查是否有搜索结果
241
+ if (!state.searchResults || state.searchResults.length === 0) {
242
+ logger.warn('No search results available', {
243
+ taskId: state.taskId,
244
+ });
245
+
246
+ // 如果没有搜索结果,生成基础结构
247
+ const basicOutput: OrganizedInfo = {
248
+ outline: `# ${state.topic}\n\n## 引言\n\n## 正文\n\n## 结语\n`,
249
+ keyPoints: [`${state.topic}的相关内容`],
250
+ summary: `这是一篇关于${state.topic}的文章。`,
251
+ };
252
+
253
+ return {
254
+ organizedInfo: basicOutput,
255
+ };
256
+ }
257
+
258
+ // 2. 调用 LLM 生成组织结构
259
+ const output = await this.callLLM(state);
260
+
261
+ // 3. 构建返回结果
262
+ const organizedInfo: OrganizedInfo = {
263
+ outline: output.outline,
264
+ keyPoints: output.keyPoints,
265
+ summary: output.summary,
266
+ };
267
+
268
+ logger.info('Organize completed successfully', {
269
+ taskId: state.taskId,
270
+ outlineLength: output.outline.length,
271
+ keyPointsCount: output.keyPoints.length,
272
+ summaryLength: output.summary.length,
273
+ });
274
+
275
+ return {
276
+ organizedInfo,
277
+ };
278
+ } catch (error) {
279
+ logger.error('Organize failed', {
280
+ taskId: state.taskId,
281
+ error: error instanceof Error ? error.message : String(error),
282
+ });
283
+
284
+ // 整理失败时,抛出错误(这个步骤很关键)
285
+ throw error;
286
+ }
287
+ }
288
+
289
+ /**
290
+ * 验证输入状态
291
+ */
292
+ protected validateState(state: WorkflowState): void {
293
+ super.validateState(state);
294
+
295
+ if (!state.requirements || state.requirements.trim().length === 0) {
296
+ throw new Error('Requirements are required for organize');
297
+ }
298
+ }
299
+ }
300
+
301
+ /**
302
+ * Organize Node 单例导出(默认配置)
303
+ */
304
+ export const organizeNode = new OrganizeNode();