@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,502 @@
1
+ /**
2
+ * @fileoverview Memory Session Store
3
+ *
4
+ * In-memory implementation of SessionStore with checkpoint support
5
+ */
6
+
7
+ import type {
8
+ Session,
9
+ CreateSessionOptions,
10
+ UpdateSessionOptions,
11
+ ListSessionsOptions,
12
+ SessionMessage,
13
+ SessionCheckpoint,
14
+ GetMessagesOptions,
15
+ SessionCheckpointsMeta,
16
+ SearchMessagesOptions,
17
+ MessageMatch,
18
+ } from "../types";
19
+ import type { SessionStore } from "../session-store";
20
+ import { SessionMessageConverter } from "../session-message-converter";
21
+ import { randomUUID } from "crypto";
22
+
23
+ /**
24
+ * Generate a unique session ID using crypto UUID
25
+ */
26
+ function generateSessionId(): string {
27
+ return `session_${randomUUID()}`;
28
+ }
29
+
30
+ /**
31
+ * Generate a unique message ID using crypto UUID
32
+ */
33
+ function generateMessageId(): string {
34
+ return `msg_${randomUUID()}`;
35
+ }
36
+
37
+ /**
38
+ * Memory-based Session Store with checkpoint support
39
+ */
40
+ export class MemorySessionStore implements SessionStore {
41
+ private sessions = new Map<string, Session>();
42
+ private messages = new Map<string, SessionMessage[]>();
43
+ private checkpoints = new Map<string, SessionCheckpoint[]>();
44
+ private messageConverter = new SessionMessageConverter();
45
+
46
+ // ========================================================================
47
+ // Session CRUD
48
+ // ========================================================================
49
+
50
+ async create(options: CreateSessionOptions): Promise<Session> {
51
+ const now = Date.now();
52
+ const session: Session = {
53
+ id: options.id ?? generateSessionId(), // Use custom ID if provided
54
+ title: options.title ?? "Session",
55
+ directory: options.directory ?? "/tmp",
56
+ parentID: options.parentID,
57
+ createdAt: now,
58
+ updatedAt: now,
59
+ messageCount: 0,
60
+ metadata: {
61
+ ...options.metadata,
62
+ messageCount: 0,
63
+ checkpoints: { checkpoints: [] },
64
+ },
65
+ };
66
+
67
+ // Check for duplicate ID
68
+ if (this.sessions.has(session.id)) {
69
+ throw new Error(`Session with ID '${session.id}' already exists`);
70
+ }
71
+
72
+ this.sessions.set(session.id, session);
73
+ this.messages.set(session.id, []);
74
+ this.checkpoints.set(session.id, []);
75
+
76
+ return session;
77
+ }
78
+
79
+ async get(id: string): Promise<Session | undefined> {
80
+ return this.sessions.get(id);
81
+ }
82
+
83
+ async list(options?: ListSessionsOptions): Promise<Session[]> {
84
+ let sessions = Array.from(this.sessions.values());
85
+
86
+ // Filter by metadata
87
+ if (options?.filter?.metadata) {
88
+ sessions = sessions.filter((s) => {
89
+ for (const [key, value] of Object.entries(options.filter!.metadata!)) {
90
+ if (s.metadata?.[key] !== value) return false;
91
+ }
92
+ return true;
93
+ });
94
+ }
95
+
96
+ // Filter by time range
97
+ if (options?.filter?.startTime) {
98
+ sessions = sessions.filter((s) => s.createdAt >= options.filter!.startTime!);
99
+ }
100
+ if (options?.filter?.endTime) {
101
+ sessions = sessions.filter((s) => s.createdAt <= options.filter!.endTime!);
102
+ }
103
+
104
+ // Sort
105
+ const sortField = options?.sort?.field ?? "updatedAt";
106
+ const sortOrder = options?.sort?.order ?? "desc";
107
+ sessions.sort((a, b) => {
108
+ let aVal: number | string;
109
+ let bVal: number | string;
110
+
111
+ if (sortField === "title") {
112
+ aVal = a.title;
113
+ bVal = b.title;
114
+ } else if (sortField === "createdAt") {
115
+ aVal = a.createdAt;
116
+ bVal = b.createdAt;
117
+ } else {
118
+ aVal = a.updatedAt;
119
+ bVal = b.updatedAt;
120
+ }
121
+
122
+ if (aVal < bVal) return sortOrder === "asc" ? -1 : 1;
123
+ if (aVal > bVal) return sortOrder === "asc" ? 1 : -1;
124
+ return 0;
125
+ });
126
+
127
+ // Paginate
128
+ const offset = options?.offset ?? 0;
129
+ const limit = options?.limit ?? 100;
130
+ return sessions.slice(offset, offset + limit);
131
+ }
132
+
133
+ async update(id: string, updates: UpdateSessionOptions): Promise<boolean> {
134
+ const session = this.sessions.get(id);
135
+ if (!session) return false;
136
+
137
+ if (updates.title !== undefined) {
138
+ session.title = updates.title;
139
+ }
140
+ if (updates.metadata !== undefined) {
141
+ session.metadata = { ...session.metadata, ...updates.metadata };
142
+ }
143
+ session.updatedAt = Date.now();
144
+
145
+ return true;
146
+ }
147
+
148
+ async delete(id: string): Promise<boolean> {
149
+ const deleted = this.sessions.delete(id);
150
+ if (deleted) {
151
+ this.messages.delete(id);
152
+ this.checkpoints.delete(id);
153
+ }
154
+ return deleted;
155
+ }
156
+
157
+ async getCount(): Promise<number> {
158
+ return this.sessions.size;
159
+ }
160
+
161
+ // ========================================================================
162
+ // Messages
163
+ // ========================================================================
164
+
165
+ async addMessage(
166
+ sessionId: string,
167
+ message: { role: string; content: string; parts?: unknown[]; metadata?: Record<string, unknown> }
168
+ ): Promise<string> {
169
+ const session = this.sessions.get(sessionId);
170
+ if (!session) {
171
+ throw new Error(`Session not found: ${sessionId}`);
172
+ }
173
+
174
+ // Create raw message
175
+ const rawMessage: Partial<SessionMessage> = {
176
+ sessionID: sessionId,
177
+ role: message.role as SessionMessage["role"],
178
+ content: message.content,
179
+ parts: message.parts as SessionMessage["parts"],
180
+ metadata: message.metadata as SessionMessage["metadata"],
181
+ };
182
+
183
+ // Apply migration to ensure new format (backward compatibility)
184
+ const msg = this.messageConverter.migrateMessage(rawMessage);
185
+ msg.id = generateMessageId();
186
+ msg.timestamp = Date.now();
187
+
188
+ const sessionMessages = this.messages.get(sessionId) ?? [];
189
+ sessionMessages.push(msg);
190
+ this.messages.set(sessionId, sessionMessages);
191
+
192
+ // Update message count (non-archived only)
193
+ session.messageCount = sessionMessages.filter((m) => !m.isArchived).length;
194
+
195
+ // Update metadata with messageCount
196
+ session.metadata = {
197
+ ...session.metadata,
198
+ messageCount: session.messageCount
199
+ };
200
+
201
+ session.updatedAt = Date.now();
202
+
203
+ return msg.id;
204
+ }
205
+
206
+ async getMessages(
207
+ sessionId: string,
208
+ offset = 0,
209
+ limit = 50,
210
+ options?: GetMessagesOptions
211
+ ): Promise<SessionMessage[]> {
212
+ let messages = this.messages.get(sessionId) ?? [];
213
+
214
+ // Handle archived messages
215
+ if (!options?.includeArchived) {
216
+ messages = messages.filter((m) => !m.isArchived);
217
+ }
218
+
219
+ // Handle fromCheckpointId
220
+ if (options?.fromCheckpointId) {
221
+ const checkpoint = await this.getCheckpoint(sessionId, options.fromCheckpointId);
222
+ if (checkpoint) {
223
+ const checkpointIndex = messages.findIndex(
224
+ (m) => m.metadata?.checkpointId === options.fromCheckpointId
225
+ );
226
+ if (checkpointIndex >= 0) {
227
+ messages = messages.slice(checkpointIndex);
228
+ }
229
+ }
230
+ }
231
+
232
+ // Handle negative offset: count total messages first, then calculate actual offset
233
+ // offset = -1, limit = 50: latest 50 messages → offset = total - limit
234
+ // offset = -2, limit = 50: 2nd latest 50 messages → offset = total - 2*limit
235
+ let actualOffset = offset;
236
+ if (offset < 0) {
237
+ const total = messages.length;
238
+ actualOffset = Math.max(0, total + offset * limit);
239
+ }
240
+
241
+ // Handle reverse
242
+ if (options?.reverse) {
243
+ messages = messages.reverse();
244
+ }
245
+
246
+ return messages.slice(actualOffset, actualOffset + limit);
247
+ }
248
+
249
+ async getMessageCount(sessionId: string, includeArchived = false): Promise<number> {
250
+ const messages = this.messages.get(sessionId) ?? [];
251
+ if (includeArchived) {
252
+ return messages.length;
253
+ }
254
+ return messages.filter((m) => !m.isArchived).length;
255
+ }
256
+
257
+ async getMessageIndexes(sessionId: string, role: string): Promise<number[]> {
258
+ const messages = this.messages.get(sessionId) ?? [];
259
+ const indexes: number[] = [];
260
+
261
+ // Return index based on timestamp ASC order (same as getMessages default)
262
+ messages
263
+ .filter(m => !m.isArchived)
264
+ .forEach((msg, filteredIdx) => {
265
+ if (msg.role === role) {
266
+ indexes.push(filteredIdx);
267
+ }
268
+ });
269
+
270
+ return indexes;
271
+ }
272
+
273
+ // ========================================================================
274
+ // Checkpoint Management
275
+ // ========================================================================
276
+
277
+ async saveCheckpoint(sessionId: string, checkpoint: SessionCheckpoint): Promise<void> {
278
+ const session = this.sessions.get(sessionId);
279
+ if (!session) {
280
+ throw new Error(`Session not found: ${sessionId}`);
281
+ }
282
+
283
+ // Save to checkpoints map
284
+ const cps = this.checkpoints.get(sessionId) ?? [];
285
+ cps.push(checkpoint);
286
+ this.checkpoints.set(sessionId, cps);
287
+
288
+ // Update session metadata
289
+ const meta = session.metadata as Record<string, unknown> || {};
290
+ const checkpointsMeta: SessionCheckpointsMeta = (meta.checkpoints as SessionCheckpointsMeta) || { checkpoints: [] };
291
+ checkpointsMeta.checkpoints.push({
292
+ id: checkpoint.id,
293
+ messageIndex: checkpoint.messageIndex,
294
+ title: checkpoint.title,
295
+ createdAt: checkpoint.createdAt,
296
+ type: checkpoint.type,
297
+ });
298
+ checkpointsMeta.latestCheckpointId = checkpoint.id;
299
+
300
+ meta.checkpoints = checkpointsMeta;
301
+
302
+ // Store checkpoint details separately
303
+ if (!meta.checkpointDetails) {
304
+ meta.checkpointDetails = {};
305
+ }
306
+ (meta.checkpointDetails as Record<string, SessionCheckpoint>)[checkpoint.id] = checkpoint;
307
+
308
+ session.metadata = meta as Session["metadata"];
309
+ session.updatedAt = Date.now();
310
+ }
311
+
312
+ async getCheckpoints(sessionId: string): Promise<SessionCheckpoint[]> {
313
+ return this.checkpoints.get(sessionId) ?? [];
314
+ }
315
+
316
+ async getCheckpoint(sessionId: string, checkpointId: string): Promise<SessionCheckpoint | undefined> {
317
+ const cps = this.checkpoints.get(sessionId) ?? [];
318
+ return cps.find((cp) => cp.id === checkpointId);
319
+ }
320
+
321
+ async deleteCheckpoint(sessionId: string, checkpointId: string): Promise<boolean> {
322
+ const session = this.sessions.get(sessionId);
323
+ if (!session) return false;
324
+
325
+ const cps = this.checkpoints.get(sessionId) ?? [];
326
+ const index = cps.findIndex((cp) => cp.id === checkpointId);
327
+ if (index === -1) return false;
328
+
329
+ // Remove checkpoint
330
+ cps.splice(index, 1);
331
+ this.checkpoints.set(sessionId, cps);
332
+
333
+ // Restore archived messages
334
+ const messages = this.messages.get(sessionId) ?? [];
335
+ for (const msg of messages) {
336
+ if (msg.checkpointId === checkpointId) {
337
+ msg.isArchived = false;
338
+ msg.archivedAt = undefined;
339
+ msg.checkpointId = undefined;
340
+ }
341
+ }
342
+
343
+ // Update session metadata
344
+ const meta = session.metadata as Record<string, unknown> || {};
345
+ const checkpointsMeta: SessionCheckpointsMeta = (meta.checkpoints as SessionCheckpointsMeta) || { checkpoints: [] };
346
+ checkpointsMeta.checkpoints = checkpointsMeta.checkpoints.filter((cp) => cp.id !== checkpointId);
347
+ checkpointsMeta.latestCheckpointId = cps[cps.length - 1]?.id;
348
+
349
+ if (meta.checkpointDetails) {
350
+ delete (meta.checkpointDetails as Record<string, SessionCheckpoint>)[checkpointId];
351
+ }
352
+
353
+ session.metadata = meta as Session["metadata"];
354
+ session.messageCount = messages.filter((m) => !m.isArchived).length;
355
+ session.updatedAt = Date.now();
356
+
357
+ return true;
358
+ }
359
+
360
+ async archiveMessages(sessionId: string, checkpointId: string, beforeIndex: number): Promise<number> {
361
+ const session = this.sessions.get(sessionId);
362
+ if (!session) return 0;
363
+
364
+ const messages = this.messages.get(sessionId) ?? [];
365
+ let archivedCount = 0;
366
+
367
+ for (let i = 0; i < beforeIndex; i++) {
368
+ if (!messages[i].isArchived) {
369
+ messages[i].isArchived = true;
370
+ messages[i].archivedAt = Date.now();
371
+ messages[i].checkpointId = checkpointId;
372
+ archivedCount++;
373
+ }
374
+ }
375
+
376
+ // Update session message count (non-archived only)
377
+ session.messageCount = messages.filter((m) => !m.isArchived).length;
378
+ session.updatedAt = Date.now();
379
+
380
+ return archivedCount;
381
+ }
382
+
383
+ async getActiveMessages(sessionId: string, offset = 0, limit = 50): Promise<SessionMessage[]> {
384
+ const messages = this.messages.get(sessionId) ?? [];
385
+ const activeMessages = messages.filter((m) => !m.isArchived);
386
+ return activeMessages.slice(offset, offset + limit);
387
+ }
388
+
389
+ // ========================================================================
390
+ // Search [new]
391
+ // ========================================================================
392
+
393
+ async searchMessages(options: SearchMessagesOptions): Promise<MessageMatch[]> {
394
+ const matches: MessageMatch[] = [];
395
+ const {
396
+ query,
397
+ sessionId,
398
+ limit = 10,
399
+ beforeTime,
400
+ afterTime,
401
+ includeArchived = false,
402
+ } = options;
403
+
404
+ // Determine which sessions to search
405
+ let sessionsToSearch: Session[];
406
+ if (sessionId) {
407
+ const session = await this.get(sessionId);
408
+ sessionsToSearch = session ? [session] : [];
409
+ } else {
410
+ sessionsToSearch = Array.from(this.sessions.values());
411
+ }
412
+
413
+ // Parse query for simple text matching
414
+ const queryTerms = this.parseQuery(query);
415
+
416
+ // Search through each session's messages
417
+ for (const session of sessionsToSearch) {
418
+ // Time constraint on session
419
+ if (beforeTime && session.updatedAt > beforeTime) continue;
420
+ if (afterTime && session.updatedAt < afterTime) continue;
421
+
422
+ let messages = this.messages.get(session.id) ?? [];
423
+
424
+ // Filter archived messages if needed
425
+ if (!includeArchived) {
426
+ messages = messages.filter((m) => !m.isArchived);
427
+ }
428
+
429
+ // Search through messages
430
+ for (const msg of messages) {
431
+ // Time constraint on message
432
+ if (beforeTime && msg.timestamp > beforeTime) continue;
433
+ if (afterTime && msg.timestamp < afterTime) continue;
434
+
435
+ // Simple text search
436
+ const content = msg.content.toLowerCase();
437
+ let matchesQuery = true;
438
+
439
+ for (const term of queryTerms.required) {
440
+ if (!content.includes(term.toLowerCase())) {
441
+ matchesQuery = false;
442
+ break;
443
+ }
444
+ }
445
+
446
+ for (const term of queryTerms.excluded) {
447
+ if (content.includes(term.toLowerCase())) {
448
+ matchesQuery = false;
449
+ break;
450
+ }
451
+ }
452
+
453
+ if (matchesQuery) {
454
+ matches.push({
455
+ messageId: msg.id,
456
+ sessionId: session.id,
457
+ role: msg.role,
458
+ content: msg.content,
459
+ timestamp: msg.timestamp,
460
+ });
461
+
462
+ if (matches.length >= limit) {
463
+ return matches;
464
+ }
465
+ }
466
+ }
467
+ }
468
+
469
+ return matches;
470
+ }
471
+
472
+ /**
473
+ * Parse simple query into terms
474
+ */
475
+ private parseQuery(query: string): { required: string[]; excluded: string[] } {
476
+ // Remove quoted phrases (simplified)
477
+ const terms = query.split(/\s+/).filter((t) => !t.startsWith('"') && !t.endsWith('"'));
478
+
479
+ const required: string[] = [];
480
+ const excluded: string[] = [];
481
+
482
+ for (const term of terms) {
483
+ if (term.startsWith("-") || term.startsWith("NOT ")) {
484
+ excluded.push(term.replace(/^-|^NOT /i, ""));
485
+ } else {
486
+ required.push(term);
487
+ }
488
+ }
489
+
490
+ return { required, excluded };
491
+ }
492
+
493
+ // ========================================================================
494
+ // Lifecycle
495
+ // ========================================================================
496
+
497
+ async close(): Promise<void> {
498
+ this.sessions.clear();
499
+ this.messages.clear();
500
+ this.checkpoints.clear();
501
+ }
502
+ }