@ai-setting/roy-agent-core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (378) hide show
  1. package/dist/index.js +99145 -0
  2. package/package.json +114 -0
  3. package/src/config/config-component.test.ts +627 -0
  4. package/src/config/config-component.ts +906 -0
  5. package/src/config/config-parser.test.ts +319 -0
  6. package/src/config/config-parser.ts +203 -0
  7. package/src/config/decentralized-config.test.ts +740 -0
  8. package/src/config/env-key.ts +210 -0
  9. package/src/config/env-source.test.ts +252 -0
  10. package/src/config/env-source.ts +301 -0
  11. package/src/config/file-source.test.ts +357 -0
  12. package/src/config/file-source.ts +421 -0
  13. package/src/config/index.ts +24 -0
  14. package/src/config/protocol-resolver.test.ts +217 -0
  15. package/src/config/protocol-resolver.ts +228 -0
  16. package/src/env/agent/agent-component.abort.test.ts +511 -0
  17. package/src/env/agent/agent-component.record-session.test.ts +349 -0
  18. package/src/env/agent/agent-component.test.ts +1389 -0
  19. package/src/env/agent/agent-component.tool-error.test.ts +327 -0
  20. package/src/env/agent/agent-component.ts +1711 -0
  21. package/src/env/agent/agent-config-registration.test.ts +226 -0
  22. package/src/env/agent/agent-config-registration.ts +46 -0
  23. package/src/env/agent/agent-reminder-plugin.integration.test.ts +243 -0
  24. package/src/env/agent/index.ts +10 -0
  25. package/src/env/agent/summary-agent.parse-hint.test.ts +360 -0
  26. package/src/env/agent/summary-agent.ts +508 -0
  27. package/src/env/agent/types.ts +536 -0
  28. package/src/env/commands/commands-component.test.ts +364 -0
  29. package/src/env/commands/commands-component.ts +604 -0
  30. package/src/env/commands/commands-config-registration.test.ts +198 -0
  31. package/src/env/commands/commands-config-registration.ts +38 -0
  32. package/src/env/commands/index.ts +21 -0
  33. package/src/env/commands/parser.test.ts +203 -0
  34. package/src/env/commands/parser.ts +115 -0
  35. package/src/env/commands/types.ts +184 -0
  36. package/src/env/commands-prompt-integration.test.ts +243 -0
  37. package/src/env/component-env.test.ts +119 -0
  38. package/src/env/component.ts +335 -0
  39. package/src/env/constants.test.ts +72 -0
  40. package/src/env/constants.ts +123 -0
  41. package/src/env/debug/debug-component.test.ts +114 -0
  42. package/src/env/debug/debug-component.ts +547 -0
  43. package/src/env/debug/formatters/index.ts +9 -0
  44. package/src/env/debug/formatters/repl-formatter.test.ts +139 -0
  45. package/src/env/debug/formatters/repl-formatter.ts +358 -0
  46. package/src/env/debug/formatters/trace-formatter.test.ts +119 -0
  47. package/src/env/debug/formatters/trace-formatter.ts +191 -0
  48. package/src/env/debug/formatters/tree-formatter.test.ts +107 -0
  49. package/src/env/debug/formatters/tree-formatter.ts +325 -0
  50. package/src/env/debug/index.ts +38 -0
  51. package/src/env/debug/parser/regex-parser.test.ts +201 -0
  52. package/src/env/debug/parser/regex-parser.ts +196 -0
  53. package/src/env/debug/parser/span-builder.test.ts +241 -0
  54. package/src/env/debug/parser/span-builder.ts +386 -0
  55. package/src/env/debug/reader/log-reader.test.ts +170 -0
  56. package/src/env/debug/reader/log-reader.ts +186 -0
  57. package/src/env/debug/reader/span-db-reader.test.ts +118 -0
  58. package/src/env/debug/reader/span-db-reader.ts +201 -0
  59. package/src/env/debug/types.test.ts +187 -0
  60. package/src/env/debug/types.ts +171 -0
  61. package/src/env/environment-init.test.ts +183 -0
  62. package/src/env/environment-lifecycle.test.ts +516 -0
  63. package/src/env/environment-service.test.ts +332 -0
  64. package/src/env/environment.handle-query.test.ts +96 -0
  65. package/src/env/environment.test.ts +232 -0
  66. package/src/env/environment.ts +708 -0
  67. package/src/env/errors.test.ts +165 -0
  68. package/src/env/errors.ts +157 -0
  69. package/src/env/event-source/event-source-agent-handler.test.ts +193 -0
  70. package/src/env/event-source/event-source-agent-handler.ts +111 -0
  71. package/src/env/event-source/event-source-component.process-cleanup.test.ts +236 -0
  72. package/src/env/event-source/event-source-component.stop.test.ts +346 -0
  73. package/src/env/event-source/event-source-component.test.ts +1207 -0
  74. package/src/env/event-source/event-source-component.ts +1379 -0
  75. package/src/env/event-source/event-source-config-registration.test.ts +242 -0
  76. package/src/env/event-source/event-source-config-registration.ts +37 -0
  77. package/src/env/event-source/event-source-integration.test.ts +320 -0
  78. package/src/env/event-source/event-source-platform.test.ts +630 -0
  79. package/src/env/event-source/types.ts +298 -0
  80. package/src/env/hook/global-hook-manager.ts +162 -0
  81. package/src/env/hook/hook-manager.test.ts +374 -0
  82. package/src/env/hook/hook-manager.ts +309 -0
  83. package/src/env/hook/index.ts +38 -0
  84. package/src/env/hook/types.ts +138 -0
  85. package/src/env/index.ts +144 -0
  86. package/src/env/interface.ts +203 -0
  87. package/src/env/llm/hooks.test.ts +293 -0
  88. package/src/env/llm/hooks.ts +316 -0
  89. package/src/env/llm/index.ts +61 -0
  90. package/src/env/llm/invoke-threshold-check.test.ts +88 -0
  91. package/src/env/llm/invoke-timeout.test.ts +54 -0
  92. package/src/env/llm/invoke.test.ts +71 -0
  93. package/src/env/llm/invoke.ts +1039 -0
  94. package/src/env/llm/llm-config.test.ts +523 -0
  95. package/src/env/llm/llm.test.ts +233 -0
  96. package/src/env/llm/llm.ts +568 -0
  97. package/src/env/llm/provider.test.ts +182 -0
  98. package/src/env/llm/provider.ts +108 -0
  99. package/src/env/llm/transform.test.ts +251 -0
  100. package/src/env/llm/transform.ts +286 -0
  101. package/src/env/llm/types.test.ts +580 -0
  102. package/src/env/llm/types.ts +424 -0
  103. package/src/env/log-trace/decorator-otel.test.ts +182 -0
  104. package/src/env/log-trace/decorator.ts +230 -0
  105. package/src/env/log-trace/index.ts +79 -0
  106. package/src/env/log-trace/log-trace-component.test.ts +242 -0
  107. package/src/env/log-trace/log-trace-component.ts +497 -0
  108. package/src/env/log-trace/log-trace-config-registration.test.ts +348 -0
  109. package/src/env/log-trace/log-trace-config-registration.ts +45 -0
  110. package/src/env/log-trace/logger.test.ts +149 -0
  111. package/src/env/log-trace/logger.ts +522 -0
  112. package/src/env/log-trace/opentelemetry/cli-propagation.test.ts +147 -0
  113. package/src/env/log-trace/opentelemetry/cli-propagation.ts +194 -0
  114. package/src/env/log-trace/opentelemetry/integration.test.ts +668 -0
  115. package/src/env/log-trace/opentelemetry/mod.ts +25 -0
  116. package/src/env/log-trace/opentelemetry/propagation-env.test.ts +181 -0
  117. package/src/env/log-trace/opentelemetry/propagation-env.ts +136 -0
  118. package/src/env/log-trace/opentelemetry/propagation.test.ts +259 -0
  119. package/src/env/log-trace/opentelemetry/propagation.ts +215 -0
  120. package/src/env/log-trace/opentelemetry/tracer-provider-context.test.ts +166 -0
  121. package/src/env/log-trace/opentelemetry/tracer-provider.test.ts +379 -0
  122. package/src/env/log-trace/opentelemetry/tracer-provider.ts +612 -0
  123. package/src/env/log-trace/span-storage.test.ts +145 -0
  124. package/src/env/log-trace/span-storage.ts +230 -0
  125. package/src/env/log-trace/trace-context.test.ts +187 -0
  126. package/src/env/log-trace/trace-context.ts +162 -0
  127. package/src/env/log-trace/types.test.ts +63 -0
  128. package/src/env/log-trace/types.ts +172 -0
  129. package/src/env/mcp/README.md +244 -0
  130. package/src/env/mcp/__integration__/mcp-component.integration.test.ts +373 -0
  131. package/src/env/mcp/config.test.ts +74 -0
  132. package/src/env/mcp/config.ts +116 -0
  133. package/src/env/mcp/index.ts +41 -0
  134. package/src/env/mcp/loader.test.ts +161 -0
  135. package/src/env/mcp/loader.ts +209 -0
  136. package/src/env/mcp/mcp-component.test.ts +111 -0
  137. package/src/env/mcp/mcp-component.ts +358 -0
  138. package/src/env/mcp/mcp-config-registration.test.ts +304 -0
  139. package/src/env/mcp/mcp-config-registration.ts +50 -0
  140. package/src/env/mcp/scanner.test.ts +170 -0
  141. package/src/env/mcp/scanner.ts +246 -0
  142. package/src/env/mcp/tool/adapter.test.ts +520 -0
  143. package/src/env/mcp/tool/adapter.ts +521 -0
  144. package/src/env/mcp/tool/index.ts +5 -0
  145. package/src/env/mcp/types.test.ts +171 -0
  146. package/src/env/mcp/types.ts +79 -0
  147. package/src/env/memory/README.md +177 -0
  148. package/src/env/memory/built-in/index.ts +59 -0
  149. package/src/env/memory/built-in/recall-memory.ts +103 -0
  150. package/src/env/memory/built-in/record-memory.ts +148 -0
  151. package/src/env/memory/index.ts +20 -0
  152. package/src/env/memory/memory-component.test.ts +239 -0
  153. package/src/env/memory/memory-component.ts +503 -0
  154. package/src/env/memory/memory-config-registration.test.ts +67 -0
  155. package/src/env/memory/memory-config-registration.ts +48 -0
  156. package/src/env/memory/memory-config.ts +45 -0
  157. package/src/env/memory/memory-file.test.ts +268 -0
  158. package/src/env/memory/plugin/index.ts +48 -0
  159. package/src/env/memory/plugin/memory-agent.test.ts +249 -0
  160. package/src/env/memory/plugin/memory-agent.ts +365 -0
  161. package/src/env/memory/plugin/memory-manager.ts +198 -0
  162. package/src/env/memory/plugin/memory-plugin-agent.test.ts +145 -0
  163. package/src/env/memory/plugin/memory-plugin.ts +210 -0
  164. package/src/env/memory/plugin/plugin-simplified.test.ts +51 -0
  165. package/src/env/memory/plugin/recall-memory.test.ts +106 -0
  166. package/src/env/memory/plugin/recall-memory.ts +53 -0
  167. package/src/env/memory/plugin/types.ts +101 -0
  168. package/src/env/memory/tools/memory-agent-tools.ts +228 -0
  169. package/src/env/memory/types.ts +85 -0
  170. package/src/env/paths.ts +118 -0
  171. package/src/env/prompt/index.ts +18 -0
  172. package/src/env/prompt/memory-prompts.test.ts +91 -0
  173. package/src/env/prompt/prompt-component.test.ts +491 -0
  174. package/src/env/prompt/prompt-component.ts +619 -0
  175. package/src/env/prompt/prompt-config-registration.test.ts +213 -0
  176. package/src/env/prompt/prompt-config-registration.ts +39 -0
  177. package/src/env/prompt/prompts-index.ts +504 -0
  178. package/src/env/prompt/renderer.ts +67 -0
  179. package/src/env/prompt/types.ts +136 -0
  180. package/src/env/session/hooks.ts +18 -0
  181. package/src/env/session/index.ts +37 -0
  182. package/src/env/session/search-query-parser.test.ts +425 -0
  183. package/src/env/session/search-query-parser.ts +171 -0
  184. package/src/env/session/session-checkpoint.test.ts +523 -0
  185. package/src/env/session/session-component.extract-recent-messages.test.ts +209 -0
  186. package/src/env/session/session-component.test.ts +132 -0
  187. package/src/env/session/session-component.ts +1249 -0
  188. package/src/env/session/session-config-registration.test.ts +138 -0
  189. package/src/env/session/session-config-registration.ts +52 -0
  190. package/src/env/session/session-message-converter.test.ts +763 -0
  191. package/src/env/session/session-message-converter.ts +415 -0
  192. package/src/env/session/session-message-e2e.test.ts +448 -0
  193. package/src/env/session/session-search.test.ts +391 -0
  194. package/src/env/session/session-store.test.ts +362 -0
  195. package/src/env/session/session-store.ts +141 -0
  196. package/src/env/session/storage/index.ts +6 -0
  197. package/src/env/session/storage/memory.ts +502 -0
  198. package/src/env/session/storage/sqlite.ts +794 -0
  199. package/src/env/session/types.ts +742 -0
  200. package/src/env/skill/config.ts +39 -0
  201. package/src/env/skill/index.ts +6 -0
  202. package/src/env/skill/parser.test.ts +116 -0
  203. package/src/env/skill/parser.ts +77 -0
  204. package/src/env/skill/scanner.test.ts +211 -0
  205. package/src/env/skill/scanner.ts +119 -0
  206. package/src/env/skill/skill-component.test.ts +234 -0
  207. package/src/env/skill/skill-component.ts +352 -0
  208. package/src/env/skill/skill-config-registration.test.ts +60 -0
  209. package/src/env/skill/skill-config-registration.ts +43 -0
  210. package/src/env/skill/tool/index.ts +1 -0
  211. package/src/env/skill/tool/skill-tool.test.ts +100 -0
  212. package/src/env/skill/tool/skill-tool.ts +72 -0
  213. package/src/env/skill/types.ts +64 -0
  214. package/src/env/task/delegate/delegate-tool.test.ts +498 -0
  215. package/src/env/task/delegate/delegate-tool.ts +1014 -0
  216. package/src/env/task/delegate/index.ts +18 -0
  217. package/src/env/task/delegate/stop-tool.test.ts +140 -0
  218. package/src/env/task/delegate/stop-tool.ts +119 -0
  219. package/src/env/task/delegate/task-events.test.ts +178 -0
  220. package/src/env/task/delegate/task-events.ts +143 -0
  221. package/src/env/task/hooks/contexts.test.ts +92 -0
  222. package/src/env/task/hooks/contexts.ts +192 -0
  223. package/src/env/task/hooks/index.ts +23 -0
  224. package/src/env/task/hooks/task-hook-points.test.ts +32 -0
  225. package/src/env/task/hooks/task-hook-points.ts +54 -0
  226. package/src/env/task/index.ts +7 -0
  227. package/src/env/task/plugins/index.ts +13 -0
  228. package/src/env/task/plugins/task-plugin.test.ts +74 -0
  229. package/src/env/task/plugins/task-plugin.ts +89 -0
  230. package/src/env/task/plugins/task-tag-plugin.test.ts +377 -0
  231. package/src/env/task/plugins/task-tag-plugin.ts +319 -0
  232. package/src/env/task/plugins/task-workflow-extractor.integration.test.ts +226 -0
  233. package/src/env/task/plugins/workflow-extractor-agent.test.ts +107 -0
  234. package/src/env/task/plugins/workflow-extractor-agent.ts +225 -0
  235. package/src/env/task/storage/index.ts +6 -0
  236. package/src/env/task/storage/sqlite-task-store.test.ts +283 -0
  237. package/src/env/task/storage/sqlite-task-store.ts +903 -0
  238. package/src/env/task/storage/task-search.test.ts +291 -0
  239. package/src/env/task/tag-service.test.ts +198 -0
  240. package/src/env/task/tag-service.ts +264 -0
  241. package/src/env/task/task-component.test.ts +193 -0
  242. package/src/env/task/task-component.ts +658 -0
  243. package/src/env/task/task-config-registration.test.ts +57 -0
  244. package/src/env/task/task-config-registration.ts +37 -0
  245. package/src/env/task/task-types.test.ts +137 -0
  246. package/src/env/task/tools/complete-tool.ts +44 -0
  247. package/src/env/task/tools/create-tool.ts +49 -0
  248. package/src/env/task/tools/delete-tool.ts +43 -0
  249. package/src/env/task/tools/get-tool.ts +59 -0
  250. package/src/env/task/tools/index.ts +10 -0
  251. package/src/env/task/tools/list-tool.ts +40 -0
  252. package/src/env/task/tools/operation/create-tool.ts +48 -0
  253. package/src/env/task/tools/operation/delete-tool.ts +43 -0
  254. package/src/env/task/tools/operation/get-tool.ts +43 -0
  255. package/src/env/task/tools/operation/index.ts +9 -0
  256. package/src/env/task/tools/operation/list-tool.ts +40 -0
  257. package/src/env/task/tools/operation/operation-tools.test.ts +274 -0
  258. package/src/env/task/tools/operation/operation-types.ts +75 -0
  259. package/src/env/task/tools/operation/update-tool.ts +47 -0
  260. package/src/env/task/tools/task-tools.test.ts +203 -0
  261. package/src/env/task/tools/task-types.test.ts +75 -0
  262. package/src/env/task/tools/task-types.ts +68 -0
  263. package/src/env/task/tools/update-tool.ts +70 -0
  264. package/src/env/task/types.ts +160 -0
  265. package/src/env/tool/built-in/bash.ts +201 -0
  266. package/src/env/tool/built-in/echo.ts +29 -0
  267. package/src/env/tool/built-in/edit-file.test.ts +136 -0
  268. package/src/env/tool/built-in/edit-file.ts +92 -0
  269. package/src/env/tool/built-in/glob.test.ts +94 -0
  270. package/src/env/tool/built-in/glob.ts +65 -0
  271. package/src/env/tool/built-in/grep.test.ts +122 -0
  272. package/src/env/tool/built-in/grep.ts +108 -0
  273. package/src/env/tool/built-in/index.ts +44 -0
  274. package/src/env/tool/built-in/read-file.test.ts +84 -0
  275. package/src/env/tool/built-in/read-file.ts +75 -0
  276. package/src/env/tool/built-in/write-file.test.ts +119 -0
  277. package/src/env/tool/built-in/write-file.ts +68 -0
  278. package/src/env/tool/index.ts +24 -0
  279. package/src/env/tool/registry.test.ts +257 -0
  280. package/src/env/tool/registry.ts +167 -0
  281. package/src/env/tool/tool-component.test.ts +559 -0
  282. package/src/env/tool/tool-component.ts +563 -0
  283. package/src/env/tool/tool-config-registration.test.ts +249 -0
  284. package/src/env/tool/tool-config-registration.ts +46 -0
  285. package/src/env/tool/types.ts +267 -0
  286. package/src/env/tool/validator.test.ts +143 -0
  287. package/src/env/tool/validator.ts +44 -0
  288. package/src/env/types.ts +180 -0
  289. package/src/env/workflow/ask-user-tool-registration.test.ts +216 -0
  290. package/src/env/workflow/complex-workflow.integration.test.ts +1900 -0
  291. package/src/env/workflow/decorators/decorator-node.ts +229 -0
  292. package/src/env/workflow/decorators/decorator.test.ts +196 -0
  293. package/src/env/workflow/decorators/edge.ts +82 -0
  294. package/src/env/workflow/decorators/index.ts +31 -0
  295. package/src/env/workflow/decorators/node-as.ts +98 -0
  296. package/src/env/workflow/decorators/workflow.ts +54 -0
  297. package/src/env/workflow/engine/dag-manager.test.ts +570 -0
  298. package/src/env/workflow/engine/dag-manager.ts +594 -0
  299. package/src/env/workflow/engine/engine.ts +1422 -0
  300. package/src/env/workflow/engine/event-bus.test.ts +359 -0
  301. package/src/env/workflow/engine/event-bus.ts +156 -0
  302. package/src/env/workflow/engine/executor-agent-session.test.ts +84 -0
  303. package/src/env/workflow/engine/executor.test.ts +619 -0
  304. package/src/env/workflow/engine/executor.ts +593 -0
  305. package/src/env/workflow/engine/index.ts +24 -0
  306. package/src/env/workflow/engine/node-registry.test.ts +560 -0
  307. package/src/env/workflow/engine/node-registry.ts +289 -0
  308. package/src/env/workflow/engine/resume-removed.test.ts +22 -0
  309. package/src/env/workflow/engine/scheduler.test.ts +715 -0
  310. package/src/env/workflow/engine/scheduler.ts +318 -0
  311. package/src/env/workflow/engine/workflow-engine.test.ts +815 -0
  312. package/src/env/workflow/extractor/workflow-converter.ts +306 -0
  313. package/src/env/workflow/fixtures.ts +380 -0
  314. package/src/env/workflow/index.ts +38 -0
  315. package/src/env/workflow/integration/run-resume-unified.test.ts +186 -0
  316. package/src/env/workflow/integration/service-integration.test.ts +267 -0
  317. package/src/env/workflow/metadata/keys.ts +12 -0
  318. package/src/env/workflow/nodes/agent-component-adapter.test.ts +318 -0
  319. package/src/env/workflow/nodes/agent-component-adapter.ts +448 -0
  320. package/src/env/workflow/nodes/agent-node.test.ts +371 -0
  321. package/src/env/workflow/nodes/agent-node.ts +598 -0
  322. package/src/env/workflow/nodes/ask-user-node.ts +113 -0
  323. package/src/env/workflow/nodes/condition-node.ts +200 -0
  324. package/src/env/workflow/nodes/index.ts +9 -0
  325. package/src/env/workflow/nodes/merge-node.ts +141 -0
  326. package/src/env/workflow/nodes/skill-node.test.ts +253 -0
  327. package/src/env/workflow/nodes/skill-node.ts +393 -0
  328. package/src/env/workflow/nodes/tool-node.test.ts +251 -0
  329. package/src/env/workflow/nodes/tool-node.ts +493 -0
  330. package/src/env/workflow/nodes/workflow-llm-history.test.ts +455 -0
  331. package/src/env/workflow/nodes/workflow-node.test.ts +315 -0
  332. package/src/env/workflow/nodes/workflow-node.ts +311 -0
  333. package/src/env/workflow/service/index.ts +27 -0
  334. package/src/env/workflow/service/registry.test.ts +133 -0
  335. package/src/env/workflow/service/registry.ts +71 -0
  336. package/src/env/workflow/service/workflow-service.test.ts +310 -0
  337. package/src/env/workflow/service/workflow-service.ts +393 -0
  338. package/src/env/workflow/storage/index.ts +28 -0
  339. package/src/env/workflow/storage/mock-repositories.ts +385 -0
  340. package/src/env/workflow/storage/sqlite.test.ts +179 -0
  341. package/src/env/workflow/storage/sqlite.ts +163 -0
  342. package/src/env/workflow/storage/workflow-repo.test.ts +780 -0
  343. package/src/env/workflow/storage/workflow-repo.ts +342 -0
  344. package/src/env/workflow/tools/ask-user-tool.ts +82 -0
  345. package/src/env/workflow/tools/index.ts +26 -0
  346. package/src/env/workflow/tools/run-workflow.test.ts +352 -0
  347. package/src/env/workflow/tools/run-workflow.ts +214 -0
  348. package/src/env/workflow/types/context.ts +18 -0
  349. package/src/env/workflow/types/decorators-types.ts +198 -0
  350. package/src/env/workflow/types/event.test.ts +515 -0
  351. package/src/env/workflow/types/event.ts +193 -0
  352. package/src/env/workflow/types/index.ts +49 -0
  353. package/src/env/workflow/types/run.test.ts +437 -0
  354. package/src/env/workflow/types/run.ts +173 -0
  355. package/src/env/workflow/types/workflow-hil.ts +114 -0
  356. package/src/env/workflow/types/workflow-message.test.ts +138 -0
  357. package/src/env/workflow/types/workflow-message.ts +196 -0
  358. package/src/env/workflow/types/workflow-session.test.ts +95 -0
  359. package/src/env/workflow/types/workflow-session.ts +59 -0
  360. package/src/env/workflow/types/workflow.test.ts +495 -0
  361. package/src/env/workflow/types/workflow.ts +195 -0
  362. package/src/env/workflow/types_compat.ts +51 -0
  363. package/src/env/workflow/utils/create-workflow.ts +47 -0
  364. package/src/env/workflow/utils/execution-state.ts +245 -0
  365. package/src/env/workflow/utils/index.ts +18 -0
  366. package/src/env/workflow/utils/node-registry-helper.ts +58 -0
  367. package/src/env/workflow/utils/recovery-validator.test.ts +460 -0
  368. package/src/env/workflow/utils/recovery-validator.ts +377 -0
  369. package/src/env/workflow/utils/session-parser.test.ts +111 -0
  370. package/src/env/workflow/utils/session-parser.ts +94 -0
  371. package/src/env/workflow/utils/session-recovery.test.ts +334 -0
  372. package/src/env/workflow/utils/session-recovery.ts +188 -0
  373. package/src/env/workflow/utils/template-resolver.test.ts +258 -0
  374. package/src/env/workflow/utils/template-resolver.ts +436 -0
  375. package/src/env/workflow/utils/validation-rules.ts +149 -0
  376. package/src/env/workflow/workflow-component.ts +544 -0
  377. package/src/index.ts +422 -0
  378. package/src/utils/id.ts +21 -0
@@ -0,0 +1,619 @@
1
+ /**
2
+ * @fileoverview PromptComponent
3
+ *
4
+ * 管理提示词存储、加载和渲染
5
+ * - 内置 prompts 在构建时嵌入到 bundle 中(通过 prompts-index.ts)
6
+ * - 外部 prompts 通过配置从指定路径加载
7
+ *
8
+ * 配置通过 ConfigComponent 实时获取,支持配置热更新
9
+ */
10
+
11
+ import { z } from "zod";
12
+ import { BaseComponent, type ComponentConfig, type HookFn } from "../component";
13
+ import {
14
+ PromptConfigSchema,
15
+ type PromptConfig,
16
+ type PromptPath,
17
+ type PromptEntry,
18
+ type PromptHook,
19
+ type PromptHookContext,
20
+ PromptHookPoints,
21
+ } from "./types";
22
+ import { PromptRenderer } from "./renderer";
23
+ import { createLogger } from "../log-trace/logger";
24
+ import { readFile, readdir } from "fs/promises";
25
+ import { join, basename, extname } from "path";
26
+ import { dirname } from "path";
27
+ import type { ConfigComponent } from "../../config/config-component";
28
+ import { PROMPT_CONFIG_REGISTRATION, PROMPT_DEFAULTS } from "./prompt-config-registration";
29
+ import { toEnvKey, envKeyToConfigKey } from "../../config/env-key";
30
+ import { builtInPrompts } from "./prompts-index";
31
+
32
+ const logger = createLogger("prompt");
33
+
34
+ /**
35
+ * PromptComponent 配置选项(通过 options 传递)
36
+ *
37
+ * 配置加载顺序(优先级从低到高):
38
+ * 1. File - 配置文件(通过 configPath 指定)
39
+ * 2. Env - 环境变量(通过 envPrefix 配置前缀)
40
+ * 3. Object - 直接传入的配置对象(最高优先级)
41
+ */
42
+ export interface PromptComponentOptions {
43
+ /** ConfigComponent 实例(必填) */
44
+ configComponent: ConfigComponent;
45
+
46
+ /** 配置文件相对路径(可选,基于 XDG_DATA_HOME) */
47
+ configPath?: string;
48
+
49
+ /** 环境变量前缀(可选,默认 "PROMPT") */
50
+ envPrefix?: string;
51
+
52
+ /** 默认 prompt 名称 */
53
+ defaultName?: string;
54
+
55
+ /** 外部 prompt 路径列表 */
56
+ promptPaths?: PromptPath[];
57
+
58
+ /** 变量前缀(默认 "{{") */
59
+ variablePrefix?: string;
60
+
61
+ /** 变量后缀(默认 "}}") */
62
+ variableSuffix?: string;
63
+
64
+ /** 直接传入的配置对象(可选,优先级最高) */
65
+ config?: Partial<PromptConfig>;
66
+ }
67
+
68
+ /**
69
+ * PromptComponent
70
+ *
71
+ * 管理提示词存储、加载和渲染
72
+ * 配置通过 ConfigComponent 实时获取,支持配置热更新
73
+ */
74
+ export class PromptComponent extends BaseComponent {
75
+ readonly name = "prompt";
76
+ readonly version = "1.0.0";
77
+
78
+ // 核心存储:name → entry
79
+ private prompts: Map<string, PromptEntry> = new Map();
80
+
81
+ private config?: PromptConfig;
82
+ private configComponent?: ConfigComponent;
83
+ private renderer!: PromptRenderer;
84
+
85
+ /** 配置变更 watcher 清理函数 */
86
+ private configWatcher?: () => void;
87
+
88
+ constructor() {
89
+ super();
90
+ }
91
+
92
+ // ============================================================================
93
+ // Component Lifecycle
94
+ // ============================================================================
95
+
96
+ /**
97
+ * 初始化组件
98
+ *
99
+ * 配置加载优先级(从高到低):
100
+ * 1. Object - 直接传入的 config 对象
101
+ * 2. Env - 环境变量(通过 envPrefix 配置前缀)
102
+ * 3. File - 配置文件(通过 configPath 指定)
103
+ */
104
+ async init(config: ComponentConfig): Promise<void> {
105
+ // 调用基类 init,注入 env
106
+ await super.init(config);
107
+
108
+ // 从 options 获取 ConfigComponent
109
+ const options = config.options as unknown as PromptComponentOptions | undefined;
110
+ if (!options?.configComponent) {
111
+ throw new Error("ConfigComponent is required for PromptComponent initialization");
112
+ }
113
+
114
+ this.configComponent = options.configComponent;
115
+ await this.registerConfig(options);
116
+
117
+ // 初始化渲染器
118
+ this.initRenderer();
119
+
120
+ // 加载 prompts
121
+ await this.loadPrompts();
122
+
123
+ this.setStatus("running");
124
+ logger.info(`[PromptComponent] Initialized with ${this.prompts.size} prompts`);
125
+ }
126
+
127
+ /**
128
+ * 注册配置到 ConfigComponent
129
+ *
130
+ * 配置加载顺序(优先级从低到高):
131
+ * 1. Env - 环境变量(通过 load 加载 + 直接读取)
132
+ * 2. Defaults - 默认值(在环境变量检查之后设置)
133
+ * 3. Config Object - 直接配置对象(最高优先级)
134
+ */
135
+ private async registerConfig(options: PromptComponentOptions): Promise<void> {
136
+ const configComponent = options.configComponent;
137
+ if (!configComponent) return;
138
+
139
+ const { config, defaultName, promptPaths, variablePrefix, variableSuffix } = options;
140
+
141
+ // 1. 使用 registerComponent 注册配置(会自动注册 sources 和 keys)
142
+ configComponent.registerComponent(PROMPT_CONFIG_REGISTRATION);
143
+
144
+ // 2. 使用 load 加载配置(从 env/file source 加载)
145
+ await configComponent.load("prompt");
146
+
147
+ // 3. 后备方案:直接读取环境变量(如果 load 未覆盖)
148
+ const prefix = "PROMPT";
149
+ const promptKeys = [
150
+ "prompt.defaultName",
151
+ "prompt.promptPaths",
152
+ "prompt.variablePrefix",
153
+ "prompt.variableSuffix",
154
+ "prompt.strictMode",
155
+ ];
156
+
157
+ for (const key of promptKeys) {
158
+ const envKey = toEnvKey(key, prefix);
159
+ const value = process.env[envKey];
160
+ if (value !== undefined) {
161
+ await configComponent.set(key, value);
162
+ }
163
+ }
164
+
165
+ // 4. 自动发现其他相关环境变量
166
+ const loadedKeys = new Set(promptKeys);
167
+ for (const envKey of Object.keys(process.env)) {
168
+ const configKey = envKeyToConfigKey(envKey, prefix, "prompt");
169
+ if (!configKey) continue;
170
+ if (loadedKeys.has(configKey)) continue;
171
+ loadedKeys.add(configKey);
172
+ const value = process.env[envKey];
173
+ if (value !== undefined) {
174
+ await configComponent.set(configKey, value);
175
+ }
176
+ }
177
+
178
+ // 5. 设置默认值(只有当配置不存在时)
179
+ for (const [key, value] of Object.entries(PROMPT_DEFAULTS)) {
180
+ if (configComponent.get(key) === undefined) {
181
+ await configComponent.set(key, value);
182
+ }
183
+ }
184
+
185
+ // 6. 直接配置对象(最高优先级)
186
+ if (config) {
187
+ const flatConfig = this.flattenConfig(config);
188
+ for (const [key, value] of Object.entries(flatConfig)) {
189
+ await configComponent.set(key, value);
190
+ }
191
+ }
192
+
193
+ // 6.5 直接选项(也属于最高优先级)
194
+ if (defaultName !== undefined) {
195
+ await configComponent.set("prompt.defaultName", defaultName);
196
+ }
197
+ if (promptPaths !== undefined) {
198
+ await configComponent.set("prompt.promptPaths", promptPaths);
199
+ }
200
+ if (variablePrefix !== undefined) {
201
+ await configComponent.set("prompt.variablePrefix", variablePrefix);
202
+ }
203
+ if (variableSuffix !== undefined) {
204
+ await configComponent.set("prompt.variableSuffix", variableSuffix);
205
+ }
206
+
207
+ // 7. 注册配置热更新监听
208
+ this.registerConfigWatcher(configComponent);
209
+
210
+ // 8. 从 ConfigComponent 获取最终配置
211
+ // 注意:默认值已通过 registerComponent.defaults 设置到 ConfigComponent
212
+ this.config = {
213
+ defaultName: (configComponent.get("prompt.defaultName") as string) || "default",
214
+ promptPaths: (configComponent.get("prompt.promptPaths") as PromptPath[]) || [],
215
+ variablePrefix: (configComponent.get("prompt.variablePrefix") as string) || "{{",
216
+ variableSuffix: (configComponent.get("prompt.variableSuffix") as string) || "}}",
217
+ strictMode: (configComponent.get("prompt.strictMode") as boolean) || false,
218
+ };
219
+ }
220
+
221
+ /**
222
+ * 将配置对象展平为点号路径
223
+ */
224
+ private flattenConfig(
225
+ obj: Record<string, unknown>,
226
+ prefix = "prompt"
227
+ ): Record<string, unknown> {
228
+ const result: Record<string, unknown> = {};
229
+ for (const [key, value] of Object.entries(obj)) {
230
+ const fullKey = `${prefix}.${key}`;
231
+ if (value && typeof value === "object" && !Array.isArray(value)) {
232
+ Object.assign(result, this.flattenConfig(value as Record<string, unknown>, fullKey));
233
+ } else {
234
+ result[fullKey] = value;
235
+ }
236
+ }
237
+ return result;
238
+ }
239
+
240
+ /**
241
+ * 注册配置热更新监听
242
+ */
243
+ private registerConfigWatcher(configComponent: ConfigComponent): void {
244
+ if (typeof configComponent.watch !== "function") {
245
+ return;
246
+ }
247
+
248
+ this.configWatcher = configComponent.watch("prompt.*", (event) => {
249
+ this.onConfigChange(event);
250
+ });
251
+ }
252
+
253
+ /**
254
+ * 处理配置变更
255
+ */
256
+ private onConfigChange(event: { key: string; oldValue?: unknown; newValue?: unknown }): void {
257
+ const key = event.key;
258
+ const value = event.newValue;
259
+
260
+ if (value === undefined) return;
261
+
262
+ logger.debug(`[PromptComponent] Config updated: ${key} = ${JSON.stringify(value)}`);
263
+
264
+ // 更新本地配置
265
+ switch (key) {
266
+ case "prompt.defaultName":
267
+ if (this.config) this.config.defaultName = value as string;
268
+ break;
269
+ case "prompt.promptPaths":
270
+ if (this.config) this.config.promptPaths = value as PromptPath[];
271
+ break;
272
+ case "prompt.variablePrefix":
273
+ if (this.config) {
274
+ this.config.variablePrefix = value as string;
275
+ this.initRenderer(); // 重新初始化渲染器
276
+ }
277
+ break;
278
+ case "prompt.variableSuffix":
279
+ if (this.config) {
280
+ this.config.variableSuffix = value as string;
281
+ this.initRenderer(); // 重新初始化渲染器
282
+ }
283
+ break;
284
+ case "prompt.strictMode":
285
+ if (this.config) this.config.strictMode = value as boolean;
286
+ break;
287
+ }
288
+ }
289
+
290
+ private initRenderer(): void {
291
+ const config = this.config || {
292
+ defaultName: "default",
293
+ promptPaths: [],
294
+ variablePrefix: "{{",
295
+ variableSuffix: "}}",
296
+ strictMode: false,
297
+ };
298
+
299
+ this.renderer = new PromptRenderer({
300
+ prefix: config.variablePrefix,
301
+ suffix: config.variableSuffix,
302
+ strict: config.strictMode,
303
+ onMissingVariable: (name) => {
304
+ logger.warn(`Undefined variable: ${name}`);
305
+ return `{{${name}}}`;
306
+ },
307
+ });
308
+ }
309
+
310
+ async onStart(): Promise<void> {
311
+ logger.info("[PromptComponent] Started");
312
+ }
313
+
314
+ async onStop(): Promise<void> {
315
+ this.prompts.clear();
316
+ this.setStatus("stopped");
317
+ logger.info("[PromptComponent] Stopped");
318
+ }
319
+
320
+ // ============================================================================
321
+ // Config Access
322
+ // ============================================================================
323
+
324
+ private getPromptConfig<T>(key: keyof PromptConfig, defaultValue?: T): T {
325
+ if (this.config && key in this.config) {
326
+ return (this.config[key] as T) ?? defaultValue as T;
327
+ }
328
+
329
+ return defaultValue as T;
330
+ }
331
+
332
+ // ============================================================================
333
+ // Core Methods
334
+ // ============================================================================
335
+
336
+ /**
337
+ * 添加 prompt
338
+ */
339
+ add(name: string, content: string, source: PromptEntry["source"] = "inline"): void {
340
+ const entry: PromptEntry = {
341
+ name,
342
+ content,
343
+ source,
344
+ overridable: true,
345
+ loadedAt: Date.now(),
346
+ };
347
+
348
+ // 如果已存在且不可覆盖,则跳过
349
+ const existing = this.prompts.get(name);
350
+ if (existing && !existing.overridable) {
351
+ logger.debug(`[PromptComponent] Skip override for non-overridable prompt: ${name}`);
352
+ return;
353
+ }
354
+
355
+ this.prompts.set(name, entry);
356
+ logger.debug(`[PromptComponent] Added prompt: ${name} (${source})`);
357
+ }
358
+
359
+ /**
360
+ * 获取 prompt 原始内容
361
+ */
362
+ get(name: string): string | undefined {
363
+ return this.prompts.get(name)?.content;
364
+ }
365
+
366
+ /**
367
+ * 获取 prompt 条目
368
+ */
369
+ getEntry(name: string): PromptEntry | undefined {
370
+ return this.prompts.get(name);
371
+ }
372
+
373
+ /**
374
+ * 检查 prompt 是否存在
375
+ */
376
+ has(name: string): boolean {
377
+ return this.prompts.has(name);
378
+ }
379
+
380
+ /**
381
+ * 删除 prompt
382
+ */
383
+ delete(name: string): boolean {
384
+ return this.prompts.delete(name);
385
+ }
386
+
387
+ /**
388
+ * 列出所有 prompt 名称
389
+ */
390
+ list(): string[] {
391
+ return Array.from(this.prompts.keys());
392
+ }
393
+
394
+ /**
395
+ * 获取数量
396
+ */
397
+ size(): number {
398
+ return this.prompts.size;
399
+ }
400
+
401
+ // ============================================================================
402
+ // Render Methods
403
+ // ============================================================================
404
+
405
+ /**
406
+ * 获取并渲染 prompt
407
+ */
408
+ async getPrompt(name: string, variables: Record<string, string> = {}): Promise<string> {
409
+ const defaultName = this.getPromptConfig("defaultName", "default");
410
+ const targetName = this.has(name) ? name : defaultName;
411
+
412
+ const entry = this.prompts.get(targetName);
413
+ if (!entry) {
414
+ logger.warn(`[PromptComponent] Prompt not found: ${name}, using fallback`);
415
+ return "You are a helpful assistant.";
416
+ }
417
+
418
+ return this.render(entry.content, variables, { name: targetName });
419
+ }
420
+
421
+ /**
422
+ * 渲染内容(异步方法)
423
+ */
424
+ async render(content: string, variables: Record<string, string> = {}, context?: Partial<PromptHookContext>): Promise<string> {
425
+ const hookContext: PromptHookContext = {
426
+ name: context?.name || "anonymous",
427
+ originalContent: content,
428
+ renderedContent: content,
429
+ variables,
430
+ };
431
+
432
+ // Hook: before.render
433
+ await this.executeHooks(PromptHookPoints.BEFORE_RENDER, hookContext);
434
+
435
+ // 执行渲染
436
+ hookContext.renderedContent = this.renderer.render(
437
+ hookContext.originalContent,
438
+ variables
439
+ );
440
+
441
+ // Hook: after.render
442
+ await this.executeHooks(PromptHookPoints.AFTER_RENDER, hookContext);
443
+
444
+ return hookContext.renderedContent;
445
+ }
446
+
447
+ /**
448
+ * 提取内容中的变量
449
+ */
450
+ extractVariables(content: string): string[] {
451
+ return this.renderer.extractVariables(content);
452
+ }
453
+
454
+ // ============================================================================
455
+ // Loading
456
+ // ============================================================================
457
+
458
+ /**
459
+ * 加载所有 prompts(内置 + 外部)
460
+ */
461
+ private async loadPrompts(): Promise<void> {
462
+ // 1. 加载内置 prompts
463
+ await this.loadBuiltInPrompts();
464
+
465
+ // 2. 加载外部 prompts(可覆盖内置)
466
+ await this.loadExternalPrompts();
467
+ }
468
+
469
+ /**
470
+ * 加载内置 prompts
471
+ *
472
+ * 使用嵌入的 prompts(在构建时打包到 bundle 中)
473
+ */
474
+ private async loadBuiltInPrompts(): Promise<void> {
475
+ // 遍历嵌入的 prompts 并注册
476
+ for (const [name, content] of Object.entries(builtInPrompts)) {
477
+ if (content) {
478
+ this.prompts.set(name, {
479
+ name,
480
+ content,
481
+ source: "built-in",
482
+ overridable: false,
483
+ loadedAt: Date.now(),
484
+ });
485
+ logger.debug(`[PromptComponent] Loaded built-in prompt: ${name}`);
486
+ }
487
+ }
488
+
489
+ logger.info(`[PromptComponent] Loaded ${this.prompts.size} built-in prompts`);
490
+ }
491
+
492
+ /**
493
+ * 加载外部 prompts
494
+ */
495
+ private async loadExternalPrompts(): Promise<void> {
496
+ const promptPaths = this.getPromptConfig<PromptPath[]>("promptPaths", []);
497
+
498
+ for (const pathConfig of promptPaths) {
499
+ try {
500
+ if (pathConfig.type === "file") {
501
+ await this.loadFromFile(pathConfig.path, pathConfig.name);
502
+ } else if (pathConfig.type === "directory") {
503
+ await this.loadFromDirectory(
504
+ pathConfig.path,
505
+ pathConfig.extension || ".md",
506
+ pathConfig.recursive !== false
507
+ );
508
+ }
509
+ } catch (error) {
510
+ logger.error(`[PromptComponent] Failed to load from ${pathConfig.path}:`, error);
511
+ }
512
+ }
513
+ }
514
+
515
+ /**
516
+ * 从文件加载单个 prompt
517
+ */
518
+ async loadFromFile(filePath: string, name?: string): Promise<boolean> {
519
+ try {
520
+ const content = await readFile(filePath, "utf-8");
521
+ const promptName = name || basename(filePath, extname(filePath));
522
+
523
+ this.add(promptName, content.trim(), "file");
524
+ const entry = this.prompts.get(promptName);
525
+ if (entry) entry.filePath = filePath;
526
+
527
+ logger.debug(`[PromptComponent] Loaded prompt from file: ${filePath}`);
528
+ return true;
529
+ } catch (error) {
530
+ logger.error(`[PromptComponent] Failed to load file ${filePath}:`, error);
531
+ return false;
532
+ }
533
+ }
534
+
535
+ /**
536
+ * 从目录加载多个 prompt
537
+ */
538
+ async loadFromDirectory(directory: string, extension: string = ".md", recursive: boolean = true): Promise<number> {
539
+ let loaded = 0;
540
+
541
+ try {
542
+ const files = await this.findFiles(directory, extension, recursive);
543
+
544
+ for (const filePath of files) {
545
+ const relativePath = filePath.replace(directory + "/", "");
546
+ const promptName = relativePath
547
+ .replace(/\\/g, "/")
548
+ .replace(new RegExp(escapeRegex(extension) + "$"), "")
549
+ .replace(/\//g, "-");
550
+
551
+ const content = await readFile(filePath, "utf-8");
552
+ this.add(promptName, content.trim(), "directory");
553
+
554
+ const entry = this.prompts.get(promptName);
555
+ if (entry) entry.filePath = filePath;
556
+
557
+ loaded++;
558
+ }
559
+
560
+ logger.info(`[PromptComponent] Loaded ${loaded} prompts from directory: ${directory}`);
561
+ } catch (error) {
562
+ logger.error(`[PromptComponent] Failed to load directory ${directory}:`, error);
563
+ }
564
+
565
+ return loaded;
566
+ }
567
+
568
+ private async findFiles(dir: string, extension: string, recursive: boolean): Promise<string[]> {
569
+ const files: string[] = [];
570
+
571
+ try {
572
+ const entries = await readdir(dir, { withFileTypes: true });
573
+
574
+ for (const entry of entries) {
575
+ const fullPath = join(dir, entry.name);
576
+
577
+ if (entry.isDirectory() && recursive) {
578
+ const subFiles = await this.findFiles(fullPath, extension, true);
579
+ files.push(...subFiles);
580
+ } else if (entry.isFile() && entry.name.endsWith(extension)) {
581
+ files.push(fullPath);
582
+ }
583
+ }
584
+ } catch (error) {
585
+ logger.warn(`[PromptComponent] Cannot read directory ${dir}:`, error);
586
+ }
587
+
588
+ return files;
589
+ }
590
+
591
+ // ============================================================================
592
+ // Hooks
593
+ // ============================================================================
594
+
595
+ /**
596
+ * 注册 Prompt Hook(公开便捷方法,供外部调用)
597
+ *
598
+ * 与 BaseComponent.registerHook 不同,这个方法接受 name + fn 参数
599
+ */
600
+ registerPromptHook(
601
+ hookPoint: string,
602
+ name: string,
603
+ fn: HookFn<unknown>,
604
+ priority?: number
605
+ ): void {
606
+ this.addHook(hookPoint, name, fn, priority);
607
+ }
608
+
609
+ /**
610
+ * 获取 Prompt Hook 点列表
611
+ */
612
+ getHookPoints(): string[] {
613
+ return [PromptHookPoints.BEFORE_RENDER, PromptHookPoints.AFTER_RENDER];
614
+ }
615
+ }
616
+
617
+ function escapeRegex(str: string): string {
618
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
619
+ }