@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,448 @@
1
+ /**
2
+ * @fileoverview Session Message Format E2E Tests
3
+ *
4
+ * End-to-end tests for the new Session message format with AI SDK v6 support.
5
+ * Tests the complete flow from adding messages to converting for LLM calls.
6
+ */
7
+
8
+ import { describe, test, expect, beforeEach, afterEach } from "bun:test";
9
+ import { SessionComponent } from "./session-component";
10
+ import { ConfigComponent } from "../../config/config-component";
11
+ import type { Environment } from "../interface";
12
+ import * as fsSync from "fs";
13
+ import * as path from "path";
14
+ import * as os from "os";
15
+ import { vi } from "bun:test";
16
+
17
+ // ============================================================================
18
+ // Test Setup
19
+ // ============================================================================
20
+
21
+ describe("Session Message Format E2E", () => {
22
+ let sessionComponent: SessionComponent;
23
+ let configComponent: ConfigComponent;
24
+ let mockEnv: Environment;
25
+ let tempDir: string;
26
+
27
+ beforeEach(async () => {
28
+ // Create temp directory for test
29
+ tempDir = path.join(os.tmpdir(), `session-e2e-test-${Date.now()}`);
30
+ fsSync.mkdirSync(tempDir, { recursive: true });
31
+
32
+ sessionComponent = new SessionComponent();
33
+ configComponent = new ConfigComponent();
34
+
35
+ mockEnv = {
36
+ name: "test-env",
37
+ version: "1.0.0",
38
+ getComponent: vi.fn((name: string) => {
39
+ if (name === "config") return configComponent;
40
+ return undefined;
41
+ }),
42
+ hasComponent: vi.fn((name: string) => name === "config"),
43
+ logger: vi.fn(),
44
+ trace: vi.fn(),
45
+ } as unknown as Environment;
46
+
47
+ await sessionComponent.init({
48
+ env: mockEnv,
49
+ options: {
50
+ configComponent,
51
+ config: {
52
+ defaultDirectory: tempDir,
53
+ maxMessages: 100,
54
+ autoCompact: false,
55
+ storage: { type: "memory" },
56
+ },
57
+ },
58
+ });
59
+ });
60
+
61
+ afterEach(async () => {
62
+ // Cleanup
63
+ if (fsSync.existsSync(tempDir)) {
64
+ fsSync.rmSync(tempDir, { recursive: true });
65
+ }
66
+ });
67
+
68
+ // ============================================================================
69
+ // E2E: User Message → Assistant with Reasoning → Tool Call → Tool Result
70
+ // ============================================================================
71
+
72
+ describe("Complete conversation flow with reasoning and tools", () => {
73
+ test("should handle a complete AI conversation with reasoning, tool calls, and results", async () => {
74
+ // First create a session
75
+ const session = await sessionComponent.create({ title: "Test Session" });
76
+
77
+ // Step 1: User sends a message
78
+ const userMsgId = await sessionComponent.addMessage(session.id, {
79
+ role: "user",
80
+ content: "帮我搜索代码中的 TODO 注释",
81
+ });
82
+
83
+ expect(userMsgId).toBeDefined();
84
+ expect(userMsgId).toMatch(/^msg_/);
85
+
86
+ // Step 2: Assistant responds with reasoning and tool call
87
+ const assistantMsgId = await sessionComponent.addMessage(session.id, {
88
+ role: "assistant",
89
+ content: "我来帮你搜索 TODO 注释",
90
+ parts: [
91
+ {
92
+ type: "reasoning",
93
+ content: "用户想要搜索代码中的 TODO 注释,我应该使用 grep 工具来搜索。",
94
+ reasoningType: "core",
95
+ state: "completed",
96
+ },
97
+ {
98
+ type: "text",
99
+ content: "我来帮你搜索 TODO 注释"
100
+ },
101
+ {
102
+ type: "tool-call",
103
+ toolCallId: "call_001",
104
+ toolName: "grep",
105
+ arguments: { pattern: "TODO", path: "/src" },
106
+ state: "pending",
107
+ },
108
+ ],
109
+ });
110
+
111
+ expect(assistantMsgId).toBeDefined();
112
+
113
+ // Step 3: Tool returns result
114
+ const toolResultMsgId = await sessionComponent.addMessage(session.id, {
115
+ role: "tool",
116
+ content: "找到 3 处 TODO:\n1. src/index.ts:15\n2. src/app.ts:42\n3. src/utils.ts:8",
117
+ parts: [
118
+ {
119
+ type: "tool-result",
120
+ toolCallId: "call_001",
121
+ toolName: "grep",
122
+ output: "找到 3 处 TODO:\n1. src/index.ts:15\n2. src/app.ts:42\n3. src/utils.ts:8",
123
+ state: "completed",
124
+ },
125
+ ],
126
+ });
127
+
128
+ expect(toolResultMsgId).toBeDefined();
129
+
130
+ // Step 4: Assistant gives final response
131
+ const finalMsgId = await sessionComponent.addMessage(session.id, {
132
+ role: "assistant",
133
+ content: "代码中发现 3 处 TODO 标记:\n1. src/index.ts:15\n2. src/app.ts:42\n3. src/utils.ts:8",
134
+ parts: [
135
+ { type: "text", content: "代码中发现 3 处 TODO 标记:" },
136
+ ],
137
+ });
138
+
139
+ expect(finalMsgId).toBeDefined();
140
+
141
+ // Verify all messages are stored correctly
142
+ const messages = await sessionComponent.getMessages(session.id);
143
+ expect(messages).toHaveLength(4);
144
+ expect(messages[0].role).toBe("user");
145
+ expect(messages[1].role).toBe("assistant");
146
+ expect(messages[1].parts![0].type).toBe("reasoning");
147
+ expect(messages[2].role).toBe("tool");
148
+ expect(messages[2].parts![0].type).toBe("tool-result");
149
+ expect(messages[3].role).toBe("assistant");
150
+ });
151
+
152
+ test("should convert messages to AI SDK history format", async () => {
153
+ // Import the converter
154
+ const { sessionToHistory } = await import("./session-message-converter");
155
+
156
+ // Create session
157
+ const session = await sessionComponent.create({ title: "History Test" });
158
+
159
+ // Add a conversation
160
+ await sessionComponent.addMessage(session.id, {
161
+ role: "user",
162
+ content: "Hello!",
163
+ });
164
+
165
+ await sessionComponent.addMessage(session.id, {
166
+ role: "assistant",
167
+ content: "Hi there!",
168
+ parts: [
169
+ { type: "reasoning", content: "User is greeting me", reasoningType: "core" },
170
+ { type: "text", content: "Hi there!" },
171
+ ],
172
+ });
173
+
174
+ await sessionComponent.addMessage(session.id, {
175
+ role: "assistant",
176
+ content: "Let me search...",
177
+ parts: [
178
+ { type: "text", content: "Let me search..." },
179
+ { type: "tool-call", toolCallId: "c1", toolName: "search", arguments: {}, state: "pending" },
180
+ ],
181
+ });
182
+
183
+ await sessionComponent.addMessage(session.id, {
184
+ role: "tool",
185
+ content: "Search results",
186
+ parts: [
187
+ { type: "tool-result", toolCallId: "c1", toolName: "search", output: "Results", state: "completed" },
188
+ ],
189
+ });
190
+
191
+ // Get messages and convert to history
192
+ const messages = await sessionComponent.getMessages(session.id);
193
+ const history = sessionToHistory(messages);
194
+
195
+ // Verify history format
196
+ expect(history).toHaveLength(4);
197
+
198
+ // User message
199
+ expect(history[0].role).toBe("user");
200
+ expect(history[0].content).toBe("Hello!");
201
+
202
+ // Assistant with reasoning
203
+ expect(history[1].role).toBe("assistant");
204
+ expect(Array.isArray(history[1].content)).toBe(true);
205
+ const content1 = history[1].content as any[];
206
+ expect(content1.some(c => c.type === "reasoning")).toBe(true);
207
+ expect(content1.some(c => c.type === "text")).toBe(true);
208
+
209
+ // Assistant with tool call
210
+ expect(history[2].role).toBe("assistant");
211
+ const content2 = history[2].content as any[];
212
+ expect(content2.some(c => c.type === "tool-call")).toBe(true);
213
+
214
+ // Tool result
215
+ expect(history[3].role).toBe("tool");
216
+ const content3 = history[3].content as any[];
217
+ expect(content3[0].type).toBe("tool-result");
218
+ });
219
+
220
+ test("should filter out archived messages when converting to history", async () => {
221
+ const { sessionToHistory } = await import("./session-message-converter");
222
+
223
+ const session = await sessionComponent.create({ title: "Archive Test" });
224
+
225
+ // Add messages
226
+ await sessionComponent.addMessage(session.id, {
227
+ role: "user",
228
+ content: "Message 1",
229
+ });
230
+
231
+ await sessionComponent.addMessage(session.id, {
232
+ role: "user",
233
+ content: "Message 2 (archived)",
234
+ });
235
+
236
+ await sessionComponent.addMessage(session.id, {
237
+ role: "user",
238
+ content: "Message 3",
239
+ });
240
+
241
+ // Get all messages
242
+ const messages = await sessionComponent.getMessages(session.id);
243
+ const history = sessionToHistory(messages);
244
+
245
+ // All non-archived messages should be in history
246
+ expect(history.length).toBe(3);
247
+ });
248
+ });
249
+
250
+ // ============================================================================
251
+ // E2E: File Attachment
252
+ // ============================================================================
253
+
254
+ describe("File attachment handling", () => {
255
+ test("should handle messages with file attachments", async () => {
256
+ const session = await sessionComponent.create({ title: "File Test" });
257
+
258
+ const msgId = await sessionComponent.addMessage(session.id, {
259
+ role: "user",
260
+ content: "Here's a screenshot",
261
+ parts: [
262
+ {
263
+ type: "file",
264
+ mime: "image/png",
265
+ url: "file:///tmp/screenshot.png",
266
+ filename: "screenshot.png",
267
+ },
268
+ ],
269
+ });
270
+
271
+ expect(msgId).toBeDefined();
272
+
273
+ // Retrieve and verify
274
+ const messages = await sessionComponent.getMessages(session.id);
275
+ expect(messages).toHaveLength(1);
276
+ expect(messages[0].parts![0].type).toBe("file");
277
+ expect((messages[0].parts![0] as any).mime).toBe("image/png");
278
+ expect((messages[0].parts![0] as any).filename).toBe("screenshot.png");
279
+ });
280
+ });
281
+
282
+ // ============================================================================
283
+ // E2E: Checkpoint with new format
284
+ // ============================================================================
285
+
286
+ describe("Checkpoint with new message format", () => {
287
+ test("should store messages with checkpoint metadata", async () => {
288
+ const session = await sessionComponent.create({ title: "Checkpoint Test" });
289
+
290
+ // Add messages with new format
291
+ await sessionComponent.addMessage(session.id, {
292
+ role: "user",
293
+ content: "Let's do something complex",
294
+ });
295
+
296
+ await sessionComponent.addMessage(session.id, {
297
+ role: "assistant",
298
+ content: "I'll analyze this",
299
+ parts: [
300
+ { type: "reasoning", content: "Analyzing...", reasoningType: "core" },
301
+ { type: "text", content: "I'll analyze this" },
302
+ ],
303
+ });
304
+
305
+ // Get messages - they should preserve the new format
306
+ const messages = await sessionComponent.getMessages(session.id);
307
+
308
+ expect(messages).toHaveLength(2);
309
+ expect(messages[1].parts).toHaveLength(2);
310
+ expect(messages[1].parts![0].type).toBe("reasoning");
311
+ expect(messages[1].parts![1].type).toBe("text");
312
+ });
313
+ });
314
+
315
+ // ============================================================================
316
+ // E2E: Provider Options Extraction
317
+ // ============================================================================
318
+
319
+ describe("Provider options for different models", () => {
320
+ test("should extract OpenAI thinking options", async () => {
321
+ const { extractProviderOptions } = await import("./session-message-converter");
322
+
323
+ const message = {
324
+ id: "msg_test",
325
+ sessionID: "session_test",
326
+ role: "assistant" as const,
327
+ content: "Thinking...",
328
+ timestamp: Date.now(),
329
+ parts: [
330
+ {
331
+ type: "reasoning",
332
+ content: "Deep analysis...",
333
+ reasoningType: "core" as const,
334
+ state: "completed" as const,
335
+ },
336
+ ],
337
+ };
338
+
339
+ const options = extractProviderOptions(message);
340
+
341
+ expect(options).toHaveProperty("openai");
342
+ expect((options as any).openai).toHaveProperty("thinking");
343
+ });
344
+
345
+ test("should extract Anthropic extended thinking options", async () => {
346
+ const { extractProviderOptions } = await import("./session-message-converter");
347
+
348
+ const message = {
349
+ id: "msg_test",
350
+ sessionID: "session_test",
351
+ role: "assistant" as const,
352
+ content: "Extended thinking...",
353
+ timestamp: Date.now(),
354
+ parts: [
355
+ {
356
+ type: "reasoning",
357
+ content: "Extended analysis with more detail...",
358
+ reasoningType: "effort" as const,
359
+ state: "completed" as const,
360
+ },
361
+ ],
362
+ };
363
+
364
+ const options = extractProviderOptions(message);
365
+
366
+ expect(options).toHaveProperty("anthropic");
367
+ expect((options as any).anthropic).toHaveProperty("thinking");
368
+ });
369
+ });
370
+
371
+ // ============================================================================
372
+ // E2E: Backward Compatibility
373
+ // ============================================================================
374
+
375
+ describe("Backward compatibility with old message format", () => {
376
+ test("should handle old format messages without parts", async () => {
377
+ const session = await sessionComponent.create({ title: "Legacy Test" });
378
+
379
+ // Old format: message with just content, no parts
380
+ // Note: addMessage always wraps content in parts now
381
+ const msgId = await sessionComponent.addMessage(session.id, {
382
+ role: "user",
383
+ content: "Old style message",
384
+ });
385
+
386
+ expect(msgId).toBeDefined();
387
+
388
+ // Get the message to verify
389
+ const messages = await sessionComponent.getMessages(session.id);
390
+ expect(messages).toHaveLength(1);
391
+
392
+ const msg = messages[0];
393
+ expect(msg.content).toBe("Old style message");
394
+
395
+ // Verify parts are created (migrated from old format)
396
+ expect(msg.parts).toBeDefined();
397
+ expect(msg.parts).toHaveLength(1);
398
+ expect(msg.parts![0].type).toBe("text");
399
+ expect((msg.parts![0] as any).content).toBe("Old style message");
400
+ });
401
+
402
+ test("should convert old messages when reading from storage", async () => {
403
+ // This tests the migration path - simulate reading old format
404
+ const { migrateMessage } = await import("./session-message-converter");
405
+
406
+ // Old format from storage
407
+ const oldStoredMsg = {
408
+ id: "msg_legacy",
409
+ sessionID: "session_test",
410
+ role: "user" as const,
411
+ content: "This was stored in old format",
412
+ timestamp: Date.now(),
413
+ };
414
+
415
+ // Migrate
416
+ const migrated = migrateMessage(oldStoredMsg);
417
+
418
+ expect(migrated.content).toBe("This was stored in old format");
419
+ expect(migrated.parts).toBeDefined();
420
+ expect(migrated.parts).toHaveLength(1);
421
+ expect(migrated.parts![0].type).toBe("text");
422
+ });
423
+
424
+ test("should preserve new format when already correct", async () => {
425
+ const { migrateMessage } = await import("./session-message-converter");
426
+
427
+ // Already new format
428
+ const newFormatMsg = {
429
+ id: "msg_new",
430
+ sessionID: "session_test",
431
+ role: "assistant" as const,
432
+ content: "New format message",
433
+ timestamp: Date.now(),
434
+ parts: [
435
+ { type: "reasoning", content: "Thinking...", reasoningType: "core" as const },
436
+ { type: "text", content: "New format message" },
437
+ ],
438
+ };
439
+
440
+ // Migrate (should be no-op)
441
+ const migrated = migrateMessage(newFormatMsg);
442
+
443
+ expect(migrated.parts).toHaveLength(2);
444
+ expect(migrated.parts![0].type).toBe("reasoning");
445
+ expect(migrated.parts![1].type).toBe("text");
446
+ });
447
+ });
448
+ });