beddel 0.2.2 → 0.2.3

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 (330) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +117 -14
  3. package/dist/agents/chat/chat.handler.d.ts +12 -0
  4. package/dist/agents/chat/chat.handler.d.ts.map +1 -0
  5. package/dist/agents/chat/chat.handler.js +143 -0
  6. package/dist/agents/chat/chat.handler.js.map +1 -0
  7. package/dist/agents/chat/chat.schema.d.ts +38 -0
  8. package/dist/agents/chat/chat.schema.d.ts.map +1 -0
  9. package/dist/agents/chat/chat.schema.js +31 -0
  10. package/dist/agents/chat/chat.schema.js.map +1 -0
  11. package/dist/agents/chat/chat.types.d.ts +42 -0
  12. package/dist/agents/chat/chat.types.d.ts.map +1 -0
  13. package/dist/agents/chat/chat.types.js +6 -0
  14. package/dist/agents/chat/chat.types.js.map +1 -0
  15. package/dist/agents/chat/chat.yaml +150 -0
  16. package/dist/agents/chat/index.d.ts +16 -0
  17. package/dist/agents/chat/index.d.ts.map +1 -0
  18. package/dist/agents/chat/index.js +21 -0
  19. package/dist/agents/chat/index.js.map +1 -0
  20. package/dist/agents/chromadb/chromadb.handler.d.ts +12 -0
  21. package/dist/agents/chromadb/chromadb.handler.d.ts.map +1 -0
  22. package/dist/agents/chromadb/chromadb.handler.js +139 -0
  23. package/dist/agents/chromadb/chromadb.handler.js.map +1 -0
  24. package/dist/agents/chromadb/chromadb.schema.d.ts +36 -0
  25. package/dist/agents/chromadb/chromadb.schema.d.ts.map +1 -0
  26. package/dist/agents/chromadb/chromadb.schema.js +33 -0
  27. package/dist/agents/chromadb/chromadb.schema.js.map +1 -0
  28. package/dist/agents/chromadb/chromadb.types.d.ts +49 -0
  29. package/dist/agents/chromadb/chromadb.types.d.ts.map +1 -0
  30. package/dist/agents/chromadb/chromadb.types.js +6 -0
  31. package/dist/agents/chromadb/chromadb.types.js.map +1 -0
  32. package/dist/agents/chromadb/chromadb.yaml +128 -0
  33. package/dist/agents/chromadb/index.d.ts +15 -0
  34. package/dist/agents/chromadb/index.d.ts.map +1 -0
  35. package/dist/agents/chromadb/index.js +20 -0
  36. package/dist/agents/chromadb/index.js.map +1 -0
  37. package/dist/agents/gemini-vectorize/gemini-vectorize.handler.d.ts +8 -0
  38. package/dist/agents/gemini-vectorize/gemini-vectorize.handler.d.ts.map +1 -0
  39. package/dist/agents/gemini-vectorize/gemini-vectorize.handler.js +58 -0
  40. package/dist/agents/gemini-vectorize/gemini-vectorize.handler.js.map +1 -0
  41. package/dist/agents/gemini-vectorize/gemini-vectorize.schema.d.ts +22 -0
  42. package/dist/agents/gemini-vectorize/gemini-vectorize.schema.d.ts.map +1 -0
  43. package/dist/agents/gemini-vectorize/gemini-vectorize.schema.js +20 -0
  44. package/dist/agents/gemini-vectorize/gemini-vectorize.schema.js.map +1 -0
  45. package/dist/agents/gemini-vectorize/gemini-vectorize.types.d.ts +32 -0
  46. package/dist/agents/gemini-vectorize/gemini-vectorize.types.d.ts.map +1 -0
  47. package/dist/agents/gemini-vectorize/gemini-vectorize.types.js +6 -0
  48. package/dist/agents/gemini-vectorize/gemini-vectorize.types.js.map +1 -0
  49. package/dist/agents/gemini-vectorize/gemini-vectorize.yaml +84 -0
  50. package/dist/agents/gemini-vectorize/index.d.ts +15 -0
  51. package/dist/agents/gemini-vectorize/index.d.ts.map +1 -0
  52. package/dist/agents/gemini-vectorize/index.js +20 -0
  53. package/dist/agents/gemini-vectorize/index.js.map +1 -0
  54. package/dist/agents/gitmcp/gitmcp.handler.d.ts +12 -0
  55. package/dist/agents/gitmcp/gitmcp.handler.d.ts.map +1 -0
  56. package/dist/agents/gitmcp/gitmcp.handler.js +95 -0
  57. package/dist/agents/gitmcp/gitmcp.handler.js.map +1 -0
  58. package/dist/agents/gitmcp/gitmcp.schema.d.ts +17 -0
  59. package/dist/agents/gitmcp/gitmcp.schema.d.ts.map +1 -0
  60. package/dist/agents/gitmcp/gitmcp.schema.js +18 -0
  61. package/dist/agents/gitmcp/gitmcp.schema.js.map +1 -0
  62. package/dist/agents/gitmcp/gitmcp.types.d.ts +31 -0
  63. package/dist/agents/gitmcp/gitmcp.types.d.ts.map +1 -0
  64. package/dist/agents/gitmcp/gitmcp.types.js +6 -0
  65. package/dist/agents/gitmcp/gitmcp.types.js.map +1 -0
  66. package/dist/agents/gitmcp/gitmcp.yaml +71 -0
  67. package/dist/agents/gitmcp/index.d.ts +16 -0
  68. package/dist/agents/gitmcp/index.d.ts.map +1 -0
  69. package/dist/agents/gitmcp/index.js +21 -0
  70. package/dist/agents/gitmcp/index.js.map +1 -0
  71. package/dist/agents/image/image.handler.d.ts +8 -0
  72. package/dist/agents/image/image.handler.d.ts.map +1 -0
  73. package/dist/agents/image/image.handler.js +66 -0
  74. package/dist/agents/image/image.handler.js.map +1 -0
  75. package/dist/agents/image/image.schema.d.ts +29 -0
  76. package/dist/agents/image/image.schema.d.ts.map +1 -0
  77. package/dist/agents/image/image.schema.js +26 -0
  78. package/dist/agents/image/image.schema.js.map +1 -0
  79. package/dist/agents/image/image.types.d.ts +42 -0
  80. package/dist/agents/image/image.types.d.ts.map +1 -0
  81. package/dist/agents/image/image.types.js +6 -0
  82. package/dist/agents/image/image.types.js.map +1 -0
  83. package/{src/agents/image-agent.yaml → dist/agents/image/image.yaml} +21 -21
  84. package/dist/agents/image/index.d.ts +14 -0
  85. package/dist/agents/image/index.d.ts.map +1 -0
  86. package/dist/agents/image/index.js +19 -0
  87. package/dist/agents/image/index.js.map +1 -0
  88. package/dist/agents/index.d.ts +95 -0
  89. package/dist/agents/index.d.ts.map +1 -0
  90. package/dist/agents/index.js +76 -0
  91. package/dist/agents/index.js.map +1 -0
  92. package/dist/agents/joker/index.d.ts +14 -0
  93. package/dist/agents/joker/index.d.ts.map +1 -0
  94. package/dist/agents/joker/index.js +19 -0
  95. package/dist/agents/joker/index.js.map +1 -0
  96. package/dist/agents/joker/joker.handler.d.ts +8 -0
  97. package/dist/agents/joker/joker.handler.d.ts.map +1 -0
  98. package/dist/agents/joker/joker.handler.js +48 -0
  99. package/dist/agents/joker/joker.handler.js.map +1 -0
  100. package/dist/agents/joker/joker.schema.d.ts +12 -0
  101. package/dist/agents/joker/joker.schema.d.ts.map +1 -0
  102. package/dist/agents/joker/joker.schema.js +13 -0
  103. package/dist/agents/joker/joker.schema.js.map +1 -0
  104. package/dist/agents/joker/joker.types.d.ts +35 -0
  105. package/dist/agents/joker/joker.types.d.ts.map +1 -0
  106. package/dist/agents/joker/joker.types.js +6 -0
  107. package/dist/agents/joker/joker.types.js.map +1 -0
  108. package/{src/agents/joker-agent.yaml → dist/agents/joker/joker.yaml} +4 -4
  109. package/dist/agents/mcp-tool/index.d.ts +14 -0
  110. package/dist/agents/mcp-tool/index.d.ts.map +1 -0
  111. package/dist/agents/mcp-tool/index.js +19 -0
  112. package/dist/agents/mcp-tool/index.js.map +1 -0
  113. package/dist/agents/mcp-tool/mcp-tool.handler.d.ts +12 -0
  114. package/dist/agents/mcp-tool/mcp-tool.handler.d.ts.map +1 -0
  115. package/dist/agents/mcp-tool/mcp-tool.handler.js +116 -0
  116. package/dist/agents/mcp-tool/mcp-tool.handler.js.map +1 -0
  117. package/dist/agents/mcp-tool/mcp-tool.schema.d.ts +19 -0
  118. package/dist/agents/mcp-tool/mcp-tool.schema.d.ts.map +1 -0
  119. package/dist/agents/mcp-tool/mcp-tool.schema.js +20 -0
  120. package/dist/agents/mcp-tool/mcp-tool.schema.js.map +1 -0
  121. package/dist/agents/mcp-tool/mcp-tool.types.d.ts +31 -0
  122. package/dist/agents/mcp-tool/mcp-tool.types.d.ts.map +1 -0
  123. package/dist/agents/mcp-tool/mcp-tool.types.js +6 -0
  124. package/dist/agents/mcp-tool/mcp-tool.types.js.map +1 -0
  125. package/dist/agents/mcp-tool/mcp-tool.yaml +71 -0
  126. package/dist/agents/rag/index.d.ts +15 -0
  127. package/dist/agents/rag/index.d.ts.map +1 -0
  128. package/dist/agents/rag/index.js +20 -0
  129. package/dist/agents/rag/index.js.map +1 -0
  130. package/dist/agents/rag/rag.handler.d.ts +8 -0
  131. package/dist/agents/rag/rag.handler.d.ts.map +1 -0
  132. package/dist/agents/rag/rag.handler.js +101 -0
  133. package/dist/agents/rag/rag.handler.js.map +1 -0
  134. package/dist/agents/rag/rag.schema.d.ts +27 -0
  135. package/dist/agents/rag/rag.schema.d.ts.map +1 -0
  136. package/dist/agents/rag/rag.schema.js +24 -0
  137. package/dist/agents/rag/rag.schema.js.map +1 -0
  138. package/dist/agents/rag/rag.types.d.ts +47 -0
  139. package/dist/agents/rag/rag.types.d.ts.map +1 -0
  140. package/dist/agents/rag/rag.types.js +6 -0
  141. package/dist/agents/rag/rag.types.js.map +1 -0
  142. package/dist/agents/rag/rag.yaml +89 -0
  143. package/dist/agents/{agentRegistry.d.ts → registry/agentRegistry.d.ts} +25 -1
  144. package/dist/agents/registry/agentRegistry.d.ts.map +1 -0
  145. package/dist/agents/{agentRegistry.js → registry/agentRegistry.js} +154 -4
  146. package/dist/agents/registry/agentRegistry.js.map +1 -0
  147. package/dist/agents/registry/index.d.ts +6 -0
  148. package/dist/agents/registry/index.d.ts.map +1 -0
  149. package/dist/agents/registry/index.js +10 -0
  150. package/dist/agents/registry/index.js.map +1 -0
  151. package/dist/agents/translator/index.d.ts +14 -0
  152. package/dist/agents/translator/index.d.ts.map +1 -0
  153. package/dist/agents/translator/index.js +19 -0
  154. package/dist/agents/translator/index.js.map +1 -0
  155. package/dist/agents/translator/translator.handler.d.ts +8 -0
  156. package/dist/agents/translator/translator.handler.d.ts.map +1 -0
  157. package/dist/agents/translator/translator.handler.js +83 -0
  158. package/dist/agents/translator/translator.handler.js.map +1 -0
  159. package/dist/agents/translator/translator.schema.d.ts +27 -0
  160. package/dist/agents/translator/translator.schema.d.ts.map +1 -0
  161. package/dist/agents/translator/translator.schema.js +28 -0
  162. package/dist/agents/translator/translator.schema.js.map +1 -0
  163. package/dist/agents/translator/translator.types.d.ts +40 -0
  164. package/dist/agents/translator/translator.types.d.ts.map +1 -0
  165. package/dist/agents/translator/translator.types.js +6 -0
  166. package/dist/agents/translator/translator.types.js.map +1 -0
  167. package/{src/agents/translator-agent.yaml → dist/agents/translator/translator.yaml} +27 -27
  168. package/dist/client/index.d.ts +89 -0
  169. package/dist/client/index.d.ts.map +1 -0
  170. package/dist/client/index.js +93 -0
  171. package/dist/client/index.js.map +1 -0
  172. package/dist/client/types.d.ts +17 -0
  173. package/dist/client/types.d.ts.map +1 -0
  174. package/dist/client/types.js +7 -0
  175. package/dist/client/types.js.map +1 -0
  176. package/dist/firebase/tenantManager.d.ts +34 -2
  177. package/dist/firebase/tenantManager.d.ts.map +1 -1
  178. package/dist/firebase/tenantManager.js +67 -1
  179. package/dist/firebase/tenantManager.js.map +1 -1
  180. package/dist/index.d.ts +8 -4
  181. package/dist/index.d.ts.map +1 -1
  182. package/dist/index.js +22 -7
  183. package/dist/index.js.map +1 -1
  184. package/dist/runtime/declarativeAgentRuntime.d.ts +14 -49
  185. package/dist/runtime/declarativeAgentRuntime.d.ts.map +1 -1
  186. package/dist/runtime/declarativeAgentRuntime.js +248 -355
  187. package/dist/runtime/declarativeAgentRuntime.js.map +1 -1
  188. package/dist/runtime/index.d.ts +12 -0
  189. package/dist/runtime/index.d.ts.map +1 -0
  190. package/dist/runtime/index.js +33 -0
  191. package/dist/runtime/index.js.map +1 -0
  192. package/dist/runtime/workflowExecutor.d.ts +30 -0
  193. package/dist/runtime/workflowExecutor.d.ts.map +1 -0
  194. package/dist/runtime/workflowExecutor.js +70 -0
  195. package/dist/runtime/workflowExecutor.js.map +1 -0
  196. package/dist/server/api/graphql.js +3 -3
  197. package/dist/server/api/graphql.js.map +1 -1
  198. package/dist/server/index.d.ts +2 -2
  199. package/dist/server/index.d.ts.map +1 -1
  200. package/dist/server/index.js +2 -2
  201. package/dist/server/index.js.map +1 -1
  202. package/dist/shared/index.d.ts +7 -0
  203. package/dist/shared/index.d.ts.map +1 -0
  204. package/dist/shared/index.js +23 -0
  205. package/dist/shared/index.js.map +1 -0
  206. package/dist/shared/types/agent.types.d.ts +50 -0
  207. package/dist/shared/types/agent.types.d.ts.map +1 -0
  208. package/dist/shared/types/agent.types.js +7 -0
  209. package/dist/shared/types/agent.types.js.map +1 -0
  210. package/dist/shared/types/execution.types.d.ts +42 -0
  211. package/dist/shared/types/execution.types.d.ts.map +1 -0
  212. package/dist/shared/types/execution.types.js +7 -0
  213. package/dist/shared/types/execution.types.js.map +1 -0
  214. package/dist/shared/types/index.d.ts +7 -0
  215. package/dist/shared/types/index.d.ts.map +1 -0
  216. package/dist/shared/types/index.js +23 -0
  217. package/dist/shared/types/index.js.map +1 -0
  218. package/dist/shared/types/schema.types.d.ts +52 -0
  219. package/dist/shared/types/schema.types.d.ts.map +1 -0
  220. package/dist/shared/types/schema.types.js +7 -0
  221. package/dist/shared/types/schema.types.js.map +1 -0
  222. package/dist/shared/utils/index.d.ts +5 -0
  223. package/dist/shared/utils/index.d.ts.map +1 -0
  224. package/dist/shared/utils/index.js +21 -0
  225. package/dist/shared/utils/index.js.map +1 -0
  226. package/dist/shared/utils/validation.d.ts +42 -0
  227. package/dist/shared/utils/validation.d.ts.map +1 -0
  228. package/dist/shared/utils/validation.js +93 -0
  229. package/dist/shared/utils/validation.js.map +1 -0
  230. package/dist/tenant/TenantManager.d.ts +152 -0
  231. package/dist/tenant/TenantManager.d.ts.map +1 -0
  232. package/dist/tenant/TenantManager.js +392 -0
  233. package/dist/tenant/TenantManager.js.map +1 -0
  234. package/dist/tenant/index.d.ts +47 -0
  235. package/dist/tenant/index.d.ts.map +1 -0
  236. package/dist/tenant/index.js +74 -0
  237. package/dist/tenant/index.js.map +1 -0
  238. package/dist/tenant/interfaces.d.ts +170 -0
  239. package/dist/tenant/interfaces.d.ts.map +1 -0
  240. package/dist/tenant/interfaces.js +67 -0
  241. package/dist/tenant/interfaces.js.map +1 -0
  242. package/dist/tenant/providerFactory.d.ts +43 -0
  243. package/dist/tenant/providerFactory.d.ts.map +1 -0
  244. package/dist/tenant/providerFactory.js +70 -0
  245. package/dist/tenant/providerFactory.js.map +1 -0
  246. package/dist/tenant/providerRegistry.d.ts +47 -0
  247. package/dist/tenant/providerRegistry.d.ts.map +1 -0
  248. package/dist/tenant/providerRegistry.js +79 -0
  249. package/dist/tenant/providerRegistry.js.map +1 -0
  250. package/dist/tenant/providers/FirebaseTenantProvider.d.ts +41 -0
  251. package/dist/tenant/providers/FirebaseTenantProvider.d.ts.map +1 -0
  252. package/dist/tenant/providers/FirebaseTenantProvider.js +290 -0
  253. package/dist/tenant/providers/FirebaseTenantProvider.js.map +1 -0
  254. package/dist/tenant/providers/InMemoryTenantProvider.d.ts +18 -0
  255. package/dist/tenant/providers/InMemoryTenantProvider.d.ts.map +1 -0
  256. package/dist/tenant/providers/InMemoryTenantProvider.js +137 -0
  257. package/dist/tenant/providers/InMemoryTenantProvider.js.map +1 -0
  258. package/package.json +46 -12
  259. package/src/agents/chat/chat.handler.ts +209 -0
  260. package/src/agents/chat/chat.schema.ts +33 -0
  261. package/src/agents/chat/chat.types.ts +46 -0
  262. package/src/agents/chat/chat.yaml +150 -0
  263. package/src/agents/chat/index.ts +21 -0
  264. package/src/agents/chromadb/chromadb.handler.ts +130 -0
  265. package/src/agents/chromadb/chromadb.schema.ts +35 -0
  266. package/src/agents/chromadb/chromadb.types.ts +52 -0
  267. package/src/agents/chromadb/chromadb.yaml +128 -0
  268. package/src/agents/chromadb/index.ts +20 -0
  269. package/src/agents/gemini-vectorize/gemini-vectorize.handler.ts +72 -0
  270. package/src/agents/gemini-vectorize/gemini-vectorize.schema.ts +22 -0
  271. package/src/agents/gemini-vectorize/gemini-vectorize.types.ts +34 -0
  272. package/src/agents/gemini-vectorize/gemini-vectorize.yaml +84 -0
  273. package/src/agents/gemini-vectorize/index.ts +20 -0
  274. package/src/agents/gitmcp/gitmcp.handler.ts +122 -0
  275. package/src/agents/gitmcp/gitmcp.schema.ts +20 -0
  276. package/src/agents/gitmcp/gitmcp.types.ts +33 -0
  277. package/src/agents/gitmcp/gitmcp.yaml +71 -0
  278. package/src/agents/gitmcp/index.ts +21 -0
  279. package/src/agents/image/image.handler.ts +82 -0
  280. package/src/agents/image/image.schema.ts +28 -0
  281. package/src/agents/image/image.types.ts +45 -0
  282. package/src/agents/image/image.yaml +86 -0
  283. package/src/agents/image/index.ts +19 -0
  284. package/src/agents/index.ts +59 -0
  285. package/src/agents/joker/index.ts +19 -0
  286. package/src/agents/joker/joker.handler.ts +60 -0
  287. package/src/agents/joker/joker.schema.ts +15 -0
  288. package/src/agents/joker/joker.types.ts +37 -0
  289. package/src/agents/joker/joker.yaml +47 -0
  290. package/src/agents/mcp-tool/index.ts +19 -0
  291. package/src/agents/mcp-tool/mcp-tool.handler.ts +112 -0
  292. package/src/agents/mcp-tool/mcp-tool.schema.ts +22 -0
  293. package/src/agents/mcp-tool/mcp-tool.types.ts +33 -0
  294. package/src/agents/mcp-tool/mcp-tool.yaml +71 -0
  295. package/src/agents/rag/index.ts +20 -0
  296. package/src/agents/rag/rag.handler.ts +119 -0
  297. package/src/agents/rag/rag.schema.ts +26 -0
  298. package/src/agents/rag/rag.types.ts +51 -0
  299. package/src/agents/rag/rag.yaml +89 -0
  300. package/src/agents/{agentRegistry.ts → registry/agentRegistry.ts} +161 -5
  301. package/src/agents/registry/index.ts +6 -0
  302. package/src/agents/translator/index.ts +19 -0
  303. package/src/agents/translator/translator.handler.ts +99 -0
  304. package/src/agents/translator/translator.schema.ts +30 -0
  305. package/src/agents/translator/translator.types.ts +42 -0
  306. package/src/agents/translator/translator.yaml +80 -0
  307. package/src/client/index.ts +53 -0
  308. package/src/client/types.ts +38 -0
  309. package/src/index.ts +48 -5
  310. package/src/runtime/declarativeAgentRuntime.ts +367 -489
  311. package/src/runtime/index.ts +31 -0
  312. package/src/runtime/workflowExecutor.ts +94 -0
  313. package/src/server/api/graphql.ts +1 -1
  314. package/src/server/index.ts +2 -2
  315. package/src/shared/index.ts +7 -0
  316. package/src/shared/types/agent.types.ts +80 -0
  317. package/src/shared/types/execution.types.ts +45 -0
  318. package/src/shared/types/index.ts +7 -0
  319. package/src/shared/types/schema.types.ts +55 -0
  320. package/src/shared/utils/index.ts +5 -0
  321. package/src/shared/utils/validation.ts +100 -0
  322. package/src/tenant/TenantManager.ts +488 -0
  323. package/src/tenant/index.ts +101 -0
  324. package/src/tenant/interfaces.ts +231 -0
  325. package/src/tenant/providerFactory.ts +75 -0
  326. package/src/tenant/providerRegistry.ts +86 -0
  327. package/src/tenant/providers/InMemoryTenantProvider.ts +168 -0
  328. package/dist/agents/agentRegistry.d.ts.map +0 -1
  329. package/dist/agents/agentRegistry.js.map +0 -1
  330. package/src/firebase/tenantManager.ts +0 -443
@@ -1,19 +1,34 @@
1
1
  /**
2
2
  * Declarative Agent Runtime - YAML Interpreter for Beddel Declarative Protocol
3
3
  * Safely interprets declarative YAML agent definitions without dynamic code execution
4
+ *
5
+ * Phase 3 Refactored: Delegates to individual agent handlers via workflowExecutor
4
6
  */
5
7
 
6
- import * as yaml from "js-yaml";
7
- import { experimental_generateImage, generateText } from "ai";
8
- import { createGoogleGenerativeAI } from "@ai-sdk/google";
9
- import { type ZodTypeAny } from "zod";
10
- import { ExecutionContext } from "../types/executionContext";
11
- import { agentRegistry } from "../agents/agentRegistry";
8
+ import 'server-only';
9
+
10
+ import * as yaml from 'js-yaml';
11
+ import { type ZodTypeAny } from 'zod';
12
+ import { ExecutionContext } from '../types/executionContext';
13
+ import { agentRegistry } from '../agents/registry';
12
14
  import {
13
15
  DeclarativeSchemaCompiler,
14
16
  DeclarativeSchemaValidationError,
15
17
  type DeclarativeSchemaPhase,
16
- } from "./schemaCompiler";
18
+ } from './schemaCompiler';
19
+
20
+ // Import handlers from workflowExecutor
21
+ import {
22
+ executeJokeHandler,
23
+ executeTranslationHandler,
24
+ executeImageHandler,
25
+ executeMcpToolHandler,
26
+ executeVectorizeHandler,
27
+ executeChromaDBHandler,
28
+ executeGitMcpHandler,
29
+ executeRagHandler,
30
+ executeChatHandler,
31
+ } from './workflowExecutor';
17
32
 
18
33
  export interface YamlAgentDefinition {
19
34
  agent: {
@@ -63,14 +78,12 @@ export type YamlExecutionResult = Record<string, any>;
63
78
 
64
79
  /**
65
80
  * Safe declarative YAML interpreter - no dynamic code execution
81
+ * Delegates execution to individual agent handlers
66
82
  */
67
83
  export class DeclarativeAgentInterpreter {
68
- private readonly MAX_VARIABLE_SIZE = 1024; // 1KB max variable size
69
- private readonly MAX_WORKFLOW_STEPS = 100; // Prevent infinite loops
70
- private readonly MAX_OUTPUT_SIZE = 5 * 1024 * 1024; // 5MB max output to accommodate image payloads
71
- private readonly GEMINI_MODEL = "models/gemini-2.5-flash";
72
- private readonly GEMINI_IMAGE_MODEL = "imagen-4.0-fast-generate-001";
73
- private readonly SUPPORTED_TRANSLATION_LANGUAGES = ["pt", "en", "es", "fr"];
84
+ private readonly MAX_VARIABLE_SIZE = 1024;
85
+ private readonly MAX_WORKFLOW_STEPS = 100;
86
+ private readonly MAX_OUTPUT_SIZE = 5 * 1024 * 1024;
74
87
  private readonly schemaCompiler = new DeclarativeSchemaCompiler();
75
88
 
76
89
  /**
@@ -82,16 +95,14 @@ export class DeclarativeAgentInterpreter {
82
95
  const startTime = Date.now();
83
96
 
84
97
  try {
85
- // Parse and validate YAML
86
98
  const agent = this.parseYaml(options.yamlContent);
87
99
  this.validateAgentDefinition(agent);
88
100
 
89
- // Compile schemas and validate input up front
90
101
  const schemas = this.buildSchemaSet(agent);
91
102
  const validatedInput = this.validateAgainstSchema(
92
103
  options.input,
93
104
  schemas.input,
94
- "input",
105
+ 'input',
95
106
  options.context
96
107
  );
97
108
 
@@ -100,14 +111,12 @@ export class DeclarativeAgentInterpreter {
100
111
  input: validatedInput,
101
112
  };
102
113
 
103
- // Execute declarative logic
104
114
  const result = await this.executeWorkflow(agent, executionOptions);
105
115
 
106
- // Validate output
107
116
  const validatedOutput = this.validateAgainstSchema(
108
117
  result,
109
118
  schemas.output,
110
- "output",
119
+ 'output',
111
120
  options.context
112
121
  );
113
122
  this.enforceOutputSize(validatedOutput);
@@ -117,30 +126,24 @@ export class DeclarativeAgentInterpreter {
117
126
 
118
127
  return validatedOutput;
119
128
  } catch (error) {
120
- const executionTime = Date.now() - startTime;
121
129
  options.context.log(`Declarative agent execution failed: ${error}`);
122
130
  options.context.setError(
123
- error instanceof Error
124
- ? error.message
125
- : "Unknown declarative agent error"
131
+ error instanceof Error ? error.message : 'Unknown declarative agent error'
126
132
  );
127
133
  throw error;
128
134
  }
129
135
  }
130
136
 
131
- /**
132
- * Parse and validate YAML content
133
- */
134
137
  private parseYaml(yamlContent: string): YamlAgentDefinition {
135
138
  try {
136
139
  const parsed = yaml.load(yamlContent) as YamlAgentDefinition;
137
140
 
138
- if (!parsed || typeof parsed !== "object") {
139
- throw new Error("Invalid YAML: expected object");
141
+ if (!parsed || typeof parsed !== 'object') {
142
+ throw new Error('Invalid YAML: expected object');
140
143
  }
141
144
 
142
145
  if (!parsed.agent || !parsed.logic || !parsed.schema) {
143
- throw new Error("Invalid agent definition: missing required sections");
146
+ throw new Error('Invalid agent definition: missing required sections');
144
147
  }
145
148
 
146
149
  return parsed;
@@ -149,32 +152,21 @@ export class DeclarativeAgentInterpreter {
149
152
  }
150
153
  }
151
154
 
152
- /**
153
- * Validate agent definition structure
154
- */
155
155
  private validateAgentDefinition(agent: YamlAgentDefinition): void {
156
- // Validate protocol version
157
- if (agent.agent.protocol !== "beddel-declarative-protocol/v2.0") {
156
+ if (agent.agent.protocol !== 'beddel-declarative-protocol/v2.0') {
158
157
  throw new Error(`Unsupported protocol: ${agent.agent.protocol}`);
159
158
  }
160
159
 
161
- // Validate schema
162
160
  if (!agent.schema.input || !agent.schema.output) {
163
- throw new Error("Invalid schema: missing input or output definition");
161
+ throw new Error('Invalid schema: missing input or output definition');
164
162
  }
165
163
 
166
- // Validate workflow
167
- if (
168
- !Array.isArray(agent.logic.workflow) ||
169
- agent.logic.workflow.length === 0
170
- ) {
171
- throw new Error("Invalid workflow: must be non-empty array");
164
+ if (!Array.isArray(agent.logic.workflow) || agent.logic.workflow.length === 0) {
165
+ throw new Error('Invalid workflow: must be non-empty array');
172
166
  }
173
167
 
174
168
  if (agent.logic.workflow.length > this.MAX_WORKFLOW_STEPS) {
175
- throw new Error(
176
- `Workflow too complex: max ${this.MAX_WORKFLOW_STEPS} steps allowed`
177
- );
169
+ throw new Error(`Workflow too complex: max ${this.MAX_WORKFLOW_STEPS} steps allowed`);
178
170
  }
179
171
  }
180
172
 
@@ -183,8 +175,8 @@ export class DeclarativeAgentInterpreter {
183
175
  output: ZodTypeAny;
184
176
  } {
185
177
  return {
186
- input: this.schemaCompiler.compile(agent.schema.input, "schema.input"),
187
- output: this.schemaCompiler.compile(agent.schema.output, "schema.output"),
178
+ input: this.schemaCompiler.compile(agent.schema.input, 'schema.input'),
179
+ output: this.schemaCompiler.compile(agent.schema.output, 'schema.output'),
188
180
  };
189
181
  }
190
182
 
@@ -198,29 +190,23 @@ export class DeclarativeAgentInterpreter {
198
190
  if (!validationResult.success) {
199
191
  const issues = validationResult.error.issues;
200
192
  const issueSummary = issues
201
- .map((issue) => `${issue.path.join(".") || "root"}: ${issue.message}`)
202
- .join("; ");
203
- const label = phase === "input" ? "Input" : "Output";
193
+ .map((issue) => `${issue.path.join('.') || 'root'}: ${issue.message}`)
194
+ .join('; ');
195
+ const label = phase === 'input' ? 'Input' : 'Output';
204
196
  const message = `${label} validation failed: ${issueSummary}`;
205
197
  context.setError(message);
206
198
  throw new DeclarativeSchemaValidationError(message, phase, issues);
207
199
  }
208
-
209
200
  return validationResult.data;
210
201
  }
211
202
 
212
203
  private enforceOutputSize(output: any): void {
213
204
  const outputSize = JSON.stringify(output).length;
214
205
  if (outputSize > this.MAX_OUTPUT_SIZE) {
215
- throw new Error(
216
- `Output size exceeds maximum allowed: ${outputSize} > ${this.MAX_OUTPUT_SIZE}`
217
- );
206
+ throw new Error(`Output size exceeds maximum allowed: ${outputSize} > ${this.MAX_OUTPUT_SIZE}`);
218
207
  }
219
208
  }
220
209
 
221
- /**
222
- * Execute declarative workflow
223
- */
224
210
  private async executeWorkflow(
225
211
  agent: YamlAgentDefinition,
226
212
  options: YamlAgentInterpreterOptions
@@ -228,7 +214,6 @@ export class DeclarativeAgentInterpreter {
228
214
  const variables = new Map<string, any>();
229
215
  let output: any = undefined;
230
216
 
231
- // Initialize variables
232
217
  if (agent.logic.variables) {
233
218
  for (const variable of agent.logic.variables) {
234
219
  this.validateVariable(variable);
@@ -237,7 +222,6 @@ export class DeclarativeAgentInterpreter {
237
222
  }
238
223
  }
239
224
 
240
- // Execute workflow steps
241
225
  for (const step of agent.logic.workflow) {
242
226
  output = await this.executeWorkflowStep(step, variables, options);
243
227
  }
@@ -245,9 +229,6 @@ export class DeclarativeAgentInterpreter {
245
229
  return output;
246
230
  }
247
231
 
248
- /**
249
- * Execute single workflow step
250
- */
251
232
  private async executeWorkflowStep(
252
233
  step: any,
253
234
  variables: Map<string, any>,
@@ -256,53 +237,60 @@ export class DeclarativeAgentInterpreter {
256
237
  options.context.log(`Executing workflow step: ${step.name} (${step.type})`);
257
238
 
258
239
  switch (step.type) {
259
- case "output-generator":
240
+ case 'output-generator':
260
241
  return this.executeOutputGenerator(step, variables, options);
261
- case "genkit-joke":
242
+ case 'genkit-joke':
262
243
  return this.executeGenkitJoke(step, variables, options);
263
- case "genkit-translation":
244
+ case 'genkit-translation':
264
245
  return this.executeGenkitTranslation(step, variables, options);
265
- case "genkit-image":
246
+ case 'genkit-image':
266
247
  return this.executeGenkitImage(step, variables, options);
267
- case "custom-action":
248
+ case 'custom-action':
268
249
  return this.executeCustomAction(step, variables, options);
250
+ case 'mcp-tool':
251
+ return this.executeMcpTool(step, variables, options);
252
+ case 'gemini-vectorize':
253
+ return this.executeGeminiVectorize(step, variables, options);
254
+ case 'chromadb':
255
+ return this.executeChromaDB(step, variables, options);
256
+ case 'gitmcp':
257
+ return this.executeGitMcp(step, variables, options);
258
+ case 'rag':
259
+ return this.executeRag(step, variables, options);
260
+ case 'chat':
261
+ return this.executeChat(step, variables, options);
262
+ case 'builtin-agent':
263
+ return this.executeBuiltinAgent(step, variables, options);
269
264
  default:
270
265
  throw new Error(`Unsupported workflow step type: ${step.type}`);
271
266
  }
272
267
  }
273
268
 
274
- /**
275
- * Execute output generator step
276
- */
269
+ // ============================================================================
270
+ // Output Generator (kept inline - orchestration logic)
271
+ // ============================================================================
272
+
277
273
  private executeOutputGenerator(
278
274
  step: any,
279
275
  variables: Map<string, any>,
280
276
  options: YamlAgentInterpreterOptions
281
277
  ): any {
282
- if (step.action?.type !== "generate" || !step.action.output) {
283
- throw new Error("Invalid output generator configuration");
278
+ if (step.action?.type !== 'generate' || !step.action.output) {
279
+ throw new Error('Invalid output generator configuration');
284
280
  }
285
281
 
286
- // Build output object
287
282
  const output: any = {};
288
283
 
289
- // Debug: Log available variables
290
284
  options.context.log(
291
- `Output generator: Available variables: ${Array.from(variables.keys()).join(", ")}`
285
+ `Output generator: Available variables: ${Array.from(variables.keys()).join(', ')}`
292
286
  );
293
287
 
294
288
  for (const [key, valueExpr] of Object.entries(step.action.output)) {
295
- if (typeof valueExpr === "string" && valueExpr.startsWith("$")) {
289
+ if (typeof valueExpr === 'string' && valueExpr.startsWith('$')) {
296
290
  try {
297
291
  const reference = valueExpr.substring(1);
298
- options.context.log(
299
- `Output generator: Resolving reference ${valueExpr} -> ${reference}`
300
- );
301
292
  const resolved = this.resolveReference(reference, variables);
302
293
  output[key] = resolved;
303
- options.context.log(
304
- `Output generator: Resolved ${key} = ${typeof resolved === "string" ? resolved.substring(0, 50) + "..." : JSON.stringify(resolved).substring(0, 100)}`
305
- );
306
294
  } catch (error) {
307
295
  options.context.log(
308
296
  `Output generator: Failed to resolve ${valueExpr}: ${error instanceof Error ? error.message : String(error)}`
@@ -314,72 +302,62 @@ export class DeclarativeAgentInterpreter {
314
302
  }
315
303
  }
316
304
 
317
- options.context.log(
318
- `Output generator: Final output keys: ${Object.keys(output).join(", ")}`
319
- );
320
-
321
305
  return output;
322
306
  }
323
307
 
324
- /**
325
- * Execute Gemini Flash text helper for the joke agent
326
- */
308
+ // ============================================================================
309
+ // Delegated Handlers - Using extracted agent handlers
310
+ // ============================================================================
311
+
327
312
  private async executeGenkitJoke(
328
313
  step: any,
329
314
  variables: Map<string, any>,
330
315
  options: YamlAgentInterpreterOptions
331
316
  ): Promise<any> {
332
317
  const prompt =
333
- typeof step.action?.prompt === "string" && step.action.prompt.trim().length
318
+ typeof step.action?.prompt === 'string' && step.action.prompt.trim().length
334
319
  ? step.action.prompt.trim()
335
- : "Conte uma piada curta e original em português.";
320
+ : 'Tell a short and original joke that works for any audience.';
336
321
  const temperature =
337
- typeof step.action?.temperature === "number"
338
- ? step.action.temperature
339
- : 0.8;
322
+ typeof step.action?.temperature === 'number' ? step.action.temperature : 0.8;
340
323
  const maxTokens =
341
- typeof step.action?.maxTokens === "number"
342
- ? step.action.maxTokens
343
- : undefined;
324
+ typeof step.action?.maxTokens === 'number' ? step.action.maxTokens : undefined;
344
325
  const resultVar =
345
- typeof step.action?.result === "string" && step.action.result.length > 0
326
+ typeof step.action?.result === 'string' && step.action.result.length > 0
346
327
  ? step.action.result
347
- : "jokerResult";
328
+ : 'jokerResult';
348
329
 
349
- const joke = await this.callGeminiFlashText(
330
+ const result = await executeJokeHandler(
350
331
  { prompt, temperature, maxTokens },
351
332
  options.props,
352
333
  options.context
353
334
  );
354
335
 
355
- variables.set(resultVar, joke);
356
- return joke;
336
+ variables.set(resultVar, result);
337
+ return result;
357
338
  }
358
339
 
359
- /**
360
- * Execute translation step backed by Gemini Flash
361
- */
362
340
  private async executeGenkitTranslation(
363
341
  step: any,
364
342
  variables: Map<string, any>,
365
343
  options: YamlAgentInterpreterOptions
366
344
  ): Promise<any> {
367
- const texto = options.input?.texto;
368
- const idiomaOrigem = options.input?.idioma_origem;
369
- const idiomaDestino = options.input?.idioma_destino;
345
+ const text = options.input?.texto || options.input?.text;
346
+ const sourceLanguage = options.input?.idioma_origem || options.input?.source_language;
347
+ const targetLanguage = options.input?.idioma_destino || options.input?.target_language;
370
348
 
371
349
  const resultVar =
372
- typeof step.action?.result === "string" && step.action.result.length > 0
350
+ typeof step.action?.result === 'string' && step.action.result.length > 0
373
351
  ? step.action.result
374
- : "translationResult";
352
+ : 'translationResult';
375
353
 
376
- const translation = await this.callGeminiFlashTranslation(
354
+ const result = await executeTranslationHandler(
377
355
  {
378
- texto,
379
- idioma_origem: idiomaOrigem,
380
- idioma_destino: idiomaDestino,
356
+ text,
357
+ source_language: sourceLanguage,
358
+ target_language: targetLanguage,
381
359
  promptTemplate:
382
- typeof step.action?.promptTemplate === "string"
360
+ typeof step.action?.promptTemplate === 'string'
383
361
  ? step.action.promptTemplate
384
362
  : undefined,
385
363
  },
@@ -387,80 +365,228 @@ export class DeclarativeAgentInterpreter {
387
365
  options.context
388
366
  );
389
367
 
390
- variables.set(resultVar, translation);
391
- return translation;
368
+ variables.set(resultVar, result);
369
+ return result;
392
370
  }
393
371
 
394
- /**
395
- * Execute image generation step backed by Gemini Flash
396
- */
397
372
  private async executeGenkitImage(
398
373
  step: any,
399
374
  variables: Map<string, any>,
400
375
  options: YamlAgentInterpreterOptions
401
376
  ): Promise<any> {
402
- const descricao =
403
- typeof options.input?.descricao === "string"
377
+ const description =
378
+ typeof options.input?.descricao === 'string'
404
379
  ? options.input.descricao.trim()
405
- : "";
406
- const estilo =
407
- typeof options.input?.estilo === "string"
380
+ : typeof options.input?.description === 'string'
381
+ ? options.input.description.trim()
382
+ : '';
383
+ const style =
384
+ typeof options.input?.estilo === 'string'
408
385
  ? options.input.estilo.trim()
409
- : "";
410
- const resolucaoInput =
411
- typeof options.input?.resolucao === "string"
386
+ : typeof options.input?.style === 'string'
387
+ ? options.input.style.trim()
388
+ : '';
389
+ const resolution =
390
+ typeof options.input?.resolucao === 'string'
412
391
  ? options.input.resolucao.trim()
413
- : "";
392
+ : typeof options.input?.resolution === 'string'
393
+ ? options.input.resolution.trim()
394
+ : '';
414
395
 
415
- if (!descricao) {
416
- throw new Error("Missing required image input: descricao");
396
+ if (!description) {
397
+ throw new Error('Missing required image input: description');
417
398
  }
418
- if (!estilo) {
419
- throw new Error("Missing required image input: estilo");
399
+ if (!style) {
400
+ throw new Error('Missing required image input: style');
420
401
  }
421
- if (!resolucaoInput) {
422
- throw new Error("Missing required image input: resolucao");
402
+ if (!resolution) {
403
+ throw new Error('Missing required image input: resolution');
423
404
  }
424
405
 
425
406
  const promptTemplate =
426
- typeof step.action?.promptTemplate === "string" &&
427
- step.action.promptTemplate.trim().length > 0
407
+ typeof step.action?.promptTemplate === 'string' &&
408
+ step.action.promptTemplate.trim().length > 0
428
409
  ? step.action.promptTemplate
429
- : "Gere uma imagem detalhada no estilo {{estilo}} baseada na descrição: {{descricao}}";
430
-
431
- const prompt = promptTemplate
432
- .replace(/{{descricao}}/g, descricao)
433
- .replace(/{{estilo}}/g, estilo)
434
- .trim();
410
+ : 'Create a detailed image in {{style}} style focusing on: {{description}}';
435
411
 
436
412
  const resultVar =
437
- typeof step.action?.result === "string" && step.action.result.length > 0
413
+ typeof step.action?.result === 'string' && step.action.result.length > 0
438
414
  ? step.action.result
439
- : "imageResult";
415
+ : 'imageResult';
440
416
 
441
- const imageResult = await this.callGeminiFlashImage(
417
+ const result = await executeImageHandler(
442
418
  {
443
- prompt,
444
- estilo,
445
- resolucao: resolucaoInput,
419
+ description,
420
+ style,
421
+ resolution,
422
+ promptTemplate,
446
423
  },
447
424
  options.props,
448
425
  options.context
449
426
  );
450
427
 
451
- variables.set(resultVar, imageResult);
452
- options.context.log(
453
- `Image generator: Saved result in variable '${resultVar}' with keys: ${Object.keys(imageResult).join(", ")}`
428
+ variables.set(resultVar, result);
429
+ return result;
430
+ }
431
+
432
+ private async executeMcpTool(
433
+ step: any,
434
+ variables: Map<string, any>,
435
+ options: YamlAgentInterpreterOptions
436
+ ): Promise<any> {
437
+ const serverUrl = this.resolveInputValue(step.action?.server_url, options.input, variables);
438
+ const toolName = this.resolveInputValue(step.action?.tool_name, options.input, variables);
439
+ const toolArguments =
440
+ this.resolveInputValue(step.action?.tool_arguments, options.input, variables) || {};
441
+ const resultVar = step.action?.result || 'mcpResult';
442
+
443
+ const result = await executeMcpToolHandler(
444
+ {
445
+ server_url: serverUrl,
446
+ tool_name: toolName,
447
+ tool_arguments: toolArguments,
448
+ },
449
+ options.props,
450
+ options.context
454
451
  );
455
- options.context.log(
456
- `Image generator: imageResult.image_url exists: ${!!imageResult?.image_url}`
452
+
453
+ variables.set(resultVar, result);
454
+ return result;
455
+ }
456
+
457
+ private async executeGeminiVectorize(
458
+ step: any,
459
+ variables: Map<string, any>,
460
+ options: YamlAgentInterpreterOptions
461
+ ): Promise<any> {
462
+ const action = step.action?.action || 'embedSingle';
463
+ const resultVar = step.action?.result || 'vectorizeResult';
464
+
465
+ let result;
466
+ if (action === 'embedSingle') {
467
+ const text = this.resolveInputValue(step.action?.text, options.input, variables);
468
+ result = await executeVectorizeHandler(
469
+ { action: 'embedSingle', text },
470
+ options.props,
471
+ options.context
472
+ );
473
+ } else if (action === 'embedBatch') {
474
+ const texts = this.resolveInputValue(step.action?.texts, options.input, variables);
475
+ result = await executeVectorizeHandler(
476
+ { action: 'embedBatch', texts },
477
+ options.props,
478
+ options.context
479
+ );
480
+ } else {
481
+ throw new Error(`Unknown vectorize action: ${action}`);
482
+ }
483
+
484
+ variables.set(resultVar, result);
485
+ return result;
486
+ }
487
+
488
+ private async executeChromaDB(
489
+ step: any,
490
+ variables: Map<string, any>,
491
+ options: YamlAgentInterpreterOptions
492
+ ): Promise<any> {
493
+ const action = this.resolveInputValue(step.action?.action, options.input, variables);
494
+ const collectionName = this.resolveInputValue(
495
+ step.action?.collection_name,
496
+ options.input,
497
+ variables
457
498
  );
458
- return imageResult;
499
+ const resultVar = step.action?.result || 'chromaResult';
500
+
501
+ let params: any = { action, collection_name: collectionName };
502
+
503
+ if (action === 'hasData') {
504
+ params.min_count =
505
+ this.resolveInputValue(step.action?.min_count, options.input, variables) || 1;
506
+ } else if (action === 'store') {
507
+ params.ids = this.resolveInputValue(step.action?.ids, options.input, variables);
508
+ params.vectors = this.resolveInputValue(step.action?.vectors, options.input, variables);
509
+ params.documents = this.resolveInputValue(step.action?.documents, options.input, variables);
510
+ params.metadatas = this.resolveInputValue(step.action?.metadatas, options.input, variables);
511
+ } else if (action === 'search') {
512
+ params.query_vector = this.resolveInputValue(
513
+ step.action?.query_vector,
514
+ options.input,
515
+ variables
516
+ );
517
+ params.limit =
518
+ this.resolveInputValue(step.action?.limit, options.input, variables) || 5;
519
+ }
520
+
521
+ const result = await executeChromaDBHandler(params, options.props, options.context);
522
+
523
+ variables.set(resultVar, result);
524
+ return result;
459
525
  }
460
526
 
461
- /**
462
- * Execute custom action backed by TypeScript implementation
463
- */
527
+ private async executeGitMcp(
528
+ step: any,
529
+ variables: Map<string, any>,
530
+ options: YamlAgentInterpreterOptions
531
+ ): Promise<any> {
532
+ const gitmcpUrl = this.resolveInputValue(step.action?.gitmcp_url, options.input, variables);
533
+ const resultVar = step.action?.result || 'gitmcpResult';
534
+
535
+ const result = await executeGitMcpHandler(
536
+ { gitmcp_url: gitmcpUrl },
537
+ options.props,
538
+ options.context
539
+ );
540
+
541
+ variables.set(resultVar, result);
542
+ return result;
543
+ }
544
+
545
+ private async executeRag(
546
+ step: any,
547
+ variables: Map<string, any>,
548
+ options: YamlAgentInterpreterOptions
549
+ ): Promise<any> {
550
+ const query = this.resolveInputValue(step.action?.query, options.input, variables);
551
+ const context =
552
+ this.resolveInputValue(step.action?.context, options.input, variables) ||
553
+ this.resolveInputValue(step.action?.documents, options.input, variables);
554
+ const history = this.resolveInputValue(step.action?.history, options.input, variables);
555
+ const resultVar = step.action?.result || 'ragResult';
556
+
557
+ const result = await executeRagHandler(
558
+ { query, context, documents: context, history },
559
+ options.props,
560
+ options.context
561
+ );
562
+
563
+ variables.set(resultVar, result);
564
+ return result;
565
+ }
566
+
567
+ private async executeChat(
568
+ step: any,
569
+ variables: Map<string, any>,
570
+ options: YamlAgentInterpreterOptions
571
+ ): Promise<any> {
572
+ const messages = this.resolveInputValue(step.action?.messages, options.input, variables);
573
+ const query = this.resolveInputValue(step.action?.query, options.input, variables);
574
+ const resultVar = step.action?.result || 'chatResult';
575
+
576
+ const result = await executeChatHandler(
577
+ { messages, query },
578
+ options.props,
579
+ options.context
580
+ );
581
+
582
+ variables.set(resultVar, result);
583
+ return result;
584
+ }
585
+
586
+ // ============================================================================
587
+ // Custom Action & Builtin Agent (orchestration logic)
588
+ // ============================================================================
589
+
464
590
  private async executeCustomAction(
465
591
  step: any,
466
592
  variables: Map<string, any>,
@@ -473,16 +599,14 @@ export class DeclarativeAgentInterpreter {
473
599
 
474
600
  options.context.log(`Custom action: Looking up function '${functionName}'`);
475
601
 
476
- // Retrieve Code Implementation
477
602
  const customFunc = agentRegistry.getCustomFunction(functionName);
478
603
  if (!customFunc) {
479
604
  throw new Error(
480
605
  `Custom function '${functionName}' not found in registry. ` +
481
- `Make sure the corresponding .ts file is in the /agents directory.`
606
+ `Make sure the corresponding .ts file is in the /agents directory.`
482
607
  );
483
608
  }
484
609
 
485
- // Prepare Arguments
486
610
  const args = {
487
611
  input: options.input,
488
612
  variables: Object.fromEntries(variables),
@@ -492,16 +616,11 @@ export class DeclarativeAgentInterpreter {
492
616
 
493
617
  options.context.log(`Custom action: Executing function '${functionName}'`);
494
618
 
495
- // Execute Code
496
619
  try {
497
620
  const result = await customFunc(args);
498
621
 
499
- // Save Result
500
622
  if (step.action.result) {
501
623
  variables.set(step.action.result, result);
502
- options.context.log(
503
- `Custom action: Saved result to variable '${step.action.result}'`
504
- );
505
624
  }
506
625
 
507
626
  return result;
@@ -513,77 +632,129 @@ export class DeclarativeAgentInterpreter {
513
632
  }
514
633
  }
515
634
 
635
+ private async executeBuiltinAgent(
636
+ step: any,
637
+ variables: Map<string, any>,
638
+ options: YamlAgentInterpreterOptions
639
+ ): Promise<any> {
640
+ const agentName = step.action?.agent;
641
+ const agentInput =
642
+ this.resolveInputValue(step.action?.input, options.input, variables) || options.input;
643
+ const agentProps = step.action?.props || options.props;
644
+ const resultVar = step.action?.result || 'builtinResult';
645
+
646
+ if (!agentName) {
647
+ throw new Error('Missing required builtin-agent input: agent');
648
+ }
649
+
650
+ options.context.log(`[Builtin Agent] Invoking agent: ${agentName}`);
651
+
652
+ try {
653
+ const result = await agentRegistry.executeAgent(
654
+ agentName,
655
+ agentInput,
656
+ agentProps,
657
+ options.context
658
+ );
659
+
660
+ variables.set(resultVar, result);
661
+ return result;
662
+ } catch (error: unknown) {
663
+ const message = error instanceof Error ? error.message : String(error);
664
+ options.context.log(`[Builtin Agent] Error: ${message}`);
665
+ throw new Error(`Builtin agent '${agentName}' execution failed: ${message}`);
666
+ }
667
+ }
668
+
669
+ // ============================================================================
670
+ // Helper Methods
671
+ // ============================================================================
672
+
673
+ private resolveInputValue(
674
+ value: any,
675
+ input: Record<string, any>,
676
+ variables: Map<string, any>
677
+ ): any {
678
+ if (value === undefined || value === null) return undefined;
679
+
680
+ if (typeof value === 'string' && value.startsWith('$')) {
681
+ const ref = value.substring(1);
682
+ if (ref.startsWith('input.')) {
683
+ const inputKey = ref.substring(6);
684
+ return this.getNestedValue(input, inputKey);
685
+ }
686
+ return this.resolveReference(ref, variables);
687
+ }
688
+
689
+ if (typeof value === 'string' && input[value] !== undefined) {
690
+ return input[value];
691
+ }
692
+
693
+ return value;
694
+ }
695
+
696
+ private getNestedValue(obj: any, path: string): any {
697
+ const parts = path.split('.');
698
+ let current = obj;
699
+ for (const part of parts) {
700
+ if (current == null) return undefined;
701
+ current = current[part];
702
+ }
703
+ return current;
704
+ }
516
705
 
517
- /**
518
- * Evaluate value expression
519
- */
520
706
  private evaluateValue(expr: string, variables: Map<string, any>): any {
521
- // Handle string literals
522
707
  if (expr.startsWith('"') && expr.endsWith('"')) {
523
708
  if (expr.length - 2 > this.MAX_VARIABLE_SIZE) {
524
- throw new Error("Variable initialization exceeds maximum size");
709
+ throw new Error('Variable initialization exceeds maximum size');
525
710
  }
526
711
  return expr.slice(1, -1);
527
712
  }
528
713
 
529
714
  if (expr.startsWith("'") && expr.endsWith("'")) {
530
715
  if (expr.length - 2 > this.MAX_VARIABLE_SIZE) {
531
- throw new Error("Variable initialization exceeds maximum size");
716
+ throw new Error('Variable initialization exceeds maximum size');
532
717
  }
533
718
  return expr.slice(1, -1);
534
719
  }
535
720
 
536
721
  if (expr.length > this.MAX_VARIABLE_SIZE) {
537
- throw new Error("Variable initialization exceeds maximum size");
722
+ throw new Error('Variable initialization exceeds maximum size');
538
723
  }
539
724
 
540
- // Handle boolean literals
541
- if (expr === "true") return true;
542
- if (expr === "false") return false;
543
-
544
- // Handle null literal
545
- if (expr === "null") return null;
725
+ if (expr === 'true') return true;
726
+ if (expr === 'false') return false;
727
+ if (expr === 'null') return null;
546
728
 
547
- // Handle variable references
548
- if (expr.startsWith("$")) {
729
+ if (expr.startsWith('$')) {
549
730
  return this.resolveReference(expr.substring(1), variables);
550
731
  }
551
732
 
552
- // Handle numbers
553
733
  if (/^-?\d+$/.test(expr)) return parseInt(expr, 10);
554
734
  if (/^-?\d+\.\d+$/.test(expr)) return parseFloat(expr);
555
735
 
556
736
  throw new Error(`Unsupported value expression: ${expr}`);
557
737
  }
558
738
 
559
- /**
560
- * Validate variable declaration
561
- */
562
739
  private validateVariable(variable: any): void {
563
740
  if (!variable.name || !variable.type) {
564
- throw new Error("Invalid variable declaration: missing name or type");
741
+ throw new Error('Invalid variable declaration: missing name or type');
565
742
  }
566
743
 
567
- if (!["string", "number", "boolean", "object"].includes(variable.type)) {
744
+ if (!['string', 'number', 'boolean', 'object'].includes(variable.type)) {
568
745
  throw new Error(`Unsupported variable type: ${variable.type}`);
569
746
  }
570
747
  }
571
748
 
572
- /**
573
- * Resolve variable reference, including nested properties (e.g., foo.bar.baz)
574
- */
575
- private resolveReference(
576
- reference: string,
577
- variables: Map<string, any>
578
- ): any {
579
- const [varName, ...pathSegments] = reference.split(".");
749
+ private resolveReference(reference: string, variables: Map<string, any>): any {
750
+ const [varName, ...pathSegments] = reference.split('.');
580
751
  let value = variables.get(varName);
581
752
  if (value === undefined) {
582
753
  throw new Error(`Undefined variable referenced: ${varName}`);
583
754
  }
584
755
 
585
756
  for (const segment of pathSegments) {
586
- if (value == null || typeof value !== "object") {
757
+ if (value == null || typeof value !== 'object') {
587
758
  throw new Error(
588
759
  `Cannot resolve path '${reference}': segment '${segment}' is invalid`
589
760
  );
@@ -593,299 +764,6 @@ export class DeclarativeAgentInterpreter {
593
764
 
594
765
  return value;
595
766
  }
596
-
597
- /**
598
- * Ensure we have a Gemini API key before calling Genkit helpers
599
- */
600
- private ensureGeminiApiKey(props: Record<string, string>): string {
601
- const apiKey = props?.gemini_api_key?.trim();
602
- if (!apiKey) {
603
- throw new Error(
604
- "Missing required prop: gemini_api_key. Configure a valid Gemini API key before calling this agent."
605
- );
606
- }
607
- return apiKey;
608
- }
609
-
610
- private createGeminiModel(props: Record<string, string>) {
611
- const apiKey = this.ensureGeminiApiKey(props);
612
- const google = createGoogleGenerativeAI({ apiKey });
613
- const model = google(this.GEMINI_MODEL);
614
- return model;
615
- }
616
-
617
- private createGeminiImageModel(props: Record<string, string>) {
618
- const apiKey = this.ensureGeminiApiKey(props);
619
- const google = createGoogleGenerativeAI({ apiKey });
620
- return google.image(this.GEMINI_IMAGE_MODEL);
621
- }
622
-
623
- private async callGeminiFlashText(
624
- params: {
625
- prompt: string;
626
- temperature?: number;
627
- maxTokens?: number;
628
- },
629
- props: Record<string, string>,
630
- context: ExecutionContext
631
- ): Promise<{
632
- texto: string;
633
- metadados: {
634
- modelo_utilizado: string;
635
- tempo_processamento: number;
636
- temperature: number;
637
- max_tokens: number | null;
638
- prompt_utilizado: string;
639
- };
640
- }> {
641
- const prompt = params.prompt?.trim();
642
- if (!prompt) {
643
- throw new Error("Gemini Flash text helper requires a prompt");
644
- }
645
-
646
- const temperature =
647
- typeof params.temperature === "number" ? params.temperature : 0.7;
648
- const maxTokens =
649
- typeof params.maxTokens === "number" ? params.maxTokens : undefined;
650
-
651
- const model = this.createGeminiModel(props);
652
- const startTime = Date.now();
653
-
654
- try {
655
- context.log(
656
- `Invoking Gemini Flash text helper (temperature=${temperature}, maxTokens=${typeof maxTokens === "number" ? maxTokens : "provider-default"
657
- })`
658
- );
659
- const generationOptions: Record<string, any> = {
660
- model,
661
- prompt,
662
- temperature,
663
- };
664
- if (typeof maxTokens === "number") {
665
- generationOptions.maxOutputTokens = maxTokens;
666
- }
667
- const { text, content } = await generateText(
668
- generationOptions as any
669
- );
670
- const contentText = content
671
- ? content
672
- .map((part: any) =>
673
- typeof part?.text === "string" ? part.text : ""
674
- )
675
- .join(" ")
676
- .trim()
677
- : "";
678
- const finalText = (text || "").trim() || contentText || "";
679
- if (!finalText) {
680
- throw new Error("Gemini Flash text helper returned empty response");
681
- }
682
-
683
- return {
684
- texto: finalText,
685
- metadados: {
686
- modelo_utilizado: this.GEMINI_MODEL,
687
- tempo_processamento: Date.now() - startTime,
688
- temperature,
689
- max_tokens: typeof maxTokens === "number" ? maxTokens : null,
690
- prompt_utilizado: prompt,
691
- },
692
- };
693
- } catch (error) {
694
- const message =
695
- error instanceof Error ? error.message : "Unknown Gemini Flash error";
696
- context.log(`Gemini Flash text helper failed: ${message}`);
697
- context.setError(message);
698
- throw error;
699
- }
700
- }
701
-
702
- private async callGeminiFlashTranslation(
703
- params: {
704
- texto?: string;
705
- idioma_origem?: string;
706
- idioma_destino?: string;
707
- promptTemplate?: string;
708
- },
709
- props: Record<string, string>,
710
- context: ExecutionContext
711
- ): Promise<{
712
- texto_traduzido: string;
713
- metadados: {
714
- modelo_utilizado: string;
715
- tempo_processamento: number;
716
- confianca: number;
717
- idiomas_suportados: string[];
718
- idiomas_solicitados: {
719
- origem: string;
720
- destino: string;
721
- };
722
- prompt_utilizado: string;
723
- };
724
- }> {
725
- const texto = params.texto?.trim();
726
- const idiomaOrigem = params.idioma_origem?.trim().toLowerCase();
727
- const idiomaDestino = params.idioma_destino?.trim().toLowerCase();
728
-
729
- if (!texto || !idiomaOrigem || !idiomaDestino) {
730
- throw new Error(
731
- "Missing required translation parameters: texto, idioma_origem, idioma_destino"
732
- );
733
- }
734
-
735
- if (idiomaOrigem === idiomaDestino) {
736
- return {
737
- texto_traduzido: texto,
738
- metadados: {
739
- modelo_utilizado: this.GEMINI_MODEL,
740
- tempo_processamento: 0,
741
- confianca: 1,
742
- idiomas_suportados: this.SUPPORTED_TRANSLATION_LANGUAGES,
743
- idiomas_solicitados: {
744
- origem: idiomaOrigem,
745
- destino: idiomaDestino,
746
- },
747
- prompt_utilizado: "Bypass: idiomas de origem e destino são iguais",
748
- },
749
- };
750
- }
751
-
752
- const template =
753
- params.promptTemplate && params.promptTemplate.trim().length > 0
754
- ? params.promptTemplate
755
- : `Traduza o texto abaixo de {{idioma_origem}} para {{idioma_destino}}.
756
- Responda somente com o texto traduzido sem comentários adicionais.
757
-
758
- Texto:
759
- {{texto}}`;
760
-
761
- const prompt = template
762
- .replace(/{{texto}}/g, texto)
763
- .replace(/{{idioma_origem}}/g, idiomaOrigem)
764
- .replace(/{{idioma_destino}}/g, idiomaDestino)
765
- .trim();
766
-
767
- const model = this.createGeminiModel(props);
768
- const startTime = Date.now();
769
-
770
- try {
771
- context.log(
772
- `Invoking Gemini Flash translation helper (${idiomaOrigem}->${idiomaDestino})`
773
- );
774
- const { text, content } = await generateText({
775
- model,
776
- prompt,
777
- temperature: 0.2,
778
- });
779
-
780
- const contentText = content
781
- ? content
782
- .map((part: any) =>
783
- typeof part?.text === "string" ? part.text : ""
784
- )
785
- .join(" ")
786
- .trim()
787
- : "";
788
- const translatedText = (text || "").trim() || contentText || "";
789
- if (!translatedText) {
790
- throw new Error("Gemini Flash translation returned empty response");
791
- }
792
-
793
- return {
794
- texto_traduzido: translatedText,
795
- metadados: {
796
- modelo_utilizado: this.GEMINI_MODEL,
797
- tempo_processamento: Date.now() - startTime,
798
- confianca: 0.85,
799
- idiomas_suportados: this.SUPPORTED_TRANSLATION_LANGUAGES,
800
- idiomas_solicitados: {
801
- origem: idiomaOrigem,
802
- destino: idiomaDestino,
803
- },
804
- prompt_utilizado: prompt,
805
- },
806
- };
807
- } catch (error) {
808
- const message =
809
- error instanceof Error ? error.message : "Unknown translation error";
810
- context.log(`Gemini Flash translation failed: ${message}`);
811
- context.setError(message);
812
- throw error;
813
- }
814
- }
815
-
816
- private async callGeminiFlashImage(
817
- params: { prompt: string; estilo: string; resolucao: string },
818
- props: Record<string, string>,
819
- context: ExecutionContext
820
- ): Promise<{
821
- image_url: string;
822
- image_base64: string;
823
- media_type: string;
824
- prompt_utilizado: string;
825
- metadados: {
826
- modelo_utilizado: string;
827
- tempo_processamento: number;
828
- estilo: string;
829
- resolucao: string;
830
- };
831
- }> {
832
- const prompt = params.prompt?.trim();
833
- const estilo = params.estilo?.trim();
834
- const resolucao = params.resolucao?.trim();
835
-
836
- if (!prompt) {
837
- throw new Error("Gemini Flash image helper requires a prompt");
838
- }
839
- if (!estilo) {
840
- throw new Error("Gemini Flash image helper requires an estilo value");
841
- }
842
- if (!resolucao || !/^\d+x\d+$/.test(resolucao)) {
843
- throw new Error(
844
- "Gemini Flash image helper requires uma resolução no formato LARGURAxALTURA (ex: 1024x1024)"
845
- );
846
- }
847
-
848
- const model = this.createGeminiImageModel(props);
849
- const startTime = Date.now();
850
-
851
- try {
852
- context.log(
853
- `Invoking Gemini Flash image helper (estilo=${estilo}, resolucao=${resolucao})`
854
- );
855
- const result = await experimental_generateImage({
856
- model,
857
- prompt,
858
- size: resolucao as `${number}x${number}`,
859
- });
860
-
861
- const image = result.image;
862
- if (!image?.base64 || !image.mediaType) {
863
- throw new Error("Gemini Flash image helper returned an invalid file");
864
- }
865
-
866
- const normalizedBase64 = image.base64.replace(/\s+/g, "");
867
- const imageUrl = `data:${image.mediaType};base64,${normalizedBase64}`;
868
-
869
- return {
870
- image_url: imageUrl,
871
- image_base64: normalizedBase64,
872
- media_type: image.mediaType,
873
- prompt_utilizado: prompt,
874
- metadados: {
875
- modelo_utilizado: this.GEMINI_IMAGE_MODEL,
876
- tempo_processamento: Date.now() - startTime,
877
- estilo,
878
- resolucao,
879
- },
880
- };
881
- } catch (error) {
882
- const message =
883
- error instanceof Error ? error.message : "Unknown image error";
884
- context.log(`Gemini Flash image helper failed: ${message}`);
885
- context.setError(message);
886
- throw error;
887
- }
888
- }
889
767
  }
890
768
 
891
769
  // Singleton instance