n8n-workflow 2.31.2 → 2.32.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 (406) hide show
  1. package/dist/cjs/augment-object.js +136 -146
  2. package/dist/cjs/augment-object.js.map +1 -1
  3. package/dist/cjs/build.tsbuildinfo +1 -1
  4. package/dist/cjs/common/find-ai-root-node-names.js +36 -46
  5. package/dist/cjs/common/find-ai-root-node-names.js.map +1 -1
  6. package/dist/cjs/common/get-child-nodes.js +8 -18
  7. package/dist/cjs/common/get-child-nodes.js.map +1 -1
  8. package/dist/cjs/common/get-connected-nodes.js +84 -94
  9. package/dist/cjs/common/get-connected-nodes.js.map +1 -1
  10. package/dist/cjs/common/get-node-by-name.js +16 -26
  11. package/dist/cjs/common/get-node-by-name.js.map +1 -1
  12. package/dist/cjs/common/get-parent-nodes.js +14 -24
  13. package/dist/cjs/common/get-parent-nodes.js.map +1 -1
  14. package/dist/cjs/common/index.js +9 -19
  15. package/dist/cjs/common/index.js.map +1 -1
  16. package/dist/cjs/common/map-connections-by-destination.js +31 -41
  17. package/dist/cjs/common/map-connections-by-destination.js.map +1 -1
  18. package/dist/cjs/common/resolve-variables.d.ts +8 -0
  19. package/dist/cjs/common/resolve-variables.d.ts.map +1 -1
  20. package/dist/cjs/common/resolve-variables.js +46 -33
  21. package/dist/cjs/common/resolve-variables.js.map +1 -1
  22. package/dist/cjs/connections-diff.js +58 -68
  23. package/dist/cjs/connections-diff.js.map +1 -1
  24. package/dist/cjs/constants.d.ts +3 -3
  25. package/dist/cjs/constants.d.ts.map +1 -1
  26. package/dist/cjs/constants.js +157 -166
  27. package/dist/cjs/constants.js.map +1 -1
  28. package/dist/cjs/credential-domain-restrictions.js +153 -163
  29. package/dist/cjs/credential-domain-restrictions.js.map +1 -1
  30. package/dist/cjs/cron.d.ts.map +1 -1
  31. package/dist/cjs/cron.js +25 -35
  32. package/dist/cjs/cron.js.map +1 -1
  33. package/dist/cjs/data-table.types.js +10 -20
  34. package/dist/cjs/data-table.types.js.map +1 -1
  35. package/dist/cjs/dynamic-credentials-helpers.js +93 -103
  36. package/dist/cjs/dynamic-credentials-helpers.js.map +1 -1
  37. package/dist/cjs/errors/abstract/execution-base.error.d.ts.map +1 -1
  38. package/dist/cjs/errors/abstract/execution-base.error.js +41 -51
  39. package/dist/cjs/errors/abstract/execution-base.error.js.map +1 -1
  40. package/dist/cjs/errors/abstract/node.error.d.ts.map +1 -1
  41. package/dist/cjs/errors/abstract/node.error.js +142 -152
  42. package/dist/cjs/errors/abstract/node.error.js.map +1 -1
  43. package/dist/cjs/errors/base/base.error.d.ts.map +1 -1
  44. package/dist/cjs/errors/base/base.error.js +35 -45
  45. package/dist/cjs/errors/base/base.error.js.map +1 -1
  46. package/dist/cjs/errors/base/operational.error.d.ts.map +1 -1
  47. package/dist/cjs/errors/base/operational.error.js +17 -27
  48. package/dist/cjs/errors/base/operational.error.js.map +1 -1
  49. package/dist/cjs/errors/base/unexpected.error.d.ts.map +1 -1
  50. package/dist/cjs/errors/base/unexpected.error.js +17 -27
  51. package/dist/cjs/errors/base/unexpected.error.js.map +1 -1
  52. package/dist/cjs/errors/base/user.error.d.ts.map +1 -1
  53. package/dist/cjs/errors/base/user.error.js +17 -27
  54. package/dist/cjs/errors/base/user.error.js.map +1 -1
  55. package/dist/cjs/errors/cli-subworkflow-operation.error.js +7 -17
  56. package/dist/cjs/errors/cli-subworkflow-operation.error.js.map +1 -1
  57. package/dist/cjs/errors/db-connection-timeout-error.d.ts.map +1 -1
  58. package/dist/cjs/errors/db-connection-timeout-error.js +11 -21
  59. package/dist/cjs/errors/db-connection-timeout-error.js.map +1 -1
  60. package/dist/cjs/errors/execution-cancelled.error.d.ts.map +1 -1
  61. package/dist/cjs/errors/execution-cancelled.error.js +33 -43
  62. package/dist/cjs/errors/execution-cancelled.error.js.map +1 -1
  63. package/dist/cjs/errors/expression-class-extension.error.d.ts.map +1 -1
  64. package/dist/cjs/errors/expression-class-extension.error.js +9 -19
  65. package/dist/cjs/errors/expression-class-extension.error.js.map +1 -1
  66. package/dist/cjs/errors/expression-computed-destructuring.error.d.ts.map +1 -1
  67. package/dist/cjs/errors/expression-computed-destructuring.error.js +9 -19
  68. package/dist/cjs/errors/expression-computed-destructuring.error.js.map +1 -1
  69. package/dist/cjs/errors/expression-destructuring.error.d.ts.map +1 -1
  70. package/dist/cjs/errors/expression-destructuring.error.js +9 -19
  71. package/dist/cjs/errors/expression-destructuring.error.js.map +1 -1
  72. package/dist/cjs/errors/expression-extension.error.js +7 -17
  73. package/dist/cjs/errors/expression-extension.error.js.map +1 -1
  74. package/dist/cjs/errors/expression-reserved-variable.error.d.ts.map +1 -1
  75. package/dist/cjs/errors/expression-reserved-variable.error.js +9 -19
  76. package/dist/cjs/errors/expression-reserved-variable.error.js.map +1 -1
  77. package/dist/cjs/errors/expression-with-statement.error.d.ts.map +1 -1
  78. package/dist/cjs/errors/expression-with-statement.error.js +9 -19
  79. package/dist/cjs/errors/expression-with-statement.error.js.map +1 -1
  80. package/dist/cjs/errors/expression.error.d.ts.map +1 -1
  81. package/dist/cjs/errors/expression.error.js +33 -43
  82. package/dist/cjs/errors/expression.error.js.map +1 -1
  83. package/dist/cjs/errors/index.js +62 -72
  84. package/dist/cjs/errors/index.js.map +1 -1
  85. package/dist/cjs/errors/node-api.error.d.ts.map +1 -1
  86. package/dist/cjs/errors/node-api.error.js +227 -237
  87. package/dist/cjs/errors/node-api.error.js.map +1 -1
  88. package/dist/cjs/errors/node-operation.error.d.ts.map +1 -1
  89. package/dist/cjs/errors/node-operation.error.js +43 -53
  90. package/dist/cjs/errors/node-operation.error.js.map +1 -1
  91. package/dist/cjs/errors/node-ssl.error.d.ts.map +1 -1
  92. package/dist/cjs/errors/node-ssl.error.js +9 -19
  93. package/dist/cjs/errors/node-ssl.error.js.map +1 -1
  94. package/dist/cjs/errors/subworkflow-operation.error.d.ts.map +1 -1
  95. package/dist/cjs/errors/subworkflow-operation.error.js +18 -28
  96. package/dist/cjs/errors/subworkflow-operation.error.js.map +1 -1
  97. package/dist/cjs/errors/trigger-close.error.d.ts.map +1 -1
  98. package/dist/cjs/errors/trigger-close.error.js +11 -21
  99. package/dist/cjs/errors/trigger-close.error.js.map +1 -1
  100. package/dist/cjs/errors/webhook-taken.error.d.ts.map +1 -1
  101. package/dist/cjs/errors/webhook-taken.error.js +9 -19
  102. package/dist/cjs/errors/webhook-taken.error.js.map +1 -1
  103. package/dist/cjs/errors/workflow-activation.error.d.ts.map +1 -1
  104. package/dist/cjs/errors/workflow-activation.error.js +54 -64
  105. package/dist/cjs/errors/workflow-activation.error.js.map +1 -1
  106. package/dist/cjs/errors/workflow-configuration.error.js +10 -20
  107. package/dist/cjs/errors/workflow-configuration.error.js.map +1 -1
  108. package/dist/cjs/errors/workflow-deactivation.error.js +7 -17
  109. package/dist/cjs/errors/workflow-deactivation.error.js.map +1 -1
  110. package/dist/cjs/errors/workflow-operation.error.d.ts.map +1 -1
  111. package/dist/cjs/errors/workflow-operation.error.js +20 -30
  112. package/dist/cjs/errors/workflow-operation.error.js.map +1 -1
  113. package/dist/cjs/evaluation-helpers.js +16 -26
  114. package/dist/cjs/evaluation-helpers.js.map +1 -1
  115. package/dist/cjs/execution-context-establishment-hooks.d.ts.map +1 -1
  116. package/dist/cjs/execution-context-establishment-hooks.js +43 -53
  117. package/dist/cjs/execution-context-establishment-hooks.js.map +1 -1
  118. package/dist/cjs/execution-context.d.ts +14 -14
  119. package/dist/cjs/execution-context.d.ts.map +1 -1
  120. package/dist/cjs/execution-context.js +203 -213
  121. package/dist/cjs/execution-context.js.map +1 -1
  122. package/dist/cjs/execution-status.d.ts +2 -2
  123. package/dist/cjs/execution-status.d.ts.map +1 -1
  124. package/dist/cjs/execution-status.js +27 -37
  125. package/dist/cjs/execution-status.js.map +1 -1
  126. package/dist/cjs/expression-evaluator-proxy.d.ts.map +1 -1
  127. package/dist/cjs/expression-evaluator-proxy.js +18 -28
  128. package/dist/cjs/expression-evaluator-proxy.js.map +1 -1
  129. package/dist/cjs/expression-sandboxing.d.ts.map +1 -1
  130. package/dist/cjs/expression-sandboxing.js +447 -457
  131. package/dist/cjs/expression-sandboxing.js.map +1 -1
  132. package/dist/cjs/expression.d.ts.map +1 -1
  133. package/dist/cjs/expression.js +535 -546
  134. package/dist/cjs/expression.js.map +1 -1
  135. package/dist/cjs/expressions/expression-helpers.d.ts.map +1 -1
  136. package/dist/cjs/expressions/expression-helpers.js +13 -23
  137. package/dist/cjs/expressions/expression-helpers.js.map +1 -1
  138. package/dist/cjs/extensions/array-extensions.js +591 -601
  139. package/dist/cjs/extensions/array-extensions.js.map +1 -1
  140. package/dist/cjs/extensions/boolean-extensions.d.ts +1 -1
  141. package/dist/cjs/extensions/boolean-extensions.js +38 -48
  142. package/dist/cjs/extensions/boolean-extensions.js.map +1 -1
  143. package/dist/cjs/extensions/date-extensions.js +507 -517
  144. package/dist/cjs/extensions/date-extensions.js.map +1 -1
  145. package/dist/cjs/extensions/expression-extension.d.ts.map +1 -1
  146. package/dist/cjs/extensions/expression-extension.js +455 -465
  147. package/dist/cjs/extensions/expression-extension.js.map +1 -1
  148. package/dist/cjs/extensions/expression-parser.d.ts.map +1 -1
  149. package/dist/cjs/extensions/expression-parser.js +82 -92
  150. package/dist/cjs/extensions/expression-parser.js.map +1 -1
  151. package/dist/cjs/extensions/extended-functions.d.ts +10 -18
  152. package/dist/cjs/extensions/extended-functions.d.ts.map +1 -1
  153. package/dist/cjs/extensions/extended-functions.js +80 -90
  154. package/dist/cjs/extensions/extended-functions.js.map +1 -1
  155. package/dist/cjs/extensions/extensions.js +2 -12
  156. package/dist/cjs/extensions/index.js +10 -20
  157. package/dist/cjs/extensions/index.js.map +1 -1
  158. package/dist/cjs/extensions/number-extensions.js +226 -236
  159. package/dist/cjs/extensions/number-extensions.js.map +1 -1
  160. package/dist/cjs/extensions/object-extensions.js +274 -284
  161. package/dist/cjs/extensions/object-extensions.js.map +1 -1
  162. package/dist/cjs/extensions/string-extensions.d.ts +1 -1
  163. package/dist/cjs/extensions/string-extensions.d.ts.map +1 -1
  164. package/dist/cjs/extensions/string-extensions.js +769 -779
  165. package/dist/cjs/extensions/string-extensions.js.map +1 -1
  166. package/dist/cjs/extensions/utils.d.ts.map +1 -1
  167. package/dist/cjs/extensions/utils.js +35 -45
  168. package/dist/cjs/extensions/utils.js.map +1 -1
  169. package/dist/cjs/from-ai-parse-utils.js +393 -403
  170. package/dist/cjs/from-ai-parse-utils.js.map +1 -1
  171. package/dist/cjs/global-state.js +12 -22
  172. package/dist/cjs/global-state.js.map +1 -1
  173. package/dist/cjs/graph/graph-utils.js +166 -176
  174. package/dist/cjs/graph/graph-utils.js.map +1 -1
  175. package/dist/cjs/highlighted-data.js +13 -23
  176. package/dist/cjs/highlighted-data.js.map +1 -1
  177. package/dist/cjs/index.js +105 -115
  178. package/dist/cjs/index.js.map +1 -1
  179. package/dist/cjs/interfaces.d.ts +112 -22
  180. package/dist/cjs/interfaces.d.ts.map +1 -1
  181. package/dist/cjs/interfaces.js +62 -72
  182. package/dist/cjs/interfaces.js.map +1 -1
  183. package/dist/cjs/jmespath-query.js +26 -36
  184. package/dist/cjs/jmespath-query.js.map +1 -1
  185. package/dist/cjs/logger-proxy.d.ts.map +1 -1
  186. package/dist/cjs/logger-proxy.js +15 -25
  187. package/dist/cjs/logger-proxy.js.map +1 -1
  188. package/dist/cjs/mcp-helpers.js +10 -20
  189. package/dist/cjs/mcp-helpers.js.map +1 -1
  190. package/dist/cjs/message-event-bus.d.ts +184 -165
  191. package/dist/cjs/message-event-bus.d.ts.map +1 -1
  192. package/dist/cjs/message-event-bus.js +207 -217
  193. package/dist/cjs/message-event-bus.js.map +1 -1
  194. package/dist/cjs/metadata-utils.js +35 -45
  195. package/dist/cjs/metadata-utils.js.map +1 -1
  196. package/dist/cjs/native-methods/array.methods.js +527 -537
  197. package/dist/cjs/native-methods/array.methods.js.map +1 -1
  198. package/dist/cjs/native-methods/boolean.methods.js +18 -28
  199. package/dist/cjs/native-methods/boolean.methods.js.map +1 -1
  200. package/dist/cjs/native-methods/index.js +16 -26
  201. package/dist/cjs/native-methods/index.js.map +1 -1
  202. package/dist/cjs/native-methods/number.methods.js +79 -89
  203. package/dist/cjs/native-methods/number.methods.js.map +1 -1
  204. package/dist/cjs/native-methods/object.methods.js +7 -17
  205. package/dist/cjs/native-methods/object.methods.js.map +1 -1
  206. package/dist/cjs/native-methods/string.methods.js +474 -484
  207. package/dist/cjs/native-methods/string.methods.js.map +1 -1
  208. package/dist/cjs/node-grouping-validation.d.ts +6 -0
  209. package/dist/cjs/node-grouping-validation.d.ts.map +1 -1
  210. package/dist/cjs/node-grouping-validation.js +165 -144
  211. package/dist/cjs/node-grouping-validation.js.map +1 -1
  212. package/dist/cjs/node-helpers.d.ts.map +1 -1
  213. package/dist/cjs/node-helpers.js +1486 -1493
  214. package/dist/cjs/node-helpers.js.map +1 -1
  215. package/dist/cjs/node-parameters/filter-parameter.d.ts.map +1 -1
  216. package/dist/cjs/node-parameters/filter-parameter.js +315 -325
  217. package/dist/cjs/node-parameters/filter-parameter.js.map +1 -1
  218. package/dist/cjs/node-parameters/node-parameter-value-type-guard.js +105 -115
  219. package/dist/cjs/node-parameters/node-parameter-value-type-guard.js.map +1 -1
  220. package/dist/cjs/node-parameters/parameter-type-validation.js +120 -130
  221. package/dist/cjs/node-parameters/parameter-type-validation.js.map +1 -1
  222. package/dist/cjs/node-parameters/path-utils.js +21 -31
  223. package/dist/cjs/node-parameters/path-utils.js.map +1 -1
  224. package/dist/cjs/node-parameters/rename-node-utils.js +22 -32
  225. package/dist/cjs/node-parameters/rename-node-utils.js.map +1 -1
  226. package/dist/cjs/node-reference-parser-utils.js +472 -482
  227. package/dist/cjs/node-reference-parser-utils.js.map +1 -1
  228. package/dist/cjs/node-validation.js +59 -69
  229. package/dist/cjs/node-validation.js.map +1 -1
  230. package/dist/cjs/observable-object.js +56 -66
  231. package/dist/cjs/observable-object.js.map +1 -1
  232. package/dist/cjs/redaction-channels.js +36 -46
  233. package/dist/cjs/redaction-channels.js.map +1 -1
  234. package/dist/cjs/run-execution-data/run-execution-data.js +15 -25
  235. package/dist/cjs/run-execution-data/run-execution-data.js.map +1 -1
  236. package/dist/cjs/run-execution-data/run-execution-data.v0.js +2 -12
  237. package/dist/cjs/run-execution-data/run-execution-data.v1.js +26 -36
  238. package/dist/cjs/run-execution-data/run-execution-data.v1.js.map +1 -1
  239. package/dist/cjs/run-execution-data-factory.js +113 -123
  240. package/dist/cjs/run-execution-data-factory.js.map +1 -1
  241. package/dist/cjs/schemas.d.ts +13 -13
  242. package/dist/cjs/schemas.d.ts.map +1 -1
  243. package/dist/cjs/schemas.js +351 -360
  244. package/dist/cjs/schemas.js.map +1 -1
  245. package/dist/cjs/sub-workflow-output.js +10 -20
  246. package/dist/cjs/sub-workflow-output.js.map +1 -1
  247. package/dist/cjs/telemetry-helpers.d.ts.map +1 -1
  248. package/dist/cjs/telemetry-helpers.js +716 -726
  249. package/dist/cjs/telemetry-helpers.js.map +1 -1
  250. package/dist/cjs/tool-helpers.js +18 -28
  251. package/dist/cjs/tool-helpers.js.map +1 -1
  252. package/dist/cjs/trigger-identity.js +41 -51
  253. package/dist/cjs/trigger-identity.js.map +1 -1
  254. package/dist/cjs/trimmed-task-data.js +21 -31
  255. package/dist/cjs/trimmed-task-data.js.map +1 -1
  256. package/dist/cjs/type-guards.d.ts +3 -3
  257. package/dist/cjs/type-guards.d.ts.map +1 -1
  258. package/dist/cjs/type-guards.js +74 -84
  259. package/dist/cjs/type-guards.js.map +1 -1
  260. package/dist/cjs/type-validation.d.ts.map +1 -1
  261. package/dist/cjs/type-validation.js +383 -393
  262. package/dist/cjs/type-validation.js.map +1 -1
  263. package/dist/cjs/utils.d.ts +2 -2
  264. package/dist/cjs/utils.d.ts.map +1 -1
  265. package/dist/cjs/utils.js +430 -440
  266. package/dist/cjs/utils.js.map +1 -1
  267. package/dist/cjs/versioned-node-type.d.ts.map +1 -1
  268. package/dist/cjs/versioned-node-type.js +20 -30
  269. package/dist/cjs/versioned-node-type.js.map +1 -1
  270. package/dist/cjs/workflow-checksum.js +67 -77
  271. package/dist/cjs/workflow-checksum.js.map +1 -1
  272. package/dist/cjs/workflow-data-proxy-env-provider.js +58 -68
  273. package/dist/cjs/workflow-data-proxy-env-provider.js.map +1 -1
  274. package/dist/cjs/workflow-data-proxy-helpers.js +8 -18
  275. package/dist/cjs/workflow-data-proxy-helpers.js.map +1 -1
  276. package/dist/cjs/workflow-data-proxy.d.ts.map +1 -1
  277. package/dist/cjs/workflow-data-proxy.js +1162 -1172
  278. package/dist/cjs/workflow-data-proxy.js.map +1 -1
  279. package/dist/cjs/workflow-diff.d.ts +2 -1
  280. package/dist/cjs/workflow-diff.d.ts.map +1 -1
  281. package/dist/cjs/workflow-diff.js +292 -300
  282. package/dist/cjs/workflow-diff.js.map +1 -1
  283. package/dist/cjs/workflow-environments-helper.js +23 -33
  284. package/dist/cjs/workflow-environments-helper.js.map +1 -1
  285. package/dist/cjs/workflow-expression.d.ts.map +1 -1
  286. package/dist/cjs/workflow-expression.js +97 -107
  287. package/dist/cjs/workflow-expression.js.map +1 -1
  288. package/dist/cjs/workflow-structure-validation.d.ts.map +1 -1
  289. package/dist/cjs/workflow-structure-validation.js +140 -150
  290. package/dist/cjs/workflow-structure-validation.js.map +1 -1
  291. package/dist/cjs/workflow-validation.js +40 -50
  292. package/dist/cjs/workflow-validation.js.map +1 -1
  293. package/dist/cjs/workflow.d.ts.map +1 -1
  294. package/dist/cjs/workflow.js +612 -622
  295. package/dist/cjs/workflow.js.map +1 -1
  296. package/dist/esm/common/get-child-nodes.js.map +1 -1
  297. package/dist/esm/common/get-connected-nodes.js.map +1 -1
  298. package/dist/esm/common/get-parent-nodes.js.map +1 -1
  299. package/dist/esm/common/resolve-variables.d.ts +8 -0
  300. package/dist/esm/common/resolve-variables.d.ts.map +1 -1
  301. package/dist/esm/common/resolve-variables.js +22 -0
  302. package/dist/esm/common/resolve-variables.js.map +1 -1
  303. package/dist/esm/constants.d.ts +3 -3
  304. package/dist/esm/constants.d.ts.map +1 -1
  305. package/dist/esm/cron.d.ts.map +1 -1
  306. package/dist/esm/errors/abstract/execution-base.error.d.ts.map +1 -1
  307. package/dist/esm/errors/abstract/execution-base.error.js.map +1 -1
  308. package/dist/esm/errors/abstract/node.error.d.ts.map +1 -1
  309. package/dist/esm/errors/abstract/node.error.js.map +1 -1
  310. package/dist/esm/errors/base/base.error.d.ts.map +1 -1
  311. package/dist/esm/errors/base/base.error.js.map +1 -1
  312. package/dist/esm/errors/base/operational.error.d.ts.map +1 -1
  313. package/dist/esm/errors/base/operational.error.js.map +1 -1
  314. package/dist/esm/errors/base/unexpected.error.d.ts.map +1 -1
  315. package/dist/esm/errors/base/unexpected.error.js.map +1 -1
  316. package/dist/esm/errors/base/user.error.d.ts.map +1 -1
  317. package/dist/esm/errors/base/user.error.js.map +1 -1
  318. package/dist/esm/errors/db-connection-timeout-error.d.ts.map +1 -1
  319. package/dist/esm/errors/execution-cancelled.error.d.ts.map +1 -1
  320. package/dist/esm/errors/expression-class-extension.error.d.ts.map +1 -1
  321. package/dist/esm/errors/expression-computed-destructuring.error.d.ts.map +1 -1
  322. package/dist/esm/errors/expression-destructuring.error.d.ts.map +1 -1
  323. package/dist/esm/errors/expression-reserved-variable.error.d.ts.map +1 -1
  324. package/dist/esm/errors/expression-with-statement.error.d.ts.map +1 -1
  325. package/dist/esm/errors/expression.error.d.ts.map +1 -1
  326. package/dist/esm/errors/node-api.error.d.ts.map +1 -1
  327. package/dist/esm/errors/node-api.error.js.map +1 -1
  328. package/dist/esm/errors/node-operation.error.d.ts.map +1 -1
  329. package/dist/esm/errors/node-operation.error.js.map +1 -1
  330. package/dist/esm/errors/node-ssl.error.d.ts.map +1 -1
  331. package/dist/esm/errors/subworkflow-operation.error.d.ts.map +1 -1
  332. package/dist/esm/errors/trigger-close.error.d.ts.map +1 -1
  333. package/dist/esm/errors/trigger-close.error.js.map +1 -1
  334. package/dist/esm/errors/webhook-taken.error.d.ts.map +1 -1
  335. package/dist/esm/errors/workflow-activation.error.d.ts.map +1 -1
  336. package/dist/esm/errors/workflow-activation.error.js.map +1 -1
  337. package/dist/esm/errors/workflow-operation.error.d.ts.map +1 -1
  338. package/dist/esm/execution-context-establishment-hooks.d.ts.map +1 -1
  339. package/dist/esm/execution-context.d.ts +14 -14
  340. package/dist/esm/execution-context.d.ts.map +1 -1
  341. package/dist/esm/execution-status.d.ts +2 -2
  342. package/dist/esm/execution-status.d.ts.map +1 -1
  343. package/dist/esm/expression-evaluator-proxy.d.ts.map +1 -1
  344. package/dist/esm/expression-sandboxing.d.ts.map +1 -1
  345. package/dist/esm/expression-sandboxing.js.map +1 -1
  346. package/dist/esm/expression.d.ts.map +1 -1
  347. package/dist/esm/expression.js.map +1 -1
  348. package/dist/esm/expressions/expression-helpers.d.ts.map +1 -1
  349. package/dist/esm/extensions/boolean-extensions.d.ts +1 -1
  350. package/dist/esm/extensions/expression-extension.d.ts.map +1 -1
  351. package/dist/esm/extensions/expression-parser.d.ts.map +1 -1
  352. package/dist/esm/extensions/extended-functions.d.ts +10 -18
  353. package/dist/esm/extensions/extended-functions.d.ts.map +1 -1
  354. package/dist/esm/extensions/number-extensions.js.map +1 -1
  355. package/dist/esm/extensions/string-extensions.d.ts +1 -1
  356. package/dist/esm/extensions/string-extensions.d.ts.map +1 -1
  357. package/dist/esm/extensions/string-extensions.js.map +1 -1
  358. package/dist/esm/extensions/utils.d.ts.map +1 -1
  359. package/dist/esm/from-ai-parse-utils.js.map +1 -1
  360. package/dist/esm/interfaces.d.ts +112 -22
  361. package/dist/esm/interfaces.d.ts.map +1 -1
  362. package/dist/esm/interfaces.js.map +1 -1
  363. package/dist/esm/logger-proxy.d.ts.map +1 -1
  364. package/dist/esm/message-event-bus.d.ts +184 -165
  365. package/dist/esm/message-event-bus.d.ts.map +1 -1
  366. package/dist/esm/message-event-bus.js +2 -2
  367. package/dist/esm/message-event-bus.js.map +1 -1
  368. package/dist/esm/node-grouping-validation.d.ts +6 -0
  369. package/dist/esm/node-grouping-validation.d.ts.map +1 -1
  370. package/dist/esm/node-grouping-validation.js +34 -5
  371. package/dist/esm/node-grouping-validation.js.map +1 -1
  372. package/dist/esm/node-helpers.d.ts.map +1 -1
  373. package/dist/esm/node-helpers.js +3 -0
  374. package/dist/esm/node-helpers.js.map +1 -1
  375. package/dist/esm/node-parameters/filter-parameter.d.ts.map +1 -1
  376. package/dist/esm/node-parameters/filter-parameter.js.map +1 -1
  377. package/dist/esm/node-reference-parser-utils.js.map +1 -1
  378. package/dist/esm/run-execution-data-factory.js.map +1 -1
  379. package/dist/esm/schemas.d.ts +13 -13
  380. package/dist/esm/schemas.d.ts.map +1 -1
  381. package/dist/esm/schemas.js +1 -0
  382. package/dist/esm/schemas.js.map +1 -1
  383. package/dist/esm/telemetry-helpers.d.ts.map +1 -1
  384. package/dist/esm/telemetry-helpers.js.map +1 -1
  385. package/dist/esm/type-guards.d.ts +3 -3
  386. package/dist/esm/type-guards.d.ts.map +1 -1
  387. package/dist/esm/type-validation.d.ts.map +1 -1
  388. package/dist/esm/type-validation.js.map +1 -1
  389. package/dist/esm/typecheck.tsbuildinfo +1 -1
  390. package/dist/esm/utils.d.ts +2 -2
  391. package/dist/esm/utils.d.ts.map +1 -1
  392. package/dist/esm/utils.js.map +1 -1
  393. package/dist/esm/versioned-node-type.d.ts.map +1 -1
  394. package/dist/esm/workflow-data-proxy.d.ts.map +1 -1
  395. package/dist/esm/workflow-data-proxy.js.map +1 -1
  396. package/dist/esm/workflow-diff.d.ts +2 -1
  397. package/dist/esm/workflow-diff.d.ts.map +1 -1
  398. package/dist/esm/workflow-diff.js +3 -1
  399. package/dist/esm/workflow-diff.js.map +1 -1
  400. package/dist/esm/workflow-expression.d.ts.map +1 -1
  401. package/dist/esm/workflow-expression.js.map +1 -1
  402. package/dist/esm/workflow-structure-validation.d.ts.map +1 -1
  403. package/dist/esm/workflow-structure-validation.js.map +1 -1
  404. package/dist/esm/workflow.d.ts.map +1 -1
  405. package/dist/esm/workflow.js.map +1 -1
  406. package/package.json +10 -9
@@ -1,733 +1,723 @@
1
- (function (factory) {
2
- if (typeof module === "object" && typeof module.exports === "object") {
3
- var v = factory(require, exports);
4
- if (v !== undefined) module.exports = v;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.userInInstanceRanOutOfFreeAiCredits = exports.ANONYMIZATION_CHARACTER = void 0;
4
+ exports.getNodeTypeForName = getNodeTypeForName;
5
+ exports.isNumber = isNumber;
6
+ exports.getDomainBase = getDomainBase;
7
+ exports.getDomainPath = getDomainPath;
8
+ exports.generateNodesGraph = generateNodesGraph;
9
+ exports.extractLastExecutedNodeCredentialData = extractLastExecutedNodeCredentialData;
10
+ exports.resolveAIMetrics = resolveAIMetrics;
11
+ exports.resolveVectorStoreMetrics = resolveVectorStoreMetrics;
12
+ exports.extractLastExecutedNodeStructuredOutputErrorInfo = extractLastExecutedNodeStructuredOutputErrorInfo;
13
+ exports.getNodeRole = getNodeRole;
14
+ const constants_1 = require("./constants");
15
+ const errors_1 = require("./errors");
16
+ const evaluation_helpers_1 = require("./evaluation-helpers");
17
+ const expression_helpers_1 = require("./expressions/expression-helpers");
18
+ const interfaces_1 = require("./interfaces");
19
+ const node_helpers_1 = require("./node-helpers");
20
+ const utils_1 = require("./utils");
21
+ const isNodeApiError = (error) => typeof error === 'object' && error !== null && 'name' in error && error?.name === 'NodeApiError';
22
+ function getNodeTypeForName(workflow, nodeName) {
23
+ return workflow.nodes.find((node) => node.name === nodeName);
24
+ }
25
+ function isNumber(value) {
26
+ return typeof value === 'number';
27
+ }
28
+ function isTokenUsage(value) {
29
+ return (typeof value === 'object' &&
30
+ value !== null &&
31
+ 'promptTokens' in value &&
32
+ typeof value.promptTokens === 'number' &&
33
+ 'completionTokens' in value &&
34
+ typeof value.completionTokens === 'number');
35
+ }
36
+ function resolveParameterValue(value) {
37
+ if (typeof value === 'string') {
38
+ return value;
5
39
  }
6
- else if (typeof define === "function" && define.amd) {
7
- define(["require", "exports", "./constants", "./errors", "./evaluation-helpers", "./expressions/expression-helpers", "./interfaces", "./node-helpers", "./utils"], factory);
40
+ if (typeof value === 'object' && value && 'value' in value && typeof value.value === 'string') {
41
+ return value.value;
8
42
  }
9
- })(function (require, exports) {
10
- "use strict";
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.userInInstanceRanOutOfFreeAiCredits = exports.ANONYMIZATION_CHARACTER = void 0;
13
- exports.getNodeTypeForName = getNodeTypeForName;
14
- exports.isNumber = isNumber;
15
- exports.getDomainBase = getDomainBase;
16
- exports.getDomainPath = getDomainPath;
17
- exports.generateNodesGraph = generateNodesGraph;
18
- exports.extractLastExecutedNodeCredentialData = extractLastExecutedNodeCredentialData;
19
- exports.resolveAIMetrics = resolveAIMetrics;
20
- exports.resolveVectorStoreMetrics = resolveVectorStoreMetrics;
21
- exports.extractLastExecutedNodeStructuredOutputErrorInfo = extractLastExecutedNodeStructuredOutputErrorInfo;
22
- exports.getNodeRole = getNodeRole;
23
- const constants_1 = require("./constants");
24
- const errors_1 = require("./errors");
25
- const evaluation_helpers_1 = require("./evaluation-helpers");
26
- const expression_helpers_1 = require("./expressions/expression-helpers");
27
- const interfaces_1 = require("./interfaces");
28
- const node_helpers_1 = require("./node-helpers");
29
- const utils_1 = require("./utils");
30
- const isNodeApiError = (error) => typeof error === 'object' && error !== null && 'name' in error && error?.name === 'NodeApiError';
31
- function getNodeTypeForName(workflow, nodeName) {
32
- return workflow.nodes.find((node) => node.name === nodeName);
33
- }
34
- function isNumber(value) {
35
- return typeof value === 'number';
36
- }
37
- function isTokenUsage(value) {
38
- return (typeof value === 'object' &&
39
- value !== null &&
40
- 'promptTokens' in value &&
41
- typeof value.promptTokens === 'number' &&
42
- 'completionTokens' in value &&
43
- typeof value.completionTokens === 'number');
44
- }
45
- function resolveParameterValue(value) {
46
- if (typeof value === 'string') {
47
- return value;
48
- }
49
- if (typeof value === 'object' && value && 'value' in value && typeof value.value === 'string') {
50
- return value.value;
51
- }
52
- return undefined;
53
- }
54
- function extractNodeTokenUsage(nodeRunData) {
55
- let input = 0;
56
- let output = 0;
57
- for (const task of nodeRunData) {
58
- const lmOutputs = task.data?.[interfaces_1.NodeConnectionTypes.AiLanguageModel];
59
- if (lmOutputs) {
60
- // LM sub-nodes (connected to Agent/Chain) — token data from N8nLlmTracing
61
- for (const branch of lmOutputs) {
62
- for (const item of branch ?? []) {
63
- const usage = item?.json?.tokenUsage ?? item?.json?.tokenUsageEstimate;
64
- if (!isTokenUsage(usage))
65
- continue;
66
- input += usage.promptTokens;
67
- output += usage.completionTokens;
68
- }
43
+ return undefined;
44
+ }
45
+ function extractNodeTokenUsage(nodeRunData) {
46
+ let input = 0;
47
+ let output = 0;
48
+ for (const task of nodeRunData) {
49
+ const lmOutputs = task.data?.[interfaces_1.NodeConnectionTypes.AiLanguageModel];
50
+ if (lmOutputs) {
51
+ // LM sub-nodes (connected to Agent/Chain) — token data from N8nLlmTracing
52
+ for (const branch of lmOutputs) {
53
+ for (const item of branch ?? []) {
54
+ const usage = item?.json?.tokenUsage ?? item?.json?.tokenUsageEstimate;
55
+ if (!isTokenUsage(usage))
56
+ continue;
57
+ input += usage.promptTokens;
58
+ output += usage.completionTokens;
69
59
  }
70
60
  }
71
- else if (task.metadata?.tokenUsage) {
72
- // Standalone vendor nodes — token data captured via setMetadata before simplify
73
- input += task.metadata.tokenUsage.inputTokens ?? 0;
74
- output += task.metadata.tokenUsage.outputTokens ?? 0;
75
- }
76
61
  }
77
- return input > 0 || output > 0 ? { input, output } : undefined;
62
+ else if (task.metadata?.tokenUsage) {
63
+ // Standalone vendor nodes — token data captured via setMetadata before simplify
64
+ input += task.metadata.tokenUsage.inputTokens ?? 0;
65
+ output += task.metadata.tokenUsage.outputTokens ?? 0;
66
+ }
78
67
  }
79
- const countPlaceholders = (text) => {
80
- const placeholder = /(\{[a-zA-Z0-9_]+\})/g;
81
- let returnData = 0;
82
- try {
83
- const matches = text.matchAll(placeholder);
84
- for (const _ of matches)
85
- returnData++;
68
+ return input > 0 || output > 0 ? { input, output } : undefined;
69
+ }
70
+ const countPlaceholders = (text) => {
71
+ const placeholder = /(\{[a-zA-Z0-9_]+\})/g;
72
+ let returnData = 0;
73
+ try {
74
+ const matches = text.matchAll(placeholder);
75
+ for (const _ of matches)
76
+ returnData++;
77
+ }
78
+ catch (error) { }
79
+ return returnData;
80
+ };
81
+ const countPlaceholdersInParameters = (parameters) => {
82
+ let returnData = 0;
83
+ for (const parameter of parameters) {
84
+ if (!parameter.value) {
85
+ //count parameters provided by model
86
+ returnData++;
86
87
  }
87
- catch (error) { }
88
- return returnData;
89
- };
90
- const countPlaceholdersInParameters = (parameters) => {
91
- let returnData = 0;
92
- for (const parameter of parameters) {
93
- if (!parameter.value) {
94
- //count parameters provided by model
95
- returnData++;
96
- }
97
- else {
98
- //check if any placeholders in user provided value
99
- returnData += countPlaceholders(String(parameter.value));
100
- }
88
+ else {
89
+ //check if any placeholders in user provided value
90
+ returnData += countPlaceholders(String(parameter.value));
101
91
  }
102
- return returnData;
103
- };
104
- function areOverlapping(topLeft, bottomRight, targetPos) {
105
- return (targetPos[0] > topLeft[0] &&
106
- targetPos[1] > topLeft[1] &&
107
- targetPos[0] < bottomRight[0] &&
108
- targetPos[1] < bottomRight[1]);
109
92
  }
110
- const URL_PARTS_REGEX = /(?<protocolPlusDomain>.*?\..*?)(?<pathname>\/.*)/;
111
- // List of common multi-level TLDs (public suffixes)
112
- // Covers 95%+ of real-world domains for telemetry privacy purposes
113
- const MULTI_LEVEL_TLDS = new Set([
114
- // UK
115
- 'co.uk',
116
- 'gov.uk',
117
- 'org.uk',
118
- 'ac.uk',
119
- 'sch.uk',
120
- // Australia
121
- 'com.au',
122
- 'gov.au',
123
- 'edu.au',
124
- 'org.au',
125
- 'net.au',
126
- // New Zealand
127
- 'co.nz',
128
- 'org.nz',
129
- 'net.nz',
130
- 'govt.nz',
131
- 'ac.nz',
132
- // Japan
133
- 'co.jp',
134
- 'or.jp',
135
- 'ne.jp',
136
- 'ac.jp',
137
- 'go.jp',
138
- // Brazil
139
- 'com.br',
140
- 'gov.br',
141
- 'org.br',
142
- 'edu.br',
143
- // India
144
- 'co.in',
145
- 'org.in',
146
- 'net.in',
147
- 'gov.in',
148
- 'edu.in',
149
- // South Africa
150
- 'co.za',
151
- 'org.za',
152
- 'gov.za',
153
- 'ac.za',
154
- // AWS S3 (special case for cloud services)
155
- 's3.amazonaws.com',
156
- ]);
157
- function getDomainBase(raw, urlParts = URL_PARTS_REGEX) {
158
- let hostname;
159
- try {
160
- const url = new URL(raw);
161
- hostname = url.hostname;
93
+ return returnData;
94
+ };
95
+ function areOverlapping(topLeft, bottomRight, targetPos) {
96
+ return (targetPos[0] > topLeft[0] &&
97
+ targetPos[1] > topLeft[1] &&
98
+ targetPos[0] < bottomRight[0] &&
99
+ targetPos[1] < bottomRight[1]);
100
+ }
101
+ const URL_PARTS_REGEX = /(?<protocolPlusDomain>.*?\..*?)(?<pathname>\/.*)/;
102
+ // List of common multi-level TLDs (public suffixes)
103
+ // Covers 95%+ of real-world domains for telemetry privacy purposes
104
+ const MULTI_LEVEL_TLDS = new Set([
105
+ // UK
106
+ 'co.uk',
107
+ 'gov.uk',
108
+ 'org.uk',
109
+ 'ac.uk',
110
+ 'sch.uk',
111
+ // Australia
112
+ 'com.au',
113
+ 'gov.au',
114
+ 'edu.au',
115
+ 'org.au',
116
+ 'net.au',
117
+ // New Zealand
118
+ 'co.nz',
119
+ 'org.nz',
120
+ 'net.nz',
121
+ 'govt.nz',
122
+ 'ac.nz',
123
+ // Japan
124
+ 'co.jp',
125
+ 'or.jp',
126
+ 'ne.jp',
127
+ 'ac.jp',
128
+ 'go.jp',
129
+ // Brazil
130
+ 'com.br',
131
+ 'gov.br',
132
+ 'org.br',
133
+ 'edu.br',
134
+ // India
135
+ 'co.in',
136
+ 'org.in',
137
+ 'net.in',
138
+ 'gov.in',
139
+ 'edu.in',
140
+ // South Africa
141
+ 'co.za',
142
+ 'org.za',
143
+ 'gov.za',
144
+ 'ac.za',
145
+ // AWS S3 (special case for cloud services)
146
+ 's3.amazonaws.com',
147
+ ]);
148
+ function getDomainBase(raw, urlParts = URL_PARTS_REGEX) {
149
+ let hostname;
150
+ try {
151
+ const url = new URL(raw);
152
+ hostname = url.hostname;
153
+ }
154
+ catch {
155
+ const match = urlParts.exec(raw);
156
+ if (!match?.groups?.protocolPlusDomain)
157
+ return '';
158
+ // Extract hostname from malformed URL
159
+ hostname = match.groups.protocolPlusDomain.replace(/^https?:\/\//, '');
160
+ }
161
+ // Handle edge cases
162
+ if (!hostname || hostname === 'localhost')
163
+ return hostname;
164
+ // Handle IP addresses (v4 and v6) - return as-is
165
+ if (/^(\d{1,3}\.){3}\d{1,3}$/.test(hostname) || hostname.includes(':')) {
166
+ return hostname;
167
+ }
168
+ const parts = hostname.split('.');
169
+ // Single-word domain (e.g., "localhost", "example")
170
+ if (parts.length === 1) {
171
+ return hostname;
172
+ }
173
+ // Check for multi-level TLDs (e.g., co.uk, com.au)
174
+ if (parts.length >= 3) {
175
+ const lastTwoParts = `${parts[parts.length - 2]}.${parts[parts.length - 1]}`;
176
+ if (MULTI_LEVEL_TLDS.has(lastTwoParts)) {
177
+ // Return last 3 parts for multi-level TLD
178
+ return parts.slice(-3).join('.');
162
179
  }
163
- catch {
164
- const match = urlParts.exec(raw);
165
- if (!match?.groups?.protocolPlusDomain)
166
- return '';
167
- // Extract hostname from malformed URL
168
- hostname = match.groups.protocolPlusDomain.replace(/^https?:\/\//, '');
169
- }
170
- // Handle edge cases
171
- if (!hostname || hostname === 'localhost')
172
- return hostname;
173
- // Handle IP addresses (v4 and v6) - return as-is
174
- if (/^(\d{1,3}\.){3}\d{1,3}$/.test(hostname) || hostname.includes(':')) {
175
- return hostname;
176
- }
177
- const parts = hostname.split('.');
178
- // Single-word domain (e.g., "localhost", "example")
179
- if (parts.length === 1) {
180
- return hostname;
181
- }
182
- // Check for multi-level TLDs (e.g., co.uk, com.au)
183
- if (parts.length >= 3) {
184
- const lastTwoParts = `${parts[parts.length - 2]}.${parts[parts.length - 1]}`;
185
- if (MULTI_LEVEL_TLDS.has(lastTwoParts)) {
186
- // Return last 3 parts for multi-level TLD
187
- return parts.slice(-3).join('.');
188
- }
189
- // Check for 3-level TLDs (e.g., s3.amazonaws.com)
190
- if (parts.length >= 4) {
191
- const lastThreeParts = `${parts[parts.length - 3]}.${parts[parts.length - 2]}.${parts[parts.length - 1]}`;
192
- if (MULTI_LEVEL_TLDS.has(lastThreeParts)) {
193
- // Return last 4 parts for 3-level TLD
194
- return parts.slice(-4).join('.');
195
- }
180
+ // Check for 3-level TLDs (e.g., s3.amazonaws.com)
181
+ if (parts.length >= 4) {
182
+ const lastThreeParts = `${parts[parts.length - 3]}.${parts[parts.length - 2]}.${parts[parts.length - 1]}`;
183
+ if (MULTI_LEVEL_TLDS.has(lastThreeParts)) {
184
+ // Return last 4 parts for 3-level TLD
185
+ return parts.slice(-4).join('.');
196
186
  }
197
187
  }
198
- // Default: return last 2 parts (standard TLD like .com, .org, .net)
199
- return parts.slice(-2).join('.');
200
188
  }
201
- function isSensitive(segment) {
202
- if (/^v\d+$/.test(segment))
203
- return false;
204
- return /%40/.test(segment) || /\d/.test(segment) || /^[0-9A-F]{8}/i.test(segment);
189
+ // Default: return last 2 parts (standard TLD like .com, .org, .net)
190
+ return parts.slice(-2).join('.');
191
+ }
192
+ function isSensitive(segment) {
193
+ if (/^v\d+$/.test(segment))
194
+ return false;
195
+ return /%40/.test(segment) || /\d/.test(segment) || /^[0-9A-F]{8}/i.test(segment);
196
+ }
197
+ exports.ANONYMIZATION_CHARACTER = '*';
198
+ function sanitizeRoute(raw, check = isSensitive, char = exports.ANONYMIZATION_CHARACTER) {
199
+ return raw
200
+ .split('/')
201
+ .map((segment) => (check(segment) ? char.repeat(segment.length) : segment))
202
+ .join('/');
203
+ }
204
+ /**
205
+ * Return pathname plus query string from URL, anonymizing IDs in route and query params.
206
+ */
207
+ function getDomainPath(raw, urlParts = URL_PARTS_REGEX) {
208
+ try {
209
+ const url = new URL(raw);
210
+ if (!url.hostname)
211
+ throw new errors_1.UnexpectedError('Malformed URL');
212
+ return sanitizeRoute(url.pathname);
205
213
  }
206
- exports.ANONYMIZATION_CHARACTER = '*';
207
- function sanitizeRoute(raw, check = isSensitive, char = exports.ANONYMIZATION_CHARACTER) {
208
- return raw
209
- .split('/')
210
- .map((segment) => (check(segment) ? char.repeat(segment.length) : segment))
211
- .join('/');
214
+ catch {
215
+ const match = urlParts.exec(raw);
216
+ if (!match?.groups?.pathname)
217
+ return '';
218
+ // discard query string
219
+ const route = match.groups.pathname.split('?').shift();
220
+ return sanitizeRoute(route);
212
221
  }
213
- /**
214
- * Return pathname plus query string from URL, anonymizing IDs in route and query params.
215
- */
216
- function getDomainPath(raw, urlParts = URL_PARTS_REGEX) {
222
+ }
223
+ function getNumberOfItemsInRuns(runs) {
224
+ return runs.reduce((total, run) => {
225
+ const data = run.data ?? {};
226
+ let count = 0;
227
+ Object.keys(data).forEach((type) => {
228
+ const conn = data[type] ?? [];
229
+ conn.forEach((branch) => {
230
+ count += (branch ?? []).length;
231
+ });
232
+ });
233
+ return total + count;
234
+ }, 0);
235
+ }
236
+ function generateNodesGraph(workflow, nodeTypes, options) {
237
+ const { runData } = options ?? {};
238
+ const nodeGraph = {
239
+ node_types: [],
240
+ node_connections: [],
241
+ nodes: {},
242
+ notes: {},
243
+ is_pinned: Object.keys(workflow.pinData ?? {}).length > 0,
244
+ };
245
+ const nameIndices = {};
246
+ const webhookNodeNames = [];
247
+ const evaluationTriggerNodeNames = [];
248
+ const nodes = (workflow.nodes ?? []).filter((node) => node.type === constants_1.STICKY_NODE_TYPE);
249
+ const otherNodes = (workflow.nodes ?? []).filter((node) => node.type !== constants_1.STICKY_NODE_TYPE);
250
+ nodes.forEach((stickyNote, index) => {
251
+ const stickyType = nodeTypes.getByNameAndVersion(constants_1.STICKY_NODE_TYPE, stickyNote.typeVersion);
252
+ if (!stickyType) {
253
+ return;
254
+ }
255
+ let nodeParameters = {};
217
256
  try {
218
- const url = new URL(raw);
219
- if (!url.hostname)
220
- throw new errors_1.UnexpectedError('Malformed URL');
221
- return sanitizeRoute(url.pathname);
257
+ nodeParameters =
258
+ (0, node_helpers_1.getNodeParameters)(stickyType.description.properties, stickyNote.parameters, true, false, stickyNote, stickyType.description) ?? {};
222
259
  }
223
260
  catch {
224
- const match = urlParts.exec(raw);
225
- if (!match?.groups?.pathname)
226
- return '';
227
- // discard query string
228
- const route = match.groups.pathname.split('?').shift();
229
- return sanitizeRoute(route);
261
+ // prevent node param resolution from failing graph generation
230
262
  }
231
- }
232
- function getNumberOfItemsInRuns(runs) {
233
- return runs.reduce((total, run) => {
234
- const data = run.data ?? {};
235
- let count = 0;
236
- Object.keys(data).forEach((type) => {
237
- const conn = data[type] ?? [];
238
- conn.forEach((branch) => {
239
- count += (branch ?? []).length;
240
- });
241
- });
242
- return total + count;
243
- }, 0);
244
- }
245
- function generateNodesGraph(workflow, nodeTypes, options) {
246
- const { runData } = options ?? {};
247
- const nodeGraph = {
248
- node_types: [],
249
- node_connections: [],
250
- nodes: {},
251
- notes: {},
252
- is_pinned: Object.keys(workflow.pinData ?? {}).length > 0,
263
+ const height = typeof nodeParameters.height === 'number' ? nodeParameters.height : 0;
264
+ const width = typeof nodeParameters.width === 'number' ? nodeParameters.width : 0;
265
+ const topLeft = stickyNote.position;
266
+ const bottomRight = [topLeft[0] + width, topLeft[1] + height];
267
+ const overlapping = Boolean(otherNodes.find((node) => areOverlapping(topLeft, bottomRight, node.position)));
268
+ nodeGraph.notes[index] = {
269
+ overlapping,
270
+ position: topLeft,
271
+ height,
272
+ width,
253
273
  };
254
- const nameIndices = {};
255
- const webhookNodeNames = [];
256
- const evaluationTriggerNodeNames = [];
257
- const nodes = (workflow.nodes ?? []).filter((node) => node.type === constants_1.STICKY_NODE_TYPE);
258
- const otherNodes = (workflow.nodes ?? []).filter((node) => node.type !== constants_1.STICKY_NODE_TYPE);
259
- nodes.forEach((stickyNote, index) => {
260
- const stickyType = nodeTypes.getByNameAndVersion(constants_1.STICKY_NODE_TYPE, stickyNote.typeVersion);
261
- if (!stickyType) {
262
- return;
274
+ });
275
+ // eslint-disable-next-line complexity
276
+ otherNodes.forEach((node, index) => {
277
+ nodeGraph.node_types.push(node.type);
278
+ const nodeItem = {
279
+ id: node.id,
280
+ type: node.type,
281
+ version: node.typeVersion,
282
+ position: node.position,
283
+ };
284
+ const nodeType = nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
285
+ if (nodeType?.description?.communityNodePackageVersion) {
286
+ nodeItem.package_version = nodeType.description.communityNodePackageVersion;
287
+ }
288
+ if (runData?.[node.name]) {
289
+ const runs = runData[node.name] ?? [];
290
+ nodeItem.runs = runs.length;
291
+ nodeItem.items_total = getNumberOfItemsInRuns(runs);
292
+ }
293
+ if (options?.sourceInstanceId) {
294
+ nodeItem.src_instance_id = options.sourceInstanceId;
295
+ }
296
+ if (node.id && options?.nodeIdMap?.[node.id]) {
297
+ nodeItem.src_node_id = options.nodeIdMap[node.id];
298
+ }
299
+ if (node.type === constants_1.AI_TRANSFORM_NODE_TYPE && options?.isCloudDeployment) {
300
+ nodeItem.prompts = { instructions: node.parameters.instructions };
301
+ }
302
+ else if (node.type === constants_1.AGENT_LANGCHAIN_NODE_TYPE) {
303
+ nodeItem.agent = node.parameters.agent ?? 'toolsAgent';
304
+ if (node.typeVersion >= 2.1) {
305
+ const options = node.parameters?.options;
306
+ if (typeof options === 'object' &&
307
+ options &&
308
+ 'enableStreaming' in options &&
309
+ options.enableStreaming === false) {
310
+ nodeItem.is_streaming = false;
311
+ }
312
+ else {
313
+ nodeItem.is_streaming = true;
314
+ }
263
315
  }
264
- let nodeParameters = {};
316
+ }
317
+ else if (node.type === constants_1.MERGE_NODE_TYPE) {
318
+ nodeItem.operation = node.parameters.mode;
319
+ if (options?.isCloudDeployment && node.parameters.mode === 'combineBySql') {
320
+ nodeItem.sql = node.parameters.query;
321
+ }
322
+ }
323
+ else if (node.type === constants_1.HTTP_REQUEST_NODE_TYPE && node.typeVersion === 1) {
265
324
  try {
266
- nodeParameters =
267
- (0, node_helpers_1.getNodeParameters)(stickyType.description.properties, stickyNote.parameters, true, false, stickyNote, stickyType.description) ?? {};
325
+ nodeItem.domain = new URL(node.parameters.url).hostname;
268
326
  }
269
327
  catch {
270
- // prevent node param resolution from failing graph generation
271
- }
272
- const height = typeof nodeParameters.height === 'number' ? nodeParameters.height : 0;
273
- const width = typeof nodeParameters.width === 'number' ? nodeParameters.width : 0;
274
- const topLeft = stickyNote.position;
275
- const bottomRight = [topLeft[0] + width, topLeft[1] + height];
276
- const overlapping = Boolean(otherNodes.find((node) => areOverlapping(topLeft, bottomRight, node.position)));
277
- nodeGraph.notes[index] = {
278
- overlapping,
279
- position: topLeft,
280
- height,
281
- width,
282
- };
283
- });
284
- // eslint-disable-next-line complexity
285
- otherNodes.forEach((node, index) => {
286
- nodeGraph.node_types.push(node.type);
287
- const nodeItem = {
288
- id: node.id,
289
- type: node.type,
290
- version: node.typeVersion,
291
- position: node.position,
292
- };
293
- const nodeType = nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
294
- if (nodeType?.description?.communityNodePackageVersion) {
295
- nodeItem.package_version = nodeType.description.communityNodePackageVersion;
328
+ nodeItem.domain = getDomainBase(node.parameters.url);
296
329
  }
297
- if (runData?.[node.name]) {
298
- const runs = runData[node.name] ?? [];
299
- nodeItem.runs = runs.length;
300
- nodeItem.items_total = getNumberOfItemsInRuns(runs);
301
- }
302
- if (options?.sourceInstanceId) {
303
- nodeItem.src_instance_id = options.sourceInstanceId;
304
- }
305
- if (node.id && options?.nodeIdMap?.[node.id]) {
306
- nodeItem.src_node_id = options.nodeIdMap[node.id];
307
- }
308
- if (node.type === constants_1.AI_TRANSFORM_NODE_TYPE && options?.isCloudDeployment) {
309
- nodeItem.prompts = { instructions: node.parameters.instructions };
310
- }
311
- else if (node.type === constants_1.AGENT_LANGCHAIN_NODE_TYPE) {
312
- nodeItem.agent = node.parameters.agent ?? 'toolsAgent';
313
- if (node.typeVersion >= 2.1) {
314
- const options = node.parameters?.options;
315
- if (typeof options === 'object' &&
316
- options &&
317
- 'enableStreaming' in options &&
318
- options.enableStreaming === false) {
319
- nodeItem.is_streaming = false;
320
- }
321
- else {
322
- nodeItem.is_streaming = true;
323
- }
330
+ }
331
+ else if (node.type === constants_1.HTTP_REQUEST_NODE_TYPE && node.typeVersion > 1) {
332
+ const { authentication } = node.parameters;
333
+ nodeItem.credential_type = {
334
+ none: 'none',
335
+ genericCredentialType: node.parameters.genericAuthType,
336
+ predefinedCredentialType: node.parameters.nodeCredentialType,
337
+ }[authentication];
338
+ nodeItem.credential_set = node.credentials ? Object.keys(node.credentials).length > 0 : false;
339
+ const { url } = node.parameters;
340
+ nodeItem.domain_base = getDomainBase(url);
341
+ nodeItem.method = node.parameters.requestMethod;
342
+ }
343
+ else if (constants_1.HTTP_REQUEST_TOOL_LANGCHAIN_NODE_TYPE === node.type) {
344
+ if (!nodeItem.toolSettings)
345
+ nodeItem.toolSettings = {};
346
+ nodeItem.toolSettings.url_type = 'other';
347
+ nodeItem.toolSettings.uses_auth = false;
348
+ nodeItem.toolSettings.placeholders = 0;
349
+ nodeItem.toolSettings.query_from_model_only = false;
350
+ nodeItem.toolSettings.headers_from_model_only = false;
351
+ nodeItem.toolSettings.body_from_model_only = false;
352
+ const toolUrl = node.parameters?.url ?? '';
353
+ nodeItem.toolSettings.placeholders += countPlaceholders(toolUrl);
354
+ const authType = node.parameters?.authentication ?? '';
355
+ if (authType && authType !== 'none') {
356
+ nodeItem.toolSettings.uses_auth = true;
357
+ }
358
+ if (toolUrl.startsWith('{') && toolUrl.endsWith('}')) {
359
+ nodeItem.toolSettings.url_type = 'any';
360
+ }
361
+ else if (toolUrl.includes('google.com')) {
362
+ nodeItem.toolSettings.url_type = 'google';
363
+ }
364
+ if (node.parameters?.sendBody) {
365
+ if (node.parameters?.specifyBody === 'model') {
366
+ nodeItem.toolSettings.body_from_model_only = true;
324
367
  }
325
- }
326
- else if (node.type === constants_1.MERGE_NODE_TYPE) {
327
- nodeItem.operation = node.parameters.mode;
328
- if (options?.isCloudDeployment && node.parameters.mode === 'combineBySql') {
329
- nodeItem.sql = node.parameters.query;
368
+ if (node.parameters?.jsonBody) {
369
+ nodeItem.toolSettings.placeholders += countPlaceholders(node.parameters?.jsonBody);
330
370
  }
331
- }
332
- else if (node.type === constants_1.HTTP_REQUEST_NODE_TYPE && node.typeVersion === 1) {
333
- try {
334
- nodeItem.domain = new URL(node.parameters.url).hostname;
371
+ if (node.parameters?.parametersBody) {
372
+ const parameters = (node.parameters?.parametersBody)
373
+ .values;
374
+ nodeItem.toolSettings.placeholders += countPlaceholdersInParameters(parameters);
335
375
  }
336
- catch {
337
- nodeItem.domain = getDomainBase(node.parameters.url);
338
- }
339
- }
340
- else if (node.type === constants_1.HTTP_REQUEST_NODE_TYPE && node.typeVersion > 1) {
341
- const { authentication } = node.parameters;
342
- nodeItem.credential_type = {
343
- none: 'none',
344
- genericCredentialType: node.parameters.genericAuthType,
345
- predefinedCredentialType: node.parameters.nodeCredentialType,
346
- }[authentication];
347
- nodeItem.credential_set = node.credentials ? Object.keys(node.credentials).length > 0 : false;
348
- const { url } = node.parameters;
349
- nodeItem.domain_base = getDomainBase(url);
350
- nodeItem.method = node.parameters.requestMethod;
351
376
  }
352
- else if (constants_1.HTTP_REQUEST_TOOL_LANGCHAIN_NODE_TYPE === node.type) {
353
- if (!nodeItem.toolSettings)
354
- nodeItem.toolSettings = {};
355
- nodeItem.toolSettings.url_type = 'other';
356
- nodeItem.toolSettings.uses_auth = false;
357
- nodeItem.toolSettings.placeholders = 0;
358
- nodeItem.toolSettings.query_from_model_only = false;
359
- nodeItem.toolSettings.headers_from_model_only = false;
360
- nodeItem.toolSettings.body_from_model_only = false;
361
- const toolUrl = node.parameters?.url ?? '';
362
- nodeItem.toolSettings.placeholders += countPlaceholders(toolUrl);
363
- const authType = node.parameters?.authentication ?? '';
364
- if (authType && authType !== 'none') {
365
- nodeItem.toolSettings.uses_auth = true;
366
- }
367
- if (toolUrl.startsWith('{') && toolUrl.endsWith('}')) {
368
- nodeItem.toolSettings.url_type = 'any';
377
+ if (node.parameters?.sendHeaders) {
378
+ if (node.parameters?.specifyHeaders === 'model') {
379
+ nodeItem.toolSettings.headers_from_model_only = true;
369
380
  }
370
- else if (toolUrl.includes('google.com')) {
371
- nodeItem.toolSettings.url_type = 'google';
372
- }
373
- if (node.parameters?.sendBody) {
374
- if (node.parameters?.specifyBody === 'model') {
375
- nodeItem.toolSettings.body_from_model_only = true;
376
- }
377
- if (node.parameters?.jsonBody) {
378
- nodeItem.toolSettings.placeholders += countPlaceholders(node.parameters?.jsonBody);
379
- }
380
- if (node.parameters?.parametersBody) {
381
- const parameters = (node.parameters?.parametersBody)
382
- .values;
383
- nodeItem.toolSettings.placeholders += countPlaceholdersInParameters(parameters);
384
- }
381
+ if (node.parameters?.jsonHeaders) {
382
+ nodeItem.toolSettings.placeholders += countPlaceholders(node.parameters?.jsonHeaders);
385
383
  }
386
- if (node.parameters?.sendHeaders) {
387
- if (node.parameters?.specifyHeaders === 'model') {
388
- nodeItem.toolSettings.headers_from_model_only = true;
389
- }
390
- if (node.parameters?.jsonHeaders) {
391
- nodeItem.toolSettings.placeholders += countPlaceholders(node.parameters?.jsonHeaders);
392
- }
393
- if (node.parameters?.parametersHeaders) {
394
- const parameters = (node.parameters?.parametersHeaders)
395
- .values;
396
- nodeItem.toolSettings.placeholders += countPlaceholdersInParameters(parameters);
397
- }
384
+ if (node.parameters?.parametersHeaders) {
385
+ const parameters = (node.parameters?.parametersHeaders)
386
+ .values;
387
+ nodeItem.toolSettings.placeholders += countPlaceholdersInParameters(parameters);
398
388
  }
399
- if (node.parameters?.sendQuery) {
400
- if (node.parameters?.specifyQuery === 'model') {
401
- nodeItem.toolSettings.query_from_model_only = true;
402
- }
403
- if (node.parameters?.jsonQuery) {
404
- nodeItem.toolSettings.placeholders += countPlaceholders(node.parameters?.jsonQuery);
405
- }
406
- if (node.parameters?.parametersQuery) {
407
- const parameters = (node.parameters?.parametersQuery)
408
- .values;
409
- nodeItem.toolSettings.placeholders += countPlaceholdersInParameters(parameters);
410
- }
411
- }
412
- }
413
- else if (node.type === constants_1.WEBHOOK_NODE_TYPE) {
414
- webhookNodeNames.push(node.name);
415
- const responseMode = node.parameters?.responseMode;
416
- nodeItem.response_mode = typeof responseMode === 'string' ? responseMode : 'onReceived';
417
389
  }
418
- else if (node.type === constants_1.CHAT_TRIGGER_NODE_TYPE) {
419
- // Capture streaming response mode parameter
420
- const options = node.parameters?.options;
421
- if (typeof options === 'object' &&
422
- options &&
423
- 'responseMode' in options &&
424
- typeof options.responseMode === 'string') {
425
- nodeItem.response_mode = options.responseMode;
390
+ if (node.parameters?.sendQuery) {
391
+ if (node.parameters?.specifyQuery === 'model') {
392
+ nodeItem.toolSettings.query_from_model_only = true;
426
393
  }
427
- // Capture public chat setting
428
- const isPublic = node.parameters?.public;
429
- if (typeof isPublic === 'boolean') {
430
- nodeItem.public_chat = isPublic;
394
+ if (node.parameters?.jsonQuery) {
395
+ nodeItem.toolSettings.placeholders += countPlaceholders(node.parameters?.jsonQuery);
431
396
  }
432
- }
433
- else if (node.type === constants_1.EXECUTE_WORKFLOW_NODE_TYPE ||
434
- node.type === constants_1.WORKFLOW_TOOL_LANGCHAIN_NODE_TYPE) {
435
- if (node.parameters?.workflowId) {
436
- nodeItem.workflow_id = node.parameters?.workflowId;
397
+ if (node.parameters?.parametersQuery) {
398
+ const parameters = (node.parameters?.parametersQuery)
399
+ .values;
400
+ nodeItem.toolSettings.placeholders += countPlaceholdersInParameters(parameters);
437
401
  }
438
402
  }
439
- else if (node.type === constants_1.EVALUATION_TRIGGER_NODE_TYPE) {
440
- evaluationTriggerNodeNames.push(node.name);
441
- }
442
- else if (node.type === constants_1.EVALUATION_NODE_TYPE &&
443
- options?.isCloudDeployment &&
444
- node.parameters?.operation === 'setMetrics') {
445
- const metrics = node.parameters?.metrics;
446
- // If metrics are not defined, it means the node is using preconfigured metric
447
- if (!metrics) {
448
- const predefinedMetricKey = node.parameters?.metric ?? evaluation_helpers_1.DEFAULT_EVALUATION_METRIC;
449
- nodeItem.metric_names = [predefinedMetricKey];
450
- }
451
- else {
452
- nodeItem.metric_names = metrics.assignments?.map((metric) => metric.name);
453
- }
403
+ }
404
+ else if (node.type === constants_1.WEBHOOK_NODE_TYPE) {
405
+ webhookNodeNames.push(node.name);
406
+ const responseMode = node.parameters?.responseMode;
407
+ nodeItem.response_mode = typeof responseMode === 'string' ? responseMode : 'onReceived';
408
+ }
409
+ else if (node.type === constants_1.CHAT_TRIGGER_NODE_TYPE) {
410
+ // Capture streaming response mode parameter
411
+ const options = node.parameters?.options;
412
+ if (typeof options === 'object' &&
413
+ options &&
414
+ 'responseMode' in options &&
415
+ typeof options.responseMode === 'string') {
416
+ nodeItem.response_mode = options.responseMode;
417
+ }
418
+ // Capture public chat setting
419
+ const isPublic = node.parameters?.public;
420
+ if (typeof isPublic === 'boolean') {
421
+ nodeItem.public_chat = isPublic;
454
422
  }
455
- else if (node.type === constants_1.CODE_NODE_TYPE) {
456
- const { language } = node.parameters;
457
- nodeItem.language =
458
- language === undefined
459
- ? 'javascript'
460
- : language === 'python' || language === 'pythonNative'
461
- ? 'python'
462
- : 'unknown';
423
+ }
424
+ else if (node.type === constants_1.EXECUTE_WORKFLOW_NODE_TYPE ||
425
+ node.type === constants_1.WORKFLOW_TOOL_LANGCHAIN_NODE_TYPE) {
426
+ if (node.parameters?.workflowId) {
427
+ nodeItem.workflow_id = node.parameters?.workflowId;
463
428
  }
464
- else if (node.type === constants_1.GUARDRAILS_NODE_TYPE) {
465
- nodeItem.operation = node.parameters.operation;
466
- const usedGuardrails = Object.keys(node.parameters?.guardrails ?? {});
467
- nodeItem.used_guardrails = usedGuardrails;
429
+ }
430
+ else if (node.type === constants_1.EVALUATION_TRIGGER_NODE_TYPE) {
431
+ evaluationTriggerNodeNames.push(node.name);
432
+ }
433
+ else if (node.type === constants_1.EVALUATION_NODE_TYPE &&
434
+ options?.isCloudDeployment &&
435
+ node.parameters?.operation === 'setMetrics') {
436
+ const metrics = node.parameters?.metrics;
437
+ // If metrics are not defined, it means the node is using preconfigured metric
438
+ if (!metrics) {
439
+ const predefinedMetricKey = node.parameters?.metric ?? evaluation_helpers_1.DEFAULT_EVALUATION_METRIC;
440
+ nodeItem.metric_names = [predefinedMetricKey];
468
441
  }
469
- else if (node.type === constants_1.OPENAI_CHAT_LANGCHAIN_NODE_TYPE) {
470
- const enabledDefault = node.typeVersion >= 1.3 ? true : false;
471
- // For 1.3+ node version by default it is true and isn't stored in parameters
472
- nodeItem.use_responses_api = (node.parameters?.responsesApiEnabled ??
473
- enabledDefault);
442
+ else {
443
+ nodeItem.metric_names = metrics.assignments?.map((metric) => metric.name);
474
444
  }
475
- else if (node.type === constants_1.MCP_CLIENT_TOOL_NODE_TYPE || node.type === constants_1.MCP_CLIENT_NODE_TYPE) {
476
- nodeItem.mcp_client_auth_method = (node.parameters?.authentication ?? 'none');
477
- const mcpServerUrl = (node.parameters?.endpointUrl ??
478
- node.parameters?.sseEndpoint ??
479
- '');
480
- if (!(0, expression_helpers_1.isExpression)(mcpServerUrl)) {
481
- const mcpServerDomainBase = getDomainBase(mcpServerUrl);
482
- if (mcpServerDomainBase) {
483
- nodeItem.mcp_server_domain_base = mcpServerDomainBase;
484
- }
445
+ }
446
+ else if (node.type === constants_1.CODE_NODE_TYPE) {
447
+ const { language } = node.parameters;
448
+ nodeItem.language =
449
+ language === undefined
450
+ ? 'javascript'
451
+ : language === 'python' || language === 'pythonNative'
452
+ ? 'python'
453
+ : 'unknown';
454
+ }
455
+ else if (node.type === constants_1.GUARDRAILS_NODE_TYPE) {
456
+ nodeItem.operation = node.parameters.operation;
457
+ const usedGuardrails = Object.keys(node.parameters?.guardrails ?? {});
458
+ nodeItem.used_guardrails = usedGuardrails;
459
+ }
460
+ else if (node.type === constants_1.OPENAI_CHAT_LANGCHAIN_NODE_TYPE) {
461
+ const enabledDefault = node.typeVersion >= 1.3 ? true : false;
462
+ // For 1.3+ node version by default it is true and isn't stored in parameters
463
+ nodeItem.use_responses_api = (node.parameters?.responsesApiEnabled ??
464
+ enabledDefault);
465
+ }
466
+ else if (node.type === constants_1.MCP_CLIENT_TOOL_NODE_TYPE || node.type === constants_1.MCP_CLIENT_NODE_TYPE) {
467
+ nodeItem.mcp_client_auth_method = (node.parameters?.authentication ?? 'none');
468
+ const mcpServerUrl = (node.parameters?.endpointUrl ??
469
+ node.parameters?.sseEndpoint ??
470
+ '');
471
+ if (!(0, expression_helpers_1.isExpression)(mcpServerUrl)) {
472
+ const mcpServerDomainBase = getDomainBase(mcpServerUrl);
473
+ if (mcpServerDomainBase) {
474
+ nodeItem.mcp_server_domain_base = mcpServerDomainBase;
485
475
  }
486
476
  }
487
- else {
488
- try {
489
- const nodeType = nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
490
- if (nodeType) {
491
- const nodeParameters = (0, node_helpers_1.getNodeParameters)(nodeType.description.properties, node.parameters, true, false, node, nodeType.description);
492
- if (nodeParameters) {
493
- const keys = [
494
- 'operation',
495
- 'resource',
496
- 'mode',
497
- ];
498
- keys.forEach((key) => {
499
- if (nodeParameters.hasOwnProperty(key)) {
500
- nodeItem[key] = nodeParameters[key]?.toString();
501
- }
502
- });
503
- }
504
- }
505
- }
506
- catch (e) {
507
- if (!(e instanceof Error &&
508
- typeof e.message === 'string' &&
509
- e.message.includes('Unrecognized node type'))) {
510
- throw e;
477
+ }
478
+ else {
479
+ try {
480
+ const nodeType = nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
481
+ if (nodeType) {
482
+ const nodeParameters = (0, node_helpers_1.getNodeParameters)(nodeType.description.properties, node.parameters, true, false, node, nodeType.description);
483
+ if (nodeParameters) {
484
+ const keys = [
485
+ 'operation',
486
+ 'resource',
487
+ 'mode',
488
+ ];
489
+ keys.forEach((key) => {
490
+ if (nodeParameters.hasOwnProperty(key)) {
491
+ nodeItem[key] = nodeParameters[key]?.toString();
492
+ }
493
+ });
511
494
  }
512
495
  }
513
496
  }
514
- // Capture ai_model for Language Model nodes
515
- if (node.type.startsWith(constants_1.LANGCHAIN_LM_NODE_TYPE_PREFIX)) {
516
- const modelNameKeys = ['model', 'modelName'];
517
- for (const key of modelNameKeys) {
518
- const resolved = resolveParameterValue(node.parameters?.[key]);
519
- if (resolved) {
520
- nodeItem.ai_model = resolved;
521
- break;
522
- }
497
+ catch (e) {
498
+ if (!(e instanceof Error &&
499
+ typeof e.message === 'string' &&
500
+ e.message.includes('Unrecognized node type'))) {
501
+ throw e;
523
502
  }
524
503
  }
525
- // Capture ai_model for vendor/standalone AI nodes
526
- if (constants_1.AI_VENDOR_NODE_TYPES.includes(node.type)) {
527
- const resolved = resolveParameterValue(node.parameters?.modelId);
504
+ }
505
+ // Capture ai_model for Language Model nodes
506
+ if (node.type.startsWith(constants_1.LANGCHAIN_LM_NODE_TYPE_PREFIX)) {
507
+ const modelNameKeys = ['model', 'modelName'];
508
+ for (const key of modelNameKeys) {
509
+ const resolved = resolveParameterValue(node.parameters?.[key]);
528
510
  if (resolved) {
529
511
  nodeItem.ai_model = resolved;
512
+ break;
530
513
  }
531
514
  }
532
- if (nodeItem.ai_model && runData?.[node.name]) {
533
- const tokenUsage = extractNodeTokenUsage(runData[node.name]);
534
- if (tokenUsage) {
535
- nodeItem.ai_input_tokens = tokenUsage.input;
536
- nodeItem.ai_output_tokens = tokenUsage.output;
537
- }
515
+ }
516
+ // Capture ai_model for vendor/standalone AI nodes
517
+ if (constants_1.AI_VENDOR_NODE_TYPES.includes(node.type)) {
518
+ const resolved = resolveParameterValue(node.parameters?.modelId);
519
+ if (resolved) {
520
+ nodeItem.ai_model = resolved;
538
521
  }
539
- if (Object.values(node.credentials ?? {}).some((cred) => cred.__aiGatewayManaged === true)) {
540
- nodeItem.ai_gateway_credentials = true;
522
+ }
523
+ if (nodeItem.ai_model && runData?.[node.name]) {
524
+ const tokenUsage = extractNodeTokenUsage(runData[node.name]);
525
+ if (tokenUsage) {
526
+ nodeItem.ai_input_tokens = tokenUsage.input;
527
+ nodeItem.ai_output_tokens = tokenUsage.output;
541
528
  }
542
- if (options?.isCloudDeployment === true) {
543
- if (node.type === constants_1.OPENAI_LANGCHAIN_NODE_TYPE) {
544
- nodeItem.prompts =
545
- (node.parameters?.messages ?? {}).values ?? [];
529
+ }
530
+ if (Object.values(node.credentials ?? {}).some((cred) => cred.__aiGatewayManaged === true)) {
531
+ nodeItem.ai_gateway_credentials = true;
532
+ }
533
+ if (options?.isCloudDeployment === true) {
534
+ if (node.type === constants_1.OPENAI_LANGCHAIN_NODE_TYPE) {
535
+ nodeItem.prompts =
536
+ (node.parameters?.messages ?? {}).values ?? [];
537
+ }
538
+ if (node.type === constants_1.AGENT_LANGCHAIN_NODE_TYPE || node.type === constants_1.AGENT_TOOL_LANGCHAIN_NODE_TYPE) {
539
+ const prompts = {};
540
+ if (node.parameters?.text) {
541
+ prompts.text = node.parameters.text;
546
542
  }
547
- if (node.type === constants_1.AGENT_LANGCHAIN_NODE_TYPE || node.type === constants_1.AGENT_TOOL_LANGCHAIN_NODE_TYPE) {
548
- const prompts = {};
549
- if (node.parameters?.text) {
550
- prompts.text = node.parameters.text;
551
- }
552
- const nodeOptions = node.parameters?.options;
553
- if (nodeOptions) {
554
- const optionalMessagesKeys = [
555
- 'humanMessage',
556
- 'systemMessage',
557
- 'humanMessageTemplate',
558
- 'prefix',
559
- 'suffixChat',
560
- 'suffix',
561
- 'prefixPrompt',
562
- 'suffixPrompt',
563
- ];
564
- for (const key of optionalMessagesKeys) {
565
- if (nodeOptions[key]) {
566
- prompts[key] = nodeOptions[key];
567
- }
543
+ const nodeOptions = node.parameters?.options;
544
+ if (nodeOptions) {
545
+ const optionalMessagesKeys = [
546
+ 'humanMessage',
547
+ 'systemMessage',
548
+ 'humanMessageTemplate',
549
+ 'prefix',
550
+ 'suffixChat',
551
+ 'suffix',
552
+ 'prefixPrompt',
553
+ 'suffixPrompt',
554
+ ];
555
+ for (const key of optionalMessagesKeys) {
556
+ if (nodeOptions[key]) {
557
+ prompts[key] = nodeOptions[key];
568
558
  }
569
559
  }
570
- if (Object.keys(prompts).length) {
571
- nodeItem.prompts = prompts;
572
- }
573
560
  }
574
- if (node.type === constants_1.CHAIN_SUMMARIZATION_LANGCHAIN_NODE_TYPE) {
575
- nodeItem.prompts = ((node.parameters?.options ?? {})
576
- .summarizationMethodAndPrompts ?? {}).values;
577
- }
578
- if (constants_1.LANGCHAIN_CUSTOM_TOOLS.includes(node.type)) {
579
- nodeItem.prompts = {
580
- description: node.parameters?.description ?? '',
581
- };
582
- }
583
- if (node.type === constants_1.CHAIN_LLM_LANGCHAIN_NODE_TYPE) {
584
- nodeItem.prompts =
585
- (node.parameters?.messages ?? {}).messageValues ?? [];
586
- }
587
- if (node.type === constants_1.MERGE_NODE_TYPE && node.parameters?.operation === 'combineBySql') {
588
- nodeItem.sql = node.parameters?.query;
561
+ if (Object.keys(prompts).length) {
562
+ nodeItem.prompts = prompts;
589
563
  }
590
564
  }
591
- nodeGraph.nodes[index.toString()] = nodeItem;
592
- nameIndices[node.name] = index.toString();
593
- });
594
- const getGraphConnectionItem = (startNode, connectionItem) => {
595
- return { start: nameIndices[startNode], end: nameIndices[connectionItem.node] };
596
- };
597
- Object.keys(workflow.connections ?? []).forEach((nodeName) => {
598
- const connections = workflow.connections?.[nodeName];
599
- if (!connections) {
600
- return;
565
+ if (node.type === constants_1.CHAIN_SUMMARIZATION_LANGCHAIN_NODE_TYPE) {
566
+ nodeItem.prompts = ((node.parameters?.options ?? {})
567
+ .summarizationMethodAndPrompts ?? {}).values;
568
+ }
569
+ if (constants_1.LANGCHAIN_CUSTOM_TOOLS.includes(node.type)) {
570
+ nodeItem.prompts = {
571
+ description: node.parameters?.description ?? '',
572
+ };
573
+ }
574
+ if (node.type === constants_1.CHAIN_LLM_LANGCHAIN_NODE_TYPE) {
575
+ nodeItem.prompts =
576
+ (node.parameters?.messages ?? {}).messageValues ?? [];
601
577
  }
602
- Object.keys(connections).forEach((key) => {
603
- connections[key].forEach((element) => {
604
- (element ?? []).forEach((element2) => {
605
- nodeGraph.node_connections.push(getGraphConnectionItem(nodeName, element2));
606
- });
578
+ if (node.type === constants_1.MERGE_NODE_TYPE && node.parameters?.operation === 'combineBySql') {
579
+ nodeItem.sql = node.parameters?.query;
580
+ }
581
+ }
582
+ nodeGraph.nodes[index.toString()] = nodeItem;
583
+ nameIndices[node.name] = index.toString();
584
+ });
585
+ const getGraphConnectionItem = (startNode, connectionItem) => {
586
+ return { start: nameIndices[startNode], end: nameIndices[connectionItem.node] };
587
+ };
588
+ Object.keys(workflow.connections ?? []).forEach((nodeName) => {
589
+ const connections = workflow.connections?.[nodeName];
590
+ if (!connections) {
591
+ return;
592
+ }
593
+ Object.keys(connections).forEach((key) => {
594
+ connections[key].forEach((element) => {
595
+ (element ?? []).forEach((element2) => {
596
+ nodeGraph.node_connections.push(getGraphConnectionItem(nodeName, element2));
607
597
  });
608
598
  });
609
599
  });
610
- return { nodeGraph, nameIndices, webhookNodeNames, evaluationTriggerNodeNames };
611
- }
612
- function extractLastExecutedNodeCredentialData(runData) {
613
- const nodeCredentials = runData?.data?.executionData?.nodeExecutionStack?.[0]?.node?.credentials;
614
- if (!nodeCredentials)
615
- return null;
616
- const credentialType = Object.keys(nodeCredentials)[0] ?? null;
617
- if (!credentialType)
618
- return null;
619
- const { id } = nodeCredentials[credentialType];
620
- if (!id)
621
- return null;
622
- return { credentialId: id, credentialType };
623
- }
624
- const userInInstanceRanOutOfFreeAiCredits = (runData) => {
625
- const credentials = extractLastExecutedNodeCredentialData(runData);
626
- if (!credentials)
627
- return false;
628
- if (credentials.credentialType !== constants_1.OPEN_AI_API_CREDENTIAL_TYPE)
629
- return false;
630
- const { error } = runData.data.resultData;
631
- if (!isNodeApiError(error) || !error.messages[0])
632
- return false;
633
- const rawErrorResponse = error.messages[0].replace(`${error.httpCode} -`, '');
634
- try {
635
- const errorResponse = (0, utils_1.jsonParse)(rawErrorResponse);
636
- if (errorResponse?.error?.type === constants_1.FREE_AI_CREDITS_ERROR_TYPE &&
637
- errorResponse.error.code === constants_1.FREE_AI_CREDITS_USED_ALL_CREDITS_ERROR_CODE) {
638
- return true;
639
- }
640
- }
641
- catch {
642
- return false;
600
+ });
601
+ return { nodeGraph, nameIndices, webhookNodeNames, evaluationTriggerNodeNames };
602
+ }
603
+ function extractLastExecutedNodeCredentialData(runData) {
604
+ const nodeCredentials = runData?.data?.executionData?.nodeExecutionStack?.[0]?.node?.credentials;
605
+ if (!nodeCredentials)
606
+ return null;
607
+ const credentialType = Object.keys(nodeCredentials)[0] ?? null;
608
+ if (!credentialType)
609
+ return null;
610
+ const { id } = nodeCredentials[credentialType];
611
+ if (!id)
612
+ return null;
613
+ return { credentialId: id, credentialType };
614
+ }
615
+ const userInInstanceRanOutOfFreeAiCredits = (runData) => {
616
+ const credentials = extractLastExecutedNodeCredentialData(runData);
617
+ if (!credentials)
618
+ return false;
619
+ if (credentials.credentialType !== constants_1.OPEN_AI_API_CREDENTIAL_TYPE)
620
+ return false;
621
+ const { error } = runData.data.resultData;
622
+ if (!isNodeApiError(error) || !error.messages[0])
623
+ return false;
624
+ const rawErrorResponse = error.messages[0].replace(`${error.httpCode} -`, '');
625
+ try {
626
+ const errorResponse = (0, utils_1.jsonParse)(rawErrorResponse);
627
+ if (errorResponse?.error?.type === constants_1.FREE_AI_CREDITS_ERROR_TYPE &&
628
+ errorResponse.error.code === constants_1.FREE_AI_CREDITS_USED_ALL_CREDITS_ERROR_CODE) {
629
+ return true;
643
630
  }
631
+ }
632
+ catch {
644
633
  return false;
645
- };
646
- exports.userInInstanceRanOutOfFreeAiCredits = userInInstanceRanOutOfFreeAiCredits;
647
- function resolveAIMetrics(nodes, nodeTypes) {
648
- const resolvedNodes = nodes
649
- .map((x) => [x, nodeTypes.getByNameAndVersion(x.type, x.typeVersion)])
650
- .filter((x) => !!x[1]?.description);
651
- const aiNodeCount = resolvedNodes.reduce((acc, x) => acc + Number(x[1].description.codex?.categories?.includes('AI')), 0);
652
- if (aiNodeCount === 0)
653
- return {};
654
- let fromAIOverrideCount = 0;
655
- let fromAIExpressionCount = 0;
656
- const tools = resolvedNodes.filter((node) => node[1].description.codex?.subcategories?.AI?.includes('Tools'));
657
- for (const [node, _] of tools) {
658
- // FlatMap to support values in resourceLocators
659
- const values = Object.values(node.parameters).flatMap((param) => {
660
- if (param && typeof param === 'object' && 'value' in param)
661
- param = param.value;
662
- return typeof param === 'string' ? param : [];
663
- });
664
- // Note that we don't match the i in `fromAI` to support lower case i (though we miss fromai)
665
- const overrides = values.reduce((acc, value) => acc + Number(value.startsWith(`={{ ${constants_1.FROM_AI_AUTO_GENERATED_MARKER} $fromA`)), 0);
666
- fromAIOverrideCount += overrides;
667
- // check for = to avoid scanning lengthy text fields
668
- // this will re-count overrides
669
- fromAIExpressionCount +=
670
- values.reduce((acc, value) => acc + Number(value[0] === '=' && value.includes('$fromA', 2)), 0) - overrides;
671
- }
672
- return {
673
- aiNodeCount,
674
- aiToolCount: tools.length,
675
- fromAIOverrideCount,
676
- fromAIExpressionCount,
677
- };
678
634
  }
679
- function resolveVectorStoreMetrics(nodes, nodeTypes, run) {
680
- const resolvedNodes = nodes
681
- .map((x) => [x, nodeTypes.getByNameAndVersion(x.type, x.typeVersion)])
682
- .filter((x) => !!x[1]?.description);
683
- const vectorStores = resolvedNodes.filter((x) => x[1].description.codex?.categories?.includes('AI') &&
684
- x[1].description.codex?.subcategories?.AI?.includes('Vector Stores'));
685
- if (vectorStores.length === 0)
686
- return {};
687
- const runData = run?.data?.resultData?.runData;
688
- const succeededVectorStores = vectorStores.filter((x) => runData?.[x[0].name]?.some((execution) => execution.executionStatus === 'success'));
689
- const insertingVectorStores = succeededVectorStores.filter((x) => x[0].parameters?.mode === 'insert');
690
- const retrievingVectorStores = succeededVectorStores.filter((x) => ['retrieve-as-tool', 'retrieve', 'load'].find((y) => y === x[0].parameters?.mode));
691
- return {
692
- insertedIntoVectorStore: insertingVectorStores.length > 0,
693
- queriedDataFromVectorStore: retrievingVectorStores.length > 0,
694
- };
635
+ return false;
636
+ };
637
+ exports.userInInstanceRanOutOfFreeAiCredits = userInInstanceRanOutOfFreeAiCredits;
638
+ function resolveAIMetrics(nodes, nodeTypes) {
639
+ const resolvedNodes = nodes
640
+ .map((x) => [x, nodeTypes.getByNameAndVersion(x.type, x.typeVersion)])
641
+ .filter((x) => !!x[1]?.description);
642
+ const aiNodeCount = resolvedNodes.reduce((acc, x) => acc + Number(x[1].description.codex?.categories?.includes('AI')), 0);
643
+ if (aiNodeCount === 0)
644
+ return {};
645
+ let fromAIOverrideCount = 0;
646
+ let fromAIExpressionCount = 0;
647
+ const tools = resolvedNodes.filter((node) => node[1].description.codex?.subcategories?.AI?.includes('Tools'));
648
+ for (const [node, _] of tools) {
649
+ // FlatMap to support values in resourceLocators
650
+ const values = Object.values(node.parameters).flatMap((param) => {
651
+ if (param && typeof param === 'object' && 'value' in param)
652
+ param = param.value;
653
+ return typeof param === 'string' ? param : [];
654
+ });
655
+ // Note that we don't match the i in `fromAI` to support lower case i (though we miss fromai)
656
+ const overrides = values.reduce((acc, value) => acc + Number(value.startsWith(`={{ ${constants_1.FROM_AI_AUTO_GENERATED_MARKER} $fromA`)), 0);
657
+ fromAIOverrideCount += overrides;
658
+ // check for = to avoid scanning lengthy text fields
659
+ // this will re-count overrides
660
+ fromAIExpressionCount +=
661
+ values.reduce((acc, value) => acc + Number(value[0] === '=' && value.includes('$fromA', 2)), 0) - overrides;
695
662
  }
696
- /**
697
- * Extract additional debug information if the last executed node was an agent node
698
- */
699
- function extractLastExecutedNodeStructuredOutputErrorInfo(workflow, nodeTypes, runData) {
700
- const info = {};
701
- if (runData?.data.resultData.error && runData.data.resultData.lastNodeExecuted) {
702
- const lastNode = getNodeTypeForName(workflow, runData.data.resultData.lastNodeExecuted);
703
- if (lastNode !== undefined) {
704
- if (lastNode.type === constants_1.AGENT_LANGCHAIN_NODE_TYPE && lastNode.parameters.hasOutputParser) {
705
- // Add additional debug info for agent node structured output errors
706
- const agentOutputError = runData.data.resultData.runData[lastNode.name]?.[0]?.error;
707
- if (agentOutputError &&
708
- agentOutputError.message === "Model output doesn't fit required format") {
709
- info.output_parser_fail_reason = agentOutputError.context
710
- ?.outputParserFailReason;
711
- }
712
- if (workflow.connections) {
713
- // Count connected tools
714
- info.num_tools =
715
- Object.keys(workflow.connections).filter((node) => workflow.connections[node]?.[interfaces_1.NodeConnectionTypes.AiTool]?.[0]?.some((connectedNode) => connectedNode.node === lastNode.name))?.length ?? 0;
716
- // Extract model name from the language model node if connected
717
- const languageModelNodeName = Object.keys(workflow.connections).find((node) => workflow.connections[node]?.[interfaces_1.NodeConnectionTypes.AiLanguageModel]?.[0]?.some((connectedNode) => connectedNode.node === lastNode.name));
718
- if (languageModelNodeName) {
719
- const languageModelNode = getNodeTypeForName(workflow, languageModelNodeName);
720
- if (languageModelNode) {
721
- const nodeType = nodeTypes.getByNameAndVersion(languageModelNode.type, languageModelNode.typeVersion);
722
- if (nodeType) {
723
- const nodeParameters = (0, node_helpers_1.getNodeParameters)(nodeType.description.properties, languageModelNode.parameters, true, false, languageModelNode, nodeType.description);
724
- const modelNameKeys = ['model', 'modelName'];
725
- for (const key of modelNameKeys) {
726
- const resolved = resolveParameterValue(nodeParameters?.[key]);
727
- if (resolved) {
728
- info.model_name = resolved;
729
- break;
730
- }
663
+ return {
664
+ aiNodeCount,
665
+ aiToolCount: tools.length,
666
+ fromAIOverrideCount,
667
+ fromAIExpressionCount,
668
+ };
669
+ }
670
+ function resolveVectorStoreMetrics(nodes, nodeTypes, run) {
671
+ const resolvedNodes = nodes
672
+ .map((x) => [x, nodeTypes.getByNameAndVersion(x.type, x.typeVersion)])
673
+ .filter((x) => !!x[1]?.description);
674
+ const vectorStores = resolvedNodes.filter((x) => x[1].description.codex?.categories?.includes('AI') &&
675
+ x[1].description.codex?.subcategories?.AI?.includes('Vector Stores'));
676
+ if (vectorStores.length === 0)
677
+ return {};
678
+ const runData = run?.data?.resultData?.runData;
679
+ const succeededVectorStores = vectorStores.filter((x) => runData?.[x[0].name]?.some((execution) => execution.executionStatus === 'success'));
680
+ const insertingVectorStores = succeededVectorStores.filter((x) => x[0].parameters?.mode === 'insert');
681
+ const retrievingVectorStores = succeededVectorStores.filter((x) => ['retrieve-as-tool', 'retrieve', 'load'].find((y) => y === x[0].parameters?.mode));
682
+ return {
683
+ insertedIntoVectorStore: insertingVectorStores.length > 0,
684
+ queriedDataFromVectorStore: retrievingVectorStores.length > 0,
685
+ };
686
+ }
687
+ /**
688
+ * Extract additional debug information if the last executed node was an agent node
689
+ */
690
+ function extractLastExecutedNodeStructuredOutputErrorInfo(workflow, nodeTypes, runData) {
691
+ const info = {};
692
+ if (runData?.data.resultData.error && runData.data.resultData.lastNodeExecuted) {
693
+ const lastNode = getNodeTypeForName(workflow, runData.data.resultData.lastNodeExecuted);
694
+ if (lastNode !== undefined) {
695
+ if (lastNode.type === constants_1.AGENT_LANGCHAIN_NODE_TYPE && lastNode.parameters.hasOutputParser) {
696
+ // Add additional debug info for agent node structured output errors
697
+ const agentOutputError = runData.data.resultData.runData[lastNode.name]?.[0]?.error;
698
+ if (agentOutputError &&
699
+ agentOutputError.message === "Model output doesn't fit required format") {
700
+ info.output_parser_fail_reason = agentOutputError.context
701
+ ?.outputParserFailReason;
702
+ }
703
+ if (workflow.connections) {
704
+ // Count connected tools
705
+ info.num_tools =
706
+ Object.keys(workflow.connections).filter((node) => workflow.connections[node]?.[interfaces_1.NodeConnectionTypes.AiTool]?.[0]?.some((connectedNode) => connectedNode.node === lastNode.name))?.length ?? 0;
707
+ // Extract model name from the language model node if connected
708
+ const languageModelNodeName = Object.keys(workflow.connections).find((node) => workflow.connections[node]?.[interfaces_1.NodeConnectionTypes.AiLanguageModel]?.[0]?.some((connectedNode) => connectedNode.node === lastNode.name));
709
+ if (languageModelNodeName) {
710
+ const languageModelNode = getNodeTypeForName(workflow, languageModelNodeName);
711
+ if (languageModelNode) {
712
+ const nodeType = nodeTypes.getByNameAndVersion(languageModelNode.type, languageModelNode.typeVersion);
713
+ if (nodeType) {
714
+ const nodeParameters = (0, node_helpers_1.getNodeParameters)(nodeType.description.properties, languageModelNode.parameters, true, false, languageModelNode, nodeType.description);
715
+ const modelNameKeys = ['model', 'modelName'];
716
+ for (const key of modelNameKeys) {
717
+ const resolved = resolveParameterValue(nodeParameters?.[key]);
718
+ if (resolved) {
719
+ info.model_name = resolved;
720
+ break;
731
721
  }
732
722
  }
733
723
  }
@@ -736,78 +726,78 @@
736
726
  }
737
727
  }
738
728
  }
739
- return info;
740
729
  }
741
- /**
742
- * Determines the role of a node in a workflow based on its connections.
743
- *
744
- * @param nodeName - The name of the node to check
745
- * @param connections - The workflow connections (connectionsBySourceNode format)
746
- * @param nodeTypes - The node types registry
747
- * @param nodes - The workflow nodes
748
- * @returns The role of the node:
749
- * - 'trigger': Has no incoming main connections and is not a subnode
750
- * - 'terminal': Has no outgoing connections
751
- * - 'internal': Has both incoming and outgoing connections, or is a subnode
752
- */
753
- function getNodeRole(nodeName, connections, nodeTypes, nodes) {
754
- // partial executions of tools get a special name
755
- if (nodeName === 'PartialExecutionToolExecutor') {
756
- return 'internal';
757
- }
758
- // Check if node is a subnode based on its type description
759
- const node = nodes.find((n) => n.name === nodeName);
760
- const nodeTypeDescription = node
761
- ? (nodeTypes.getByNameAndVersion(node.type, node.typeVersion)?.description ?? null)
762
- : null;
763
- const isSubnode = (0, node_helpers_1.isSubNodeType)(nodeTypeDescription);
764
- // Subnodes are always internal (they connect via AI connection types, not main)
765
- if (isSubnode) {
766
- return 'internal';
767
- }
768
- const hasOutgoingConnections = hasOutgoing(nodeName, connections);
769
- const hasIncomingMainConnections = hasIncomingMain(nodeName, connections);
770
- // A trigger has no incoming main connections
771
- if (!hasIncomingMainConnections) {
772
- return 'trigger';
773
- }
774
- // A terminal node has no outgoing connections
775
- if (!hasOutgoingConnections) {
776
- return 'terminal';
777
- }
778
- // Otherwise it's internal
730
+ return info;
731
+ }
732
+ /**
733
+ * Determines the role of a node in a workflow based on its connections.
734
+ *
735
+ * @param nodeName - The name of the node to check
736
+ * @param connections - The workflow connections (connectionsBySourceNode format)
737
+ * @param nodeTypes - The node types registry
738
+ * @param nodes - The workflow nodes
739
+ * @returns The role of the node:
740
+ * - 'trigger': Has no incoming main connections and is not a subnode
741
+ * - 'terminal': Has no outgoing connections
742
+ * - 'internal': Has both incoming and outgoing connections, or is a subnode
743
+ */
744
+ function getNodeRole(nodeName, connections, nodeTypes, nodes) {
745
+ // partial executions of tools get a special name
746
+ if (nodeName === 'PartialExecutionToolExecutor') {
779
747
  return 'internal';
780
748
  }
781
- function hasOutgoing(nodeName, connections) {
782
- const mainConnections = connections[nodeName]?.[interfaces_1.NodeConnectionTypes.Main];
783
- if (!mainConnections) {
784
- return false;
785
- }
786
- for (const outputIndex of mainConnections) {
787
- if (outputIndex && outputIndex.length > 0) {
788
- return true;
789
- }
790
- }
749
+ // Check if node is a subnode based on its type description
750
+ const node = nodes.find((n) => n.name === nodeName);
751
+ const nodeTypeDescription = node
752
+ ? (nodeTypes.getByNameAndVersion(node.type, node.typeVersion)?.description ?? null)
753
+ : null;
754
+ const isSubnode = (0, node_helpers_1.isSubNodeType)(nodeTypeDescription);
755
+ // Subnodes are always internal (they connect via AI connection types, not main)
756
+ if (isSubnode) {
757
+ return 'internal';
758
+ }
759
+ const hasOutgoingConnections = hasOutgoing(nodeName, connections);
760
+ const hasIncomingMainConnections = hasIncomingMain(nodeName, connections);
761
+ // A trigger has no incoming main connections
762
+ if (!hasIncomingMainConnections) {
763
+ return 'trigger';
764
+ }
765
+ // A terminal node has no outgoing connections
766
+ if (!hasOutgoingConnections) {
767
+ return 'terminal';
768
+ }
769
+ // Otherwise it's internal
770
+ return 'internal';
771
+ }
772
+ function hasOutgoing(nodeName, connections) {
773
+ const mainConnections = connections[nodeName]?.[interfaces_1.NodeConnectionTypes.Main];
774
+ if (!mainConnections) {
791
775
  return false;
792
776
  }
793
- function hasIncomingMain(nodeName, connections) {
794
- // Check all source nodes to see if any connect to this node via main connection
795
- for (const sourceNode of Object.keys(connections)) {
796
- const sourceConnections = connections[sourceNode];
797
- const mainConnections = sourceConnections?.[interfaces_1.NodeConnectionTypes.Main];
798
- if (!mainConnections)
777
+ for (const outputIndex of mainConnections) {
778
+ if (outputIndex && outputIndex.length > 0) {
779
+ return true;
780
+ }
781
+ }
782
+ return false;
783
+ }
784
+ function hasIncomingMain(nodeName, connections) {
785
+ // Check all source nodes to see if any connect to this node via main connection
786
+ for (const sourceNode of Object.keys(connections)) {
787
+ const sourceConnections = connections[sourceNode];
788
+ const mainConnections = sourceConnections?.[interfaces_1.NodeConnectionTypes.Main];
789
+ if (!mainConnections)
790
+ continue;
791
+ for (const outputIndex of mainConnections) {
792
+ if (!outputIndex)
799
793
  continue;
800
- for (const outputIndex of mainConnections) {
801
- if (!outputIndex)
802
- continue;
803
- for (const conn of outputIndex) {
804
- if (conn.node === nodeName) {
805
- return true;
806
- }
794
+ for (const conn of outputIndex) {
795
+ if (conn.node === nodeName) {
796
+ return true;
807
797
  }
808
798
  }
809
799
  }
810
- return false;
811
800
  }
812
- });
801
+ return false;
802
+ }
813
803
  //# sourceMappingURL=telemetry-helpers.js.map