@elevasis/core 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (473) hide show
  1. package/package.json +3 -3
  2. package/src/README.md +41 -41
  3. package/src/__tests__/publish.test.ts +18 -18
  4. package/src/__tests__/{template-foundations-compatibility.test.ts → template-core-compatibility.test.ts} +99 -99
  5. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +1135 -1131
  6. package/src/_gen/__tests__/scaffold-contracts.test.ts +53 -53
  7. package/src/_gen/scaffold-contracts.ts +45 -45
  8. package/src/auth/multi-tenancy/credentials/README.md +38 -38
  9. package/src/auth/multi-tenancy/credentials/index.ts +6 -6
  10. package/src/auth/multi-tenancy/credentials/server/encryption.ts +39 -39
  11. package/src/auth/multi-tenancy/credentials/server/service.ts +60 -60
  12. package/src/auth/multi-tenancy/index.ts +17 -17
  13. package/src/auth/multi-tenancy/invitations/api-schemas.ts +107 -107
  14. package/src/auth/multi-tenancy/invitations/index.ts +37 -37
  15. package/src/auth/multi-tenancy/invitations/invitation.ts +86 -86
  16. package/src/auth/multi-tenancy/invitations/server/index.ts +25 -25
  17. package/src/auth/multi-tenancy/invitations/server/transforms.ts +24 -24
  18. package/src/auth/multi-tenancy/invitations/server/workos.ts +24 -24
  19. package/src/auth/multi-tenancy/invitations/supabase.ts +50 -50
  20. package/src/auth/multi-tenancy/memberships/api-schemas.ts +126 -126
  21. package/src/auth/multi-tenancy/memberships/index.ts +21 -21
  22. package/src/auth/multi-tenancy/memberships/membership.ts +138 -138
  23. package/src/auth/multi-tenancy/memberships/server/index.ts +15 -15
  24. package/src/auth/multi-tenancy/memberships/server/transforms.ts +32 -32
  25. package/src/auth/multi-tenancy/memberships/server/workos.ts +21 -21
  26. package/src/auth/multi-tenancy/memberships/supabase.ts +46 -46
  27. package/src/auth/multi-tenancy/organizations/api-schemas.ts +128 -128
  28. package/src/auth/multi-tenancy/organizations/index.ts +23 -23
  29. package/src/auth/multi-tenancy/organizations/organization.ts +24 -24
  30. package/src/auth/multi-tenancy/organizations/server/index.ts +10 -10
  31. package/src/auth/multi-tenancy/organizations/server/transforms.ts +35 -35
  32. package/src/auth/multi-tenancy/organizations/server/workos.ts +20 -20
  33. package/src/auth/multi-tenancy/types.ts +83 -83
  34. package/src/auth/multi-tenancy/users/api-schemas.ts +194 -194
  35. package/src/auth/multi-tenancy/users/index.ts +27 -27
  36. package/src/auth/multi-tenancy/users/server/index.ts +19 -19
  37. package/src/auth/multi-tenancy/users/server/transforms.ts +21 -21
  38. package/src/auth/multi-tenancy/users/server/workos.ts +16 -16
  39. package/src/auth/multi-tenancy/users/user.ts +65 -65
  40. package/src/business/README.md +52 -52
  41. package/src/business/__tests__/entities-published.test.ts +33 -33
  42. package/src/business/acquisition/api-schemas.ts +759 -759
  43. package/src/business/acquisition/index.ts +109 -109
  44. package/src/business/acquisition/types.ts +402 -402
  45. package/src/business/base-entities.test.ts +481 -481
  46. package/src/business/base-entities.ts +241 -241
  47. package/src/business/entities-published.ts +24 -24
  48. package/src/business/index.ts +15 -15
  49. package/src/business/pdf/browser/pdfmake-browser.ts +229 -229
  50. package/src/business/pdf/index.ts +10 -10
  51. package/src/business/pdf/server/index.ts +21 -21
  52. package/src/business/pdf/server/themes/default.ts +8 -8
  53. package/src/business/pdf/server/themes/index.ts +9 -9
  54. package/src/business/pdf/server/themes/types.ts +8 -8
  55. package/src/business/pdf/types.ts +272 -272
  56. package/src/business/projects/index.ts +2 -1
  57. package/src/business/projects/sse-events.ts +21 -0
  58. package/src/business/projects/types.ts +89 -89
  59. package/src/business/sales/api-schemas.ts +75 -75
  60. package/src/business/seo/__tests__/linking.test.ts +549 -549
  61. package/src/business/seo/__tests__/types.test.ts +404 -404
  62. package/src/business/seo/index.ts +2 -2
  63. package/src/business/seo/linking.ts +281 -281
  64. package/src/business/seo/types.ts +199 -199
  65. package/src/commands/queue/index.ts +3 -3
  66. package/src/commands/queue/schemas.test.ts +593 -593
  67. package/src/commands/queue/schemas.ts +125 -125
  68. package/src/commands/queue/sse-events.ts +61 -61
  69. package/src/commands/queue/types/action.ts +52 -52
  70. package/src/commands/queue/types/checkpoint.ts +44 -44
  71. package/src/commands/queue/types/index.ts +7 -7
  72. package/src/commands/queue/types/task.ts +116 -116
  73. package/src/commands/queue/types.ts +14 -14
  74. package/src/content/distribution-metadata.ts +61 -61
  75. package/src/content/index.ts +10 -10
  76. package/src/deployments/index.ts +22 -22
  77. package/src/execution/core/__tests__/archived-logs.test.ts +72 -72
  78. package/src/execution/core/index.ts +11 -11
  79. package/src/execution/core/runner-types.ts +80 -80
  80. package/src/execution/core/server/environment.ts +31 -31
  81. package/src/execution/core/sse-executions.ts +119 -119
  82. package/src/execution/core/types.ts +29 -29
  83. package/src/execution/engine/__tests__/fixtures/test-agents.ts +4 -4
  84. package/src/execution/engine/__tests__/timeout.test.ts +565 -565
  85. package/src/execution/engine/agent/__tests__/errors.test.ts +508 -508
  86. package/src/execution/engine/agent/actions/__tests__/processor.test.ts +531 -531
  87. package/src/execution/engine/agent/actions/executor.ts +205 -205
  88. package/src/execution/engine/agent/actions/navigate-knowledge-executor.ts +230 -230
  89. package/src/execution/engine/agent/actions/processor.ts +116 -116
  90. package/src/execution/engine/agent/actions/types.ts +70 -70
  91. package/src/execution/engine/agent/core/agent.ts +810 -810
  92. package/src/execution/engine/agent/core/types.ts +155 -155
  93. package/src/execution/engine/agent/errors.ts +251 -251
  94. package/src/execution/engine/agent/index.ts +78 -78
  95. package/src/execution/engine/agent/knowledge-map/types.ts +106 -106
  96. package/src/execution/engine/agent/knowledge-map/utils.ts +101 -101
  97. package/src/execution/engine/agent/memory/__tests__/manager.test.ts +754 -754
  98. package/src/execution/engine/agent/memory/domains.ts +99 -99
  99. package/src/execution/engine/agent/memory/manager.ts +365 -365
  100. package/src/execution/engine/agent/memory/processor.ts +66 -66
  101. package/src/execution/engine/agent/memory/types.ts +90 -90
  102. package/src/execution/engine/agent/memory/utils.ts +134 -134
  103. package/src/execution/engine/agent/observability/logging.ts +467 -467
  104. package/src/execution/engine/agent/observability/types.ts +64 -64
  105. package/src/execution/engine/agent/reasoning/adapters/agent-adapter-helpers.ts +349 -349
  106. package/src/execution/engine/agent/reasoning/processor.ts +92 -92
  107. package/src/execution/engine/agent/reasoning/prompt-sections/base-actions.ts +134 -134
  108. package/src/execution/engine/agent/reasoning/prompt-sections/completion.ts +49 -49
  109. package/src/execution/engine/agent/reasoning/prompt-sections/knowledge-map.ts +93 -93
  110. package/src/execution/engine/agent/reasoning/prompt-sections/memory.ts +65 -65
  111. package/src/execution/engine/agent/reasoning/prompt-sections/tools.ts +44 -44
  112. package/src/execution/engine/agent/reasoning/request-builder.ts +169 -169
  113. package/src/execution/engine/agent/reasoning/types.ts +18 -18
  114. package/src/execution/engine/base/errors.ts +118 -118
  115. package/src/execution/engine/base/index.ts +2 -2
  116. package/src/execution/engine/base/logging.ts +31 -31
  117. package/src/execution/engine/base/serialization.ts +324 -324
  118. package/src/execution/engine/base/types.ts +126 -126
  119. package/src/execution/engine/base/utils.ts +41 -41
  120. package/src/execution/engine/index.ts +434 -434
  121. package/src/execution/engine/interface/index.ts +1 -1
  122. package/src/execution/engine/interface/types.ts +62 -62
  123. package/src/execution/engine/llm/__tests__/model-info.test.ts +50 -50
  124. package/src/execution/engine/llm/__tests__/model-validation.test.ts +321 -321
  125. package/src/execution/engine/llm/__tests__/response-schema-validator.test.ts +115 -115
  126. package/src/execution/engine/llm/adapters/__tests__/adapter-factory.test.ts +375 -375
  127. package/src/execution/engine/llm/adapters/__tests__/anthropic-adapter.test.ts +463 -463
  128. package/src/execution/engine/llm/adapters/__tests__/anthropic.integration.test.ts +177 -177
  129. package/src/execution/engine/llm/adapters/__tests__/google-adapter.test.ts +722 -722
  130. package/src/execution/engine/llm/adapters/__tests__/google.integration.test.ts +376 -376
  131. package/src/execution/engine/llm/adapters/__tests__/openai-adapter.test.ts +551 -551
  132. package/src/execution/engine/llm/adapters/__tests__/openrouter-adapter.test.ts +563 -563
  133. package/src/execution/engine/llm/adapters/__tests__/openrouter.integration.test.ts +105 -105
  134. package/src/execution/engine/llm/adapters/__tests__/universal-adapter.test.ts +537 -537
  135. package/src/execution/engine/llm/adapters/circuit-breaker.ts +147 -147
  136. package/src/execution/engine/llm/adapters/index.ts +17 -17
  137. package/src/execution/engine/llm/adapters/mock-adapter.ts +116 -116
  138. package/src/execution/engine/llm/adapters/server/adapter-factory.ts +130 -130
  139. package/src/execution/engine/llm/adapters/server/anthropic.ts +137 -137
  140. package/src/execution/engine/llm/adapters/server/google.ts +283 -283
  141. package/src/execution/engine/llm/adapters/server/index.ts +12 -12
  142. package/src/execution/engine/llm/adapters/server/openai.ts +206 -206
  143. package/src/execution/engine/llm/adapters/server/openrouter.ts +235 -235
  144. package/src/execution/engine/llm/adapters/universal-adapter.ts +230 -230
  145. package/src/execution/engine/llm/errors.ts +186 -186
  146. package/src/execution/engine/llm/model-info.ts +332 -332
  147. package/src/execution/engine/llm/response-schema-validator.ts +113 -113
  148. package/src/execution/engine/llm/types.ts +86 -86
  149. package/src/execution/engine/test-utils/index.ts +6 -6
  150. package/src/execution/engine/test-utils/mocks.ts +56 -56
  151. package/src/execution/engine/tools/integration/base-integration-adapter.ts +50 -50
  152. package/src/execution/engine/tools/integration/index.ts +53 -53
  153. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-adapter.ts +73 -73
  154. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-tools.ts +209 -209
  155. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-company-email/index.ts +82 -82
  156. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-decision-maker-email/index.ts +122 -122
  157. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-person-email/index.ts +89 -89
  158. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/verify-email/index.ts +84 -84
  159. package/src/execution/engine/tools/integration/server/adapters/anymailfinder/index.ts +16 -16
  160. package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +293 -293
  161. package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.ts +100 -100
  162. package/src/execution/engine/tools/integration/server/adapters/apify/apify-tools.ts +217 -217
  163. package/src/execution/engine/tools/integration/server/adapters/apify/fetch/get-dataset-items/index.ts +92 -92
  164. package/src/execution/engine/tools/integration/server/adapters/apify/fetch/run-actor/index.ts +218 -218
  165. package/src/execution/engine/tools/integration/server/adapters/apify/fetch/start-actor/index.ts +87 -87
  166. package/src/execution/engine/tools/integration/server/adapters/apify/index.ts +11 -11
  167. package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +361 -361
  168. package/src/execution/engine/tools/integration/server/adapters/attio/attio-adapter.ts +162 -162
  169. package/src/execution/engine/tools/integration/server/adapters/attio/attio-tools.ts +594 -594
  170. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-attribute/index.ts +214 -214
  171. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-note/index.ts +152 -152
  172. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-record/index.ts +141 -141
  173. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-note/index.ts +86 -86
  174. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-record/index.ts +105 -105
  175. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.ts +118 -118
  176. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-attributes/index.ts +165 -165
  177. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-notes/index.ts +96 -96
  178. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-objects/index.ts +104 -104
  179. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.ts +156 -156
  180. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-attribute/index.ts +220 -220
  181. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-record/index.ts +140 -140
  182. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/utils/types.ts +146 -146
  183. package/src/execution/engine/tools/integration/server/adapters/attio/index.ts +31 -31
  184. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +210 -210
  185. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +104 -104
  186. package/src/execution/engine/tools/integration/server/adapters/google-sheets/__tests__/google-sheets.integration.test.ts +261 -261
  187. package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-adapter.ts +1189 -1189
  188. package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-tools.ts +641 -641
  189. package/src/execution/engine/tools/integration/server/adapters/google-sheets/index.ts +18 -18
  190. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/activate-campaign/index.ts +86 -86
  191. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/__tests__/index.test.ts +289 -289
  192. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/index.ts +154 -154
  193. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/__tests__/index.test.ts +325 -325
  194. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/index.ts +153 -153
  195. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-delete-leads/index.ts +84 -84
  196. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-campaign/index.ts +125 -125
  197. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-inbox-test/index.ts +107 -107
  198. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/delete-campaign/index.ts +85 -85
  199. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-account-health/index.ts +91 -91
  200. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign/index.ts +92 -92
  201. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/__tests__/index.test.ts +195 -195
  202. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/index.ts +113 -113
  203. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-daily-campaign-analytics/index.ts +104 -104
  204. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-emails/index.ts +155 -155
  205. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/__tests__/index.test.ts +196 -196
  206. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/index.ts +102 -102
  207. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/__tests__/index.test.ts +189 -189
  208. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/index.ts +87 -87
  209. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-leads/index.ts +112 -112
  210. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/patch-lead/index.ts +76 -76
  211. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/pause-campaign/index.ts +86 -86
  212. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/remove-from-subsequence/index.ts +98 -98
  213. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/send-reply/index.ts +126 -126
  214. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/__tests__/index.test.ts +193 -193
  215. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/index.ts +99 -99
  216. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/__tests__/index.test.ts +621 -621
  217. package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/index.ts +125 -125
  218. package/src/execution/engine/tools/integration/server/adapters/instantly/index.ts +29 -29
  219. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-adapter.ts +178 -178
  220. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1473 -1473
  221. package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/check-credits/index.ts +59 -59
  222. package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/verify-email/index.ts +102 -102
  223. package/src/execution/engine/tools/integration/server/adapters/millionverifier/index.ts +17 -17
  224. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-adapter.ts +80 -80
  225. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +102 -102
  226. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/get-email/index.ts +102 -102
  227. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +134 -134
  228. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +75 -75
  229. package/src/execution/engine/tools/integration/server/adapters/resend/index.ts +27 -27
  230. package/src/execution/engine/tools/integration/server/adapters/resend/resend-adapter.ts +108 -108
  231. package/src/execution/engine/tools/integration/server/adapters/resend/resend-tools.ts +132 -132
  232. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/create-envelope/index.ts +274 -274
  233. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/download-document/index.ts +230 -230
  234. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/get-envelope/index.ts +133 -133
  235. package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/void-envelope/index.ts +90 -90
  236. package/src/execution/engine/tools/integration/server/adapters/stripe/fetch/utils/types.ts +210 -210
  237. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-adapter.ts +517 -517
  238. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +309 -309
  239. package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/domain-search/index.ts +133 -133
  240. package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-finder/index.ts +122 -122
  241. package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-verifier/index.ts +111 -111
  242. package/src/execution/engine/tools/integration/server/adapters/tomba/index.ts +11 -11
  243. package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-adapter.ts +78 -78
  244. package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-tools.ts +222 -222
  245. package/src/execution/engine/tools/integration/server/index.ts +61 -61
  246. package/src/execution/engine/tools/integration/service.ts +161 -161
  247. package/src/execution/engine/tools/integration/tool.ts +253 -253
  248. package/src/execution/engine/tools/integration/types/anymailfinder.ts +74 -74
  249. package/src/execution/engine/tools/integration/types/apify.ts +92 -92
  250. package/src/execution/engine/tools/integration/types/index.ts +19 -19
  251. package/src/execution/engine/tools/integration/types/instantly.ts +557 -557
  252. package/src/execution/engine/tools/integration/types/millionverifier.ts +56 -56
  253. package/src/execution/engine/tools/integration/types/stripe.ts +162 -162
  254. package/src/execution/engine/tools/integration/types/tomba.ts +94 -94
  255. package/src/execution/engine/tools/lead-service-types.ts +884 -884
  256. package/src/execution/engine/tools/llm/index.ts +11 -11
  257. package/src/execution/engine/tools/llm/server/index.ts +8 -8
  258. package/src/execution/engine/tools/llm/server/llm-call-tool.ts +118 -118
  259. package/src/execution/engine/tools/platform/__tests__/pdf.test.ts +441 -441
  260. package/src/execution/engine/tools/platform/acquisition/company-tools.ts +248 -248
  261. package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +319 -319
  262. package/src/execution/engine/tools/platform/acquisition/index.ts +43 -43
  263. package/src/execution/engine/tools/platform/acquisition/list-tools.ts +148 -148
  264. package/src/execution/engine/tools/platform/acquisition/types.ts +260 -260
  265. package/src/execution/engine/tools/platform/email/index.ts +122 -122
  266. package/src/execution/engine/tools/platform/email/types.ts +96 -96
  267. package/src/execution/engine/tools/platform/index.ts +157 -157
  268. package/src/execution/engine/tools/platform/notification.ts +81 -81
  269. package/src/execution/engine/tools/platform/pdf/index.ts +110 -110
  270. package/src/execution/engine/tools/platform/pdf/types.ts +77 -77
  271. package/src/execution/engine/tools/platform/scheduler.ts +87 -87
  272. package/src/execution/engine/tools/platform/storage/index.ts +370 -370
  273. package/src/execution/engine/tools/platform/types.ts +148 -148
  274. package/src/execution/engine/tools/registry.ts +700 -699
  275. package/src/execution/engine/tools/tool-maps.ts +786 -786
  276. package/src/execution/engine/tools/types.ts +233 -233
  277. package/src/execution/engine/workflow/__tests__/errors.test.ts +139 -139
  278. package/src/execution/engine/workflow/errors.ts +63 -63
  279. package/src/execution/engine/workflow/helpers/index.ts +11 -11
  280. package/src/execution/engine/workflow/helpers/server/index.ts +8 -8
  281. package/src/execution/engine/workflow/helpers/server/llm-call.ts +93 -93
  282. package/src/execution/engine/workflow/index.ts +19 -19
  283. package/src/execution/engine/workflow/log-truncate.ts +26 -26
  284. package/src/execution/engine/workflow/logging.ts +191 -191
  285. package/src/execution/engine/workflow/types.ts +182 -182
  286. package/src/execution/engine/workflow/utils.ts +280 -280
  287. package/src/execution/engine/workflow/workflow.ts +168 -168
  288. package/src/execution/index.ts +3 -3
  289. package/src/execution/scheduler/__tests__/api-schemas.test.ts +733 -733
  290. package/src/execution/scheduler/__tests__/utils.test.ts +1009 -1009
  291. package/src/execution/scheduler/api-schemas.ts +296 -296
  292. package/src/execution/scheduler/index.ts +50 -50
  293. package/src/execution/scheduler/schemas.ts +264 -264
  294. package/src/execution/scheduler/types.ts +111 -111
  295. package/src/execution/scheduler/utils.ts +364 -364
  296. package/src/forms/index.ts +7 -7
  297. package/src/forms/schemas.ts +69 -69
  298. package/src/forms/types.ts +70 -70
  299. package/src/index.ts +71 -60
  300. package/src/integrations/credentials/__tests__/schemas.test.ts +82 -82
  301. package/src/integrations/credentials/__tests__/utils.test.ts +144 -144
  302. package/src/integrations/credentials/api-schemas.ts +143 -143
  303. package/src/integrations/credentials/index.ts +32 -32
  304. package/src/integrations/credentials/schemas.ts +164 -164
  305. package/src/integrations/credentials/utils.ts +59 -59
  306. package/src/integrations/oauth/__tests__/provider-registry.test.ts +59 -59
  307. package/src/integrations/oauth/api-schemas.ts +92 -92
  308. package/src/integrations/oauth/index.ts +19 -19
  309. package/src/integrations/oauth/provider-registry.ts +61 -61
  310. package/src/integrations/oauth/server/__tests__/refresh-concurrent.test.ts +183 -183
  311. package/src/integrations/oauth/server/__tests__/refresh.test.ts +577 -577
  312. package/src/integrations/oauth/server/credentials.ts +39 -39
  313. package/src/integrations/oauth/server/refresh.ts +214 -214
  314. package/src/integrations/oauth/types.ts +34 -34
  315. package/src/integrations/webhook-endpoints/__tests__/api-schemas.test.ts +318 -318
  316. package/src/integrations/webhook-endpoints/api-schemas.ts +102 -102
  317. package/src/integrations/webhook-endpoints/index.ts +28 -28
  318. package/src/integrations/webhook-endpoints/types.ts +51 -51
  319. package/src/operations/activities/api-schemas.ts +79 -79
  320. package/src/operations/activities/index.ts +9 -9
  321. package/src/operations/activities/sse-events.ts +30 -30
  322. package/src/operations/activities/types.ts +63 -63
  323. package/src/operations/debug-logs/client.ts +60 -60
  324. package/src/operations/debug-logs/debug-logger.ts +83 -83
  325. package/src/operations/debug-logs/index.ts +8 -8
  326. package/src/operations/debug-logs/server.ts +19 -19
  327. package/src/operations/debug-logs/types.ts +33 -33
  328. package/src/operations/index.ts +50 -50
  329. package/src/operations/notifications/api-schemas.ts +91 -91
  330. package/src/operations/notifications/index.ts +3 -3
  331. package/src/operations/notifications/sse-events.ts +21 -21
  332. package/src/operations/notifications/types.ts +47 -47
  333. package/src/operations/observability/__tests__/openrouter-cost-flow.test.ts +297 -297
  334. package/src/operations/observability/__tests__/utils.test.ts +54 -54
  335. package/src/operations/observability/ai-usage-collector.ts +64 -64
  336. package/src/operations/observability/index.ts +13 -13
  337. package/src/operations/observability/metrics-collector.ts +49 -49
  338. package/src/operations/observability/schemas.ts +39 -39
  339. package/src/operations/observability/types.ts +463 -463
  340. package/src/operations/observability/utils.ts +77 -77
  341. package/src/operations/sessions/__tests__/manager.test.ts +821 -821
  342. package/src/operations/sessions/index.ts +26 -26
  343. package/src/operations/sessions/server/manager.ts +90 -90
  344. package/src/operations/sessions/server/session.ts +180 -180
  345. package/src/operations/sessions/types.ts +98 -98
  346. package/src/operations/triggers/index.ts +12 -12
  347. package/src/operations/triggers/webhook/definitions/instantly-account-error.ts +44 -44
  348. package/src/operations/triggers/webhook/definitions/instantly-auto-reply-received.ts +51 -51
  349. package/src/operations/triggers/webhook/definitions/instantly-campaign-completed.ts +45 -45
  350. package/src/operations/triggers/webhook/definitions/instantly-email-bounced.ts +49 -49
  351. package/src/operations/triggers/webhook/definitions/instantly-lead-unsubscribed.ts +45 -45
  352. package/src/operations/triggers/webhook/definitions/instantly-reply-received.ts +54 -54
  353. package/src/operations/triggers/webhook/index.ts +35 -35
  354. package/src/operations/triggers/webhook/types.ts +74 -74
  355. package/src/organization-model/README.md +97 -97
  356. package/src/organization-model/__tests__/defaults.test.ts +175 -175
  357. package/src/organization-model/__tests__/domains/customers.test.ts +295 -295
  358. package/src/organization-model/__tests__/domains/goals.test.ts +479 -479
  359. package/src/organization-model/__tests__/domains/identity.test.ts +279 -279
  360. package/src/organization-model/__tests__/domains/navigation.test.ts +212 -212
  361. package/src/organization-model/__tests__/domains/offerings.test.ts +419 -419
  362. package/src/organization-model/__tests__/domains/operations.test.ts +203 -203
  363. package/src/organization-model/__tests__/domains/resource-mappings.test.ts +362 -362
  364. package/src/organization-model/__tests__/domains/roles.test.ts +347 -347
  365. package/src/organization-model/__tests__/domains/statuses.test.ts +243 -243
  366. package/src/organization-model/__tests__/foundation.test.ts +105 -105
  367. package/src/organization-model/__tests__/graph.test.ts +894 -894
  368. package/src/organization-model/__tests__/resolve.test.ts +690 -690
  369. package/src/organization-model/__tests__/schema.test.ts +407 -407
  370. package/src/organization-model/contracts.ts +14 -14
  371. package/src/organization-model/defaults.ts +148 -148
  372. package/src/organization-model/domains/branding.ts +22 -22
  373. package/src/organization-model/domains/customers.ts +75 -75
  374. package/src/organization-model/domains/features.ts +22 -22
  375. package/src/organization-model/domains/goals.ts +80 -80
  376. package/src/organization-model/domains/identity.ts +94 -94
  377. package/src/organization-model/domains/navigation.ts +391 -391
  378. package/src/organization-model/domains/offerings.ts +66 -66
  379. package/src/organization-model/domains/operations.ts +85 -85
  380. package/src/organization-model/domains/projects.ts +48 -48
  381. package/src/organization-model/domains/prospecting.ts +33 -33
  382. package/src/organization-model/domains/roles.ts +55 -55
  383. package/src/organization-model/domains/sales.ts +94 -94
  384. package/src/organization-model/domains/shared.ts +62 -62
  385. package/src/organization-model/domains/statuses.ts +130 -130
  386. package/src/organization-model/foundation.ts +97 -97
  387. package/src/organization-model/graph/build.ts +399 -399
  388. package/src/organization-model/graph/index.ts +4 -4
  389. package/src/organization-model/graph/schema.ts +48 -48
  390. package/src/organization-model/graph/types.ts +40 -40
  391. package/src/organization-model/index.ts +13 -13
  392. package/src/organization-model/organization-graph.mdx +272 -272
  393. package/src/organization-model/organization-model.mdx +320 -320
  394. package/src/organization-model/published.ts +85 -85
  395. package/src/organization-model/resolve.ts +66 -66
  396. package/src/organization-model/schema.ts +287 -287
  397. package/src/organization-model/types.ts +46 -46
  398. package/src/platform/api/index.ts +1 -1
  399. package/src/platform/api/types.ts +35 -35
  400. package/src/platform/constants/http.ts +37 -37
  401. package/src/platform/constants/index.ts +5 -5
  402. package/src/platform/constants/limits.ts +32 -32
  403. package/src/platform/constants/resilience.ts +51 -51
  404. package/src/platform/constants/timeouts.ts +20 -20
  405. package/src/platform/constants/versions.ts +3 -3
  406. package/src/platform/registry/__tests__/resource-registry-static.test.ts +347 -347
  407. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +1028 -1028
  408. package/src/platform/registry/__tests__/resource-registry.list-executable.test.ts +393 -393
  409. package/src/platform/registry/__tests__/resource-registry.test.ts +2005 -2005
  410. package/src/platform/registry/__tests__/serialization.test.ts +1127 -1127
  411. package/src/platform/registry/command-view.ts +180 -180
  412. package/src/platform/registry/domains.ts +165 -165
  413. package/src/platform/registry/index.ts +93 -93
  414. package/src/platform/registry/reserved.ts +24 -24
  415. package/src/platform/registry/resource-metadata.ts +59 -59
  416. package/src/platform/registry/resource-registry.command-queue-groups.test.ts +129 -129
  417. package/src/platform/registry/resource-registry.ts +876 -876
  418. package/src/platform/registry/serialization.ts +273 -273
  419. package/src/platform/registry/serialized-types.ts +231 -231
  420. package/src/platform/registry/stats-types.ts +66 -66
  421. package/src/platform/registry/types.ts +404 -404
  422. package/src/platform/registry/validation.ts +513 -513
  423. package/src/platform/resilience/__tests__/rate-limiter.test.ts +471 -471
  424. package/src/platform/resilience/circuit-breaker.ts +164 -164
  425. package/src/platform/resilience/errors.ts +68 -68
  426. package/src/platform/resilience/http-error-mapper.ts +129 -129
  427. package/src/platform/resilience/index.ts +93 -93
  428. package/src/platform/resilience/rate-limiter-types.ts +46 -46
  429. package/src/platform/resilience/rate-limiter.ts +140 -140
  430. package/src/platform/resilience/retry.ts +89 -89
  431. package/src/platform/resilience/timeout.ts +63 -63
  432. package/src/platform/sse/events.ts +37 -34
  433. package/src/platform/sse/index.ts +7 -7
  434. package/src/platform/utils/__tests__/validation.test.ts +1083 -1083
  435. package/src/platform/utils/currency.ts +96 -96
  436. package/src/platform/utils/debounce.ts +52 -52
  437. package/src/platform/utils/error.ts +41 -41
  438. package/src/platform/utils/hmac.test.ts +97 -97
  439. package/src/platform/utils/index.ts +32 -32
  440. package/src/platform/utils/server/betterstack-logger.ts +210 -210
  441. package/src/platform/utils/server/hmac.ts +44 -44
  442. package/src/platform/utils/server/unsubscribe.ts +111 -111
  443. package/src/platform/utils/token-counter.ts +96 -96
  444. package/src/platform/utils/validation.ts +425 -425
  445. package/src/projects/api-schemas.ts +268 -268
  446. package/src/published.ts +1 -1
  447. package/src/reference/_generated/contracts.md +611 -607
  448. package/src/reference/glossary.md +105 -105
  449. package/src/requests/__tests__/api-schemas.test.ts +277 -277
  450. package/src/requests/api-schemas.ts +83 -83
  451. package/src/requests/index.ts +1 -1
  452. package/src/scaffold-registry/__tests__/index.test.ts +17 -0
  453. package/src/scaffold-registry/__tests__/schema.test.ts +329 -230
  454. package/src/scaffold-registry/index.ts +205 -189
  455. package/src/scaffold-registry/schema.ts +196 -128
  456. package/src/server.ts +272 -272
  457. package/src/supabase/database.types.ts +2719 -2719
  458. package/src/supabase/helpers.ts +20 -20
  459. package/src/supabase/index.ts +52 -52
  460. package/src/supabase/server/client.ts +58 -58
  461. package/src/test-utils/README.md +38 -38
  462. package/src/test-utils/browser-mocks.ts +54 -54
  463. package/src/test-utils/fixtures/api-keys.ts +52 -52
  464. package/src/test-utils/fixtures/index.ts +4 -4
  465. package/src/test-utils/fixtures/memberships.ts +80 -80
  466. package/src/test-utils/fixtures/organizations.ts +69 -69
  467. package/src/test-utils/fixtures/users.ts +79 -79
  468. package/src/test-utils/index.ts +11 -11
  469. package/src/test-utils/mocks/index.ts +2 -2
  470. package/src/test-utils/mocks/supabase.ts +142 -142
  471. package/src/test-utils/mocks/workos.ts +108 -108
  472. package/src/test-utils/rls/RLSTestContext.ts +556 -556
  473. 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
+ }