@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,547 @@
1
+ /**
2
+ * @fileoverview Debug Component
3
+ *
4
+ * Provides debugging capabilities for roy-agent applications by parsing
5
+ * trace logs and presenting formatted output.
6
+ */
7
+
8
+ import { BaseComponent, type ComponentConfig } from '../component';
9
+ import { LogReader } from './reader/log-reader';
10
+ import { SpanDbReader } from './reader/span-db-reader';
11
+ import { RegexParser } from './parser/regex-parser';
12
+ import { SpanBuilder } from './parser/span-builder';
13
+ import { TraceFormatter, TreeFormatter } from './formatters';
14
+ import type {
15
+ ParserOptions,
16
+ TraceEntry,
17
+ TraceTreeNode,
18
+ TraceIdInfo,
19
+ TraceSummary,
20
+ FormatOptions
21
+ } from './types';
22
+
23
+ /**
24
+ * Data source type for trace retrieval
25
+ */
26
+ export type TraceDataSource = 'log' | 'sqlite';
27
+
28
+ /**
29
+ * Extended parser options with data source support
30
+ */
31
+ export interface TraceParserOptions extends ParserOptions {
32
+ /** Data source type: 'log' (default) or 'sqlite' */
33
+ source?: TraceDataSource;
34
+ /** SQLite database path (required when source is 'sqlite') */
35
+ dbPath?: string;
36
+ }
37
+
38
+ /**
39
+ * DebugComponent configuration options
40
+ */
41
+ export interface DebugComponentOptions {
42
+ /** Log directory path */
43
+ logDir?: string;
44
+ /** Default log file */
45
+ defaultLogFile?: string;
46
+ }
47
+
48
+ /**
49
+ * Debug Component for trace analysis and debugging
50
+ */
51
+ export class DebugComponent extends BaseComponent {
52
+ name = 'debug';
53
+ version = '1.0.0';
54
+
55
+ private reader: LogReader;
56
+ private spanDbReader: SpanDbReader | null = null;
57
+ private parser: RegexParser;
58
+ private spanBuilder: SpanBuilder;
59
+ private traceFormatter: TraceFormatter;
60
+ private treeFormatter: TreeFormatter;
61
+ private options: DebugComponentOptions;
62
+
63
+ constructor(options?: DebugComponentOptions) {
64
+ super();
65
+ this.options = options || {};
66
+ this.reader = new LogReader({ logDir: this.options.logDir });
67
+ this.parser = new RegexParser();
68
+ this.spanBuilder = new SpanBuilder();
69
+ this.traceFormatter = new TraceFormatter();
70
+ this.treeFormatter = new TreeFormatter();
71
+ }
72
+
73
+ /**
74
+ * Initialize the span database reader
75
+ */
76
+ async initSpanDbReader(dbPath?: string): Promise<void> {
77
+ if (!this.spanDbReader) {
78
+ this.spanDbReader = new SpanDbReader({ dbPath });
79
+ await this.spanDbReader.initialize();
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Get the span database reader
85
+ */
86
+ getSpanDbReader(): SpanDbReader | null {
87
+ return this.spanDbReader;
88
+ }
89
+
90
+ // =========================================================================
91
+ // Live Trace Methods (from Tracer storage)
92
+ // =========================================================================
93
+
94
+ /**
95
+ * Get trace by ID from live Tracer storage
96
+ *
97
+ * This method retrieves traces directly from the Tracer's span storage,
98
+ * which includes spans from the current session that may not yet be persisted
99
+ * to log files.
100
+ */
101
+ async getLiveTrace(traceId: string): Promise<any | null> {
102
+ try {
103
+ // Import OTel TracerProvider utilities dynamically to avoid circular dependencies
104
+ const { getTracerProvider } = await import('../log-trace/opentelemetry/tracer-provider');
105
+ const provider = getTracerProvider();
106
+
107
+ if (!provider.isInitialized()) {
108
+ await provider.initialize();
109
+ }
110
+
111
+ // Get storage directly from provider
112
+ const storage = provider.getStorage();
113
+
114
+ // Get all spans for this trace
115
+ const spans = storage.findByTraceId(traceId);
116
+
117
+ if (spans.length === 0) {
118
+ return null;
119
+ }
120
+
121
+ // Flatten spans for call tree building
122
+ const flattenSpans = (spanList: any[]): any[] => {
123
+ const result: any[] = [];
124
+ for (const span of spanList) {
125
+ result.push({
126
+ traceId: span.traceId,
127
+ spanId: span.spanId,
128
+ parentSpanId: span.parentSpanId,
129
+ function: span.name,
130
+ action: 'enter' as const,
131
+ timestamp: new Date(span.startTime).toISOString(),
132
+ params: Object.entries(span.attributes || {}).map(([k, v]: [string, any]) => ({ key: k, value: v })),
133
+ });
134
+ if (span.children && span.children.length > 0) {
135
+ result.push(...flattenSpans(span.children));
136
+ }
137
+ }
138
+ return result;
139
+ };
140
+
141
+ // Convert tree structure to flat entries for TraceEntry
142
+ const flatSpans = flattenSpans(spans);
143
+ const tree = this.spanBuilder.buildCallTree(flatSpans);
144
+
145
+ // Get root spans (spans without parentSpanId in original list)
146
+ const rootSpans = spans.filter((s: any) => !s.parentSpanId);
147
+
148
+ return {
149
+ traceId,
150
+ spans,
151
+ callTree: tree,
152
+ spanCount: flatSpans.length,
153
+ rootSpans,
154
+ };
155
+ } catch (error) {
156
+ console.error('Failed to get trace from live storage:', error);
157
+ return null;
158
+ }
159
+ }
160
+
161
+ /**
162
+ * List all available traces from live Tracer storage
163
+ */
164
+ async listLiveTraces(limit: number = 20): Promise<any> {
165
+ try {
166
+ // Import OTel TracerProvider utilities dynamically to avoid circular dependencies
167
+ const { getTracerProvider } = await import('../log-trace/opentelemetry/tracer-provider');
168
+ const provider = getTracerProvider();
169
+
170
+ if (!provider.isInitialized()) {
171
+ await provider.initialize();
172
+ }
173
+
174
+ // Get storage directly from provider
175
+ const storage = provider.getStorage();
176
+ const traces = storage.listTraces(limit);
177
+
178
+ return {
179
+ traces,
180
+ count: traces.length,
181
+ };
182
+ } catch (error) {
183
+ console.error('Failed to list live traces:', error);
184
+ return { traces: [], count: 0 };
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Format a live trace for display
190
+ */
191
+ async formatLiveTrace(traceId: string): Promise<string> {
192
+ try {
193
+ // Import OTel TracerProvider utilities dynamically to avoid circular dependencies
194
+ const { getTracerProvider } = await import('../log-trace/opentelemetry/tracer-provider');
195
+ const provider = getTracerProvider();
196
+
197
+ if (!provider.isInitialized()) {
198
+ await provider.initialize();
199
+ }
200
+
201
+ // Get storage directly from provider
202
+ const storage = provider.getStorage();
203
+ const spans = storage.findByTraceId(traceId);
204
+
205
+ if (spans.length === 0) {
206
+ return `No trace found for traceId: ${traceId}`;
207
+ }
208
+
209
+ // Flatten spans for formatting
210
+ const flattenSpans = (spanList: any[]): any[] => {
211
+ const result: any[] = [];
212
+ for (const span of spanList) {
213
+ result.push({
214
+ traceId: span.traceId,
215
+ spanId: span.spanId,
216
+ parentSpanId: span.parentSpanId,
217
+ function: span.name,
218
+ action: 'enter' as const,
219
+ timestamp: new Date(span.startTime).toISOString(),
220
+ params: Object.entries(span.attributes || {}).map(([k, v]: [string, any]) => ({ key: k, value: v })),
221
+ });
222
+ if (span.children && span.children.length > 0) {
223
+ result.push(...flattenSpans(span.children));
224
+ }
225
+ }
226
+ return result;
227
+ };
228
+
229
+ const flatSpans = flattenSpans(spans);
230
+ const tree = this.spanBuilder.buildCallTree(flatSpans);
231
+
232
+ // Handle null case (no valid tree structure)
233
+ if (!tree) {
234
+ return 'No trace structure found';
235
+ }
236
+
237
+ // Use treeFormatter to format the call tree
238
+ return this.treeFormatter.formatTree(tree);
239
+ } catch (error) {
240
+ return `Failed to format trace: ${error}`;
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Initialize the component
246
+ */
247
+ async init(config?: ComponentConfig): Promise<void> {
248
+ await super.init(config);
249
+ this.setStatus('running');
250
+ }
251
+
252
+ /**
253
+ * Stop the component
254
+ */
255
+ async stop(): Promise<void> {
256
+ this.setStatus('stopping');
257
+ // Cleanup if needed
258
+ this.setStatus('stopped');
259
+ }
260
+
261
+ /**
262
+ * Get traces matching the options
263
+ */
264
+ async getTraces(options?: TraceParserOptions): Promise<TraceEntry[]> {
265
+ // Use SQLite data source if specified
266
+ if (options?.source === 'sqlite') {
267
+ return this.getTracesFromSqlite(options);
268
+ }
269
+
270
+ // Default: use log file
271
+ const logFile = options?.logFile || this.reader.getLogPath();
272
+
273
+ // Read and filter log lines
274
+ const lines: string[] = [];
275
+ for await (const line of this.reader.readLines(logFile, options)) {
276
+ // Filter by function name if specified
277
+ if (options?.function && !line.includes(options.function)) {
278
+ continue;
279
+ }
280
+ // Filter by traceId if specified
281
+ if (options?.traceId && !line.includes(`requestId=${options.traceId}`)) {
282
+ continue;
283
+ }
284
+ // Only include trace lines
285
+ if (this.parser.isTraceLine(line)) {
286
+ lines.push(line);
287
+ }
288
+ }
289
+
290
+ // Parse lines
291
+ const parsedLines = this.parser.parseLines(lines);
292
+
293
+ // Build trace entries
294
+ const entries = this.spanBuilder.buildTraceEntries(parsedLines);
295
+
296
+ // Filter by function name at entry level
297
+ let filteredEntries = entries;
298
+ if (options?.function) {
299
+ filteredEntries = entries.filter(e =>
300
+ e.function.includes(options.function!)
301
+ );
302
+ }
303
+
304
+ // Pair enter/quit and calculate duration
305
+ const paired = this.spanBuilder.pairEnterQuit(filteredEntries);
306
+
307
+ // Build flat list with duration info
308
+ const result: TraceEntry[] = [];
309
+ for (const span of paired) {
310
+ result.push({
311
+ ...span.enter,
312
+ durationMs: span.durationMs,
313
+ });
314
+ if (span.quit) {
315
+ result.push({
316
+ ...span.quit,
317
+ durationMs: span.durationMs,
318
+ });
319
+ }
320
+ }
321
+
322
+ return result;
323
+ }
324
+
325
+ /**
326
+ * Get traces from SQLite database
327
+ */
328
+ private async getTracesFromSqlite(options?: TraceParserOptions): Promise<TraceEntry[]> {
329
+ if (!options?.traceId) {
330
+ return [];
331
+ }
332
+
333
+ await this.initSpanDbReader(options.dbPath);
334
+ const reader = this.getSpanDbReader();
335
+
336
+ if (!reader) {
337
+ throw new Error('Failed to initialize span database reader');
338
+ }
339
+
340
+ const entries = await reader.getTraceEntries(options.traceId);
341
+
342
+ // Filter by function name if specified
343
+ if (options?.function) {
344
+ return entries.filter(e => e.function.includes(options.function!));
345
+ }
346
+
347
+ return entries;
348
+ }
349
+
350
+ /**
351
+ * List available trace IDs
352
+ */
353
+ async listTraceIds(options?: TraceParserOptions & { limit?: number }): Promise<TraceSummary> {
354
+ // Use SQLite data source if specified
355
+ if (options?.source === 'sqlite') {
356
+ return this.listTraceIdsFromSqlite(options);
357
+ }
358
+
359
+ // Default: use log file
360
+ const logFile = options?.logFile || this.reader.getLogPath();
361
+ const limit = options?.limit || 20;
362
+
363
+ // Map to store trace info
364
+ const traceMap = new Map<string, { firstTime: string; lastTime: string; count: number }>();
365
+
366
+ // Read all trace lines
367
+ for await (const line of this.reader.readLines(logFile, options)) {
368
+ if (!this.parser.isTraceLine(line)) continue;
369
+
370
+ const parsed = this.parser.parseLogLine(line);
371
+ if (!parsed) continue;
372
+
373
+ // Extract traceId or generate virtual one
374
+ const traceId = this.parser.extractTraceId(line) ||
375
+ this.spanBuilder.generateVirtualTraceId(parsed.method, parsed.timestamp);
376
+
377
+ const existing = traceMap.get(traceId);
378
+ if (existing) {
379
+ existing.lastTime = parsed.timestamp;
380
+ existing.count++;
381
+ } else {
382
+ traceMap.set(traceId, {
383
+ firstTime: parsed.timestamp,
384
+ lastTime: parsed.timestamp,
385
+ count: 1,
386
+ });
387
+ }
388
+ }
389
+
390
+ // Convert to array and sort by first time (most recent first)
391
+ const traceIds: TraceIdInfo[] = [];
392
+ for (const [traceId, info] of traceMap.entries()) {
393
+ traceIds.push({
394
+ traceId,
395
+ firstTime: info.firstTime,
396
+ lastTime: info.lastTime,
397
+ count: info.count,
398
+ });
399
+ }
400
+
401
+ traceIds.sort((a, b) => b.firstTime.localeCompare(a.firstTime));
402
+
403
+ return {
404
+ traceIds: traceIds.slice(0, limit),
405
+ count: traceIds.length,
406
+ };
407
+ }
408
+
409
+ /**
410
+ * List trace IDs from SQLite database
411
+ */
412
+ private async listTraceIdsFromSqlite(options?: TraceParserOptions & { limit?: number }): Promise<TraceSummary> {
413
+ const limit = options?.limit || 20;
414
+
415
+ await this.initSpanDbReader(options?.dbPath);
416
+ const reader = this.getSpanDbReader();
417
+
418
+ if (!reader) {
419
+ throw new Error('Failed to initialize span database reader');
420
+ }
421
+
422
+ return reader.listTraceIds(limit);
423
+ }
424
+
425
+ /**
426
+ * Get call tree for a specific trace
427
+ */
428
+ async getCallTree(options?: TraceParserOptions): Promise<TraceTreeNode | null> {
429
+ if (!options?.traceId) {
430
+ return null;
431
+ }
432
+
433
+ // Get all traces for this traceId
434
+ const traces = await this.getTraces({
435
+ ...options,
436
+ traceId: options.traceId,
437
+ });
438
+
439
+ if (traces.length === 0) {
440
+ return null;
441
+ }
442
+
443
+ return this.spanBuilder.buildCallTree(traces);
444
+ }
445
+
446
+ /**
447
+ * Get the log reader instance
448
+ */
449
+ getReader(): LogReader {
450
+ return this.reader;
451
+ }
452
+
453
+ /**
454
+ * Get the parser instance
455
+ */
456
+ getParser(): RegexParser {
457
+ return this.parser;
458
+ }
459
+
460
+ /**
461
+ * Get the span builder instance
462
+ */
463
+ getSpanBuilder(): SpanBuilder {
464
+ return this.spanBuilder;
465
+ }
466
+
467
+ /**
468
+ * Get the trace formatter instance
469
+ */
470
+ getTraceFormatter(): TraceFormatter {
471
+ return this.traceFormatter;
472
+ }
473
+
474
+ /**
475
+ * Get the tree formatter instance
476
+ */
477
+ getTreeFormatter(): TreeFormatter {
478
+ return this.treeFormatter;
479
+ }
480
+
481
+ // =========================================================================
482
+ // Formatting Methods
483
+ // =========================================================================
484
+
485
+ /**
486
+ * Format traces for display
487
+ */
488
+ formatTraces(entries: TraceEntry[], options?: FormatOptions): string {
489
+ return this.traceFormatter.formatEntries(entries, options);
490
+ }
491
+
492
+ /**
493
+ * Format a single trace entry
494
+ */
495
+ formatTraceEntry(entry: TraceEntry, options?: FormatOptions): string {
496
+ return this.traceFormatter.formatEntry(entry, options);
497
+ }
498
+
499
+ /**
500
+ * Format traces as JSON
501
+ */
502
+ tracesToJSON(entries: TraceEntry[]): string {
503
+ return this.traceFormatter.toJSON(entries);
504
+ }
505
+
506
+ /**
507
+ * Format traces as summary
508
+ */
509
+ tracesToSummary(entries: TraceEntry[]): string {
510
+ return this.traceFormatter.toSummary(entries);
511
+ }
512
+
513
+ /**
514
+ * Format call tree for display
515
+ */
516
+ formatTree(node: TraceTreeNode): string {
517
+ return this.treeFormatter.formatTree(node);
518
+ }
519
+
520
+ /**
521
+ * Format multiple call trees
522
+ */
523
+ formatTrees(trees: TraceTreeNode[]): string {
524
+ return this.treeFormatter.formatTrees(trees);
525
+ }
526
+
527
+ /**
528
+ * Format trees as JSON
529
+ */
530
+ treesToJSON(trees: TraceTreeNode[]): string {
531
+ return this.treeFormatter.toJSON(trees);
532
+ }
533
+
534
+ /**
535
+ * Format tree summary (sorted by duration)
536
+ */
537
+ formatTreeSummary(node: TraceTreeNode): string {
538
+ return this.treeFormatter.formatSummary(node);
539
+ }
540
+
541
+ /**
542
+ * Format tree with timeline visualization
543
+ */
544
+ formatTreeTimeline(node: TraceTreeNode): string {
545
+ return this.treeFormatter.formatTimeline(node);
546
+ }
547
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @fileoverview Debug Formatters
3
+ *
4
+ * Export all formatters for trace and tree visualization
5
+ */
6
+
7
+ export { TraceFormatter } from './trace-formatter';
8
+ export { TreeFormatter } from './tree-formatter';
9
+ export { ReplFormatter } from './repl-formatter';
@@ -0,0 +1,139 @@
1
+ import { describe, test, expect, beforeEach, afterEach, mock } from 'bun:test';
2
+ import { ReplFormatter } from './repl-formatter';
3
+ import type { TraceEntry, TraceTreeNode } from '../types';
4
+
5
+ // Mock readline
6
+ const mockReadline = {
7
+ createInterface: mock(() => ({
8
+ on: mock(() => {}),
9
+ close: mock(() => {}),
10
+ })),
11
+ };
12
+
13
+ describe('ReplFormatter', () => {
14
+ let formatter: ReplFormatter;
15
+
16
+ beforeEach(() => {
17
+ formatter = new ReplFormatter();
18
+ });
19
+
20
+ test('should create ReplFormatter instance', () => {
21
+ expect(formatter).toBeDefined();
22
+ });
23
+
24
+ test('should have welcome message', () => {
25
+ const welcome = formatter.getWelcomeMessage();
26
+ expect(welcome).toContain('Debug REPL');
27
+ expect(welcome).toContain('Commands:');
28
+ });
29
+
30
+ test('should format prompt with context', () => {
31
+ const prompt = formatter.formatPrompt();
32
+ expect(prompt).toContain('debug');
33
+ });
34
+
35
+ test('should format prompt with trace context', () => {
36
+ const prompt = formatter.formatPrompt({ traceId: 'trace-001' });
37
+ expect(prompt).toContain('trace-001');
38
+ });
39
+
40
+ test('should format prompt with function context', () => {
41
+ const prompt = formatter.formatPrompt({ function: 'llm.invoke' });
42
+ expect(prompt).toContain('llm.invoke');
43
+ });
44
+
45
+ test('should return help text', () => {
46
+ const help = formatter.getHelpText();
47
+ expect(help).toContain('list');
48
+ expect(help).toContain('trace');
49
+ expect(help).toContain('tree');
50
+ expect(help).toContain('exit');
51
+ });
52
+
53
+ test('should format command result - list', () => {
54
+ const mockTraces = [
55
+ { traceId: 'trace-001', firstTime: '2026-04-08T10:00:00', count: 2 },
56
+ { traceId: 'trace-002', firstTime: '2026-04-08T10:01:00', count: 1 },
57
+ ];
58
+
59
+ const result = formatter.formatCommandResult('list', { traceIds: mockTraces, count: 2 });
60
+ expect(result).toContain('trace-001');
61
+ expect(result).toContain('trace-002');
62
+ });
63
+
64
+ test('should format command result - trace', () => {
65
+ const mockEntries: TraceEntry[] = [
66
+ {
67
+ traceId: 'trace-001',
68
+ timestamp: '2026-04-08T10:00:00',
69
+ function: 'llm.invoke',
70
+ action: 'enter',
71
+ params: [{ msg: 'hello' }],
72
+ },
73
+ {
74
+ traceId: 'trace-001',
75
+ timestamp: '2026-04-08T10:00:01',
76
+ function: 'llm.invoke',
77
+ action: 'quit',
78
+ result: { content: 'hi' },
79
+ durationMs: 1000,
80
+ },
81
+ ];
82
+
83
+ const result = formatter.formatCommandResult('trace', mockEntries);
84
+ expect(result).toContain('>>>');
85
+ expect(result).toContain('<<<');
86
+ expect(result).toContain('llm.invoke');
87
+ });
88
+
89
+ test('should format command result - tree', () => {
90
+ const mockTree: TraceTreeNode = {
91
+ traceId: 'trace-001',
92
+ function: 'root',
93
+ startTime: '2026-04-08T10:00:00',
94
+ children: [
95
+ {
96
+ traceId: 'trace-001',
97
+ function: 'child1',
98
+ startTime: '2026-04-08T10:00:01',
99
+ children: [],
100
+ entry: {} as TraceEntry,
101
+ },
102
+ ],
103
+ entry: {} as TraceEntry,
104
+ };
105
+
106
+ const result = formatter.formatCommandResult('tree', [mockTree]);
107
+ expect(result).toContain('root');
108
+ expect(result).toContain('child1');
109
+ });
110
+
111
+ test('should handle empty results', () => {
112
+ const result = formatter.formatCommandResult('trace', []);
113
+ expect(result).toContain('No');
114
+ expect(result).toContain('trace');
115
+ });
116
+
117
+ test('should handle unknown command', () => {
118
+ const result = formatter.formatCommandResult('unknown', {});
119
+ expect(result).toContain('Unknown');
120
+ });
121
+
122
+ test('should parse simple commands', () => {
123
+ expect(formatter.parseCommand('list')).toEqual({ command: 'list', args: {} });
124
+ expect(formatter.parseCommand('list 5')).toEqual({ command: 'list', args: { limit: '5' } });
125
+ expect(formatter.parseCommand('trace --func llm')).toEqual({ command: 'trace', args: { func: 'llm' } });
126
+ expect(formatter.parseCommand('trace -f llm')).toEqual({ command: 'trace', args: { f: 'llm' } });
127
+ });
128
+
129
+ test('should return unknown for invalid command', () => {
130
+ const result = formatter.parseCommand('invalid command');
131
+ expect(result.command).toBe('invalid');
132
+ });
133
+
134
+ test('should handle exit command', () => {
135
+ expect(formatter.parseCommand('exit')).toEqual({ command: 'exit', args: {} });
136
+ expect(formatter.parseCommand('quit')).toEqual({ command: 'exit', args: {} });
137
+ expect(formatter.parseCommand('q')).toEqual({ command: 'exit', args: {} });
138
+ });
139
+ });