@elevasis/core 0.7.1 → 0.8.2

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 (476) hide show
  1. package/dist/test-utils/index.d.ts +3122 -0
  2. package/dist/test-utils/index.js +386 -0
  3. package/package.json +6 -1
  4. package/src/README.md +39 -36
  5. package/src/__tests__/publish.test.ts +18 -13
  6. package/src/__tests__/{template-foundations-compatibility.test.ts → template-core-compatibility.test.ts} +99 -99
  7. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +1135 -1131
  8. package/src/_gen/__tests__/scaffold-contracts.test.ts +47 -36
  9. package/src/_gen/scaffold-contracts.ts +45 -45
  10. package/src/auth/multi-tenancy/credentials/README.md +38 -38
  11. package/src/auth/multi-tenancy/credentials/index.ts +6 -6
  12. package/src/auth/multi-tenancy/credentials/server/encryption.ts +39 -39
  13. package/src/auth/multi-tenancy/credentials/server/service.ts +60 -60
  14. package/src/auth/multi-tenancy/index.ts +17 -17
  15. package/src/auth/multi-tenancy/invitations/api-schemas.ts +107 -107
  16. package/src/auth/multi-tenancy/invitations/index.ts +37 -37
  17. package/src/auth/multi-tenancy/invitations/invitation.ts +86 -86
  18. package/src/auth/multi-tenancy/invitations/server/index.ts +25 -25
  19. package/src/auth/multi-tenancy/invitations/server/transforms.ts +24 -24
  20. package/src/auth/multi-tenancy/invitations/server/workos.ts +24 -24
  21. package/src/auth/multi-tenancy/invitations/supabase.ts +50 -50
  22. package/src/auth/multi-tenancy/memberships/api-schemas.ts +126 -126
  23. package/src/auth/multi-tenancy/memberships/index.ts +21 -21
  24. package/src/auth/multi-tenancy/memberships/membership.ts +138 -138
  25. package/src/auth/multi-tenancy/memberships/server/index.ts +15 -15
  26. package/src/auth/multi-tenancy/memberships/server/transforms.ts +32 -32
  27. package/src/auth/multi-tenancy/memberships/server/workos.ts +21 -21
  28. package/src/auth/multi-tenancy/memberships/supabase.ts +46 -46
  29. package/src/auth/multi-tenancy/organizations/api-schemas.ts +128 -128
  30. package/src/auth/multi-tenancy/organizations/index.ts +23 -23
  31. package/src/auth/multi-tenancy/organizations/organization.ts +24 -24
  32. package/src/auth/multi-tenancy/organizations/server/index.ts +10 -10
  33. package/src/auth/multi-tenancy/organizations/server/transforms.ts +35 -35
  34. package/src/auth/multi-tenancy/organizations/server/workos.ts +20 -20
  35. package/src/auth/multi-tenancy/types.ts +83 -83
  36. package/src/auth/multi-tenancy/users/api-schemas.ts +194 -194
  37. package/src/auth/multi-tenancy/users/index.ts +27 -27
  38. package/src/auth/multi-tenancy/users/server/index.ts +19 -19
  39. package/src/auth/multi-tenancy/users/server/transforms.ts +21 -21
  40. package/src/auth/multi-tenancy/users/server/workos.ts +16 -16
  41. package/src/auth/multi-tenancy/users/user.ts +65 -65
  42. package/src/business/README.md +52 -52
  43. package/src/business/__tests__/entities-published.test.ts +33 -33
  44. package/src/business/acquisition/api-schemas.ts +759 -759
  45. package/src/business/acquisition/index.ts +109 -109
  46. package/src/business/acquisition/types.ts +402 -402
  47. package/src/business/base-entities.test.ts +481 -481
  48. package/src/business/base-entities.ts +241 -241
  49. package/src/business/entities-published.ts +24 -24
  50. package/src/business/index.ts +15 -15
  51. package/src/business/pdf/browser/pdfmake-browser.ts +229 -229
  52. package/src/business/pdf/index.ts +10 -10
  53. package/src/business/pdf/server/index.ts +21 -21
  54. package/src/business/pdf/server/themes/default.ts +8 -8
  55. package/src/business/pdf/server/themes/index.ts +9 -9
  56. package/src/business/pdf/server/themes/types.ts +8 -8
  57. package/src/business/pdf/types.ts +272 -272
  58. package/src/business/projects/index.ts +2 -2
  59. package/src/business/projects/sse-events.ts +21 -21
  60. package/src/business/projects/types.ts +89 -89
  61. package/src/business/sales/api-schemas.ts +75 -75
  62. package/src/business/seo/__tests__/linking.test.ts +549 -549
  63. package/src/business/seo/__tests__/types.test.ts +404 -404
  64. package/src/business/seo/index.ts +2 -2
  65. package/src/business/seo/linking.ts +281 -281
  66. package/src/business/seo/types.ts +199 -199
  67. package/src/commands/queue/index.ts +3 -3
  68. package/src/commands/queue/schemas.test.ts +593 -593
  69. package/src/commands/queue/schemas.ts +125 -125
  70. package/src/commands/queue/sse-events.ts +61 -61
  71. package/src/commands/queue/types/action.ts +52 -52
  72. package/src/commands/queue/types/checkpoint.ts +44 -44
  73. package/src/commands/queue/types/index.ts +7 -7
  74. package/src/commands/queue/types/task.ts +116 -116
  75. package/src/commands/queue/types.ts +14 -14
  76. package/src/content/distribution-metadata.ts +61 -61
  77. package/src/content/index.ts +10 -10
  78. package/src/deployments/index.ts +22 -22
  79. package/src/execution/core/__tests__/archived-logs.test.ts +72 -72
  80. package/src/execution/core/index.ts +11 -11
  81. package/src/execution/core/runner-types.ts +80 -80
  82. package/src/execution/core/server/environment.ts +31 -31
  83. package/src/execution/core/sse-executions.ts +119 -119
  84. package/src/execution/core/types.ts +29 -29
  85. package/src/execution/engine/__tests__/fixtures/test-agents.ts +4 -4
  86. package/src/execution/engine/__tests__/timeout.test.ts +565 -565
  87. package/src/execution/engine/agent/__tests__/errors.test.ts +508 -508
  88. package/src/execution/engine/agent/actions/__tests__/processor.test.ts +531 -531
  89. package/src/execution/engine/agent/actions/executor.ts +205 -205
  90. package/src/execution/engine/agent/actions/navigate-knowledge-executor.ts +230 -230
  91. package/src/execution/engine/agent/actions/processor.ts +116 -116
  92. package/src/execution/engine/agent/actions/types.ts +70 -70
  93. package/src/execution/engine/agent/core/agent.ts +810 -810
  94. package/src/execution/engine/agent/core/types.ts +155 -155
  95. package/src/execution/engine/agent/errors.ts +251 -251
  96. package/src/execution/engine/agent/index.ts +78 -78
  97. package/src/execution/engine/agent/knowledge-map/types.ts +106 -106
  98. package/src/execution/engine/agent/knowledge-map/utils.ts +101 -101
  99. package/src/execution/engine/agent/memory/__tests__/manager.test.ts +754 -754
  100. package/src/execution/engine/agent/memory/domains.ts +99 -99
  101. package/src/execution/engine/agent/memory/manager.ts +365 -365
  102. package/src/execution/engine/agent/memory/processor.ts +66 -66
  103. package/src/execution/engine/agent/memory/types.ts +90 -90
  104. package/src/execution/engine/agent/memory/utils.ts +134 -134
  105. package/src/execution/engine/agent/observability/logging.ts +467 -467
  106. package/src/execution/engine/agent/observability/types.ts +64 -64
  107. package/src/execution/engine/agent/reasoning/adapters/agent-adapter-helpers.ts +349 -349
  108. package/src/execution/engine/agent/reasoning/processor.ts +92 -92
  109. package/src/execution/engine/agent/reasoning/prompt-sections/base-actions.ts +134 -134
  110. package/src/execution/engine/agent/reasoning/prompt-sections/completion.ts +49 -49
  111. package/src/execution/engine/agent/reasoning/prompt-sections/knowledge-map.ts +93 -93
  112. package/src/execution/engine/agent/reasoning/prompt-sections/memory.ts +65 -65
  113. package/src/execution/engine/agent/reasoning/prompt-sections/tools.ts +44 -44
  114. package/src/execution/engine/agent/reasoning/request-builder.ts +169 -169
  115. package/src/execution/engine/agent/reasoning/types.ts +18 -18
  116. package/src/execution/engine/base/errors.ts +118 -118
  117. package/src/execution/engine/base/index.ts +2 -2
  118. package/src/execution/engine/base/logging.ts +31 -31
  119. package/src/execution/engine/base/serialization.ts +324 -324
  120. package/src/execution/engine/base/types.ts +126 -126
  121. package/src/execution/engine/base/utils.ts +41 -41
  122. package/src/execution/engine/index.ts +434 -434
  123. package/src/execution/engine/interface/index.ts +1 -1
  124. package/src/execution/engine/interface/types.ts +62 -62
  125. package/src/execution/engine/llm/__tests__/model-info.test.ts +50 -50
  126. package/src/execution/engine/llm/__tests__/model-validation.test.ts +321 -321
  127. package/src/execution/engine/llm/__tests__/response-schema-validator.test.ts +115 -115
  128. package/src/execution/engine/llm/adapters/__tests__/adapter-factory.test.ts +375 -375
  129. package/src/execution/engine/llm/adapters/__tests__/anthropic-adapter.test.ts +463 -463
  130. package/src/execution/engine/llm/adapters/__tests__/anthropic.integration.test.ts +177 -177
  131. package/src/execution/engine/llm/adapters/__tests__/google-adapter.test.ts +722 -722
  132. package/src/execution/engine/llm/adapters/__tests__/google.integration.test.ts +376 -376
  133. package/src/execution/engine/llm/adapters/__tests__/openai-adapter.test.ts +551 -551
  134. package/src/execution/engine/llm/adapters/__tests__/openrouter-adapter.test.ts +563 -563
  135. package/src/execution/engine/llm/adapters/__tests__/openrouter.integration.test.ts +105 -105
  136. package/src/execution/engine/llm/adapters/__tests__/universal-adapter.test.ts +537 -537
  137. package/src/execution/engine/llm/adapters/circuit-breaker.ts +147 -147
  138. package/src/execution/engine/llm/adapters/index.ts +17 -17
  139. package/src/execution/engine/llm/adapters/mock-adapter.ts +116 -116
  140. package/src/execution/engine/llm/adapters/server/adapter-factory.ts +130 -130
  141. package/src/execution/engine/llm/adapters/server/anthropic.ts +137 -137
  142. package/src/execution/engine/llm/adapters/server/google.ts +283 -283
  143. package/src/execution/engine/llm/adapters/server/index.ts +12 -12
  144. package/src/execution/engine/llm/adapters/server/openai.ts +206 -206
  145. package/src/execution/engine/llm/adapters/server/openrouter.ts +235 -235
  146. package/src/execution/engine/llm/adapters/universal-adapter.ts +230 -230
  147. package/src/execution/engine/llm/errors.ts +186 -186
  148. package/src/execution/engine/llm/model-info.ts +332 -332
  149. package/src/execution/engine/llm/response-schema-validator.ts +113 -113
  150. package/src/execution/engine/llm/types.ts +86 -86
  151. package/src/execution/engine/test-utils/index.ts +6 -6
  152. package/src/execution/engine/test-utils/mocks.ts +56 -56
  153. package/src/execution/engine/tools/integration/base-integration-adapter.ts +50 -50
  154. package/src/execution/engine/tools/integration/index.ts +53 -53
  155. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-adapter.ts +73 -73
  156. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-tools.ts +209 -209
  157. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-company-email/index.ts +82 -82
  158. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-decision-maker-email/index.ts +122 -122
  159. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-person-email/index.ts +89 -89
  160. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/verify-email/index.ts +84 -84
  161. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/index.ts +16 -16
  162. package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +293 -293
  163. package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.ts +100 -100
  164. package/src/execution/engine/tools/integration/server/adapters/apify/apify-tools.ts +217 -217
  165. package/src/execution/engine/tools/integration/server/adapters/apify/fetch/get-dataset-items/index.ts +92 -92
  166. package/src/execution/engine/tools/integration/server/adapters/apify/fetch/run-actor/index.ts +218 -218
  167. package/src/execution/engine/tools/integration/server/adapters/apify/fetch/start-actor/index.ts +87 -87
  168. package/src/execution/engine/tools/integration/server/adapters/apify/index.ts +11 -11
  169. package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +361 -361
  170. package/src/execution/engine/tools/integration/server/adapters/attio/attio-adapter.ts +162 -162
  171. package/src/execution/engine/tools/integration/server/adapters/attio/attio-tools.ts +594 -594
  172. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-attribute/index.ts +214 -214
  173. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-note/index.ts +152 -152
  174. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-record/index.ts +141 -141
  175. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-note/index.ts +86 -86
  176. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-record/index.ts +105 -105
  177. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.ts +118 -118
  178. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-attributes/index.ts +165 -165
  179. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-notes/index.ts +96 -96
  180. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-objects/index.ts +104 -104
  181. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.ts +156 -156
  182. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-attribute/index.ts +220 -220
  183. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-record/index.ts +140 -140
  184. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/utils/types.ts +146 -146
  185. package/src/execution/engine/tools/integration/server/adapters/attio/index.ts +31 -31
  186. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +210 -210
  187. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +104 -104
  188. package/src/execution/engine/tools/integration/server/adapters/google-sheets/__tests__/google-sheets.integration.test.ts +261 -261
  189. package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-adapter.ts +1189 -1189
  190. package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-tools.ts +641 -641
  191. package/src/execution/engine/tools/integration/server/adapters/google-sheets/index.ts +18 -18
  192. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/activate-campaign/index.ts +86 -86
  193. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/__tests__/index.test.ts +289 -289
  194. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/index.ts +154 -154
  195. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/__tests__/index.test.ts +325 -325
  196. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/index.ts +153 -153
  197. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-delete-leads/index.ts +84 -84
  198. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-campaign/index.ts +125 -125
  199. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-inbox-test/index.ts +107 -107
  200. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/delete-campaign/index.ts +85 -85
  201. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-account-health/index.ts +91 -91
  202. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign/index.ts +92 -92
  203. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/__tests__/index.test.ts +195 -195
  204. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/index.ts +113 -113
  205. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-daily-campaign-analytics/index.ts +104 -104
  206. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-emails/index.ts +155 -155
  207. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/__tests__/index.test.ts +196 -196
  208. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/index.ts +102 -102
  209. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/__tests__/index.test.ts +189 -189
  210. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/index.ts +87 -87
  211. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-leads/index.ts +112 -112
  212. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/patch-lead/index.ts +76 -76
  213. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/pause-campaign/index.ts +86 -86
  214. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/remove-from-subsequence/index.ts +98 -98
  215. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/send-reply/index.ts +126 -126
  216. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/__tests__/index.test.ts +193 -193
  217. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/index.ts +99 -99
  218. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/__tests__/index.test.ts +621 -621
  219. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/index.ts +125 -125
  220. package/src/execution/engine/tools/integration/server/adapters/instantly/index.ts +29 -29
  221. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-adapter.ts +178 -178
  222. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1473 -1473
  223. package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/check-credits/index.ts +59 -59
  224. package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/verify-email/index.ts +102 -102
  225. package/src/execution/engine/tools/integration/server/adapters/millionverifier/index.ts +17 -17
  226. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-adapter.ts +80 -80
  227. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +102 -102
  228. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/get-email/index.ts +102 -102
  229. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +134 -134
  230. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +75 -75
  231. package/src/execution/engine/tools/integration/server/adapters/resend/index.ts +27 -27
  232. package/src/execution/engine/tools/integration/server/adapters/resend/resend-adapter.ts +108 -108
  233. package/src/execution/engine/tools/integration/server/adapters/resend/resend-tools.ts +132 -132
  234. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/create-envelope/index.ts +274 -274
  235. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/download-document/index.ts +230 -230
  236. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/get-envelope/index.ts +133 -133
  237. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/void-envelope/index.ts +90 -90
  238. package/src/execution/engine/tools/integration/server/adapters/stripe/fetch/utils/types.ts +210 -210
  239. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-adapter.ts +517 -517
  240. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +309 -309
  241. package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/domain-search/index.ts +133 -133
  242. package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-finder/index.ts +122 -122
  243. package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-verifier/index.ts +111 -111
  244. package/src/execution/engine/tools/integration/server/adapters/tomba/index.ts +11 -11
  245. package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-adapter.ts +78 -78
  246. package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-tools.ts +222 -222
  247. package/src/execution/engine/tools/integration/server/index.ts +61 -61
  248. package/src/execution/engine/tools/integration/service.ts +161 -161
  249. package/src/execution/engine/tools/integration/tool.ts +253 -253
  250. package/src/execution/engine/tools/integration/types/anymailfinder.ts +74 -74
  251. package/src/execution/engine/tools/integration/types/apify.ts +92 -92
  252. package/src/execution/engine/tools/integration/types/index.ts +19 -19
  253. package/src/execution/engine/tools/integration/types/instantly.ts +557 -557
  254. package/src/execution/engine/tools/integration/types/millionverifier.ts +56 -56
  255. package/src/execution/engine/tools/integration/types/stripe.ts +162 -162
  256. package/src/execution/engine/tools/integration/types/tomba.ts +94 -94
  257. package/src/execution/engine/tools/lead-service-types.ts +884 -884
  258. package/src/execution/engine/tools/llm/index.ts +11 -11
  259. package/src/execution/engine/tools/llm/server/index.ts +8 -8
  260. package/src/execution/engine/tools/llm/server/llm-call-tool.ts +118 -118
  261. package/src/execution/engine/tools/platform/__tests__/pdf.test.ts +441 -441
  262. package/src/execution/engine/tools/platform/acquisition/company-tools.ts +248 -248
  263. package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +319 -319
  264. package/src/execution/engine/tools/platform/acquisition/index.ts +43 -43
  265. package/src/execution/engine/tools/platform/acquisition/list-tools.ts +148 -148
  266. package/src/execution/engine/tools/platform/acquisition/types.ts +260 -260
  267. package/src/execution/engine/tools/platform/email/index.ts +122 -122
  268. package/src/execution/engine/tools/platform/email/types.ts +96 -96
  269. package/src/execution/engine/tools/platform/index.ts +157 -157
  270. package/src/execution/engine/tools/platform/notification.ts +81 -81
  271. package/src/execution/engine/tools/platform/pdf/index.ts +110 -110
  272. package/src/execution/engine/tools/platform/pdf/types.ts +77 -77
  273. package/src/execution/engine/tools/platform/scheduler.ts +87 -87
  274. package/src/execution/engine/tools/platform/storage/index.ts +370 -370
  275. package/src/execution/engine/tools/platform/types.ts +148 -148
  276. package/src/execution/engine/tools/registry.ts +700 -700
  277. package/src/execution/engine/tools/tool-maps.ts +786 -786
  278. package/src/execution/engine/tools/types.ts +233 -233
  279. package/src/execution/engine/workflow/__tests__/errors.test.ts +139 -139
  280. package/src/execution/engine/workflow/errors.ts +63 -63
  281. package/src/execution/engine/workflow/helpers/index.ts +11 -11
  282. package/src/execution/engine/workflow/helpers/server/index.ts +8 -8
  283. package/src/execution/engine/workflow/helpers/server/llm-call.ts +93 -93
  284. package/src/execution/engine/workflow/index.ts +19 -19
  285. package/src/execution/engine/workflow/log-truncate.ts +26 -26
  286. package/src/execution/engine/workflow/logging.ts +191 -191
  287. package/src/execution/engine/workflow/types.ts +182 -182
  288. package/src/execution/engine/workflow/utils.ts +280 -280
  289. package/src/execution/engine/workflow/workflow.ts +168 -168
  290. package/src/execution/index.ts +3 -3
  291. package/src/execution/scheduler/__tests__/api-schemas.test.ts +733 -733
  292. package/src/execution/scheduler/__tests__/utils.test.ts +1009 -1009
  293. package/src/execution/scheduler/api-schemas.ts +296 -296
  294. package/src/execution/scheduler/index.ts +50 -50
  295. package/src/execution/scheduler/schemas.ts +264 -264
  296. package/src/execution/scheduler/types.ts +111 -111
  297. package/src/execution/scheduler/utils.ts +364 -364
  298. package/src/forms/index.ts +7 -7
  299. package/src/forms/schemas.ts +69 -69
  300. package/src/forms/types.ts +70 -70
  301. package/src/index.ts +71 -60
  302. package/src/integrations/credentials/__tests__/schemas.test.ts +82 -82
  303. package/src/integrations/credentials/__tests__/utils.test.ts +144 -144
  304. package/src/integrations/credentials/api-schemas.ts +143 -143
  305. package/src/integrations/credentials/index.ts +32 -32
  306. package/src/integrations/credentials/schemas.ts +164 -164
  307. package/src/integrations/credentials/utils.ts +59 -59
  308. package/src/integrations/oauth/__tests__/provider-registry.test.ts +59 -59
  309. package/src/integrations/oauth/api-schemas.ts +92 -92
  310. package/src/integrations/oauth/index.ts +19 -19
  311. package/src/integrations/oauth/provider-registry.ts +61 -61
  312. package/src/integrations/oauth/server/__tests__/refresh-concurrent.test.ts +183 -183
  313. package/src/integrations/oauth/server/__tests__/refresh.test.ts +577 -577
  314. package/src/integrations/oauth/server/credentials.ts +39 -39
  315. package/src/integrations/oauth/server/refresh.ts +214 -214
  316. package/src/integrations/oauth/types.ts +34 -34
  317. package/src/integrations/webhook-endpoints/__tests__/api-schemas.test.ts +318 -318
  318. package/src/integrations/webhook-endpoints/api-schemas.ts +102 -102
  319. package/src/integrations/webhook-endpoints/index.ts +28 -28
  320. package/src/integrations/webhook-endpoints/types.ts +51 -51
  321. package/src/operations/activities/api-schemas.ts +79 -79
  322. package/src/operations/activities/index.ts +9 -9
  323. package/src/operations/activities/sse-events.ts +30 -30
  324. package/src/operations/activities/types.ts +63 -63
  325. package/src/operations/debug-logs/client.ts +60 -60
  326. package/src/operations/debug-logs/debug-logger.ts +83 -83
  327. package/src/operations/debug-logs/index.ts +8 -8
  328. package/src/operations/debug-logs/server.ts +19 -19
  329. package/src/operations/debug-logs/types.ts +33 -33
  330. package/src/operations/index.ts +50 -50
  331. package/src/operations/notifications/api-schemas.ts +91 -91
  332. package/src/operations/notifications/index.ts +3 -3
  333. package/src/operations/notifications/sse-events.ts +21 -21
  334. package/src/operations/notifications/types.ts +47 -47
  335. package/src/operations/observability/__tests__/openrouter-cost-flow.test.ts +297 -297
  336. package/src/operations/observability/__tests__/utils.test.ts +54 -54
  337. package/src/operations/observability/ai-usage-collector.ts +64 -64
  338. package/src/operations/observability/index.ts +13 -13
  339. package/src/operations/observability/metrics-collector.ts +49 -49
  340. package/src/operations/observability/schemas.ts +39 -39
  341. package/src/operations/observability/types.ts +463 -463
  342. package/src/operations/observability/utils.ts +77 -77
  343. package/src/operations/sessions/__tests__/manager.test.ts +821 -821
  344. package/src/operations/sessions/index.ts +26 -26
  345. package/src/operations/sessions/server/manager.ts +90 -90
  346. package/src/operations/sessions/server/session.ts +180 -180
  347. package/src/operations/sessions/types.ts +98 -98
  348. package/src/operations/triggers/index.ts +12 -12
  349. package/src/operations/triggers/webhook/definitions/instantly-account-error.ts +44 -44
  350. package/src/operations/triggers/webhook/definitions/instantly-auto-reply-received.ts +51 -51
  351. package/src/operations/triggers/webhook/definitions/instantly-campaign-completed.ts +45 -45
  352. package/src/operations/triggers/webhook/definitions/instantly-email-bounced.ts +49 -49
  353. package/src/operations/triggers/webhook/definitions/instantly-lead-unsubscribed.ts +45 -45
  354. package/src/operations/triggers/webhook/definitions/instantly-reply-received.ts +54 -54
  355. package/src/operations/triggers/webhook/index.ts +35 -35
  356. package/src/operations/triggers/webhook/types.ts +74 -74
  357. package/src/organization-model/README.md +97 -97
  358. package/src/organization-model/__tests__/defaults.test.ts +175 -175
  359. package/src/organization-model/__tests__/domains/customers.test.ts +295 -295
  360. package/src/organization-model/__tests__/domains/goals.test.ts +479 -479
  361. package/src/organization-model/__tests__/domains/identity.test.ts +279 -279
  362. package/src/organization-model/__tests__/domains/navigation.test.ts +212 -212
  363. package/src/organization-model/__tests__/domains/offerings.test.ts +419 -419
  364. package/src/organization-model/__tests__/domains/operations.test.ts +203 -203
  365. package/src/organization-model/__tests__/domains/resource-mappings.test.ts +362 -362
  366. package/src/organization-model/__tests__/domains/roles.test.ts +347 -347
  367. package/src/organization-model/__tests__/domains/statuses.test.ts +243 -243
  368. package/src/organization-model/__tests__/foundation.test.ts +105 -105
  369. package/src/organization-model/__tests__/graph.test.ts +894 -894
  370. package/src/organization-model/__tests__/resolve.test.ts +690 -690
  371. package/src/organization-model/__tests__/schema.test.ts +407 -407
  372. package/src/organization-model/contracts.ts +14 -14
  373. package/src/organization-model/defaults.ts +148 -148
  374. package/src/organization-model/domains/branding.ts +22 -22
  375. package/src/organization-model/domains/customers.ts +75 -75
  376. package/src/organization-model/domains/features.ts +22 -22
  377. package/src/organization-model/domains/goals.ts +80 -80
  378. package/src/organization-model/domains/identity.ts +94 -94
  379. package/src/organization-model/domains/navigation.ts +391 -391
  380. package/src/organization-model/domains/offerings.ts +66 -66
  381. package/src/organization-model/domains/operations.ts +85 -85
  382. package/src/organization-model/domains/projects.ts +48 -48
  383. package/src/organization-model/domains/prospecting.ts +33 -33
  384. package/src/organization-model/domains/roles.ts +55 -55
  385. package/src/organization-model/domains/sales.ts +94 -94
  386. package/src/organization-model/domains/shared.ts +62 -62
  387. package/src/organization-model/domains/statuses.ts +130 -130
  388. package/src/organization-model/foundation.ts +97 -97
  389. package/src/organization-model/graph/build.ts +399 -399
  390. package/src/organization-model/graph/index.ts +4 -4
  391. package/src/organization-model/graph/schema.ts +48 -48
  392. package/src/organization-model/graph/types.ts +40 -40
  393. package/src/organization-model/index.ts +13 -13
  394. package/src/organization-model/organization-graph.mdx +272 -272
  395. package/src/organization-model/organization-model.mdx +320 -320
  396. package/src/organization-model/published.ts +85 -85
  397. package/src/organization-model/resolve.ts +66 -66
  398. package/src/organization-model/schema.ts +287 -287
  399. package/src/organization-model/types.ts +46 -46
  400. package/src/platform/api/index.ts +1 -1
  401. package/src/platform/api/types.ts +35 -35
  402. package/src/platform/constants/http.ts +37 -37
  403. package/src/platform/constants/index.ts +5 -5
  404. package/src/platform/constants/limits.ts +32 -32
  405. package/src/platform/constants/resilience.ts +51 -51
  406. package/src/platform/constants/timeouts.ts +20 -20
  407. package/src/platform/constants/versions.ts +3 -3
  408. package/src/platform/registry/__tests__/resource-registry-static.test.ts +347 -347
  409. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +1028 -1028
  410. package/src/platform/registry/__tests__/resource-registry.list-executable.test.ts +393 -393
  411. package/src/platform/registry/__tests__/resource-registry.test.ts +2005 -2005
  412. package/src/platform/registry/__tests__/serialization.test.ts +1127 -1127
  413. package/src/platform/registry/command-view.ts +180 -180
  414. package/src/platform/registry/domains.ts +165 -165
  415. package/src/platform/registry/index.ts +93 -93
  416. package/src/platform/registry/reserved.ts +24 -24
  417. package/src/platform/registry/resource-metadata.ts +59 -59
  418. package/src/platform/registry/resource-registry.command-queue-groups.test.ts +129 -129
  419. package/src/platform/registry/resource-registry.ts +876 -876
  420. package/src/platform/registry/serialization.ts +273 -273
  421. package/src/platform/registry/serialized-types.ts +231 -231
  422. package/src/platform/registry/stats-types.ts +66 -66
  423. package/src/platform/registry/types.ts +404 -404
  424. package/src/platform/registry/validation.ts +513 -513
  425. package/src/platform/resilience/__tests__/rate-limiter.test.ts +471 -471
  426. package/src/platform/resilience/circuit-breaker.ts +164 -164
  427. package/src/platform/resilience/errors.ts +68 -68
  428. package/src/platform/resilience/http-error-mapper.ts +129 -129
  429. package/src/platform/resilience/index.ts +93 -93
  430. package/src/platform/resilience/rate-limiter-types.ts +46 -46
  431. package/src/platform/resilience/rate-limiter.ts +140 -140
  432. package/src/platform/resilience/retry.ts +89 -89
  433. package/src/platform/resilience/timeout.ts +63 -63
  434. package/src/platform/sse/events.ts +37 -37
  435. package/src/platform/sse/index.ts +7 -7
  436. package/src/platform/utils/__tests__/validation.test.ts +1083 -1083
  437. package/src/platform/utils/currency.ts +96 -96
  438. package/src/platform/utils/debounce.ts +52 -52
  439. package/src/platform/utils/error.ts +41 -41
  440. package/src/platform/utils/hmac.test.ts +97 -97
  441. package/src/platform/utils/index.ts +32 -32
  442. package/src/platform/utils/server/betterstack-logger.ts +210 -210
  443. package/src/platform/utils/server/hmac.ts +44 -44
  444. package/src/platform/utils/server/unsubscribe.ts +111 -111
  445. package/src/platform/utils/token-counter.ts +96 -96
  446. package/src/platform/utils/validation.ts +425 -425
  447. package/src/projects/api-schemas.ts +268 -268
  448. package/src/published.ts +1 -1
  449. package/src/reference/_generated/contracts.md +607 -607
  450. package/src/reference/glossary.md +105 -105
  451. package/src/requests/__tests__/api-schemas.test.ts +277 -277
  452. package/src/requests/api-schemas.ts +83 -83
  453. package/src/requests/index.ts +1 -1
  454. package/src/scaffold-registry/__tests__/index.test.ts +17 -0
  455. package/src/scaffold-registry/__tests__/schema.test.ts +329 -230
  456. package/src/scaffold-registry/index.ts +205 -189
  457. package/src/scaffold-registry/schema.ts +196 -128
  458. package/src/server.ts +272 -272
  459. package/src/supabase/database.types.ts +2719 -2719
  460. package/src/supabase/helpers.ts +20 -20
  461. package/src/supabase/index.ts +52 -52
  462. package/src/supabase/server/client.ts +58 -58
  463. package/src/test-utils/README.md +30 -138
  464. package/src/test-utils/browser-mocks.ts +54 -54
  465. package/src/test-utils/fixtures/api-keys.ts +52 -52
  466. package/src/test-utils/fixtures/index.ts +4 -4
  467. package/src/test-utils/fixtures/memberships.ts +80 -80
  468. package/src/test-utils/fixtures/organizations.ts +69 -69
  469. package/src/test-utils/fixtures/users.ts +79 -79
  470. package/src/test-utils/index.ts +7 -8
  471. package/src/test-utils/mocks/index.ts +2 -2
  472. package/src/test-utils/mocks/supabase.ts +142 -142
  473. package/src/test-utils/mocks/workos.ts +108 -108
  474. package/src/test-utils/published.ts +4 -0
  475. package/src/test-utils/rls/RLSTestContext.ts +554 -554
  476. package/src/test-utils/rls/index.ts +1 -1
@@ -1,810 +1,810 @@
1
- /**
2
- * Agent class
3
- * Autonomous agents that self-orchestrate with LLM and tool calling
4
- * Uses universal protocol with vendor-independent message format
5
- */
6
-
7
- import type { Contract, ExecutionContext } from '../../base/types'
8
- import type { AgentConfig, IterationContext, AgentMemory, AgentDefinition, LLMAdapterFactory } from './types'
9
- import type { Tool } from '../../tools/types'
10
- import type { ModelConfig } from '../../llm/model-info'
11
- import { createAgentLogger, type AgentScopedLogger } from '../observability/logging'
12
- import { errorToString, getErrorDetails } from '../../../../platform/utils/error'
13
- import { processReasoning } from '../reasoning/processor'
14
- import { processActions } from '../actions/processor'
15
- import { processMemory } from '../memory/processor'
16
- import { MemoryManager } from '../memory/manager'
17
- import { callLLMForAgentCompletion } from '../reasoning/adapters/agent-adapter-helpers'
18
- import { zodToJsonSchema } from '@alcyone-labs/zod-to-json-schema'
19
- import type { KnowledgeMap } from '../knowledge-map/types'
20
- import { reloadKnowledgeMapTools } from '../knowledge-map/utils'
21
- import type { z } from 'zod'
22
- import { ZodError } from 'zod'
23
- import {
24
- AgentInitializationError,
25
- AgentIterationError,
26
- AgentCancellationError,
27
- AgentCompletionError,
28
- AgentOutputValidationError,
29
- AgentMaxIterationsError,
30
- AgentTimeoutError,
31
- AgentStalledError
32
- } from '../errors'
33
- import { ExecutionError } from '../../base/errors'
34
-
35
- /**
36
- * Create a per-execution shallow copy of the knowledge map
37
- * Prevents concurrent executions from mutating shared definition state
38
- * (node.loaded, node.prompt, and child node flattening)
39
- */
40
- function initializeKnowledgeMap(knowledgeMap?: KnowledgeMap): KnowledgeMap | undefined {
41
- if (!knowledgeMap) return undefined
42
- return {
43
- nodes: Object.fromEntries(Object.entries(knowledgeMap.nodes).map(([id, node]) => [id, { ...node }]))
44
- }
45
- }
46
-
47
- /**
48
- * Autonomous agent that uses LLM reasoning and tool calling
49
- * to complete tasks without predefined orchestration
50
- *
51
- * @template TInput - Input type validated by contract.inputSchema
52
- * @template TOutput - Output type validated by contract.outputSchema
53
- */
54
- export class Agent<TInput = unknown, TOutput = unknown> {
55
- // Base properties from definition
56
- public readonly config: AgentConfig
57
- public readonly contract: Contract
58
- private readonly toolRegistry: Map<string, Tool>
59
- public readonly modelConfig: ModelConfig
60
- private readonly knowledgeMap?: KnowledgeMap
61
- private readonly definition: AgentDefinition
62
- private readonly adapterFactory: LLMAdapterFactory
63
-
64
- // Derived properties (computed from definition)
65
- private readonly shouldGenerateOutput: boolean
66
-
67
- // Runtime state (initialized during execution)
68
- public memoryManager!: MemoryManager
69
- private logger!: AgentScopedLogger
70
- private executionContext!: ExecutionContext
71
- private iterationNumber: number = 0 // Current iteration number (used for memory context filtering)
72
-
73
- /**
74
- * Create a new agent instance from definition
75
- * Memory will be initialized during execution
76
- *
77
- * @param definition - Agent definition with config, contract, tools, and optional preloadMemory
78
- * @param adapterFactory - Factory for creating LLM adapters (decouples engine from provider SDKs)
79
- */
80
- constructor(definition: AgentDefinition, adapterFactory: LLMAdapterFactory) {
81
- this.definition = definition
82
- this.adapterFactory = adapterFactory
83
- this.config = definition.config
84
- this.contract = definition.contract
85
- this.modelConfig = definition.modelConfig // Store model config from definition
86
- this.knowledgeMap = initializeKnowledgeMap(definition.knowledgeMap)
87
-
88
- // Initialize tool registry with base tools
89
- this.toolRegistry = new Map()
90
- for (const tool of definition.tools) {
91
- this.toolRegistry.set(tool.name, tool)
92
- }
93
-
94
- // Derive shouldGenerateOutput from outputSchema presence (automatic detection)
95
- this.shouldGenerateOutput = !!definition.contract.outputSchema
96
- }
97
-
98
- /**
99
- * Execute the agent with validated input and context
100
- * Orchestrates the three lifecycle phases: initialization, iteration, completion
101
- *
102
- * @param input - Raw input (will be validated against contract.inputSchema)
103
- * @param context - Execution context (required for tracking, logging, and organization isolation)
104
- * @returns Validated output matching contract.outputSchema, or null if no output schema
105
- */
106
- async execute(input: TInput, context: ExecutionContext): Promise<TOutput | null> {
107
- // Store execution context for completion phase
108
- this.executionContext = context
109
-
110
- // Emit agent started event
111
- await context.onMessageEvent?.({ type: 'agent:started' })
112
-
113
- try {
114
- // Phase 1: Initialize
115
- await this.initialize(input, context)
116
-
117
- // Phase 2: Iterate (task execution)
118
- await this.iterate(context)
119
-
120
- // Phase 3: Complete (output generation)
121
- const output = await this.complete()
122
-
123
- // Emit agent completed event
124
- await context.onMessageEvent?.({ type: 'agent:completed' })
125
-
126
- return output
127
- } catch (error) {
128
- // Emit agent error event
129
- await context.onMessageEvent?.({ type: 'agent:error', error: String(error) })
130
- throw error
131
- }
132
- }
133
-
134
- /**
135
- * Register tools from a loaded knowledge node
136
- * Called by navigate_knowledge tool during execution
137
- *
138
- * @param tools - Array of tools to register
139
- * Note: Silently skips tools that are already registered
140
- */
141
- public registerTools(tools: Tool[]): void {
142
- for (const tool of tools) {
143
- if (!this.toolRegistry.has(tool.name)) {
144
- this.toolRegistry.set(tool.name, tool)
145
- }
146
- // Skip tools that are already registered (graceful handling)
147
- }
148
- }
149
-
150
- /**
151
- * Get all currently registered tools
152
- * Used for system prompt generation and introspection
153
- *
154
- * @returns Array of all registered tools
155
- */
156
- public getTools(): Tool[] {
157
- return Array.from(this.toolRegistry.values())
158
- }
159
-
160
- /**
161
- * Phase 1: Initialize the agent execution
162
- * Validates input, initializes memory manager
163
- *
164
- * @param input - Raw input to validate
165
- * @param context - Execution context
166
- */
167
- private async initialize(input: TInput, context: ExecutionContext): Promise<void> {
168
- const initStartTime = Date.now()
169
-
170
- try {
171
- // Create scoped logger for this execution
172
- // Pass sessionId if present in context (now directly on ExecutionMetadata)
173
- this.logger = createAgentLogger(context.logger, this.config.resourceId, context.sessionId)
174
-
175
- this.logger.lifecycle('initialization', 'started', {
176
- startTime: initStartTime
177
- })
178
-
179
- // Validate input
180
- const validatedInput = this.contract.inputSchema.parse(input) as TInput
181
-
182
- // Initialize memory manager (encapsulates all memory initialization)
183
- this.memoryManager = await this.initializeMemoryManager(validatedInput, context)
184
-
185
- const initEndTime = Date.now()
186
- this.logger.lifecycle('initialization', 'completed', {
187
- startTime: initStartTime,
188
- endTime: initEndTime,
189
- duration: initEndTime - initStartTime
190
- })
191
- } catch (error) {
192
- this.wrapAndLogError('initialization', initStartTime, error)
193
- }
194
- }
195
-
196
- /**
197
- * Initialize memory manager with preloaded memory and input entry
198
- * Encapsulates all memory initialization complexity
199
- *
200
- * Also handles cross-turn persistence: re-registers tools from knowledge nodes
201
- * that were loaded in previous session turns.
202
- *
203
- * @param validatedInput - Validated input to add to memory history
204
- * @param context - Execution context (passed to preloadMemory)
205
- * @returns Initialized MemoryManager instance
206
- */
207
- private async initializeMemoryManager(validatedInput: TInput, context: ExecutionContext): Promise<MemoryManager> {
208
- // Preload memory if callback defined
209
- let memory: AgentMemory
210
- if (this.definition.preloadMemory) {
211
- const preloadStartTime = Date.now()
212
- memory = await this.definition.preloadMemory(context)
213
- const preloadEndTime = Date.now()
214
- this.logger.action(
215
- 'memory-preload',
216
- `Preloaded ${Object.keys(memory.sessionMemory).length} session memory entries`,
217
- 0,
218
- preloadStartTime,
219
- preloadEndTime,
220
- preloadEndTime - preloadStartTime
221
- )
222
-
223
- // Reload tools from knowledge map if state exists (cross-turn persistence)
224
- await this.reloadKnowledgeMapTools(memory, context)
225
- } else {
226
- // Default: empty memory
227
- memory = {
228
- sessionMemory: {},
229
- history: []
230
- }
231
- }
232
-
233
- // Add input entry to history (iteration 0 = pre-iteration setup)
234
- const inputStartTime = Date.now()
235
-
236
- memory.history.push({
237
- type: 'input',
238
- content: JSON.stringify(validatedInput),
239
- timestamp: Date.now(),
240
- turnNumber: context.sessionTurnNumber ?? null,
241
- iterationNumber: 0
242
- })
243
- const inputEndTime = Date.now()
244
-
245
- this.logger.action(
246
- 'memory-input',
247
- `Added input entry to history`,
248
- 0,
249
- inputStartTime,
250
- inputEndTime,
251
- inputEndTime - inputStartTime
252
- )
253
-
254
- // Create and return memory manager (takes ownership of memory)
255
- return new MemoryManager(memory, this.config.constraints, this.logger)
256
- }
257
-
258
- /**
259
- * Reload tools from knowledge map state (cross-turn persistence)
260
- *
261
- * Reads the knowledge-map-state from sessionMemory and re-registers
262
- * tools from previously loaded knowledge nodes.
263
- *
264
- * @param memory - Agent memory with sessionMemory state
265
- * @param context - Execution context
266
- */
267
- private async reloadKnowledgeMapTools(memory: AgentMemory, context: ExecutionContext): Promise<void> {
268
- // Only reload if knowledge map exists
269
- if (!this.knowledgeMap) {
270
- return
271
- }
272
-
273
- const stateJson = memory.sessionMemory['knowledge-map-state']
274
- if (!stateJson) {
275
- return // No state to reload
276
- }
277
-
278
- const reloadStartTime = Date.now()
279
-
280
- try {
281
- const tools = await reloadKnowledgeMapTools(this.knowledgeMap, memory, context)
282
-
283
- // Register reloaded tools (skip duplicates gracefully)
284
- let registeredCount = 0
285
- let skippedCount = 0
286
-
287
- for (const tool of tools) {
288
- if (this.toolRegistry.has(tool.name)) {
289
- skippedCount++
290
- } else {
291
- this.toolRegistry.set(tool.name, tool)
292
- registeredCount++
293
- }
294
- }
295
-
296
- const reloadEndTime = Date.now()
297
-
298
- if (registeredCount > 0) {
299
- const state = JSON.parse(stateJson.content)
300
- this.logger.action(
301
- 'knowledge-reload',
302
- `Reloaded ${registeredCount} tools from ${state.loadedNodes.length} knowledge nodes: ${state.loadedNodes.join(', ')}`,
303
- 0,
304
- reloadStartTime,
305
- reloadEndTime,
306
- reloadEndTime - reloadStartTime
307
- )
308
- }
309
-
310
- if (skippedCount > 0) {
311
- this.logger.action(
312
- 'knowledge-reload-skipped',
313
- `Skipped ${skippedCount} already-registered tools during reload`,
314
- 0,
315
- reloadStartTime,
316
- reloadEndTime,
317
- reloadEndTime - reloadStartTime
318
- )
319
- }
320
- } catch (error) {
321
- const errorMessage = errorToString(error)
322
- const reloadEndTime = Date.now()
323
- this.logger.action(
324
- 'knowledge-reload-failed',
325
- `Failed to reload knowledge map: ${errorMessage}`,
326
- 0,
327
- reloadStartTime,
328
- reloadEndTime,
329
- reloadEndTime - reloadStartTime
330
- )
331
- // Continue execution - tools can be re-loaded on demand if needed
332
- }
333
- }
334
-
335
- /**
336
- * Phase 2: Run the agent iteration loop
337
- * Continues until LLM signals completion or max iterations reached
338
- *
339
- * @param context - Execution context
340
- */
341
- private async iterate(context: ExecutionContext): Promise<void> {
342
- const maxIterations = this.config.constraints?.maxIterations || 10
343
- let iteration = 1
344
-
345
- while (iteration <= maxIterations) {
346
- // Check for abort (timeout, stalled, or cancellation)
347
- if (context.signal?.aborted) {
348
- if (context.signal.reason === 'timeout') {
349
- throw new AgentTimeoutError(`Agent execution exceeded timeout (${this.config.constraints?.timeout}ms)`, {
350
- timeout: this.config.constraints?.timeout ?? 0,
351
- iteration
352
- })
353
- }
354
- if (context.signal.reason === 'stalled') {
355
- throw new AgentStalledError('Execution stalled: no heartbeat received within threshold', { iteration })
356
- }
357
- throw new AgentCancellationError('Execution cancelled by user', { iteration })
358
- }
359
-
360
- // Write heartbeat (non-fatal if it fails)
361
- try {
362
- await context.onHeartbeat?.()
363
- } catch {
364
- // Heartbeat failure is non-fatal — execution continues
365
- }
366
-
367
- const result = await this.runIteration(iteration, context)
368
- if (result.shouldComplete) {
369
- return // Exit iteration loop (output generated in completion phase)
370
- }
371
-
372
- iteration++
373
- }
374
-
375
- // Max iterations exceeded
376
- throw new AgentMaxIterationsError(`Agent exceeded maximum iterations (${maxIterations})`, {
377
- maxIterations,
378
- currentIteration: maxIterations
379
- })
380
- }
381
-
382
- /**
383
- * Run a single iteration of the agent loop
384
- *
385
- * Three-phase execution:
386
- * 1. REASON - Query LLM for next actions, store reasoning to memory
387
- * 2. MEMORY - Process memory operations (set/delete session memory entries)
388
- * 3. ACT - Execute planned actions, store tool results to memory
389
- *
390
- * @param iteration - Current iteration number (1-based)
391
- * @param context - Execution context
392
- * @returns Iteration result with completion flag (no finalAnswer - generated in completion phase)
393
- */
394
- private async runIteration(iteration: number, context: ExecutionContext): Promise<{ shouldComplete: boolean }> {
395
- const iterationStartTime = Date.now()
396
-
397
- // Track current iteration number (used by toContext() for memory filtering)
398
- this.iterationNumber = iteration
399
-
400
- try {
401
- this.logger.lifecycle('iteration', 'started', {
402
- iteration,
403
- startTime: iterationStartTime
404
- })
405
-
406
- // Build iteration context
407
- const iterationContext: IterationContext = this.buildIterationContext(iteration, context)
408
-
409
- // Phase 1: REASON - Get LLM's decision and store reasoning to memory
410
- const response = await processReasoning(iterationContext)
411
-
412
- // Phase 2: MEMORY - Process memory operations (agent-directed)
413
- await processMemory(this.memoryManager, response, this.logger, iteration)
414
-
415
- // Phase 3: ACT - Execute LLM's plan and store tool results to memory
416
- const { shouldComplete } = await processActions(iterationContext, response)
417
-
418
- // Log completion
419
- this.logIterationEnd(iteration, iterationStartTime)
420
-
421
- // Return result
422
- return { shouldComplete }
423
- } catch (error) {
424
- this.wrapAndLogError('iteration', iterationStartTime, error, { iteration })
425
- }
426
- }
427
-
428
- /**
429
- * Log iteration end (success only - failures handled by wrapAndLogError)
430
- */
431
- private logIterationEnd(iteration: number, startTime: number): void {
432
- const endTime = Date.now()
433
- const duration = endTime - startTime
434
-
435
- this.logger.lifecycle('iteration', 'completed', {
436
- iteration,
437
- startTime,
438
- endTime,
439
- duration
440
- })
441
- }
442
-
443
- /**
444
- * Phase 3: Complete the agent execution
445
- * Generates and validates structured output from execution history (if output schema present)
446
- * Captures memory snapshot for persistence
447
- *
448
- * @returns Validated output or null if no output schema
449
- */
450
- private async complete(): Promise<TOutput | null> {
451
- const completionStartTime = Date.now()
452
-
453
- try {
454
- this.logger.lifecycle('completion', 'started', {
455
- startTime: completionStartTime
456
- })
457
-
458
- // Conditionally generate output based on schema presence
459
- let output: TOutput | null = null
460
- let attempts: number | undefined
461
-
462
- if (this.shouldGenerateOutput) {
463
- // Generate output (includes retry logic internally)
464
- const result = await this.generateFinalOutput()
465
- output = result.output
466
- attempts = result.attempts
467
- } else {
468
- // Skip output generation (side-effect only agent)
469
- this.logger.action(
470
- 'completion-skipped',
471
- 'Output generation skipped (no output schema)',
472
- 0,
473
- completionStartTime,
474
- completionStartTime,
475
- 0
476
- )
477
- }
478
-
479
- // Capture snapshot automatically (MemoryManager stores it)
480
- this.memoryManager.toSnapshot()
481
-
482
- const snapshot = this.memoryManager.getSnapshot()!
483
- const completionEndTime = Date.now()
484
- this.logger.lifecycle('completion', 'completed', {
485
- startTime: completionStartTime,
486
- endTime: completionEndTime,
487
- duration: completionEndTime - completionStartTime,
488
- attempts,
489
- memorySize: {
490
- sessionMemoryKeys: Object.keys(snapshot.sessionMemory).length,
491
- historyEntries: snapshot.history.length
492
- }
493
- })
494
-
495
- return output
496
- } catch (error) {
497
- this.wrapAndLogError('completion', completionStartTime, error)
498
- }
499
- }
500
-
501
- /**
502
- * Generate final output from execution history with retry logic
503
- * Handles both initial generation and validation retry internally
504
- *
505
- * @returns Object with validated output and attempt count
506
- */
507
- private async generateFinalOutput(): Promise<{ output: TOutput; attempts: number }> {
508
- // Safety check: Ensure outputSchema exists before generating output
509
- if (!this.contract.outputSchema) {
510
- throw new AgentInitializationError(
511
- `Internal error: generateFinalOutput called but contract.outputSchema is undefined`,
512
- {
513
- agentId: this.config.resourceId,
514
- reason: 'missing_output_schema'
515
- }
516
- )
517
- }
518
-
519
- const outputSchema = zodToJsonSchema(this.contract.outputSchema as z.ZodSchema<any>, {
520
- $refStrategy: 'none',
521
- errorMessages: true
522
- })
523
-
524
- // Use model's configured temperature (some models like GPT-5-mini only support default)
525
- const modelTemperature = this.modelConfig.temperature ?? 0.7
526
-
527
- // Attempt 1: Initial generation
528
- const initialOutput = await this.callLLMForOutput(
529
- this.buildOutputGenerationPrompt(),
530
- outputSchema,
531
- modelTemperature,
532
- 'output-generation'
533
- )
534
-
535
- const initialResult = this.contract.outputSchema.safeParse(initialOutput)
536
-
537
- if (initialResult.success) {
538
- return { output: initialResult.data as TOutput, attempts: 1 }
539
- }
540
-
541
- // Attempt 1 failed - log and retry with error context
542
- const validationTime = Date.now()
543
- this.logger.action(
544
- 'completion-validation-failed',
545
- `Output validation failed: ${initialResult.error.message}. Retrying with error context...`,
546
- 0,
547
- validationTime,
548
- validationTime,
549
- 0
550
- )
551
-
552
- // Attempt 2: Retry with validation errors (use same temperature)
553
- const retryPrompt = this.buildRetryPrompt(initialOutput, initialResult.error)
554
- const retryOutput = await this.callLLMForOutput(
555
- retryPrompt,
556
- outputSchema,
557
- modelTemperature,
558
- 'output-generation-retry'
559
- )
560
-
561
- // Strict validation on retry (wrap Zod errors in typed core error)
562
- try {
563
- const finalOutput = this.contract.outputSchema.parse(retryOutput) as TOutput
564
- return { output: finalOutput, attempts: 2 }
565
- } catch (error) {
566
- // Don't let Zod error bubble up - wrap in typed core error
567
- throw new AgentOutputValidationError('Agent output validation failed after retry', {
568
- agentId: this.config.resourceId,
569
- attempts: 2,
570
- zodError: error instanceof ZodError ? error.format() : error
571
- })
572
- }
573
- }
574
-
575
- /**
576
- * Call LLM for output generation
577
- * Shared logic for initial and retry attempts
578
- *
579
- * @param systemPrompt - System prompt for output generation
580
- * @param outputSchema - JSON schema for output validation
581
- * @param temperature - LLM temperature setting
582
- * @param actionType - Action type for logging (output-generation or output-generation-retry)
583
- * @returns Generated structured output
584
- */
585
- private async callLLMForOutput(
586
- systemPrompt: string,
587
- outputSchema: unknown,
588
- temperature: number,
589
- actionType: 'output-generation' | 'output-generation-retry'
590
- ): Promise<unknown> {
591
- const generationStartTime = Date.now()
592
-
593
- try {
594
- this.logger.action(actionType, `${actionType} started`, 0, generationStartTime, generationStartTime, 0)
595
-
596
- // Get attempt number from action type (1 for initial, 2 for retry)
597
- const attempt = actionType === 'output-generation' ? 1 : 2
598
-
599
- const adapter = this.adapterFactory(
600
- this.modelConfig,
601
- this.executionContext?.aiUsageCollector,
602
- 'agent-completion',
603
- {
604
- type: 'agent-completion',
605
- attempt: attempt as 1 | 2,
606
- sessionId: this.executionContext?.sessionId,
607
- turnNumber: this.executionContext?.sessionTurnNumber
608
- }
609
- )
610
-
611
- // Call LLM for completion using agent-specific helper (returns output directly)
612
- const structuredOutput = await callLLMForAgentCompletion(adapter, {
613
- systemPrompt,
614
- memoryContext: this.memoryManager.toContext(this.iterationNumber, this.executionContext?.sessionTurnNumber),
615
- outputSchema,
616
- constraints: {
617
- maxOutputTokens: this.modelConfig.maxOutputTokens,
618
- temperature
619
- },
620
- model: this.modelConfig.model,
621
- signal: this.executionContext?.signal
622
- })
623
-
624
- const generationEndTime = Date.now()
625
- const generationDuration = generationEndTime - generationStartTime
626
- this.logger.action(
627
- actionType,
628
- `${actionType} completed (${generationDuration}ms)`,
629
- 0,
630
- generationStartTime,
631
- generationEndTime,
632
- generationDuration
633
- )
634
-
635
- return structuredOutput
636
- } catch (error) {
637
- const errorMessage = errorToString(error)
638
- const generationEndTime = Date.now()
639
- const generationDuration = generationEndTime - generationStartTime
640
- this.logger.action(
641
- actionType,
642
- `${actionType} failed: ${errorMessage} (${generationDuration}ms)`,
643
- 0,
644
- generationStartTime,
645
- generationEndTime,
646
- generationDuration
647
- )
648
- throw error
649
- }
650
- }
651
-
652
- /**
653
- * Build system prompt for output generation phase
654
- * Instructs LLM to synthesize execution history into structured output
655
- * Note: Only called from generateFinalOutput() which ensures outputSchema exists
656
- *
657
- * @returns System prompt for completion phase
658
- */
659
- private buildOutputGenerationPrompt(): string {
660
- // Type assertion safe: only called from generateFinalOutput() which checks outputSchema exists
661
- const schema = this.contract.outputSchema!
662
-
663
- const schemaJson = zodToJsonSchema(schema as z.ZodSchema<any>, {
664
- $refStrategy: 'none',
665
- errorMessages: true
666
- })
667
-
668
- return `
669
- You have completed a task. Generate the final output based on the execution history.
670
-
671
- ## Output Schema
672
-
673
- The output MUST match this exact structure:
674
-
675
- ${JSON.stringify(schemaJson, null, 2)}
676
-
677
- ## Task Context
678
-
679
- Review the execution history in the memory context below. Extract and structure the relevant information according to the schema.
680
-
681
- ## Requirements
682
-
683
- - Include all required fields
684
- - Use exact field names and types
685
- - Ensure data integrity (no hallucination)
686
- - Base output on actual execution results
687
-
688
- Generate the final output now.
689
- `.trim()
690
- }
691
-
692
- /**
693
- * Build retry prompt with validation error context
694
- *
695
- * @param failedOutput - The output that failed validation
696
- * @param validationError - Zod validation error with details
697
- * @returns System prompt for retry attempt
698
- */
699
- private buildRetryPrompt(failedOutput: unknown, validationError: z.ZodError): string {
700
- return `
701
- ${this.buildOutputGenerationPrompt()}
702
-
703
- ## Previous Attempt (FAILED VALIDATION)
704
-
705
- ${JSON.stringify(failedOutput, null, 2)}
706
-
707
- ## Validation Errors
708
-
709
- ${validationError.issues.map((e) => `- ${e.path.join('.')}: ${e.message}`).join('\n')}
710
-
711
- Fix the errors and generate a valid output.
712
- `.trim()
713
- }
714
-
715
- /**
716
- * Get memory snapshot after execution
717
- * Delegates to MemoryManager.getSnapshot()
718
- * @returns Memory snapshot (only available after execute() completes)
719
- */
720
- public getMemorySnapshot(): AgentMemory | undefined {
721
- return this.memoryManager.getSnapshot()
722
- }
723
-
724
- /**
725
- * Build the execution context for the agent
726
- * @param iteration - Current iteration number (1-based)
727
- * @param context - Execution context
728
- * @returns Agent execution context
729
- */
730
- private buildIterationContext(iteration: number, context: ExecutionContext): IterationContext {
731
- return {
732
- config: this.config,
733
- contract: this.contract,
734
- toolRegistry: this.toolRegistry,
735
- memoryManager: this.memoryManager,
736
- executionContext: context,
737
- iteration,
738
- logger: this.logger,
739
- modelConfig: this.modelConfig,
740
- adapterFactory: this.adapterFactory,
741
- knowledgeMap: this.knowledgeMap
742
- }
743
- }
744
-
745
- /**
746
- * Helper to wrap errors with lifecycle logging
747
- * @param phase - Lifecycle phase (initialization, iteration, completion)
748
- * @param startTime - Phase start timestamp
749
- * @param error - Original error
750
- * @param context - Additional error context
751
- */
752
- private wrapAndLogError(
753
- phase: 'initialization' | 'iteration' | 'completion',
754
- startTime: number,
755
- error: unknown,
756
- context?: Record<string, unknown>
757
- ): never {
758
- const errorMessage = errorToString(error)
759
- const errorDetails = getErrorDetails(error)
760
- const endTime = Date.now()
761
- const duration = endTime - startTime
762
-
763
- // Logger may not be created yet if error occurs during initialization
764
- if (this.logger) {
765
- const logContext: {
766
- error: string
767
- errorDetails: ReturnType<typeof getErrorDetails>
768
- startTime: number
769
- endTime: number
770
- duration: number
771
- iteration?: number
772
- } = {
773
- error: errorMessage,
774
- errorDetails, // Include full error details for debugging
775
- startTime,
776
- endTime,
777
- duration
778
- }
779
-
780
- if (phase === 'iteration' && context?.iteration) {
781
- logContext.iteration = context.iteration as number
782
- }
783
-
784
- this.logger.lifecycle(phase, 'failed', logContext)
785
- }
786
-
787
- // If the error is already a typed ExecutionError, preserve it.
788
- // Phase info is already captured in the lifecycle log above.
789
- if (error instanceof ExecutionError) {
790
- throw error
791
- }
792
-
793
- // Wrap non-ExecutionError instances in phase-appropriate class
794
- const errorContext = {
795
- ...(context || {}),
796
- agentId: this.config.resourceId,
797
- originalError: error instanceof Error ? error.name : 'unknown',
798
- ...errorDetails // Include validation errors, stack traces, etc.
799
- }
800
-
801
- if (phase === 'initialization') {
802
- throw new AgentInitializationError(errorMessage, errorContext)
803
- } else if (phase === 'iteration') {
804
- throw new AgentIterationError(errorMessage, errorContext)
805
- } else {
806
- // completion phase
807
- throw new AgentCompletionError(errorMessage, errorContext)
808
- }
809
- }
810
- }
1
+ /**
2
+ * Agent class
3
+ * Autonomous agents that self-orchestrate with LLM and tool calling
4
+ * Uses universal protocol with vendor-independent message format
5
+ */
6
+
7
+ import type { Contract, ExecutionContext } from '../../base/types'
8
+ import type { AgentConfig, IterationContext, AgentMemory, AgentDefinition, LLMAdapterFactory } from './types'
9
+ import type { Tool } from '../../tools/types'
10
+ import type { ModelConfig } from '../../llm/model-info'
11
+ import { createAgentLogger, type AgentScopedLogger } from '../observability/logging'
12
+ import { errorToString, getErrorDetails } from '../../../../platform/utils/error'
13
+ import { processReasoning } from '../reasoning/processor'
14
+ import { processActions } from '../actions/processor'
15
+ import { processMemory } from '../memory/processor'
16
+ import { MemoryManager } from '../memory/manager'
17
+ import { callLLMForAgentCompletion } from '../reasoning/adapters/agent-adapter-helpers'
18
+ import { zodToJsonSchema } from '@alcyone-labs/zod-to-json-schema'
19
+ import type { KnowledgeMap } from '../knowledge-map/types'
20
+ import { reloadKnowledgeMapTools } from '../knowledge-map/utils'
21
+ import type { z } from 'zod'
22
+ import { ZodError } from 'zod'
23
+ import {
24
+ AgentInitializationError,
25
+ AgentIterationError,
26
+ AgentCancellationError,
27
+ AgentCompletionError,
28
+ AgentOutputValidationError,
29
+ AgentMaxIterationsError,
30
+ AgentTimeoutError,
31
+ AgentStalledError
32
+ } from '../errors'
33
+ import { ExecutionError } from '../../base/errors'
34
+
35
+ /**
36
+ * Create a per-execution shallow copy of the knowledge map
37
+ * Prevents concurrent executions from mutating shared definition state
38
+ * (node.loaded, node.prompt, and child node flattening)
39
+ */
40
+ function initializeKnowledgeMap(knowledgeMap?: KnowledgeMap): KnowledgeMap | undefined {
41
+ if (!knowledgeMap) return undefined
42
+ return {
43
+ nodes: Object.fromEntries(Object.entries(knowledgeMap.nodes).map(([id, node]) => [id, { ...node }]))
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Autonomous agent that uses LLM reasoning and tool calling
49
+ * to complete tasks without predefined orchestration
50
+ *
51
+ * @template TInput - Input type validated by contract.inputSchema
52
+ * @template TOutput - Output type validated by contract.outputSchema
53
+ */
54
+ export class Agent<TInput = unknown, TOutput = unknown> {
55
+ // Base properties from definition
56
+ public readonly config: AgentConfig
57
+ public readonly contract: Contract
58
+ private readonly toolRegistry: Map<string, Tool>
59
+ public readonly modelConfig: ModelConfig
60
+ private readonly knowledgeMap?: KnowledgeMap
61
+ private readonly definition: AgentDefinition
62
+ private readonly adapterFactory: LLMAdapterFactory
63
+
64
+ // Derived properties (computed from definition)
65
+ private readonly shouldGenerateOutput: boolean
66
+
67
+ // Runtime state (initialized during execution)
68
+ public memoryManager!: MemoryManager
69
+ private logger!: AgentScopedLogger
70
+ private executionContext!: ExecutionContext
71
+ private iterationNumber: number = 0 // Current iteration number (used for memory context filtering)
72
+
73
+ /**
74
+ * Create a new agent instance from definition
75
+ * Memory will be initialized during execution
76
+ *
77
+ * @param definition - Agent definition with config, contract, tools, and optional preloadMemory
78
+ * @param adapterFactory - Factory for creating LLM adapters (decouples engine from provider SDKs)
79
+ */
80
+ constructor(definition: AgentDefinition, adapterFactory: LLMAdapterFactory) {
81
+ this.definition = definition
82
+ this.adapterFactory = adapterFactory
83
+ this.config = definition.config
84
+ this.contract = definition.contract
85
+ this.modelConfig = definition.modelConfig // Store model config from definition
86
+ this.knowledgeMap = initializeKnowledgeMap(definition.knowledgeMap)
87
+
88
+ // Initialize tool registry with base tools
89
+ this.toolRegistry = new Map()
90
+ for (const tool of definition.tools) {
91
+ this.toolRegistry.set(tool.name, tool)
92
+ }
93
+
94
+ // Derive shouldGenerateOutput from outputSchema presence (automatic detection)
95
+ this.shouldGenerateOutput = !!definition.contract.outputSchema
96
+ }
97
+
98
+ /**
99
+ * Execute the agent with validated input and context
100
+ * Orchestrates the three lifecycle phases: initialization, iteration, completion
101
+ *
102
+ * @param input - Raw input (will be validated against contract.inputSchema)
103
+ * @param context - Execution context (required for tracking, logging, and organization isolation)
104
+ * @returns Validated output matching contract.outputSchema, or null if no output schema
105
+ */
106
+ async execute(input: TInput, context: ExecutionContext): Promise<TOutput | null> {
107
+ // Store execution context for completion phase
108
+ this.executionContext = context
109
+
110
+ // Emit agent started event
111
+ await context.onMessageEvent?.({ type: 'agent:started' })
112
+
113
+ try {
114
+ // Phase 1: Initialize
115
+ await this.initialize(input, context)
116
+
117
+ // Phase 2: Iterate (task execution)
118
+ await this.iterate(context)
119
+
120
+ // Phase 3: Complete (output generation)
121
+ const output = await this.complete()
122
+
123
+ // Emit agent completed event
124
+ await context.onMessageEvent?.({ type: 'agent:completed' })
125
+
126
+ return output
127
+ } catch (error) {
128
+ // Emit agent error event
129
+ await context.onMessageEvent?.({ type: 'agent:error', error: String(error) })
130
+ throw error
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Register tools from a loaded knowledge node
136
+ * Called by navigate_knowledge tool during execution
137
+ *
138
+ * @param tools - Array of tools to register
139
+ * Note: Silently skips tools that are already registered
140
+ */
141
+ public registerTools(tools: Tool[]): void {
142
+ for (const tool of tools) {
143
+ if (!this.toolRegistry.has(tool.name)) {
144
+ this.toolRegistry.set(tool.name, tool)
145
+ }
146
+ // Skip tools that are already registered (graceful handling)
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Get all currently registered tools
152
+ * Used for system prompt generation and introspection
153
+ *
154
+ * @returns Array of all registered tools
155
+ */
156
+ public getTools(): Tool[] {
157
+ return Array.from(this.toolRegistry.values())
158
+ }
159
+
160
+ /**
161
+ * Phase 1: Initialize the agent execution
162
+ * Validates input, initializes memory manager
163
+ *
164
+ * @param input - Raw input to validate
165
+ * @param context - Execution context
166
+ */
167
+ private async initialize(input: TInput, context: ExecutionContext): Promise<void> {
168
+ const initStartTime = Date.now()
169
+
170
+ try {
171
+ // Create scoped logger for this execution
172
+ // Pass sessionId if present in context (now directly on ExecutionMetadata)
173
+ this.logger = createAgentLogger(context.logger, this.config.resourceId, context.sessionId)
174
+
175
+ this.logger.lifecycle('initialization', 'started', {
176
+ startTime: initStartTime
177
+ })
178
+
179
+ // Validate input
180
+ const validatedInput = this.contract.inputSchema.parse(input) as TInput
181
+
182
+ // Initialize memory manager (encapsulates all memory initialization)
183
+ this.memoryManager = await this.initializeMemoryManager(validatedInput, context)
184
+
185
+ const initEndTime = Date.now()
186
+ this.logger.lifecycle('initialization', 'completed', {
187
+ startTime: initStartTime,
188
+ endTime: initEndTime,
189
+ duration: initEndTime - initStartTime
190
+ })
191
+ } catch (error) {
192
+ this.wrapAndLogError('initialization', initStartTime, error)
193
+ }
194
+ }
195
+
196
+ /**
197
+ * Initialize memory manager with preloaded memory and input entry
198
+ * Encapsulates all memory initialization complexity
199
+ *
200
+ * Also handles cross-turn persistence: re-registers tools from knowledge nodes
201
+ * that were loaded in previous session turns.
202
+ *
203
+ * @param validatedInput - Validated input to add to memory history
204
+ * @param context - Execution context (passed to preloadMemory)
205
+ * @returns Initialized MemoryManager instance
206
+ */
207
+ private async initializeMemoryManager(validatedInput: TInput, context: ExecutionContext): Promise<MemoryManager> {
208
+ // Preload memory if callback defined
209
+ let memory: AgentMemory
210
+ if (this.definition.preloadMemory) {
211
+ const preloadStartTime = Date.now()
212
+ memory = await this.definition.preloadMemory(context)
213
+ const preloadEndTime = Date.now()
214
+ this.logger.action(
215
+ 'memory-preload',
216
+ `Preloaded ${Object.keys(memory.sessionMemory).length} session memory entries`,
217
+ 0,
218
+ preloadStartTime,
219
+ preloadEndTime,
220
+ preloadEndTime - preloadStartTime
221
+ )
222
+
223
+ // Reload tools from knowledge map if state exists (cross-turn persistence)
224
+ await this.reloadKnowledgeMapTools(memory, context)
225
+ } else {
226
+ // Default: empty memory
227
+ memory = {
228
+ sessionMemory: {},
229
+ history: []
230
+ }
231
+ }
232
+
233
+ // Add input entry to history (iteration 0 = pre-iteration setup)
234
+ const inputStartTime = Date.now()
235
+
236
+ memory.history.push({
237
+ type: 'input',
238
+ content: JSON.stringify(validatedInput),
239
+ timestamp: Date.now(),
240
+ turnNumber: context.sessionTurnNumber ?? null,
241
+ iterationNumber: 0
242
+ })
243
+ const inputEndTime = Date.now()
244
+
245
+ this.logger.action(
246
+ 'memory-input',
247
+ `Added input entry to history`,
248
+ 0,
249
+ inputStartTime,
250
+ inputEndTime,
251
+ inputEndTime - inputStartTime
252
+ )
253
+
254
+ // Create and return memory manager (takes ownership of memory)
255
+ return new MemoryManager(memory, this.config.constraints, this.logger)
256
+ }
257
+
258
+ /**
259
+ * Reload tools from knowledge map state (cross-turn persistence)
260
+ *
261
+ * Reads the knowledge-map-state from sessionMemory and re-registers
262
+ * tools from previously loaded knowledge nodes.
263
+ *
264
+ * @param memory - Agent memory with sessionMemory state
265
+ * @param context - Execution context
266
+ */
267
+ private async reloadKnowledgeMapTools(memory: AgentMemory, context: ExecutionContext): Promise<void> {
268
+ // Only reload if knowledge map exists
269
+ if (!this.knowledgeMap) {
270
+ return
271
+ }
272
+
273
+ const stateJson = memory.sessionMemory['knowledge-map-state']
274
+ if (!stateJson) {
275
+ return // No state to reload
276
+ }
277
+
278
+ const reloadStartTime = Date.now()
279
+
280
+ try {
281
+ const tools = await reloadKnowledgeMapTools(this.knowledgeMap, memory, context)
282
+
283
+ // Register reloaded tools (skip duplicates gracefully)
284
+ let registeredCount = 0
285
+ let skippedCount = 0
286
+
287
+ for (const tool of tools) {
288
+ if (this.toolRegistry.has(tool.name)) {
289
+ skippedCount++
290
+ } else {
291
+ this.toolRegistry.set(tool.name, tool)
292
+ registeredCount++
293
+ }
294
+ }
295
+
296
+ const reloadEndTime = Date.now()
297
+
298
+ if (registeredCount > 0) {
299
+ const state = JSON.parse(stateJson.content)
300
+ this.logger.action(
301
+ 'knowledge-reload',
302
+ `Reloaded ${registeredCount} tools from ${state.loadedNodes.length} knowledge nodes: ${state.loadedNodes.join(', ')}`,
303
+ 0,
304
+ reloadStartTime,
305
+ reloadEndTime,
306
+ reloadEndTime - reloadStartTime
307
+ )
308
+ }
309
+
310
+ if (skippedCount > 0) {
311
+ this.logger.action(
312
+ 'knowledge-reload-skipped',
313
+ `Skipped ${skippedCount} already-registered tools during reload`,
314
+ 0,
315
+ reloadStartTime,
316
+ reloadEndTime,
317
+ reloadEndTime - reloadStartTime
318
+ )
319
+ }
320
+ } catch (error) {
321
+ const errorMessage = errorToString(error)
322
+ const reloadEndTime = Date.now()
323
+ this.logger.action(
324
+ 'knowledge-reload-failed',
325
+ `Failed to reload knowledge map: ${errorMessage}`,
326
+ 0,
327
+ reloadStartTime,
328
+ reloadEndTime,
329
+ reloadEndTime - reloadStartTime
330
+ )
331
+ // Continue execution - tools can be re-loaded on demand if needed
332
+ }
333
+ }
334
+
335
+ /**
336
+ * Phase 2: Run the agent iteration loop
337
+ * Continues until LLM signals completion or max iterations reached
338
+ *
339
+ * @param context - Execution context
340
+ */
341
+ private async iterate(context: ExecutionContext): Promise<void> {
342
+ const maxIterations = this.config.constraints?.maxIterations || 10
343
+ let iteration = 1
344
+
345
+ while (iteration <= maxIterations) {
346
+ // Check for abort (timeout, stalled, or cancellation)
347
+ if (context.signal?.aborted) {
348
+ if (context.signal.reason === 'timeout') {
349
+ throw new AgentTimeoutError(`Agent execution exceeded timeout (${this.config.constraints?.timeout}ms)`, {
350
+ timeout: this.config.constraints?.timeout ?? 0,
351
+ iteration
352
+ })
353
+ }
354
+ if (context.signal.reason === 'stalled') {
355
+ throw new AgentStalledError('Execution stalled: no heartbeat received within threshold', { iteration })
356
+ }
357
+ throw new AgentCancellationError('Execution cancelled by user', { iteration })
358
+ }
359
+
360
+ // Write heartbeat (non-fatal if it fails)
361
+ try {
362
+ await context.onHeartbeat?.()
363
+ } catch {
364
+ // Heartbeat failure is non-fatal — execution continues
365
+ }
366
+
367
+ const result = await this.runIteration(iteration, context)
368
+ if (result.shouldComplete) {
369
+ return // Exit iteration loop (output generated in completion phase)
370
+ }
371
+
372
+ iteration++
373
+ }
374
+
375
+ // Max iterations exceeded
376
+ throw new AgentMaxIterationsError(`Agent exceeded maximum iterations (${maxIterations})`, {
377
+ maxIterations,
378
+ currentIteration: maxIterations
379
+ })
380
+ }
381
+
382
+ /**
383
+ * Run a single iteration of the agent loop
384
+ *
385
+ * Three-phase execution:
386
+ * 1. REASON - Query LLM for next actions, store reasoning to memory
387
+ * 2. MEMORY - Process memory operations (set/delete session memory entries)
388
+ * 3. ACT - Execute planned actions, store tool results to memory
389
+ *
390
+ * @param iteration - Current iteration number (1-based)
391
+ * @param context - Execution context
392
+ * @returns Iteration result with completion flag (no finalAnswer - generated in completion phase)
393
+ */
394
+ private async runIteration(iteration: number, context: ExecutionContext): Promise<{ shouldComplete: boolean }> {
395
+ const iterationStartTime = Date.now()
396
+
397
+ // Track current iteration number (used by toContext() for memory filtering)
398
+ this.iterationNumber = iteration
399
+
400
+ try {
401
+ this.logger.lifecycle('iteration', 'started', {
402
+ iteration,
403
+ startTime: iterationStartTime
404
+ })
405
+
406
+ // Build iteration context
407
+ const iterationContext: IterationContext = this.buildIterationContext(iteration, context)
408
+
409
+ // Phase 1: REASON - Get LLM's decision and store reasoning to memory
410
+ const response = await processReasoning(iterationContext)
411
+
412
+ // Phase 2: MEMORY - Process memory operations (agent-directed)
413
+ await processMemory(this.memoryManager, response, this.logger, iteration)
414
+
415
+ // Phase 3: ACT - Execute LLM's plan and store tool results to memory
416
+ const { shouldComplete } = await processActions(iterationContext, response)
417
+
418
+ // Log completion
419
+ this.logIterationEnd(iteration, iterationStartTime)
420
+
421
+ // Return result
422
+ return { shouldComplete }
423
+ } catch (error) {
424
+ this.wrapAndLogError('iteration', iterationStartTime, error, { iteration })
425
+ }
426
+ }
427
+
428
+ /**
429
+ * Log iteration end (success only - failures handled by wrapAndLogError)
430
+ */
431
+ private logIterationEnd(iteration: number, startTime: number): void {
432
+ const endTime = Date.now()
433
+ const duration = endTime - startTime
434
+
435
+ this.logger.lifecycle('iteration', 'completed', {
436
+ iteration,
437
+ startTime,
438
+ endTime,
439
+ duration
440
+ })
441
+ }
442
+
443
+ /**
444
+ * Phase 3: Complete the agent execution
445
+ * Generates and validates structured output from execution history (if output schema present)
446
+ * Captures memory snapshot for persistence
447
+ *
448
+ * @returns Validated output or null if no output schema
449
+ */
450
+ private async complete(): Promise<TOutput | null> {
451
+ const completionStartTime = Date.now()
452
+
453
+ try {
454
+ this.logger.lifecycle('completion', 'started', {
455
+ startTime: completionStartTime
456
+ })
457
+
458
+ // Conditionally generate output based on schema presence
459
+ let output: TOutput | null = null
460
+ let attempts: number | undefined
461
+
462
+ if (this.shouldGenerateOutput) {
463
+ // Generate output (includes retry logic internally)
464
+ const result = await this.generateFinalOutput()
465
+ output = result.output
466
+ attempts = result.attempts
467
+ } else {
468
+ // Skip output generation (side-effect only agent)
469
+ this.logger.action(
470
+ 'completion-skipped',
471
+ 'Output generation skipped (no output schema)',
472
+ 0,
473
+ completionStartTime,
474
+ completionStartTime,
475
+ 0
476
+ )
477
+ }
478
+
479
+ // Capture snapshot automatically (MemoryManager stores it)
480
+ this.memoryManager.toSnapshot()
481
+
482
+ const snapshot = this.memoryManager.getSnapshot()!
483
+ const completionEndTime = Date.now()
484
+ this.logger.lifecycle('completion', 'completed', {
485
+ startTime: completionStartTime,
486
+ endTime: completionEndTime,
487
+ duration: completionEndTime - completionStartTime,
488
+ attempts,
489
+ memorySize: {
490
+ sessionMemoryKeys: Object.keys(snapshot.sessionMemory).length,
491
+ historyEntries: snapshot.history.length
492
+ }
493
+ })
494
+
495
+ return output
496
+ } catch (error) {
497
+ this.wrapAndLogError('completion', completionStartTime, error)
498
+ }
499
+ }
500
+
501
+ /**
502
+ * Generate final output from execution history with retry logic
503
+ * Handles both initial generation and validation retry internally
504
+ *
505
+ * @returns Object with validated output and attempt count
506
+ */
507
+ private async generateFinalOutput(): Promise<{ output: TOutput; attempts: number }> {
508
+ // Safety check: Ensure outputSchema exists before generating output
509
+ if (!this.contract.outputSchema) {
510
+ throw new AgentInitializationError(
511
+ `Internal error: generateFinalOutput called but contract.outputSchema is undefined`,
512
+ {
513
+ agentId: this.config.resourceId,
514
+ reason: 'missing_output_schema'
515
+ }
516
+ )
517
+ }
518
+
519
+ const outputSchema = zodToJsonSchema(this.contract.outputSchema as z.ZodSchema<any>, {
520
+ $refStrategy: 'none',
521
+ errorMessages: true
522
+ })
523
+
524
+ // Use model's configured temperature (some models like GPT-5-mini only support default)
525
+ const modelTemperature = this.modelConfig.temperature ?? 0.7
526
+
527
+ // Attempt 1: Initial generation
528
+ const initialOutput = await this.callLLMForOutput(
529
+ this.buildOutputGenerationPrompt(),
530
+ outputSchema,
531
+ modelTemperature,
532
+ 'output-generation'
533
+ )
534
+
535
+ const initialResult = this.contract.outputSchema.safeParse(initialOutput)
536
+
537
+ if (initialResult.success) {
538
+ return { output: initialResult.data as TOutput, attempts: 1 }
539
+ }
540
+
541
+ // Attempt 1 failed - log and retry with error context
542
+ const validationTime = Date.now()
543
+ this.logger.action(
544
+ 'completion-validation-failed',
545
+ `Output validation failed: ${initialResult.error.message}. Retrying with error context...`,
546
+ 0,
547
+ validationTime,
548
+ validationTime,
549
+ 0
550
+ )
551
+
552
+ // Attempt 2: Retry with validation errors (use same temperature)
553
+ const retryPrompt = this.buildRetryPrompt(initialOutput, initialResult.error)
554
+ const retryOutput = await this.callLLMForOutput(
555
+ retryPrompt,
556
+ outputSchema,
557
+ modelTemperature,
558
+ 'output-generation-retry'
559
+ )
560
+
561
+ // Strict validation on retry (wrap Zod errors in typed core error)
562
+ try {
563
+ const finalOutput = this.contract.outputSchema.parse(retryOutput) as TOutput
564
+ return { output: finalOutput, attempts: 2 }
565
+ } catch (error) {
566
+ // Don't let Zod error bubble up - wrap in typed core error
567
+ throw new AgentOutputValidationError('Agent output validation failed after retry', {
568
+ agentId: this.config.resourceId,
569
+ attempts: 2,
570
+ zodError: error instanceof ZodError ? error.format() : error
571
+ })
572
+ }
573
+ }
574
+
575
+ /**
576
+ * Call LLM for output generation
577
+ * Shared logic for initial and retry attempts
578
+ *
579
+ * @param systemPrompt - System prompt for output generation
580
+ * @param outputSchema - JSON schema for output validation
581
+ * @param temperature - LLM temperature setting
582
+ * @param actionType - Action type for logging (output-generation or output-generation-retry)
583
+ * @returns Generated structured output
584
+ */
585
+ private async callLLMForOutput(
586
+ systemPrompt: string,
587
+ outputSchema: unknown,
588
+ temperature: number,
589
+ actionType: 'output-generation' | 'output-generation-retry'
590
+ ): Promise<unknown> {
591
+ const generationStartTime = Date.now()
592
+
593
+ try {
594
+ this.logger.action(actionType, `${actionType} started`, 0, generationStartTime, generationStartTime, 0)
595
+
596
+ // Get attempt number from action type (1 for initial, 2 for retry)
597
+ const attempt = actionType === 'output-generation' ? 1 : 2
598
+
599
+ const adapter = this.adapterFactory(
600
+ this.modelConfig,
601
+ this.executionContext?.aiUsageCollector,
602
+ 'agent-completion',
603
+ {
604
+ type: 'agent-completion',
605
+ attempt: attempt as 1 | 2,
606
+ sessionId: this.executionContext?.sessionId,
607
+ turnNumber: this.executionContext?.sessionTurnNumber
608
+ }
609
+ )
610
+
611
+ // Call LLM for completion using agent-specific helper (returns output directly)
612
+ const structuredOutput = await callLLMForAgentCompletion(adapter, {
613
+ systemPrompt,
614
+ memoryContext: this.memoryManager.toContext(this.iterationNumber, this.executionContext?.sessionTurnNumber),
615
+ outputSchema,
616
+ constraints: {
617
+ maxOutputTokens: this.modelConfig.maxOutputTokens,
618
+ temperature
619
+ },
620
+ model: this.modelConfig.model,
621
+ signal: this.executionContext?.signal
622
+ })
623
+
624
+ const generationEndTime = Date.now()
625
+ const generationDuration = generationEndTime - generationStartTime
626
+ this.logger.action(
627
+ actionType,
628
+ `${actionType} completed (${generationDuration}ms)`,
629
+ 0,
630
+ generationStartTime,
631
+ generationEndTime,
632
+ generationDuration
633
+ )
634
+
635
+ return structuredOutput
636
+ } catch (error) {
637
+ const errorMessage = errorToString(error)
638
+ const generationEndTime = Date.now()
639
+ const generationDuration = generationEndTime - generationStartTime
640
+ this.logger.action(
641
+ actionType,
642
+ `${actionType} failed: ${errorMessage} (${generationDuration}ms)`,
643
+ 0,
644
+ generationStartTime,
645
+ generationEndTime,
646
+ generationDuration
647
+ )
648
+ throw error
649
+ }
650
+ }
651
+
652
+ /**
653
+ * Build system prompt for output generation phase
654
+ * Instructs LLM to synthesize execution history into structured output
655
+ * Note: Only called from generateFinalOutput() which ensures outputSchema exists
656
+ *
657
+ * @returns System prompt for completion phase
658
+ */
659
+ private buildOutputGenerationPrompt(): string {
660
+ // Type assertion safe: only called from generateFinalOutput() which checks outputSchema exists
661
+ const schema = this.contract.outputSchema!
662
+
663
+ const schemaJson = zodToJsonSchema(schema as z.ZodSchema<any>, {
664
+ $refStrategy: 'none',
665
+ errorMessages: true
666
+ })
667
+
668
+ return `
669
+ You have completed a task. Generate the final output based on the execution history.
670
+
671
+ ## Output Schema
672
+
673
+ The output MUST match this exact structure:
674
+
675
+ ${JSON.stringify(schemaJson, null, 2)}
676
+
677
+ ## Task Context
678
+
679
+ Review the execution history in the memory context below. Extract and structure the relevant information according to the schema.
680
+
681
+ ## Requirements
682
+
683
+ - Include all required fields
684
+ - Use exact field names and types
685
+ - Ensure data integrity (no hallucination)
686
+ - Base output on actual execution results
687
+
688
+ Generate the final output now.
689
+ `.trim()
690
+ }
691
+
692
+ /**
693
+ * Build retry prompt with validation error context
694
+ *
695
+ * @param failedOutput - The output that failed validation
696
+ * @param validationError - Zod validation error with details
697
+ * @returns System prompt for retry attempt
698
+ */
699
+ private buildRetryPrompt(failedOutput: unknown, validationError: z.ZodError): string {
700
+ return `
701
+ ${this.buildOutputGenerationPrompt()}
702
+
703
+ ## Previous Attempt (FAILED VALIDATION)
704
+
705
+ ${JSON.stringify(failedOutput, null, 2)}
706
+
707
+ ## Validation Errors
708
+
709
+ ${validationError.issues.map((e) => `- ${e.path.join('.')}: ${e.message}`).join('\n')}
710
+
711
+ Fix the errors and generate a valid output.
712
+ `.trim()
713
+ }
714
+
715
+ /**
716
+ * Get memory snapshot after execution
717
+ * Delegates to MemoryManager.getSnapshot()
718
+ * @returns Memory snapshot (only available after execute() completes)
719
+ */
720
+ public getMemorySnapshot(): AgentMemory | undefined {
721
+ return this.memoryManager.getSnapshot()
722
+ }
723
+
724
+ /**
725
+ * Build the execution context for the agent
726
+ * @param iteration - Current iteration number (1-based)
727
+ * @param context - Execution context
728
+ * @returns Agent execution context
729
+ */
730
+ private buildIterationContext(iteration: number, context: ExecutionContext): IterationContext {
731
+ return {
732
+ config: this.config,
733
+ contract: this.contract,
734
+ toolRegistry: this.toolRegistry,
735
+ memoryManager: this.memoryManager,
736
+ executionContext: context,
737
+ iteration,
738
+ logger: this.logger,
739
+ modelConfig: this.modelConfig,
740
+ adapterFactory: this.adapterFactory,
741
+ knowledgeMap: this.knowledgeMap
742
+ }
743
+ }
744
+
745
+ /**
746
+ * Helper to wrap errors with lifecycle logging
747
+ * @param phase - Lifecycle phase (initialization, iteration, completion)
748
+ * @param startTime - Phase start timestamp
749
+ * @param error - Original error
750
+ * @param context - Additional error context
751
+ */
752
+ private wrapAndLogError(
753
+ phase: 'initialization' | 'iteration' | 'completion',
754
+ startTime: number,
755
+ error: unknown,
756
+ context?: Record<string, unknown>
757
+ ): never {
758
+ const errorMessage = errorToString(error)
759
+ const errorDetails = getErrorDetails(error)
760
+ const endTime = Date.now()
761
+ const duration = endTime - startTime
762
+
763
+ // Logger may not be created yet if error occurs during initialization
764
+ if (this.logger) {
765
+ const logContext: {
766
+ error: string
767
+ errorDetails: ReturnType<typeof getErrorDetails>
768
+ startTime: number
769
+ endTime: number
770
+ duration: number
771
+ iteration?: number
772
+ } = {
773
+ error: errorMessage,
774
+ errorDetails, // Include full error details for debugging
775
+ startTime,
776
+ endTime,
777
+ duration
778
+ }
779
+
780
+ if (phase === 'iteration' && context?.iteration) {
781
+ logContext.iteration = context.iteration as number
782
+ }
783
+
784
+ this.logger.lifecycle(phase, 'failed', logContext)
785
+ }
786
+
787
+ // If the error is already a typed ExecutionError, preserve it.
788
+ // Phase info is already captured in the lifecycle log above.
789
+ if (error instanceof ExecutionError) {
790
+ throw error
791
+ }
792
+
793
+ // Wrap non-ExecutionError instances in phase-appropriate class
794
+ const errorContext = {
795
+ ...(context || {}),
796
+ agentId: this.config.resourceId,
797
+ originalError: error instanceof Error ? error.name : 'unknown',
798
+ ...errorDetails // Include validation errors, stack traces, etc.
799
+ }
800
+
801
+ if (phase === 'initialization') {
802
+ throw new AgentInitializationError(errorMessage, errorContext)
803
+ } else if (phase === 'iteration') {
804
+ throw new AgentIterationError(errorMessage, errorContext)
805
+ } else {
806
+ // completion phase
807
+ throw new AgentCompletionError(errorMessage, errorContext)
808
+ }
809
+ }
810
+ }