@elevasis/core 0.1.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 (564) hide show
  1. package/dist/index.d.ts +435 -0
  2. package/dist/index.js +403 -0
  3. package/dist/organization-model/index.d.ts +435 -0
  4. package/dist/organization-model/index.js +403 -0
  5. package/package.json +62 -0
  6. package/src/README.md +34 -0
  7. package/src/__tests__/observability-exports.test.ts +36 -0
  8. package/src/__tests__/publish.test.ts +18 -0
  9. package/src/__tests__/template-foundations-compatibility.test.ts +34 -0
  10. package/src/auth/index.ts +8 -0
  11. package/src/auth/multi-tenancy/credentials/README.md +38 -0
  12. package/src/auth/multi-tenancy/credentials/__tests__/encryption.test.ts +216 -0
  13. package/src/auth/multi-tenancy/credentials/__tests__/service.test.ts +174 -0
  14. package/src/auth/multi-tenancy/credentials/index.ts +6 -0
  15. package/src/auth/multi-tenancy/credentials/server/encryption.ts +39 -0
  16. package/src/auth/multi-tenancy/credentials/server/service.ts +60 -0
  17. package/src/auth/multi-tenancy/index.ts +17 -0
  18. package/src/auth/multi-tenancy/invitations/__tests__/invitation.test.ts +237 -0
  19. package/src/auth/multi-tenancy/invitations/api-schemas.ts +107 -0
  20. package/src/auth/multi-tenancy/invitations/index.ts +38 -0
  21. package/src/auth/multi-tenancy/invitations/invitation.ts +86 -0
  22. package/src/auth/multi-tenancy/invitations/server/index.ts +25 -0
  23. package/src/auth/multi-tenancy/invitations/server/transforms.ts +24 -0
  24. package/src/auth/multi-tenancy/invitations/server/workos.ts +24 -0
  25. package/src/auth/multi-tenancy/invitations/supabase.ts +50 -0
  26. package/src/auth/multi-tenancy/memberships/__tests__/membership.test.ts +227 -0
  27. package/src/auth/multi-tenancy/memberships/__tests__/supabase-transforms.test.ts +88 -0
  28. package/src/auth/multi-tenancy/memberships/__tests__/workos-transforms.test.ts +139 -0
  29. package/src/auth/multi-tenancy/memberships/api-schemas.ts +126 -0
  30. package/src/auth/multi-tenancy/memberships/index.ts +22 -0
  31. package/src/auth/multi-tenancy/memberships/membership.ts +138 -0
  32. package/src/auth/multi-tenancy/memberships/server/index.ts +15 -0
  33. package/src/auth/multi-tenancy/memberships/server/transforms.ts +32 -0
  34. package/src/auth/multi-tenancy/memberships/server/workos.ts +21 -0
  35. package/src/auth/multi-tenancy/memberships/supabase.ts +46 -0
  36. package/src/auth/multi-tenancy/organizations/__tests__/organization.test.ts +249 -0
  37. package/src/auth/multi-tenancy/organizations/api-schemas.ts +128 -0
  38. package/src/auth/multi-tenancy/organizations/index.ts +23 -0
  39. package/src/auth/multi-tenancy/organizations/organization.ts +25 -0
  40. package/src/auth/multi-tenancy/organizations/server/index.ts +10 -0
  41. package/src/auth/multi-tenancy/organizations/server/transforms.ts +35 -0
  42. package/src/auth/multi-tenancy/organizations/server/workos.ts +20 -0
  43. package/src/auth/multi-tenancy/types.ts +89 -0
  44. package/src/auth/multi-tenancy/users/__tests__/user.test.ts +208 -0
  45. package/src/auth/multi-tenancy/users/api-schemas.ts +194 -0
  46. package/src/auth/multi-tenancy/users/index.ts +28 -0
  47. package/src/auth/multi-tenancy/users/server/index.ts +19 -0
  48. package/src/auth/multi-tenancy/users/server/transforms.ts +21 -0
  49. package/src/auth/multi-tenancy/users/server/workos.ts +16 -0
  50. package/src/auth/multi-tenancy/users/user.ts +65 -0
  51. package/src/business/acquisition/api-schemas.ts +759 -0
  52. package/src/business/acquisition/index.ts +109 -0
  53. package/src/business/acquisition/types.ts +400 -0
  54. package/src/business/crm/api-schemas.ts +75 -0
  55. package/src/business/delivery/index.ts +1 -0
  56. package/src/business/delivery/types.ts +89 -0
  57. package/src/business/index.ts +12 -0
  58. package/src/business/pdf/assets/ElevasisLogo.png +0 -0
  59. package/src/business/pdf/browser/image-utils.ts +74 -0
  60. package/src/business/pdf/browser/index.ts +16 -0
  61. package/src/business/pdf/browser/pdfmake-browser.ts +229 -0
  62. package/src/business/pdf/index.ts +10 -0
  63. package/src/business/pdf/sections/acceptance.ts +112 -0
  64. package/src/business/pdf/sections/automation.ts +56 -0
  65. package/src/business/pdf/sections/cover.ts +51 -0
  66. package/src/business/pdf/sections/index.ts +57 -0
  67. package/src/business/pdf/sections/investment.ts +69 -0
  68. package/src/business/pdf/sections/proposal-document.ts +200 -0
  69. package/src/business/pdf/sections/summary-investment.ts +124 -0
  70. package/src/business/pdf/sections/summary.ts +55 -0
  71. package/src/business/pdf/sections/table-summary.ts +59 -0
  72. package/src/business/pdf/sections/types.ts +124 -0
  73. package/src/business/pdf/server/__tests__/pdfmake-test.ts +219 -0
  74. package/src/business/pdf/server/index.ts +21 -0
  75. package/src/business/pdf/server/pdfmake-service.ts +237 -0
  76. package/src/business/pdf/server/themes/default.ts +8 -0
  77. package/src/business/pdf/server/themes/index.ts +9 -0
  78. package/src/business/pdf/server/themes/types.ts +8 -0
  79. package/src/business/pdf/shared/convert.ts +514 -0
  80. package/src/business/pdf/shared/index.ts +12 -0
  81. package/src/business/pdf/themes.ts +78 -0
  82. package/src/business/pdf/types.ts +272 -0
  83. package/src/business/seo/__tests__/linking.test.ts +549 -0
  84. package/src/business/seo/__tests__/types.test.ts +404 -0
  85. package/src/business/seo/index.ts +2 -0
  86. package/src/business/seo/linking.ts +281 -0
  87. package/src/business/seo/types.ts +199 -0
  88. package/src/commands/index.ts +8 -0
  89. package/src/commands/queue/index.ts +3 -0
  90. package/src/commands/queue/schemas.test.ts +593 -0
  91. package/src/commands/queue/schemas.ts +125 -0
  92. package/src/commands/queue/sse-events.ts +61 -0
  93. package/src/commands/queue/types/action.ts +52 -0
  94. package/src/commands/queue/types/checkpoint.ts +44 -0
  95. package/src/commands/queue/types/index.ts +7 -0
  96. package/src/commands/queue/types/task.ts +116 -0
  97. package/src/commands/queue/types.ts +14 -0
  98. package/src/content/distribution-metadata.ts +61 -0
  99. package/src/content/index.ts +10 -0
  100. package/src/deployments/index.ts +22 -0
  101. package/src/execution/calibration/__tests__/schemas.test.ts +320 -0
  102. package/src/execution/calibration/index.ts +3 -0
  103. package/src/execution/calibration/schemas.ts +121 -0
  104. package/src/execution/calibration/sse-events.ts +125 -0
  105. package/src/execution/calibration/types.ts +190 -0
  106. package/src/execution/core/__tests__/api-schemas.test.ts +667 -0
  107. package/src/execution/core/__tests__/archived-logs.test.ts +72 -0
  108. package/src/execution/core/api-schemas.ts +312 -0
  109. package/src/execution/core/index.ts +11 -0
  110. package/src/execution/core/resource-validator.test.ts +63 -0
  111. package/src/execution/core/runner-types.ts +80 -0
  112. package/src/execution/core/server/environment.ts +31 -0
  113. package/src/execution/core/sse-executions.ts +119 -0
  114. package/src/execution/core/types.ts +29 -0
  115. package/src/execution/engine/__tests__/fixtures/index.ts +2 -0
  116. package/src/execution/engine/__tests__/fixtures/mock-scenarios.ts +60 -0
  117. package/src/execution/engine/__tests__/fixtures/test-agents.ts +85 -0
  118. package/src/execution/engine/__tests__/integration/agent-framework.integration.test.ts +1031 -0
  119. package/src/execution/engine/__tests__/timeout.test.ts +565 -0
  120. package/src/execution/engine/agent/__tests__/errors.test.ts +508 -0
  121. package/src/execution/engine/agent/actions/__tests__/processor.test.ts +531 -0
  122. package/src/execution/engine/agent/actions/executor.ts +205 -0
  123. package/src/execution/engine/agent/actions/navigate-knowledge-executor.ts +230 -0
  124. package/src/execution/engine/agent/actions/processor.ts +116 -0
  125. package/src/execution/engine/agent/actions/types.ts +70 -0
  126. package/src/execution/engine/agent/core/__tests__/agent.test.ts +614 -0
  127. package/src/execution/engine/agent/core/__tests__/error-passthrough.test.ts +134 -0
  128. package/src/execution/engine/agent/core/agent.ts +810 -0
  129. package/src/execution/engine/agent/core/types.ts +155 -0
  130. package/src/execution/engine/agent/errors.ts +251 -0
  131. package/src/execution/engine/agent/index.ts +78 -0
  132. package/src/execution/engine/agent/knowledge-map/__tests__/navigate-knowledge-executor.test.ts +580 -0
  133. package/src/execution/engine/agent/knowledge-map/__tests__/utils.test.ts +622 -0
  134. package/src/execution/engine/agent/knowledge-map/types.ts +106 -0
  135. package/src/execution/engine/agent/knowledge-map/utils.ts +101 -0
  136. package/src/execution/engine/agent/memory/__tests__/domains.test.ts +72 -0
  137. package/src/execution/engine/agent/memory/__tests__/manager.test.ts +754 -0
  138. package/src/execution/engine/agent/memory/__tests__/utils.test.ts +285 -0
  139. package/src/execution/engine/agent/memory/domains.ts +99 -0
  140. package/src/execution/engine/agent/memory/manager.ts +365 -0
  141. package/src/execution/engine/agent/memory/processor.ts +66 -0
  142. package/src/execution/engine/agent/memory/types.ts +90 -0
  143. package/src/execution/engine/agent/memory/utils.ts +134 -0
  144. package/src/execution/engine/agent/observability/logging.ts +467 -0
  145. package/src/execution/engine/agent/observability/types.ts +64 -0
  146. package/src/execution/engine/agent/reasoning/__tests__/request-builder.test.ts +209 -0
  147. package/src/execution/engine/agent/reasoning/adapters/agent-adapter-helpers.ts +349 -0
  148. package/src/execution/engine/agent/reasoning/processor.ts +92 -0
  149. package/src/execution/engine/agent/reasoning/prompt-sections/base-actions.ts +134 -0
  150. package/src/execution/engine/agent/reasoning/prompt-sections/completion.ts +49 -0
  151. package/src/execution/engine/agent/reasoning/prompt-sections/knowledge-map.ts +93 -0
  152. package/src/execution/engine/agent/reasoning/prompt-sections/memory.ts +65 -0
  153. package/src/execution/engine/agent/reasoning/prompt-sections/security.ts +32 -0
  154. package/src/execution/engine/agent/reasoning/prompt-sections/tools.ts +44 -0
  155. package/src/execution/engine/agent/reasoning/request-builder.ts +169 -0
  156. package/src/execution/engine/agent/reasoning/types.ts +18 -0
  157. package/src/execution/engine/base/__tests__/errors.test.ts +246 -0
  158. package/src/execution/engine/base/__tests__/serialization.test.ts +670 -0
  159. package/src/execution/engine/base/__tests__/utils.test.ts +45 -0
  160. package/src/execution/engine/base/errors.ts +118 -0
  161. package/src/execution/engine/base/index.ts +2 -0
  162. package/src/execution/engine/base/logging.ts +31 -0
  163. package/src/execution/engine/base/serialization.ts +324 -0
  164. package/src/execution/engine/base/types.ts +126 -0
  165. package/src/execution/engine/base/utils.ts +41 -0
  166. package/src/execution/engine/index.ts +440 -0
  167. package/src/execution/engine/interface/index.ts +1 -0
  168. package/src/execution/engine/interface/types.ts +62 -0
  169. package/src/execution/engine/llm/__tests__/errors.test.ts +318 -0
  170. package/src/execution/engine/llm/__tests__/input-sanitizer.test.ts +286 -0
  171. package/src/execution/engine/llm/__tests__/model-info.test.ts +50 -0
  172. package/src/execution/engine/llm/__tests__/model-validation.test.ts +321 -0
  173. package/src/execution/engine/llm/__tests__/response-schema-validator.test.ts +115 -0
  174. package/src/execution/engine/llm/adapters/__tests__/adapter-factory.test.ts +375 -0
  175. package/src/execution/engine/llm/adapters/__tests__/anthropic-adapter.test.ts +463 -0
  176. package/src/execution/engine/llm/adapters/__tests__/anthropic.integration.test.ts +177 -0
  177. package/src/execution/engine/llm/adapters/__tests__/circuit-breaker-error.test.ts +94 -0
  178. package/src/execution/engine/llm/adapters/__tests__/google-adapter.test.ts +722 -0
  179. package/src/execution/engine/llm/adapters/__tests__/google.integration.test.ts +376 -0
  180. package/src/execution/engine/llm/adapters/__tests__/mock-adapter.test.ts +432 -0
  181. package/src/execution/engine/llm/adapters/__tests__/openai-adapter.test.ts +551 -0
  182. package/src/execution/engine/llm/adapters/__tests__/openrouter-adapter.test.ts +563 -0
  183. package/src/execution/engine/llm/adapters/__tests__/openrouter.integration.test.ts +105 -0
  184. package/src/execution/engine/llm/adapters/__tests__/universal-adapter.test.ts +537 -0
  185. package/src/execution/engine/llm/adapters/circuit-breaker.ts +147 -0
  186. package/src/execution/engine/llm/adapters/index.ts +17 -0
  187. package/src/execution/engine/llm/adapters/mock-adapter.ts +116 -0
  188. package/src/execution/engine/llm/adapters/server/adapter-factory.ts +130 -0
  189. package/src/execution/engine/llm/adapters/server/anthropic.ts +137 -0
  190. package/src/execution/engine/llm/adapters/server/compose-signal.ts +18 -0
  191. package/src/execution/engine/llm/adapters/server/google.ts +283 -0
  192. package/src/execution/engine/llm/adapters/server/index.ts +12 -0
  193. package/src/execution/engine/llm/adapters/server/openai.ts +206 -0
  194. package/src/execution/engine/llm/adapters/server/openrouter.ts +235 -0
  195. package/src/execution/engine/llm/adapters/universal-adapter.ts +230 -0
  196. package/src/execution/engine/llm/errors.ts +186 -0
  197. package/src/execution/engine/llm/input-sanitizer.ts +129 -0
  198. package/src/execution/engine/llm/model-info.ts +332 -0
  199. package/src/execution/engine/llm/response-schema-validator.ts +113 -0
  200. package/src/execution/engine/llm/types.ts +86 -0
  201. package/src/execution/engine/test-utils/index.ts +6 -0
  202. package/src/execution/engine/test-utils/mocks.ts +56 -0
  203. package/src/execution/engine/tools/__tests__/tooling-error.test.ts +265 -0
  204. package/src/execution/engine/tools/__tests__/types.test.ts +47 -0
  205. package/src/execution/engine/tools/integration/base-integration-adapter.ts +50 -0
  206. package/src/execution/engine/tools/integration/index.ts +53 -0
  207. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-adapter.ts +73 -0
  208. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-tools.ts +209 -0
  209. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-company-email/index.ts +82 -0
  210. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-decision-maker-email/index.ts +122 -0
  211. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-person-email/index.ts +89 -0
  212. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/verify-email/index.ts +84 -0
  213. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/index.ts +16 -0
  214. package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +293 -0
  215. package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.ts +100 -0
  216. package/src/execution/engine/tools/integration/server/adapters/apify/apify-tools.ts +217 -0
  217. package/src/execution/engine/tools/integration/server/adapters/apify/fetch/get-dataset-items/index.ts +92 -0
  218. package/src/execution/engine/tools/integration/server/adapters/apify/fetch/run-actor/index.ts +218 -0
  219. package/src/execution/engine/tools/integration/server/adapters/apify/fetch/start-actor/index.ts +87 -0
  220. package/src/execution/engine/tools/integration/server/adapters/apify/index.ts +11 -0
  221. package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +362 -0
  222. package/src/execution/engine/tools/integration/server/adapters/attio/attio-adapter.ts +162 -0
  223. package/src/execution/engine/tools/integration/server/adapters/attio/attio-tools.ts +594 -0
  224. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/README.md +632 -0
  225. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-attribute/index.ts +214 -0
  226. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-note/index.ts +152 -0
  227. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-record/index.ts +141 -0
  228. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-note/index.ts +86 -0
  229. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-record/index.ts +105 -0
  230. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.test.ts +186 -0
  231. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.ts +118 -0
  232. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-attributes/index.ts +165 -0
  233. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-notes/index.ts +96 -0
  234. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-objects/index.ts +104 -0
  235. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.test.ts +338 -0
  236. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.ts +156 -0
  237. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-attribute/index.ts +220 -0
  238. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-record/index.ts +140 -0
  239. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/utils/types.ts +147 -0
  240. package/src/execution/engine/tools/integration/server/adapters/attio/index.ts +31 -0
  241. package/src/execution/engine/tools/integration/server/adapters/dropbox/__tests__/dropbox-adapter.test.ts +409 -0
  242. package/src/execution/engine/tools/integration/server/adapters/dropbox/dropbox-adapter.ts +281 -0
  243. package/src/execution/engine/tools/integration/server/adapters/dropbox/dropbox-tools.ts +106 -0
  244. package/src/execution/engine/tools/integration/server/adapters/dropbox/fetch/create-folder/__tests__/index.test.ts +451 -0
  245. package/src/execution/engine/tools/integration/server/adapters/dropbox/fetch/create-folder/index.ts +114 -0
  246. package/src/execution/engine/tools/integration/server/adapters/dropbox/fetch/upload-file/__tests__/index.test.ts +415 -0
  247. package/src/execution/engine/tools/integration/server/adapters/dropbox/fetch/upload-file/index.ts +111 -0
  248. package/src/execution/engine/tools/integration/server/adapters/dropbox/index.ts +25 -0
  249. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +210 -0
  250. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +104 -0
  251. package/src/execution/engine/tools/integration/server/adapters/google-sheets/__tests__/google-sheets.integration.test.ts +261 -0
  252. package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-adapter.ts +1189 -0
  253. package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-tools.ts +641 -0
  254. package/src/execution/engine/tools/integration/server/adapters/google-sheets/index.ts +18 -0
  255. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/activate-campaign/index.ts +86 -0
  256. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/__tests__/index.test.ts +289 -0
  257. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/index.ts +154 -0
  258. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/__tests__/index.test.ts +325 -0
  259. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/index.ts +153 -0
  260. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-delete-leads/index.ts +84 -0
  261. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-campaign/index.ts +125 -0
  262. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-inbox-test/index.ts +107 -0
  263. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/delete-campaign/index.ts +85 -0
  264. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-account-health/index.ts +91 -0
  265. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign/index.ts +92 -0
  266. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/__tests__/index.test.ts +195 -0
  267. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/index.ts +113 -0
  268. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-daily-campaign-analytics/index.ts +104 -0
  269. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-emails/index.ts +155 -0
  270. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/__tests__/index.test.ts +196 -0
  271. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/index.ts +102 -0
  272. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/__tests__/index.test.ts +189 -0
  273. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/index.ts +87 -0
  274. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-leads/index.ts +112 -0
  275. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/patch-lead/index.ts +76 -0
  276. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/pause-campaign/index.ts +86 -0
  277. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/remove-from-subsequence/index.ts +98 -0
  278. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/send-reply/index.ts +126 -0
  279. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/__tests__/index.test.ts +193 -0
  280. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/index.ts +99 -0
  281. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/__tests__/index.test.ts +621 -0
  282. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/index.ts +125 -0
  283. package/src/execution/engine/tools/integration/server/adapters/instantly/index.ts +29 -0
  284. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-adapter.ts +178 -0
  285. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1473 -0
  286. package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/check-credits/index.ts +59 -0
  287. package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/verify-email/index.ts +102 -0
  288. package/src/execution/engine/tools/integration/server/adapters/millionverifier/index.ts +17 -0
  289. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-adapter.ts +80 -0
  290. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +102 -0
  291. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/get-email/index.ts +102 -0
  292. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +134 -0
  293. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +75 -0
  294. package/src/execution/engine/tools/integration/server/adapters/resend/index.ts +27 -0
  295. package/src/execution/engine/tools/integration/server/adapters/resend/resend-adapter.ts +108 -0
  296. package/src/execution/engine/tools/integration/server/adapters/resend/resend-tools.ts +132 -0
  297. package/src/execution/engine/tools/integration/server/adapters/resend/types.ts +44 -0
  298. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/create-envelope/index.ts +274 -0
  299. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/download-document/index.ts +230 -0
  300. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/get-envelope/index.ts +133 -0
  301. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/utils/types.ts +246 -0
  302. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/void-envelope/index.ts +90 -0
  303. package/src/execution/engine/tools/integration/server/adapters/signature-api/index.ts +38 -0
  304. package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-adapter.ts +87 -0
  305. package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-tools.ts +179 -0
  306. package/src/execution/engine/tools/integration/server/adapters/stripe/fetch/utils/types.ts +210 -0
  307. package/src/execution/engine/tools/integration/server/adapters/stripe/index.ts +44 -0
  308. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-adapter.ts +517 -0
  309. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +309 -0
  310. package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/domain-search/index.ts +133 -0
  311. package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-finder/index.ts +122 -0
  312. package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-verifier/index.ts +111 -0
  313. package/src/execution/engine/tools/integration/server/adapters/tomba/index.ts +11 -0
  314. package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-adapter.ts +78 -0
  315. package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-tools.ts +222 -0
  316. package/src/execution/engine/tools/integration/server/index.ts +61 -0
  317. package/src/execution/engine/tools/integration/service.ts +161 -0
  318. package/src/execution/engine/tools/integration/tool.ts +253 -0
  319. package/src/execution/engine/tools/integration/types/anymailfinder.ts +74 -0
  320. package/src/execution/engine/tools/integration/types/apify.ts +92 -0
  321. package/src/execution/engine/tools/integration/types/attio.ts +354 -0
  322. package/src/execution/engine/tools/integration/types/dropbox.ts +64 -0
  323. package/src/execution/engine/tools/integration/types/gmail.ts +35 -0
  324. package/src/execution/engine/tools/integration/types/google-sheets.ts +303 -0
  325. package/src/execution/engine/tools/integration/types/index.ts +19 -0
  326. package/src/execution/engine/tools/integration/types/instantly.ts +557 -0
  327. package/src/execution/engine/tools/integration/types/millionverifier.ts +56 -0
  328. package/src/execution/engine/tools/integration/types/resend.ts +63 -0
  329. package/src/execution/engine/tools/integration/types/signature-api.ts +164 -0
  330. package/src/execution/engine/tools/integration/types/stripe.ts +162 -0
  331. package/src/execution/engine/tools/integration/types/tomba.ts +94 -0
  332. package/src/execution/engine/tools/lead-service-types.ts +884 -0
  333. package/src/execution/engine/tools/llm/index.ts +11 -0
  334. package/src/execution/engine/tools/llm/server/index.ts +8 -0
  335. package/src/execution/engine/tools/llm/server/llm-call-tool.ts +118 -0
  336. package/src/execution/engine/tools/platform/__tests__/approval.test.ts +242 -0
  337. package/src/execution/engine/tools/platform/__tests__/email.test.ts +482 -0
  338. package/src/execution/engine/tools/platform/__tests__/hitl-cancel.test.ts +97 -0
  339. package/src/execution/engine/tools/platform/__tests__/notification.test.ts +208 -0
  340. package/src/execution/engine/tools/platform/__tests__/pdf.test.ts +441 -0
  341. package/src/execution/engine/tools/platform/__tests__/scheduler.test.ts +189 -0
  342. package/src/execution/engine/tools/platform/__tests__/schedules.test.ts +336 -0
  343. package/src/execution/engine/tools/platform/acquisition/company-tools.ts +248 -0
  344. package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +319 -0
  345. package/src/execution/engine/tools/platform/acquisition/index.ts +43 -0
  346. package/src/execution/engine/tools/platform/acquisition/list-tools.ts +148 -0
  347. package/src/execution/engine/tools/platform/acquisition/types.ts +260 -0
  348. package/src/execution/engine/tools/platform/approval/cancel-by-metadata.ts +65 -0
  349. package/src/execution/engine/tools/platform/approval/index.ts +4 -0
  350. package/src/execution/engine/tools/platform/approval/tool.ts +99 -0
  351. package/src/execution/engine/tools/platform/email/index.ts +122 -0
  352. package/src/execution/engine/tools/platform/email/types.ts +96 -0
  353. package/src/execution/engine/tools/platform/index.ts +181 -0
  354. package/src/execution/engine/tools/platform/notification.ts +81 -0
  355. package/src/execution/engine/tools/platform/pdf/index.ts +110 -0
  356. package/src/execution/engine/tools/platform/pdf/types.ts +77 -0
  357. package/src/execution/engine/tools/platform/resource-invocation/__tests__/edge-cases.test.ts +507 -0
  358. package/src/execution/engine/tools/platform/resource-invocation/__tests__/resource-invocation-service.test.ts +500 -0
  359. package/src/execution/engine/tools/platform/resource-invocation/__tests__/tool.test.ts +555 -0
  360. package/src/execution/engine/tools/platform/resource-invocation/dynamic-tool.ts +94 -0
  361. package/src/execution/engine/tools/platform/resource-invocation/index.ts +14 -0
  362. package/src/execution/engine/tools/platform/resource-invocation/resource-invocation-service.ts +147 -0
  363. package/src/execution/engine/tools/platform/resource-invocation/tool.ts +115 -0
  364. package/src/execution/engine/tools/platform/resource-invocation/types.ts +31 -0
  365. package/src/execution/engine/tools/platform/scheduler.ts +87 -0
  366. package/src/execution/engine/tools/platform/schedules/cancel-by-key-tool.ts +48 -0
  367. package/src/execution/engine/tools/platform/schedules/cancel-by-metadata-tool.ts +42 -0
  368. package/src/execution/engine/tools/platform/schedules/delete-by-key-tool.ts +43 -0
  369. package/src/execution/engine/tools/platform/schedules/index.ts +13 -0
  370. package/src/execution/engine/tools/platform/schedules/list-tool.ts +56 -0
  371. package/src/execution/engine/tools/platform/schedules/types.ts +88 -0
  372. package/src/execution/engine/tools/platform/storage/__tests__/storage.test.ts +998 -0
  373. package/src/execution/engine/tools/platform/storage/index.ts +370 -0
  374. package/src/execution/engine/tools/platform/storage/types.ts +128 -0
  375. package/src/execution/engine/tools/platform/types.ts +148 -0
  376. package/src/execution/engine/tools/registry.ts +590 -0
  377. package/src/execution/engine/tools/tool-maps.ts +694 -0
  378. package/src/execution/engine/tools/types.ts +233 -0
  379. package/src/execution/engine/workflow/__tests__/errors.test.ts +139 -0
  380. package/src/execution/engine/workflow/__tests__/utils.test.ts +645 -0
  381. package/src/execution/engine/workflow/__tests__/workflow.test.ts +818 -0
  382. package/src/execution/engine/workflow/errors.ts +63 -0
  383. package/src/execution/engine/workflow/helpers/index.ts +11 -0
  384. package/src/execution/engine/workflow/helpers/server/index.ts +8 -0
  385. package/src/execution/engine/workflow/helpers/server/llm-call.ts +93 -0
  386. package/src/execution/engine/workflow/index.ts +19 -0
  387. package/src/execution/engine/workflow/log-truncate.ts +26 -0
  388. package/src/execution/engine/workflow/logging.ts +191 -0
  389. package/src/execution/engine/workflow/types.ts +183 -0
  390. package/src/execution/engine/workflow/utils.ts +280 -0
  391. package/src/execution/engine/workflow/workflow.ts +168 -0
  392. package/src/execution/index.ts +20 -0
  393. package/src/execution/scheduler/__tests__/api-schemas.test.ts +733 -0
  394. package/src/execution/scheduler/__tests__/retry.test.ts +37 -0
  395. package/src/execution/scheduler/__tests__/utils.test.ts +1009 -0
  396. package/src/execution/scheduler/api-schemas.ts +296 -0
  397. package/src/execution/scheduler/index.ts +50 -0
  398. package/src/execution/scheduler/schemas.ts +264 -0
  399. package/src/execution/scheduler/types.ts +111 -0
  400. package/src/execution/scheduler/utils.ts +364 -0
  401. package/src/forms/index.ts +7 -0
  402. package/src/forms/schemas.test.ts +113 -0
  403. package/src/forms/schemas.ts +69 -0
  404. package/src/forms/types.ts +70 -0
  405. package/src/index.ts +54 -0
  406. package/src/integrations/credentials/__tests__/api-schemas.test.ts +496 -0
  407. package/src/integrations/credentials/__tests__/schemas.test.ts +82 -0
  408. package/src/integrations/credentials/__tests__/utils.test.ts +144 -0
  409. package/src/integrations/credentials/api-schemas.ts +143 -0
  410. package/src/integrations/credentials/index.ts +32 -0
  411. package/src/integrations/credentials/schemas.ts +164 -0
  412. package/src/integrations/credentials/utils.ts +59 -0
  413. package/src/integrations/oauth/__tests__/provider-registry.test.ts +59 -0
  414. package/src/integrations/oauth/api-schemas.ts +92 -0
  415. package/src/integrations/oauth/index.ts +19 -0
  416. package/src/integrations/oauth/provider-registry.ts +61 -0
  417. package/src/integrations/oauth/server/__tests__/refresh-concurrent.test.ts +183 -0
  418. package/src/integrations/oauth/server/__tests__/refresh.integration.test.ts +257 -0
  419. package/src/integrations/oauth/server/__tests__/refresh.test.ts +577 -0
  420. package/src/integrations/oauth/server/credentials.ts +39 -0
  421. package/src/integrations/oauth/server/refresh.ts +214 -0
  422. package/src/integrations/oauth/types.ts +34 -0
  423. package/src/integrations/webhook-endpoints/__tests__/api-schemas.test.ts +318 -0
  424. package/src/integrations/webhook-endpoints/api-schemas.ts +102 -0
  425. package/src/integrations/webhook-endpoints/index.ts +28 -0
  426. package/src/integrations/webhook-endpoints/types.ts +51 -0
  427. package/src/operations/activities/api-schemas.ts +79 -0
  428. package/src/operations/activities/index.ts +9 -0
  429. package/src/operations/activities/sse-events.ts +30 -0
  430. package/src/operations/activities/types.ts +63 -0
  431. package/src/operations/debug-logs/client.ts +60 -0
  432. package/src/operations/debug-logs/debug-logger.ts +83 -0
  433. package/src/operations/debug-logs/index.ts +8 -0
  434. package/src/operations/debug-logs/server.ts +19 -0
  435. package/src/operations/debug-logs/types.ts +33 -0
  436. package/src/operations/index.ts +50 -0
  437. package/src/operations/notifications/__tests__/api-schemas.test.ts +216 -0
  438. package/src/operations/notifications/api-schemas.ts +91 -0
  439. package/src/operations/notifications/index.ts +3 -0
  440. package/src/operations/notifications/sse-events.ts +21 -0
  441. package/src/operations/notifications/types.ts +47 -0
  442. package/src/operations/observability/__tests__/openrouter-cost-flow.test.ts +297 -0
  443. package/src/operations/observability/__tests__/schemas.test.ts +151 -0
  444. package/src/operations/observability/__tests__/types.test.ts +109 -0
  445. package/src/operations/observability/__tests__/utils.test.ts +54 -0
  446. package/src/operations/observability/ai-usage-collector.ts +64 -0
  447. package/src/operations/observability/index.ts +13 -0
  448. package/src/operations/observability/metrics-collector.ts +49 -0
  449. package/src/operations/observability/schemas.ts +39 -0
  450. package/src/operations/observability/types.ts +463 -0
  451. package/src/operations/observability/utils.ts +77 -0
  452. package/src/operations/sessions/__tests__/api-schemas.test.ts +361 -0
  453. package/src/operations/sessions/__tests__/manager.test.ts +821 -0
  454. package/src/operations/sessions/api-schemas.ts +166 -0
  455. package/src/operations/sessions/index.ts +26 -0
  456. package/src/operations/sessions/server/manager.ts +90 -0
  457. package/src/operations/sessions/server/session.ts +180 -0
  458. package/src/operations/sessions/types.ts +98 -0
  459. package/src/operations/triggers/index.ts +12 -0
  460. package/src/operations/triggers/webhook/definitions/__tests__/instantly-reply-received.test.ts +72 -0
  461. package/src/operations/triggers/webhook/definitions/instantly-account-error.ts +44 -0
  462. package/src/operations/triggers/webhook/definitions/instantly-auto-reply-received.ts +51 -0
  463. package/src/operations/triggers/webhook/definitions/instantly-campaign-completed.ts +45 -0
  464. package/src/operations/triggers/webhook/definitions/instantly-email-bounced.ts +49 -0
  465. package/src/operations/triggers/webhook/definitions/instantly-lead-unsubscribed.ts +45 -0
  466. package/src/operations/triggers/webhook/definitions/instantly-reply-received.ts +54 -0
  467. package/src/operations/triggers/webhook/index.ts +35 -0
  468. package/src/operations/triggers/webhook/types.ts +74 -0
  469. package/src/organization-model/README.md +79 -0
  470. package/src/organization-model/__tests__/graph.test.ts +250 -0
  471. package/src/organization-model/__tests__/resolve.test.ts +47 -0
  472. package/src/organization-model/defaults.ts +60 -0
  473. package/src/organization-model/domains/branding.ts +22 -0
  474. package/src/organization-model/domains/crm.ts +46 -0
  475. package/src/organization-model/domains/delivery.ts +48 -0
  476. package/src/organization-model/domains/features.ts +57 -0
  477. package/src/organization-model/domains/lead-gen.ts +33 -0
  478. package/src/organization-model/domains/navigation.ts +103 -0
  479. package/src/organization-model/domains/shared.ts +42 -0
  480. package/src/organization-model/graph/build.ts +432 -0
  481. package/src/organization-model/graph/index.ts +4 -0
  482. package/src/organization-model/graph/schema.ts +50 -0
  483. package/src/organization-model/graph/types.ts +52 -0
  484. package/src/organization-model/index.ts +11 -0
  485. package/src/organization-model/published.ts +18 -0
  486. package/src/organization-model/resolve.ts +42 -0
  487. package/src/organization-model/schema.ts +21 -0
  488. package/src/organization-model/types.ts +27 -0
  489. package/src/platform/api/index.ts +1 -0
  490. package/src/platform/api/types.ts +35 -0
  491. package/src/platform/constants/http.ts +37 -0
  492. package/src/platform/constants/index.ts +5 -0
  493. package/src/platform/constants/limits.ts +32 -0
  494. package/src/platform/constants/resilience.ts +51 -0
  495. package/src/platform/constants/timeouts.ts +20 -0
  496. package/src/platform/constants/versions.ts +3 -0
  497. package/src/platform/index.ts +27 -0
  498. package/src/platform/registry/__tests__/command-view.test.ts +410 -0
  499. package/src/platform/registry/__tests__/resource-registry-static.test.ts +347 -0
  500. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +1004 -0
  501. package/src/platform/registry/__tests__/resource-registry.list-executable.test.ts +393 -0
  502. package/src/platform/registry/__tests__/resource-registry.test.ts +1942 -0
  503. package/src/platform/registry/__tests__/serialization.test.ts +1127 -0
  504. package/src/platform/registry/__tests__/validation.test.ts +1086 -0
  505. package/src/platform/registry/command-view.ts +180 -0
  506. package/src/platform/registry/domains.ts +165 -0
  507. package/src/platform/registry/index.ts +93 -0
  508. package/src/platform/registry/reserved.ts +24 -0
  509. package/src/platform/registry/resource-metadata.ts +59 -0
  510. package/src/platform/registry/resource-registry.command-queue-groups.test.ts +129 -0
  511. package/src/platform/registry/resource-registry.ts +788 -0
  512. package/src/platform/registry/serialization.ts +273 -0
  513. package/src/platform/registry/serialized-types.ts +231 -0
  514. package/src/platform/registry/stats-types.ts +66 -0
  515. package/src/platform/registry/types.ts +404 -0
  516. package/src/platform/registry/validation.ts +513 -0
  517. package/src/platform/resilience/__tests__/circuit-breaker.test.ts +291 -0
  518. package/src/platform/resilience/__tests__/http-error-mapper.test.ts +173 -0
  519. package/src/platform/resilience/__tests__/rate-limiter.test.ts +471 -0
  520. package/src/platform/resilience/__tests__/retry.test.ts +380 -0
  521. package/src/platform/resilience/__tests__/timeout.test.ts +219 -0
  522. package/src/platform/resilience/circuit-breaker.ts +164 -0
  523. package/src/platform/resilience/errors.ts +68 -0
  524. package/src/platform/resilience/http-error-mapper.ts +129 -0
  525. package/src/platform/resilience/index.ts +93 -0
  526. package/src/platform/resilience/rate-limiter-types.ts +46 -0
  527. package/src/platform/resilience/rate-limiter.ts +140 -0
  528. package/src/platform/resilience/retry.ts +89 -0
  529. package/src/platform/resilience/timeout.ts +63 -0
  530. package/src/platform/sse/events.ts +67 -0
  531. package/src/platform/sse/index.ts +7 -0
  532. package/src/platform/utils/__tests__/currency.test.ts +77 -0
  533. package/src/platform/utils/__tests__/validation.test.ts +1083 -0
  534. package/src/platform/utils/currency.ts +96 -0
  535. package/src/platform/utils/debounce.ts +52 -0
  536. package/src/platform/utils/error.ts +42 -0
  537. package/src/platform/utils/hmac.test.ts +97 -0
  538. package/src/platform/utils/index.ts +32 -0
  539. package/src/platform/utils/server/betterstack-logger.ts +210 -0
  540. package/src/platform/utils/server/hmac.ts +44 -0
  541. package/src/platform/utils/server/unsubscribe.ts +111 -0
  542. package/src/platform/utils/token-counter.ts +96 -0
  543. package/src/platform/utils/validation.ts +425 -0
  544. package/src/projects/api-schemas.ts +265 -0
  545. package/src/published.ts +1 -0
  546. package/src/server.ts +273 -0
  547. package/src/supabase/__tests__/helpers.test.ts +51 -0
  548. package/src/supabase/database.types.ts +2674 -0
  549. package/src/supabase/helpers.ts +20 -0
  550. package/src/supabase/index.ts +52 -0
  551. package/src/supabase/server/client.ts +58 -0
  552. package/src/test-utils/README.md +150 -0
  553. package/src/test-utils/browser-mocks.ts +54 -0
  554. package/src/test-utils/fixtures/api-keys.ts +52 -0
  555. package/src/test-utils/fixtures/index.ts +4 -0
  556. package/src/test-utils/fixtures/memberships.ts +80 -0
  557. package/src/test-utils/fixtures/organizations.ts +69 -0
  558. package/src/test-utils/fixtures/users.ts +79 -0
  559. package/src/test-utils/index.ts +11 -0
  560. package/src/test-utils/mocks/index.ts +2 -0
  561. package/src/test-utils/mocks/supabase.ts +142 -0
  562. package/src/test-utils/mocks/workos.ts +108 -0
  563. package/src/test-utils/rls/RLSTestContext.ts +586 -0
  564. package/src/test-utils/rls/index.ts +1 -0
@@ -0,0 +1,1031 @@
1
+ /**
2
+ * Agent Framework Integration Tests
3
+ *
4
+ * Tests complete agent execution flows with tools and knowledge map
5
+ * using real framework components with mocked external boundaries.
6
+ *
7
+ * Mock Boundaries:
8
+ * - LLM API calls → MockAdapter with configurable responses
9
+ * - Platform services → vi.mocked(getToolServices)
10
+ *
11
+ * Test Real:
12
+ * - Agent execution (initialize → iterate → complete)
13
+ * - MemoryManager (session memory, history, auto-compaction)
14
+ * - Tool factories and execution
15
+ * - Action processors
16
+ * - ExecutionContext propagation
17
+ */
18
+
19
+ import { describe, it, expect, beforeEach, vi } from 'vitest'
20
+ import { Agent } from '../../agent/core/agent'
21
+ import { MockAdapter } from '../../llm/adapters/mock-adapter'
22
+ import type { LLMAdapterFactory } from '../../agent/core/types'
23
+ import { createApprovalTool } from '../../tools/platform/approval'
24
+ import { createNotificationTool } from '../../tools/platform/notification'
25
+ import { getToolServices } from '../../tools/registry'
26
+ import { z } from 'zod'
27
+ import type { ExecutionContext } from '../../base/types'
28
+ import { createKnowledgeMapAgent } from '../fixtures/test-agents'
29
+
30
+ /**
31
+ * Create a mock LLMAdapterFactory that returns a given MockAdapter instance.
32
+ * Satisfies the Agent constructor's second parameter (adapterFactory).
33
+ */
34
+ function createMockAdapterFactory(adapter?: MockAdapter): LLMAdapterFactory {
35
+ const mock = adapter ?? new MockAdapter()
36
+ return () => mock
37
+ }
38
+
39
+ // Mock the tools registry
40
+ vi.mock('../../tools/registry', () => ({
41
+ getToolServices: vi.fn()
42
+ }))
43
+
44
+ /**
45
+ * Phase 4: Knowledge Map Integration
46
+ *
47
+ * Validates knowledge map navigation, dynamic tool registration,
48
+ * and memory scoping (session vs task) for loaded knowledge.
49
+ */
50
+ describe('Knowledge Map Integration', () => {
51
+ const mockContext: ExecutionContext = {
52
+ executionId: 'exec-789',
53
+ organizationId: 'org-456',
54
+ resourceId: 'knowledge-agent',
55
+ resourceType: 'agent' as const,
56
+ logger: {
57
+ info: vi.fn(),
58
+ error: vi.fn(),
59
+ warn: vi.fn(),
60
+ debug: vi.fn()
61
+ }
62
+ }
63
+
64
+ beforeEach(() => {
65
+ vi.clearAllMocks()
66
+ vi.restoreAllMocks()
67
+ })
68
+
69
+ it('loads knowledge node and registers tools dynamically', async () => {
70
+ // Setup: Create configured MockAdapter for multi-iteration flow
71
+ const mockLLM = new MockAdapter({
72
+ responses: [
73
+ {
74
+ reasoning: 'I need access to test tools',
75
+ nextActions: [{
76
+ type: 'navigate-knowledge',
77
+ id: 'nav-1',
78
+ nodeId: 'test-tools'
79
+ }]
80
+ },
81
+ {
82
+ reasoning: 'Tools loaded, now I can use them',
83
+ nextActions: [{
84
+ type: 'tool-call',
85
+ id: 'call-1',
86
+ name: 'test_tool_1',
87
+ input: { input: 'test data' }
88
+ }]
89
+ },
90
+ {
91
+ reasoning: 'Task complete',
92
+ nextActions: [{ type: 'complete' }]
93
+ }
94
+ ],
95
+ completionOutput: { result: 'Successfully used loaded tool' }
96
+ })
97
+
98
+ const agent = new Agent(createKnowledgeMapAgent(), createMockAdapterFactory(mockLLM))
99
+
100
+ // Execute
101
+ const result = await agent.execute(
102
+ { task: 'Load and use test tools' },
103
+ mockContext
104
+ )
105
+
106
+ // Assert: Execution completes with expected output
107
+ expect(result).toEqual({ result: 'Successfully used loaded tool' })
108
+
109
+ // Assert: Tool was registered and used
110
+ const snapshot = agent.getMemorySnapshot()
111
+ expect(snapshot.history).toContainEqual(
112
+ expect.objectContaining({
113
+ type: 'tool-result',
114
+ content: expect.stringContaining('Result: test data')
115
+ })
116
+ )
117
+
118
+ // Assert: Knowledge loaded message in history
119
+ expect(snapshot.history).toContainEqual(
120
+ expect.objectContaining({
121
+ type: 'tool-result',
122
+ content: expect.stringContaining('Knowledge node \'test-tools\' loaded successfully')
123
+ })
124
+ )
125
+
126
+ // Assert: Correct number of LLM calls (3 iterations + 1 completion)
127
+ expect(mockLLM.getCallCount()).toBe(4)
128
+ })
129
+
130
+ it('tool availability follows N+1 iteration pattern', async () => {
131
+ // Setup: MockAdapter that tries to use tool BEFORE navigation
132
+ const mockLLM = new MockAdapter({
133
+ responses: [
134
+ {
135
+ reasoning: 'Attempting to use tool before loading knowledge',
136
+ nextActions: [{
137
+ type: 'tool-call',
138
+ id: 'call-early',
139
+ name: 'test_tool_1',
140
+ input: { input: 'premature call' }
141
+ }]
142
+ },
143
+ // This should fail - tool not registered yet
144
+
145
+ {
146
+ reasoning: 'Now loading knowledge to get the tool',
147
+ nextActions: [{
148
+ type: 'navigate-knowledge',
149
+ id: 'nav-1',
150
+ nodeId: 'test-tools'
151
+ }]
152
+ },
153
+
154
+ {
155
+ reasoning: 'Tool should be available now in N+1',
156
+ nextActions: [{
157
+ type: 'tool-call',
158
+ id: 'call-after',
159
+ name: 'test_tool_1',
160
+ input: { input: 'correct timing' }
161
+ }]
162
+ },
163
+
164
+ {
165
+ reasoning: 'Task complete',
166
+ nextActions: [{ type: 'complete' }]
167
+ }
168
+ ],
169
+ completionOutput: { result: 'N+1 pattern validated' }
170
+ })
171
+
172
+ const agent = new Agent(createKnowledgeMapAgent(), createMockAdapterFactory(mockLLM))
173
+
174
+ // Execute
175
+ const result = await agent.execute(
176
+ { task: 'Test N+1 tool availability' },
177
+ mockContext
178
+ )
179
+
180
+ // Assert: Execution completes (doesn't crash on first error)
181
+ expect(result).toEqual({ result: 'N+1 pattern validated' })
182
+
183
+ // Assert: Memory contains error from first tool call
184
+ const snapshot = agent.getMemorySnapshot()
185
+ const errorEntries = snapshot.history.filter(entry =>
186
+ entry.type === 'error' && entry.content.includes('test_tool_1')
187
+ )
188
+ expect(errorEntries.length).toBeGreaterThan(0)
189
+
190
+ // Assert: Memory contains successful result from second tool call (after navigation)
191
+ const successEntries = snapshot.history.filter(entry =>
192
+ entry.type === 'tool-result' &&
193
+ entry.content.includes('correct timing')
194
+ )
195
+ expect(successEntries.length).toBeGreaterThan(0)
196
+
197
+ // Assert: Knowledge navigation success message exists
198
+ const navEntries = snapshot.history.filter(entry =>
199
+ entry.content.includes('Knowledge node \'test-tools\' loaded successfully')
200
+ )
201
+ expect(navEntries.length).toBeGreaterThan(0)
202
+
203
+ // Assert: Correct number of LLM calls (4 iterations + 1 completion)
204
+ expect(mockLLM.getCallCount()).toBe(5)
205
+ })
206
+
207
+ it('knowledge prompts cached on node after loading', async () => {
208
+ // Setup: MockAdapter that loads knowledge
209
+ const mockLLM = new MockAdapter({
210
+ responses: [
211
+ {
212
+ reasoning: 'Loading session-scoped knowledge',
213
+ nextActions: [{
214
+ type: 'navigate-knowledge',
215
+ id: 'nav-1',
216
+ nodeId: 'test-tools'
217
+ }]
218
+ },
219
+ {
220
+ reasoning: 'Task complete',
221
+ nextActions: [{ type: 'complete' }]
222
+ }
223
+ ],
224
+ completionOutput: { result: 'Session knowledge loaded' }
225
+ })
226
+
227
+ const agent = new Agent(createKnowledgeMapAgent(), createMockAdapterFactory(mockLLM))
228
+
229
+ // Execute
230
+ const result = await agent.execute(
231
+ { task: 'Load session knowledge' },
232
+ mockContext
233
+ )
234
+
235
+ // Assert: Execution completes
236
+ expect(result).toEqual({ result: 'Session knowledge loaded' })
237
+
238
+ // Assert: Content cached on knowledge node
239
+ const tools = agent.getTools()
240
+ expect(tools.length).toBeGreaterThan(0)
241
+
242
+ // Assert: Correct number of LLM calls (2 iterations + 1 completion)
243
+ expect(mockLLM.getCallCount()).toBe(3)
244
+ })
245
+
246
+ it('knowledge tools registered and available', async () => {
247
+ // Setup: MockAdapter that loads and uses knowledge
248
+ const mockLLM = new MockAdapter({
249
+ responses: [
250
+ {
251
+ reasoning: 'Loading task-scoped knowledge',
252
+ nextActions: [{
253
+ type: 'navigate-knowledge',
254
+ id: 'nav-1',
255
+ nodeId: 'test-tools' // Key: store in history
256
+ }]
257
+ },
258
+ {
259
+ reasoning: 'Task complete',
260
+ nextActions: [{ type: 'complete' }]
261
+ }
262
+ ],
263
+ completionOutput: { result: 'Task knowledge loaded' }
264
+ })
265
+
266
+ const agent = new Agent(createKnowledgeMapAgent(), createMockAdapterFactory(mockLLM))
267
+
268
+ // Execute
269
+ const result = await agent.execute(
270
+ { task: 'Load task knowledge' },
271
+ mockContext
272
+ )
273
+
274
+ // Assert: Execution completes
275
+ expect(result).toEqual({ result: 'Task knowledge loaded' })
276
+
277
+ // Assert: Tools registered and available
278
+ const tools = agent.getTools()
279
+ expect(tools.length).toBeGreaterThan(0)
280
+ expect(tools.some(t => t.name === 'test_tool_1')).toBe(true)
281
+
282
+ // Assert: Correct number of LLM calls (2 iterations + 1 completion)
283
+ expect(mockLLM.getCallCount()).toBe(3)
284
+ })
285
+
286
+ it('handles duplicate tool registration idempotently', async () => {
287
+ // Setup: MockAdapter that loads same knowledge node twice
288
+ const mockLLM = new MockAdapter({
289
+ responses: [
290
+ {
291
+ reasoning: 'Loading knowledge first time',
292
+ nextActions: [{
293
+ type: 'navigate-knowledge',
294
+ id: 'nav-1',
295
+ nodeId: 'test-tools'
296
+ }]
297
+ },
298
+ {
299
+ reasoning: 'Loading same knowledge again',
300
+ nextActions: [{
301
+ type: 'navigate-knowledge',
302
+ id: 'nav-2',
303
+ nodeId: 'test-tools' // Same node - should skip duplicate
304
+ }]
305
+ },
306
+ {
307
+ reasoning: 'Task complete',
308
+ nextActions: [{ type: 'complete' }]
309
+ }
310
+ ],
311
+ completionOutput: { result: 'Duplicate registration handled' }
312
+ })
313
+
314
+ const agent = new Agent(createKnowledgeMapAgent(), createMockAdapterFactory(mockLLM))
315
+
316
+ // Execute
317
+ const result = await agent.execute(
318
+ { task: 'Load knowledge twice' },
319
+ mockContext
320
+ )
321
+
322
+ // Assert: Execution completes without errors
323
+ expect(result).toEqual({ result: 'Duplicate registration handled' })
324
+
325
+ // Assert: Tool registry contains only one instance
326
+ const tools = agent.getTools()
327
+ const testTools = tools.filter(t => t.name === 'test_tool_1')
328
+ expect(testTools).toHaveLength(1)
329
+
330
+ // Assert: Both knowledge loading operations succeeded
331
+ const snapshot = agent.getMemorySnapshot()
332
+ const successMessages = snapshot.history.filter(entry =>
333
+ entry.type === 'tool-result' &&
334
+ entry.content.includes('Knowledge node \'test-tools\' loaded successfully')
335
+ )
336
+ expect(successMessages).toHaveLength(2) // Both loads succeeded
337
+
338
+ // Assert: Correct number of LLM calls (3 iterations + 1 completion)
339
+ expect(mockLLM.getCallCount()).toBe(4)
340
+ })
341
+
342
+ it('hierarchical navigation - flattens child nodes into main map', async () => {
343
+ // Setup: Knowledge map with hierarchical nodes
344
+ const hierarchicalKnowledgeMap = {
345
+ organizationId: 'test-org',
346
+ nodes: {
347
+ 'parent-node': {
348
+ id: 'parent-node',
349
+ description: 'Parent node with child nodes',
350
+ load: async () => ({
351
+ prompt: '# Parent Knowledge\n\nBase tools available.',
352
+ tools: [
353
+ {
354
+ name: 'parent_tool',
355
+ description: 'Parent tool',
356
+ inputSchema: z.object({ data: z.string() }),
357
+ outputSchema: z.object({ result: z.string() }),
358
+ execute: async ({ input }: { input: Record<string, unknown> }) => ({ result: `Parent: ${input.data}` })
359
+ }
360
+ ],
361
+ nodes: {
362
+ 'child-node-1': {
363
+ id: 'child-node-1',
364
+ description: 'Child node 1',
365
+ load: async () => ({
366
+ prompt: '# Child Knowledge 1\n\nSpecialized tools.',
367
+ tools: [
368
+ {
369
+ name: 'child_tool_1',
370
+ description: 'Child tool 1',
371
+ inputSchema: z.object({ value: z.string() }),
372
+ outputSchema: z.object({ output: z.string() }),
373
+ execute: async ({ input }: { input: Record<string, unknown> }) => ({ output: `Child1: ${input.value}` })
374
+ }
375
+ ]
376
+ })
377
+ },
378
+ 'child-node-2': {
379
+ id: 'child-node-2',
380
+ description: 'Child node 2',
381
+ load: async () => ({
382
+ prompt: '# Child Knowledge 2\n\nMore specialized tools.',
383
+ tools: []
384
+ })
385
+ }
386
+ }
387
+ })
388
+ }
389
+ }
390
+ }
391
+
392
+ // Setup: MockAdapter that navigates parent, then child
393
+ const mockLLM = new MockAdapter({
394
+ responses: [
395
+ {
396
+ reasoning: 'Loading parent node first',
397
+ nextActions: [{
398
+ type: 'navigate-knowledge',
399
+ id: 'nav-1',
400
+ nodeId: 'parent-node'
401
+ }]
402
+ },
403
+ {
404
+ reasoning: 'Now child nodes should be available - navigate to child-node-1',
405
+ nextActions: [{
406
+ type: 'navigate-knowledge',
407
+ id: 'nav-2',
408
+ nodeId: 'child-node-1'
409
+ }]
410
+ },
411
+ {
412
+ reasoning: 'Using child tool',
413
+ nextActions: [{
414
+ type: 'tool-call',
415
+ id: 'call-1',
416
+ name: 'child_tool_1',
417
+ input: { value: 'hierarchical test' }
418
+ }]
419
+ },
420
+ {
421
+ reasoning: 'Task complete',
422
+ nextActions: [{ type: 'complete' }]
423
+ }
424
+ ],
425
+ completionOutput: { result: 'Hierarchical navigation successful' }
426
+ })
427
+
428
+ const agent = new Agent({
429
+ config: {
430
+ resourceId: 'hierarchical-agent',
431
+ name: 'Hierarchical Knowledge Agent',
432
+ description: 'Tests hierarchical navigation',
433
+ systemPrompt: 'Navigate knowledge hierarchically',
434
+ type: 'agent',
435
+ status: 'dev',
436
+ version: '1.0.0'
437
+ },
438
+ contract: {
439
+ inputSchema: z.object({ task: z.string() }),
440
+ outputSchema: z.object({ result: z.string() })
441
+ },
442
+ tools: [],
443
+ knowledgeMap: hierarchicalKnowledgeMap,
444
+ modelConfig: { provider: 'mock', model: 'mock', apiKey: 'test-api-key' }
445
+ }, createMockAdapterFactory(mockLLM))
446
+
447
+ // Execute
448
+ const result = await agent.execute(
449
+ { task: 'Test hierarchical navigation' },
450
+ mockContext
451
+ )
452
+
453
+ // Assert: Execution completes
454
+ expect(result).toEqual({ result: 'Hierarchical navigation successful' })
455
+
456
+ // Assert: Child nodes were discovered
457
+ const snapshot = agent.getMemorySnapshot()
458
+ const discoveryMessages = snapshot.history.filter(entry =>
459
+ entry.type === 'tool-result' &&
460
+ entry.content.includes('child nodes discovered')
461
+ )
462
+ expect(discoveryMessages.length).toBeGreaterThan(0)
463
+
464
+ // Assert: Child node was successfully loaded
465
+ const childLoadMessages = snapshot.history.filter(entry =>
466
+ entry.type === 'tool-result' &&
467
+ entry.content.includes('child-node-1')
468
+ )
469
+ expect(childLoadMessages.length).toBeGreaterThan(0)
470
+
471
+ // Assert: Child tool was used
472
+ const childToolResults = snapshot.history.filter(entry =>
473
+ entry.type === 'tool-result' &&
474
+ entry.content.includes('Child1: hierarchical test')
475
+ )
476
+ expect(childToolResults.length).toBeGreaterThan(0)
477
+
478
+ // Assert: Correct number of LLM calls (4 iterations + 1 completion)
479
+ expect(mockLLM.getCallCount()).toBe(5)
480
+ })
481
+
482
+ it('cross-turn persistence - tools reload from sessionMemory state', async () => {
483
+ // Setup: First execution loads knowledge and stores state
484
+ const firstMockLLM = new MockAdapter({
485
+ responses: [
486
+ {
487
+ reasoning: 'Loading knowledge first time',
488
+ nextActions: [{
489
+ type: 'navigate-knowledge',
490
+ id: 'nav-1',
491
+ nodeId: 'test-tools'
492
+ }]
493
+ },
494
+ {
495
+ reasoning: 'Task complete',
496
+ nextActions: [{ type: 'complete' }]
497
+ }
498
+ ],
499
+ completionOutput: { result: 'First turn complete' }
500
+ })
501
+
502
+ const agentDef = createKnowledgeMapAgent()
503
+ const firstAgent = new Agent(agentDef, createMockAdapterFactory(firstMockLLM))
504
+
505
+ // First execution
506
+ await firstAgent.execute(
507
+ { task: 'First turn - load knowledge' },
508
+ mockContext
509
+ )
510
+
511
+ const firstSnapshot = firstAgent.getMemorySnapshot()
512
+
513
+ // Assert: Knowledge state was stored
514
+ expect(firstSnapshot.sessionMemory).toHaveProperty('knowledge-map-state')
515
+ const stateJson = firstSnapshot.sessionMemory['knowledge-map-state']
516
+ expect(stateJson).toBeDefined()
517
+
518
+ const state = JSON.parse(stateJson.content)
519
+ expect(state.loadedNodes).toContain('test-tools')
520
+
521
+ // Setup: Second execution reloads tools from state
522
+ const secondMockLLM = new MockAdapter({
523
+ responses: [
524
+ {
525
+ reasoning: 'Tools should be already loaded - using them directly',
526
+ nextActions: [{
527
+ type: 'tool-call',
528
+ id: 'call-1',
529
+ name: 'test_tool_1', // Should be available without navigate-knowledge
530
+ input: { input: 'reloaded tool' }
531
+ }]
532
+ },
533
+ {
534
+ reasoning: 'Task complete',
535
+ nextActions: [{ type: 'complete' }]
536
+ }
537
+ ],
538
+ completionOutput: { result: 'Second turn - tools persisted' }
539
+ })
540
+
541
+ // Create agent with preloadMemory that returns first execution's memory
542
+ const agentDefWithPreload = {
543
+ ...agentDef,
544
+ preloadMemory: async () => firstSnapshot
545
+ }
546
+
547
+ const secondAgent = new Agent(agentDefWithPreload, createMockAdapterFactory(secondMockLLM))
548
+
549
+ // Second execution
550
+ const result = await secondAgent.execute(
551
+ { task: 'Second turn - use reloaded tools' },
552
+ mockContext
553
+ )
554
+
555
+ // Assert: Tool was available and used successfully
556
+ expect(result).toEqual({ result: 'Second turn - tools persisted' })
557
+
558
+ const secondSnapshot = secondAgent.getMemorySnapshot()
559
+ const toolResults = secondSnapshot.history.filter(entry =>
560
+ entry.type === 'tool-result' &&
561
+ entry.content.includes('Result: reloaded tool')
562
+ )
563
+ expect(toolResults.length).toBeGreaterThan(0)
564
+
565
+ // Assert: Tool was available from first iteration (no navigate-knowledge needed)
566
+ const tools = secondAgent.getTools()
567
+ const testTools = tools.filter(t => t.name === 'test_tool_1')
568
+ expect(testTools).toHaveLength(1)
569
+
570
+ // Assert: Correct number of LLM calls (2 iterations + 1 completion)
571
+ expect(secondMockLLM.getCallCount()).toBe(3)
572
+ })
573
+ })
574
+
575
+ /**
576
+ * Phase 5: Multi-Iteration Complex Scenarios
577
+ *
578
+ * Tests agent execution across multiple iterations with:
579
+ * - Tool chaining (multiple tools across iterations)
580
+ * - Memory evolution (state changes across iterations)
581
+ * - Iteration limits enforcement
582
+ * - Error recovery patterns
583
+ * - Context propagation through lifecycle
584
+ */
585
+ describe('Multi-Iteration Scenarios', () => {
586
+ const mockContext: ExecutionContext = {
587
+ executionId: 'exec-multi',
588
+ organizationId: 'org-multi',
589
+ resourceId: 'multi-agent',
590
+ resourceType: 'agent' as const,
591
+ logger: {
592
+ info: vi.fn(),
593
+ error: vi.fn(),
594
+ warn: vi.fn(),
595
+ debug: vi.fn()
596
+ }
597
+ }
598
+
599
+ beforeEach(() => {
600
+ vi.clearAllMocks()
601
+ })
602
+
603
+ it('chains tools across iterations with memory evolution', async () => {
604
+ // Setup: Mock services for multi-tool chaining
605
+ const mockCommandQueue = {
606
+ createTask: vi.fn().mockResolvedValue({ id: 'task-chain-123' })
607
+ }
608
+ const mockNotifications = {
609
+ create: vi.fn().mockResolvedValue({ id: 'notif-chain-456' })
610
+ }
611
+
612
+ vi.mocked(getToolServices).mockReturnValue({
613
+ commandQueueService: mockCommandQueue,
614
+ taskSchedulerService: null,
615
+ notificationsService: mockNotifications,
616
+ credentialsService: null,
617
+ integrationService: null
618
+ })
619
+
620
+ const agent = new Agent({
621
+ config: {
622
+ resourceId: 'multi-agent',
623
+ name: 'Multi-Tool Agent',
624
+ systemPrompt: 'You coordinate approval and notification workflows',
625
+ environment: 'test',
626
+ type: 'agent',
627
+ status: 'development',
628
+ version: '1.0.0'
629
+ },
630
+ contract: {
631
+ inputSchema: z.object({ amount: z.number() }),
632
+ outputSchema: z.object({
633
+ response: z.string().optional(),
634
+ processedAt: z.string().optional()
635
+ })
636
+ },
637
+ tools: [
638
+ createApprovalTool({
639
+ name: 'request_approval',
640
+ description: 'Request approval',
641
+ inputSchema: z.object({ amount: z.number() }),
642
+ outputSchema: z.object({ taskId: z.string() }),
643
+ approveTargetResourceId: 'approver'
644
+ }),
645
+ createNotificationTool({
646
+ name: 'send_notification',
647
+ description: 'Send notification',
648
+ inputSchema: z.object({ title: z.string(), message: z.string() }),
649
+ outputSchema: z.object({ notificationId: z.string() }),
650
+ userId: 'user-123',
651
+ category: 'info'
652
+ })
653
+ ],
654
+ modelConfig: { provider: 'mock', model: 'mock' }
655
+ }, createMockAdapterFactory())
656
+
657
+ // Execute
658
+ const result = await agent.execute({ amount: 5000 }, mockContext)
659
+
660
+ // Assert: Execution completed successfully
661
+ // Note: Default MockAdapter returns empty object for completion
662
+ // This test validates the framework machinery (agent + tools) works correctly
663
+ expect(result).toBeDefined()
664
+
665
+ // Assert: Memory snapshot available and contains execution history
666
+ const snapshot = agent.getMemorySnapshot()
667
+ expect(snapshot).toBeDefined()
668
+ expect(snapshot.history).toBeDefined()
669
+ expect(snapshot.history.length).toBeGreaterThan(0)
670
+ })
671
+
672
+ it('auto-compacts memory during execution when budget exceeded', async () => {
673
+ // Setup: Agent with low token budget that will trigger auto-compaction
674
+ const mockLLM = new MockAdapter({
675
+ responses: [
676
+ {
677
+ reasoning: 'First iteration - generating large content to fill memory',
678
+ nextActions: [{
679
+ type: 'tool-call',
680
+ id: 'call-1',
681
+ name: 'generate_large_output',
682
+ input: { size: 'large' }
683
+ }]
684
+ },
685
+ {
686
+ reasoning: 'Second iteration - more large content',
687
+ nextActions: [{
688
+ type: 'tool-call',
689
+ id: 'call-2',
690
+ name: 'generate_large_output',
691
+ input: { size: 'large' }
692
+ }]
693
+ },
694
+ {
695
+ reasoning: 'Third iteration - even more content',
696
+ nextActions: [{
697
+ type: 'tool-call',
698
+ id: 'call-3',
699
+ name: 'generate_large_output',
700
+ input: { size: 'large' }
701
+ }]
702
+ },
703
+ {
704
+ reasoning: 'Fourth iteration - final large content',
705
+ nextActions: [{
706
+ type: 'tool-call',
707
+ id: 'call-4',
708
+ name: 'generate_large_output',
709
+ input: { size: 'large' }
710
+ }]
711
+ },
712
+ {
713
+ reasoning: 'Task complete after generating lots of content',
714
+ nextActions: [{ type: 'complete' }]
715
+ }
716
+ ],
717
+ completionOutput: { result: 'Completed with auto-compaction' }
718
+ })
719
+
720
+ // Tool that generates large output to fill memory budget
721
+ const largeTool = {
722
+ name: 'generate_large_output',
723
+ description: 'Generates large output to test memory compaction',
724
+ inputSchema: z.object({ size: z.string() }),
725
+ outputSchema: z.object({ data: z.string() }),
726
+ execute: async () => ({
727
+ // Generate ~500 tokens per call (roughly 2000 chars)
728
+ data: 'A'.repeat(2000) + ' - Large output generated'
729
+ })
730
+ }
731
+
732
+ const agent = new Agent({
733
+ config: {
734
+ resourceId: 'compact-agent',
735
+ name: 'Compaction Test Agent',
736
+ description: 'Tests auto-compaction',
737
+ systemPrompt: 'Generate large outputs to test memory',
738
+ type: 'agent',
739
+ status: 'dev',
740
+ version: '1.0.0',
741
+ constraints: {
742
+ maxMemoryTokens: 2000 // Low budget to trigger compaction
743
+ }
744
+ },
745
+ contract: {
746
+ inputSchema: z.object({ task: z.string() }),
747
+ outputSchema: z.object({ result: z.string() })
748
+ },
749
+ tools: [largeTool],
750
+ modelConfig: { provider: 'mock', model: 'mock', apiKey: 'test-api-key' }
751
+ }, createMockAdapterFactory(mockLLM))
752
+
753
+ // Execute
754
+ const result = await agent.execute(
755
+ { task: 'Generate large outputs to trigger compaction' },
756
+ mockContext
757
+ )
758
+
759
+ // Assert: Execution completed
760
+ expect(result).toEqual({ result: 'Completed with auto-compaction' })
761
+
762
+ // Assert: Memory was compacted (history should be reduced)
763
+ const snapshot = agent.getMemorySnapshot()
764
+ expect(snapshot).toBeDefined()
765
+
766
+ // With 4 tool calls + reasoning entries, without compaction we'd have ~20+ entries
767
+ // After compaction, we should have first entry + last 10 (or fewer due to aggressive compaction)
768
+ expect(snapshot!.history.length).toBeLessThanOrEqual(12) // First + last 10 + some buffer
769
+
770
+ // Assert: First entry (input) is preserved
771
+ expect(snapshot!.history[0].type).toBe('input')
772
+
773
+ // Assert: Recent entries are preserved (last entries should be from later iterations)
774
+ const lastEntry = snapshot!.history[snapshot!.history.length - 1]
775
+ expect(lastEntry).toBeDefined()
776
+ })
777
+
778
+ it('enforces maxIterations constraint', async () => {
779
+ // Setup: MockAdapter that never signals completion (always continues)
780
+ const mockLLM = new MockAdapter({
781
+ responses: [
782
+ {
783
+ reasoning: 'Iteration 1 - still working',
784
+ nextActions: [{
785
+ type: 'tool-call',
786
+ id: 'call-1',
787
+ name: 'infinite_work',
788
+ input: { iteration: 1 }
789
+ }]
790
+ },
791
+ {
792
+ reasoning: 'Iteration 2 - still working',
793
+ nextActions: [{
794
+ type: 'tool-call',
795
+ id: 'call-2',
796
+ name: 'infinite_work',
797
+ input: { iteration: 2 }
798
+ }]
799
+ },
800
+ {
801
+ reasoning: 'Iteration 3 - still working (should be last allowed)',
802
+ nextActions: [{
803
+ type: 'tool-call',
804
+ id: 'call-3',
805
+ name: 'infinite_work',
806
+ input: { iteration: 3 }
807
+ }]
808
+ },
809
+ // These should never be reached due to maxIterations=3
810
+ {
811
+ reasoning: 'Iteration 4 - should not reach here',
812
+ nextActions: [{ type: 'complete' }]
813
+ }
814
+ ],
815
+ completionOutput: { result: 'Should not reach completion' }
816
+ })
817
+
818
+ // Simple tool that just returns success
819
+ const infiniteWorkTool = {
820
+ name: 'infinite_work',
821
+ description: 'Simulates work that never ends',
822
+ inputSchema: z.object({ iteration: z.number() }),
823
+ outputSchema: z.object({ status: z.string() }),
824
+ execute: async ({ input }: { input: { iteration: number } }) => ({
825
+ status: `Work completed for iteration ${input.iteration}`
826
+ })
827
+ }
828
+
829
+ const agent = new Agent({
830
+ config: {
831
+ resourceId: 'max-iter-agent',
832
+ name: 'Max Iterations Agent',
833
+ description: 'Tests maxIterations enforcement',
834
+ systemPrompt: 'Keep working forever',
835
+ type: 'agent',
836
+ status: 'dev',
837
+ version: '1.0.0',
838
+ constraints: {
839
+ maxIterations: 3 // Strict limit
840
+ }
841
+ },
842
+ contract: {
843
+ inputSchema: z.object({ task: z.string() }),
844
+ outputSchema: z.object({ result: z.string() })
845
+ },
846
+ tools: [infiniteWorkTool],
847
+ modelConfig: { provider: 'mock', model: 'mock', apiKey: 'test-api-key' }
848
+ }, createMockAdapterFactory(mockLLM))
849
+
850
+ // Execute - should throw AgentMaxIterationsError
851
+ await expect(
852
+ agent.execute({ task: 'Work forever' }, mockContext)
853
+ ).rejects.toThrow(/exceeded maximum iterations/)
854
+
855
+ // Assert: Exactly 3 iterations were executed (3 iteration calls + no completion)
856
+ // Each iteration = 1 LLM call for reasoning
857
+ expect(mockLLM.getCallCount()).toBe(3)
858
+
859
+ // Note: Memory snapshot is not available after error because toSnapshot()
860
+ // is called in complete() phase which doesn't run when maxIterations throws.
861
+ // This is correct behavior - the error bubbles up before completion.
862
+ // The test validates that:
863
+ // 1. The error is thrown with correct message
864
+ // 2. Exactly maxIterations (3) LLM calls were made
865
+ // 3. No additional iterations occurred
866
+ })
867
+
868
+ it('handles tool errors and recovers in next iteration', async () => {
869
+ // Setup: MockAdapter that first calls failing tool, then recovers with working tool
870
+ const mockLLM = new MockAdapter({
871
+ responses: [
872
+ {
873
+ reasoning: 'Calling the unreliable tool that might fail',
874
+ nextActions: [{
875
+ type: 'tool-call',
876
+ id: 'call-fail',
877
+ name: 'unreliable_tool',
878
+ input: { shouldFail: true }
879
+ }]
880
+ },
881
+ {
882
+ reasoning: 'Previous tool failed, trying reliable tool instead',
883
+ nextActions: [{
884
+ type: 'tool-call',
885
+ id: 'call-success',
886
+ name: 'reliable_tool',
887
+ input: { data: 'recovery data' }
888
+ }]
889
+ },
890
+ {
891
+ reasoning: 'Recovered successfully, completing task',
892
+ nextActions: [{ type: 'complete' }]
893
+ }
894
+ ],
895
+ completionOutput: { result: 'Recovered from error and completed' }
896
+ })
897
+
898
+ // Tool that throws an error
899
+ const unreliableTool = {
900
+ name: 'unreliable_tool',
901
+ description: 'Tool that fails when shouldFail is true',
902
+ inputSchema: z.object({ shouldFail: z.boolean() }),
903
+ outputSchema: z.object({ result: z.string() }),
904
+ execute: async ({ input }: { input: { shouldFail: boolean } }) => {
905
+ if (input.shouldFail) {
906
+ throw new Error('Simulated tool failure: Service unavailable')
907
+ }
908
+ return { result: 'Success' }
909
+ }
910
+ }
911
+
912
+ // Tool that always succeeds
913
+ const reliableTool = {
914
+ name: 'reliable_tool',
915
+ description: 'Tool that always succeeds',
916
+ inputSchema: z.object({ data: z.string() }),
917
+ outputSchema: z.object({ processed: z.string() }),
918
+ execute: async ({ input }: { input: { data: string } }) => ({
919
+ processed: `Processed: ${input.data}`
920
+ })
921
+ }
922
+
923
+ const agent = new Agent({
924
+ config: {
925
+ resourceId: 'recovery-agent',
926
+ name: 'Error Recovery Agent',
927
+ description: 'Tests error recovery patterns',
928
+ systemPrompt: 'Try tools and recover from failures',
929
+ type: 'agent',
930
+ status: 'dev',
931
+ version: '1.0.0'
932
+ },
933
+ contract: {
934
+ inputSchema: z.object({ task: z.string() }),
935
+ outputSchema: z.object({ result: z.string() })
936
+ },
937
+ tools: [unreliableTool, reliableTool],
938
+ modelConfig: { provider: 'mock', model: 'mock', apiKey: 'test-api-key' }
939
+ }, createMockAdapterFactory(mockLLM))
940
+
941
+ // Execute - should complete successfully despite first tool failure
942
+ const result = await agent.execute(
943
+ { task: 'Try unreliable tool, then recover with reliable tool' },
944
+ mockContext
945
+ )
946
+
947
+ // Assert: Execution completed successfully
948
+ expect(result).toEqual({ result: 'Recovered from error and completed' })
949
+
950
+ // Assert: Memory contains the error from failed tool
951
+ const snapshot = agent.getMemorySnapshot()
952
+ expect(snapshot).toBeDefined()
953
+
954
+ const errorEntries = snapshot!.history.filter(e => e.type === 'error')
955
+ expect(errorEntries.length).toBeGreaterThan(0)
956
+ expect(errorEntries[0].content).toContain('Simulated tool failure')
957
+
958
+ // Assert: Memory contains successful recovery
959
+ const toolResults = snapshot!.history.filter(e =>
960
+ e.type === 'tool-result' && e.content.includes('Processed: recovery data')
961
+ )
962
+ expect(toolResults.length).toBe(1)
963
+
964
+ // Assert: All 3 iterations + 1 completion call were made
965
+ expect(mockLLM.getCallCount()).toBe(4)
966
+ })
967
+
968
+ it('emits lifecycle events for SSE broadcasting', async () => {
969
+ // Setup: Simple agent that completes successfully
970
+ const mockLLM = new MockAdapter({
971
+ responses: [
972
+ {
973
+ reasoning: 'Task complete',
974
+ nextActions: [{ type: 'complete' }]
975
+ }
976
+ ],
977
+ completionOutput: { result: 'Done' }
978
+ })
979
+
980
+ // Track SSE events (observable behavior for real-time UI updates)
981
+ const emittedEvents: Array<{ type: string }> = []
982
+ const testContext: ExecutionContext = {
983
+ executionId: 'exec-sse-test',
984
+ organizationId: 'org-sse-test',
985
+ resourceId: 'sse-agent',
986
+ resourceType: 'agent' as const,
987
+ logger: {
988
+ info: vi.fn(),
989
+ error: vi.fn(),
990
+ warn: vi.fn(),
991
+ debug: vi.fn()
992
+ },
993
+ onMessageEvent: vi.fn(async (event) => {
994
+ emittedEvents.push(event)
995
+ })
996
+ }
997
+
998
+ const agent = new Agent({
999
+ config: {
1000
+ resourceId: 'sse-agent',
1001
+ name: 'SSE Lifecycle Agent',
1002
+ description: 'Tests SSE event emission',
1003
+ systemPrompt: 'Complete task',
1004
+ type: 'agent',
1005
+ status: 'dev',
1006
+ version: '1.0.0'
1007
+ },
1008
+ contract: {
1009
+ inputSchema: z.object({ task: z.string() }),
1010
+ outputSchema: z.object({ result: z.string() })
1011
+ },
1012
+ tools: [],
1013
+ modelConfig: { provider: 'mock', model: 'mock', apiKey: 'test-api-key' }
1014
+ }, createMockAdapterFactory(mockLLM))
1015
+
1016
+ // Execute
1017
+ const result = await agent.execute({ task: 'Complete' }, testContext)
1018
+
1019
+ // Assert: Execution completed
1020
+ expect(result).toEqual({ result: 'Done' })
1021
+
1022
+ // Assert: SSE lifecycle events emitted (user-facing behavior for real-time UI)
1023
+ expect(emittedEvents).toContainEqual({ type: 'agent:started' })
1024
+ expect(emittedEvents).toContainEqual({ type: 'agent:completed' })
1025
+
1026
+ // Assert: Events emitted in correct order
1027
+ const startIndex = emittedEvents.findIndex(e => e.type === 'agent:started')
1028
+ const completeIndex = emittedEvents.findIndex(e => e.type === 'agent:completed')
1029
+ expect(startIndex).toBeLessThan(completeIndex)
1030
+ })
1031
+ })