@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,415 @@
1
+ /**
2
+ * @fileoverview Session Message Converter
3
+ *
4
+ * Converts between SessionMessage (storage format) and AI SDK ModelMessage (LLM format).
5
+ *
6
+ * This module provides a class-based API for message conversion.
7
+ */
8
+
9
+ import { randomUUID } from "crypto";
10
+ import type { SessionMessage, TextPart, ToolCallPart, ToolResultPart, ReasoningPart, FilePart, SessionPart, MessagePart } from "./types";
11
+ import { TracedAs } from "../log-trace/decorator";
12
+
13
+ // ============================================================================
14
+ // Constants
15
+ // ============================================================================
16
+
17
+ /**
18
+ * Default budget tokens for extended reasoning (Anthropic-style)
19
+ */
20
+ const DEFAULT_REASONING_BUDGET_TOKENS = 10000;
21
+
22
+ // AI SDK ModelMessage type (simplified for this module)
23
+ interface ModelMessage {
24
+ role: "user" | "assistant" | "system" | "tool";
25
+ content: string | ModelContentPart[];
26
+ }
27
+
28
+ /**
29
+ * Content part for AI SDK ModelMessage
30
+ */
31
+ type ModelContentPart =
32
+ | TextContentPart
33
+ | ReasoningContentPart
34
+ | ToolCallContentPart
35
+ | ToolResultContentPart
36
+ | FileContentPart;
37
+
38
+ interface TextContentPart {
39
+ type: "text";
40
+ text: string;
41
+ synthetic?: boolean;
42
+ }
43
+
44
+ interface ReasoningContentPart {
45
+ type: "reasoning";
46
+ text: string;
47
+ reasoningType?: "core" | "effort" | "summary";
48
+ }
49
+
50
+ interface ToolCallContentPart {
51
+ type: "tool-call";
52
+ toolCallId: string;
53
+ toolName: string;
54
+ input: Record<string, unknown>;
55
+ }
56
+
57
+ interface ToolResultContentPart {
58
+ type: "tool-result";
59
+ toolCallId: string;
60
+ toolName: string;
61
+ output: string;
62
+ }
63
+
64
+ interface FileContentPart {
65
+ type: "file";
66
+ url: string;
67
+ mimeType?: string;
68
+ filename?: string;
69
+ }
70
+
71
+ /**
72
+ * SessionMessageConverter
73
+ *
74
+ * Converts between SessionMessage (storage format) and AI SDK ModelMessage (LLM format).
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const converter = new SessionMessageConverter();
79
+ * const modelMsg = converter.toModelMessage(sessionMsg);
80
+ * const sessionMsg = converter.fromModelMessage(modelMsg);
81
+ * ```
82
+ */
83
+ export class SessionMessageConverter {
84
+ /**
85
+ * Convert a SessionMessage to AI SDK ModelMessage format
86
+ *
87
+ * @param msg - SessionMessage to convert
88
+ * @returns ModelMessage compatible with AI SDK v6
89
+ */
90
+ @TracedAs("session-message-converter.toModelMessage", { recordParams: true, recordResult: true, log: true })
91
+ toModelMessage(msg: SessionMessage): ModelMessage {
92
+ // ============ Assistant Message ============
93
+ if (msg.role === "assistant") {
94
+ const content: ModelContentPart[] = [];
95
+
96
+ // Process all parts in order to preserve their original order
97
+ for (const part of msg.parts || []) {
98
+ if (part.type === "text") {
99
+ const textPart = part as TextPart;
100
+ content.push({
101
+ type: "text",
102
+ text: textPart.content,
103
+ ...(textPart.synthetic !== undefined && { synthetic: textPart.synthetic }),
104
+ });
105
+ } else if (part.type === "reasoning") {
106
+ const reasoningPart = part as ReasoningPart;
107
+ content.push({
108
+ type: "reasoning",
109
+ text: reasoningPart.content,
110
+ reasoningType: reasoningPart.reasoningType,
111
+ });
112
+ } else if (part.type === "tool-call") {
113
+ const toolPart = part as unknown as ToolCallPart;
114
+ let parsedArgs: Record<string, unknown> = {};
115
+
116
+ // Safely parse JSON arguments with error handling
117
+ if (typeof toolPart.arguments === "string") {
118
+ try {
119
+ parsedArgs = JSON.parse(toolPart.arguments);
120
+ } catch {
121
+ // If JSON parse fails, try to use the string as-is
122
+ // This handles cases where arguments are not valid JSON
123
+ parsedArgs = { _raw: toolPart.arguments };
124
+ }
125
+ } else {
126
+ parsedArgs = toolPart.arguments;
127
+ }
128
+
129
+ content.push({
130
+ type: "tool-call",
131
+ toolCallId: toolPart.toolCallId,
132
+ toolName: toolPart.toolName,
133
+ input: parsedArgs,
134
+ });
135
+ } else if (part.type === "file") {
136
+ // File parts in assistant messages are converted to AI SDK file content
137
+ const filePart = part as unknown as FilePart;
138
+ content.push({
139
+ type: "file",
140
+ url: filePart.url,
141
+ mimeType: filePart.mime,
142
+ filename: filePart.filename,
143
+ });
144
+ }
145
+ // Note: tool-result and checkpoint parts are skipped for assistant messages
146
+ // - tool-result belongs to tool messages (handled below)
147
+ // - checkpoint is a storage/compression marker, not needed for LLM calls
148
+ else if (part.type === "tool-result" || part.type === "checkpoint") {
149
+ // These types are intentionally skipped for assistant messages
150
+ // Tool results belong to tool role messages, checkpoints are metadata
151
+ }
152
+ else {
153
+ // Log any other unknown part types for debugging
154
+ console.debug(`[session-message-converter] Skipping unsupported part type in assistant: ${(part as any).type}`);
155
+ }
156
+ }
157
+
158
+ // If no parts, fall back to content field
159
+ if (content.length === 0 && msg.content) {
160
+ return { role: "assistant", content: msg.content };
161
+ }
162
+
163
+ return { role: "assistant", content };
164
+ }
165
+
166
+ // ============ Tool Message ============
167
+ if (msg.role === "tool") {
168
+ const toolPart = msg.parts?.find(p => p.type === "tool-result") as ToolResultPart | undefined;
169
+ return {
170
+ role: "tool",
171
+ content: [{
172
+ type: "tool-result",
173
+ toolCallId: toolPart?.toolCallId || "",
174
+ toolName: toolPart?.toolName || "",
175
+ output: toolPart?.output || msg.content || "",
176
+ }],
177
+ };
178
+ }
179
+
180
+ // ============ User / System Message ============
181
+ return {
182
+ role: msg.role as "system" | "user" | "assistant" | "tool",
183
+ content: msg.content || "",
184
+ };
185
+ }
186
+
187
+ /**
188
+ * Convert an AI SDK ModelMessage to SessionMessage format
189
+ *
190
+ * @param aiMsg - AI SDK ModelMessage to convert (accepts any object with role and content)
191
+ * @param options - Optional sessionID and messageID
192
+ * @returns SessionMessage compatible with storage format
193
+ *
194
+ * 设置 metadata.type 以便后续正确过滤:
195
+ * - "tool_call": assistant 消息包含 tool-call parts
196
+ * - "tool_result": tool 消息
197
+ */
198
+ @TracedAs("session-message-converter.fromModelMessage", { recordParams: true, recordResult: true, log: true })
199
+ fromModelMessage(
200
+ aiMsg: { role: string; content: unknown; [key: string]: unknown },
201
+ options?: { sessionID?: string; messageID?: string }
202
+ ): SessionMessage {
203
+ const parts: SessionPart[] = [];
204
+ // Handle content that could be string, array, or other types
205
+ const content = typeof aiMsg.content === 'string' || Array.isArray(aiMsg.content)
206
+ ? aiMsg.content
207
+ : "";
208
+ let hasToolCallPart = false;
209
+ let hasToolResultPart = false;
210
+
211
+ if (typeof content === "string") {
212
+ parts.push({ type: "text", content });
213
+ } else if (Array.isArray(content)) {
214
+ for (const part of content) {
215
+ const p = part as unknown as Record<string, unknown>;
216
+
217
+ if (p.type === "text") {
218
+ parts.push({ type: "text", content: (p.text as string) || "" });
219
+ }
220
+ else if (p.type === "reasoning") {
221
+ parts.push({
222
+ type: "reasoning",
223
+ content: (p.text as string) || "",
224
+ reasoningType: p.reasoningType as "core" | "effort" | "summary" | undefined,
225
+ state: "completed",
226
+ } as SessionPart);
227
+ }
228
+ else if (p.type === "tool-call") {
229
+ hasToolCallPart = true;
230
+ parts.push({
231
+ type: "tool-call",
232
+ toolCallId: p.toolCallId as string,
233
+ toolName: p.toolName as string,
234
+ arguments: p.input as Record<string, unknown>,
235
+ state: "pending",
236
+ } as SessionPart);
237
+ }
238
+ else if (p.type === "tool-result") {
239
+ hasToolResultPart = true;
240
+ parts.push({
241
+ type: "tool-result",
242
+ toolCallId: p.toolCallId as string,
243
+ toolName: p.toolName as string,
244
+ output: typeof p.output === "string" ? p.output : JSON.stringify(p.output),
245
+ state: "completed",
246
+ } as SessionPart);
247
+ }
248
+ else if (p.type === "file") {
249
+ parts.push({
250
+ type: "file",
251
+ mime: (p.mimeType as string) || "application/octet-stream",
252
+ url: p.url as string,
253
+ filename: p.filename as string | undefined,
254
+ } as SessionPart);
255
+ }
256
+ else {
257
+ // Log unknown part type for debugging (Minor issue #4)
258
+ // Unknown types are skipped to maintain forward compatibility
259
+ console.debug(`[session-message-converter] Unknown part type: ${p.type}`);
260
+ }
261
+ }
262
+ }
263
+
264
+ // Determine metadata type based on role and content parts
265
+ let metadataType: "tool_call" | "tool_result" | undefined;
266
+ if (aiMsg.role === "assistant" && hasToolCallPart) {
267
+ metadataType = "tool_call";
268
+ } else if (aiMsg.role === "tool") {
269
+ metadataType = "tool_result";
270
+ }
271
+
272
+ // Build the result object
273
+ const result: SessionMessage = {
274
+ id: options?.messageID || `msg_${randomUUID()}`,
275
+ sessionID: options?.sessionID || "",
276
+ role: aiMsg.role as SessionMessage["role"],
277
+ timestamp: Date.now(),
278
+ parts,
279
+ content: typeof content === "string" ? content : "",
280
+ };
281
+
282
+ // Add metadata with type if applicable
283
+ if (metadataType) {
284
+ result.metadata = { type: metadataType };
285
+ }
286
+
287
+ return result;
288
+ }
289
+
290
+ /**
291
+ * Convert a list of SessionMessages to AI SDK history format
292
+ *
293
+ * @param messages - Array of SessionMessages to convert
294
+ * @returns Array of ModelMessages filtered by archived status
295
+ */
296
+ sessionToHistory(messages: SessionMessage[]): ModelMessage[] {
297
+ return messages
298
+ .filter(msg => !msg.metadata?.isArchived && !msg.isArchived)
299
+ .map(msg => this.toModelMessage(msg));
300
+ }
301
+
302
+ /**
303
+ * Extract provider-specific options from SessionMessage
304
+ *
305
+ * Some models (e.g., DeepSeek R1, Kimi k2.5) require reasoning configuration
306
+ * through providerOptions.
307
+ *
308
+ * @param msg - SessionMessage to extract options from
309
+ * @returns Provider-specific options object for LLM calls
310
+ */
311
+ extractProviderOptions(msg: SessionMessage): Record<string, unknown> {
312
+ const options: Record<string, unknown> = {};
313
+
314
+ // Check for reasoning parts that might need provider options
315
+ const reasoningParts = msg.parts?.filter(p => p.type === "reasoning") as ReasoningPart[] | undefined;
316
+
317
+ if (reasoningParts && reasoningParts.length > 0) {
318
+ // Extract reasoning type from the first reasoning part
319
+ const firstReasoning = reasoningParts[0];
320
+ if (firstReasoning.reasoningType) {
321
+ // OpenAI-compatible thinking options
322
+ options.openai = {
323
+ thinking: {
324
+ type: firstReasoning.reasoningType === "effort" ? "extended" : "core",
325
+ },
326
+ };
327
+
328
+ // Anthropic-style budget tokens (if effort type)
329
+ if (firstReasoning.reasoningType === "effort") {
330
+ // Get budget tokens from metadata or use default
331
+ const budgetTokens = (firstReasoning.metadata?.tokenCount as number) || DEFAULT_REASONING_BUDGET_TOKENS;
332
+
333
+ options.anthropic = {
334
+ thinking: {
335
+ type: "enabled",
336
+ budgetTokens,
337
+ },
338
+ };
339
+ }
340
+ }
341
+ }
342
+
343
+ return options;
344
+ }
345
+
346
+ /**
347
+ * Migrate old format message to new format
348
+ *
349
+ * Handles backward compatibility by converting old messages with just content
350
+ * to new format with proper parts array.
351
+ *
352
+ * @param oldMsg - Message in possibly old format
353
+ * @returns Message in new format with parts array
354
+ */
355
+ migrateMessage(oldMsg: Partial<SessionMessage>): SessionMessage {
356
+ // If already has parts with new format (parts have proper type field), return as is
357
+ if (oldMsg.parts && oldMsg.parts.length > 0) {
358
+ const firstPart = oldMsg.parts[0] as unknown as Record<string, unknown>;
359
+ // Check if it's new format by looking for type field
360
+ if (firstPart && typeof firstPart.type === "string" && firstPart.type.length > 0) {
361
+ return {
362
+ ...oldMsg,
363
+ content: oldMsg.content || "",
364
+ } as SessionMessage;
365
+ }
366
+ }
367
+
368
+ // Old format: content is plain text, need to wrap as text part
369
+ return {
370
+ ...oldMsg,
371
+ content: oldMsg.content || "",
372
+ parts: oldMsg.content ? [{ type: "text", content: oldMsg.content }] : [],
373
+ } as SessionMessage;
374
+ }
375
+ }
376
+
377
+ // ============================================================================
378
+ // Backward Compatibility - Deprecated exports
379
+ // ============================================================================
380
+ //
381
+ // These functions are kept for backward compatibility but will be removed in a future version.
382
+ // Please use SessionMessageConverter class instead.
383
+ //
384
+ // @deprecated Use SessionMessageConverter.toModelMessage() instead
385
+ export function toModelMessage(msg: SessionMessage): ModelMessage {
386
+ const converter = new SessionMessageConverter();
387
+ return converter.toModelMessage(msg);
388
+ }
389
+
390
+ // @deprecated Use SessionMessageConverter.fromModelMessage() instead
391
+ export function fromModelMessage(
392
+ aiMsg: { role: string; content: unknown; [key: string]: unknown },
393
+ options?: { sessionID?: string; messageID?: string }
394
+ ): SessionMessage {
395
+ const converter = new SessionMessageConverter();
396
+ return converter.fromModelMessage(aiMsg, options);
397
+ }
398
+
399
+ // @deprecated Use SessionMessageConverter.sessionToHistory() instead
400
+ export function sessionToHistory(messages: SessionMessage[]): ModelMessage[] {
401
+ const converter = new SessionMessageConverter();
402
+ return converter.sessionToHistory(messages);
403
+ }
404
+
405
+ // @deprecated Use SessionMessageConverter.extractProviderOptions() instead
406
+ export function extractProviderOptions(msg: SessionMessage): Record<string, unknown> {
407
+ const converter = new SessionMessageConverter();
408
+ return converter.extractProviderOptions(msg);
409
+ }
410
+
411
+ // @deprecated Use SessionMessageConverter.migrateMessage() instead
412
+ export function migrateMessage(oldMsg: Partial<SessionMessage>): SessionMessage {
413
+ const converter = new SessionMessageConverter();
414
+ return converter.migrateMessage(oldMsg);
415
+ }