@agentuity/runtime 2.0.11 → 3.0.0-alpha.1

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 (415) hide show
  1. package/dist/index.d.ts +37 -65
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +59 -61
  4. package/dist/index.js.map +1 -1
  5. package/package.json +9 -38
  6. package/src/index.ts +58 -259
  7. package/AGENTS.md +0 -116
  8. package/dist/_config.d.ts +0 -100
  9. package/dist/_config.d.ts.map +0 -1
  10. package/dist/_config.js +0 -147
  11. package/dist/_config.js.map +0 -1
  12. package/dist/_context.d.ts +0 -80
  13. package/dist/_context.d.ts.map +0 -1
  14. package/dist/_context.js +0 -160
  15. package/dist/_context.js.map +0 -1
  16. package/dist/_events.d.ts +0 -64
  17. package/dist/_events.d.ts.map +0 -1
  18. package/dist/_events.js +0 -92
  19. package/dist/_events.js.map +0 -1
  20. package/dist/_globals.d.ts +0 -58
  21. package/dist/_globals.d.ts.map +0 -1
  22. package/dist/_globals.js +0 -71
  23. package/dist/_globals.js.map +0 -1
  24. package/dist/_idle.d.ts +0 -7
  25. package/dist/_idle.d.ts.map +0 -1
  26. package/dist/_idle.js +0 -10
  27. package/dist/_idle.js.map +0 -1
  28. package/dist/_metadata.d.ts +0 -117
  29. package/dist/_metadata.d.ts.map +0 -1
  30. package/dist/_metadata.js +0 -268
  31. package/dist/_metadata.js.map +0 -1
  32. package/dist/_process-protection.d.ts +0 -27
  33. package/dist/_process-protection.d.ts.map +0 -1
  34. package/dist/_process-protection.js +0 -56
  35. package/dist/_process-protection.js.map +0 -1
  36. package/dist/_server.d.ts +0 -50
  37. package/dist/_server.d.ts.map +0 -1
  38. package/dist/_server.js +0 -89
  39. package/dist/_server.js.map +0 -1
  40. package/dist/_services.d.ts +0 -25
  41. package/dist/_services.d.ts.map +0 -1
  42. package/dist/_services.js +0 -286
  43. package/dist/_services.js.map +0 -1
  44. package/dist/_standalone.d.ts +0 -212
  45. package/dist/_standalone.d.ts.map +0 -1
  46. package/dist/_standalone.js +0 -556
  47. package/dist/_standalone.js.map +0 -1
  48. package/dist/_tokens.d.ts +0 -12
  49. package/dist/_tokens.d.ts.map +0 -1
  50. package/dist/_tokens.js +0 -97
  51. package/dist/_tokens.js.map +0 -1
  52. package/dist/_util.d.ts +0 -16
  53. package/dist/_util.d.ts.map +0 -1
  54. package/dist/_util.js +0 -54
  55. package/dist/_util.js.map +0 -1
  56. package/dist/_validation.d.ts +0 -89
  57. package/dist/_validation.d.ts.map +0 -1
  58. package/dist/_validation.js +0 -29
  59. package/dist/_validation.js.map +0 -1
  60. package/dist/_waituntil.d.ts +0 -32
  61. package/dist/_waituntil.d.ts.map +0 -1
  62. package/dist/_waituntil.js +0 -156
  63. package/dist/_waituntil.js.map +0 -1
  64. package/dist/agent.d.ts +0 -1262
  65. package/dist/agent.d.ts.map +0 -1
  66. package/dist/agent.js +0 -981
  67. package/dist/agent.js.map +0 -1
  68. package/dist/app.d.ts +0 -514
  69. package/dist/app.d.ts.map +0 -1
  70. package/dist/app.js +0 -228
  71. package/dist/app.js.map +0 -1
  72. package/dist/bootstrap.d.ts +0 -44
  73. package/dist/bootstrap.d.ts.map +0 -1
  74. package/dist/bootstrap.js +0 -259
  75. package/dist/bootstrap.js.map +0 -1
  76. package/dist/bun-s3-patch.d.ts +0 -37
  77. package/dist/bun-s3-patch.d.ts.map +0 -1
  78. package/dist/bun-s3-patch.js +0 -142
  79. package/dist/bun-s3-patch.js.map +0 -1
  80. package/dist/cors.d.ts +0 -42
  81. package/dist/cors.d.ts.map +0 -1
  82. package/dist/cors.js +0 -117
  83. package/dist/cors.js.map +0 -1
  84. package/dist/dev-patches/aisdk.d.ts +0 -17
  85. package/dist/dev-patches/aisdk.d.ts.map +0 -1
  86. package/dist/dev-patches/aisdk.js +0 -160
  87. package/dist/dev-patches/aisdk.js.map +0 -1
  88. package/dist/dev-patches/gateway.d.ts +0 -16
  89. package/dist/dev-patches/gateway.d.ts.map +0 -1
  90. package/dist/dev-patches/gateway.js +0 -54
  91. package/dist/dev-patches/gateway.js.map +0 -1
  92. package/dist/dev-patches/index.d.ts +0 -21
  93. package/dist/dev-patches/index.d.ts.map +0 -1
  94. package/dist/dev-patches/index.js +0 -33
  95. package/dist/dev-patches/index.js.map +0 -1
  96. package/dist/dev-patches/otel-llm.d.ts +0 -12
  97. package/dist/dev-patches/otel-llm.d.ts.map +0 -1
  98. package/dist/dev-patches/otel-llm.js +0 -352
  99. package/dist/dev-patches/otel-llm.js.map +0 -1
  100. package/dist/devmode.d.ts +0 -3
  101. package/dist/devmode.d.ts.map +0 -1
  102. package/dist/devmode.js +0 -167
  103. package/dist/devmode.js.map +0 -1
  104. package/dist/eval.d.ts +0 -91
  105. package/dist/eval.d.ts.map +0 -1
  106. package/dist/eval.js +0 -16
  107. package/dist/eval.js.map +0 -1
  108. package/dist/handlers/_route-meta.d.ts +0 -22
  109. package/dist/handlers/_route-meta.d.ts.map +0 -1
  110. package/dist/handlers/_route-meta.js +0 -25
  111. package/dist/handlers/_route-meta.js.map +0 -1
  112. package/dist/handlers/cron.d.ts +0 -73
  113. package/dist/handlers/cron.d.ts.map +0 -1
  114. package/dist/handlers/cron.js +0 -43
  115. package/dist/handlers/cron.js.map +0 -1
  116. package/dist/handlers/index.d.ts +0 -6
  117. package/dist/handlers/index.d.ts.map +0 -1
  118. package/dist/handlers/index.js +0 -6
  119. package/dist/handlers/index.js.map +0 -1
  120. package/dist/handlers/sse.d.ts +0 -163
  121. package/dist/handlers/sse.d.ts.map +0 -1
  122. package/dist/handlers/sse.js +0 -175
  123. package/dist/handlers/sse.js.map +0 -1
  124. package/dist/handlers/stream.d.ts +0 -52
  125. package/dist/handlers/stream.d.ts.map +0 -1
  126. package/dist/handlers/stream.js +0 -108
  127. package/dist/handlers/stream.js.map +0 -1
  128. package/dist/handlers/webrtc.d.ts +0 -49
  129. package/dist/handlers/webrtc.d.ts.map +0 -1
  130. package/dist/handlers/webrtc.js +0 -109
  131. package/dist/handlers/webrtc.js.map +0 -1
  132. package/dist/handlers/websocket.d.ts +0 -88
  133. package/dist/handlers/websocket.d.ts.map +0 -1
  134. package/dist/handlers/websocket.js +0 -161
  135. package/dist/handlers/websocket.js.map +0 -1
  136. package/dist/logger/console.d.ts +0 -70
  137. package/dist/logger/console.d.ts.map +0 -1
  138. package/dist/logger/console.js +0 -278
  139. package/dist/logger/console.js.map +0 -1
  140. package/dist/logger/index.d.ts +0 -3
  141. package/dist/logger/index.d.ts.map +0 -1
  142. package/dist/logger/index.js +0 -3
  143. package/dist/logger/index.js.map +0 -1
  144. package/dist/logger/internal.d.ts +0 -79
  145. package/dist/logger/internal.d.ts.map +0 -1
  146. package/dist/logger/internal.js +0 -133
  147. package/dist/logger/internal.js.map +0 -1
  148. package/dist/logger/logger.d.ts +0 -41
  149. package/dist/logger/logger.d.ts.map +0 -1
  150. package/dist/logger/logger.js +0 -2
  151. package/dist/logger/logger.js.map +0 -1
  152. package/dist/logger/user.d.ts +0 -8
  153. package/dist/logger/user.d.ts.map +0 -1
  154. package/dist/logger/user.js +0 -7
  155. package/dist/logger/user.js.map +0 -1
  156. package/dist/logger/util.d.ts +0 -11
  157. package/dist/logger/util.d.ts.map +0 -1
  158. package/dist/logger/util.js +0 -77
  159. package/dist/logger/util.js.map +0 -1
  160. package/dist/middleware.d.ts +0 -105
  161. package/dist/middleware.d.ts.map +0 -1
  162. package/dist/middleware.js +0 -763
  163. package/dist/middleware.js.map +0 -1
  164. package/dist/otel/config.d.ts +0 -19
  165. package/dist/otel/config.d.ts.map +0 -1
  166. package/dist/otel/config.js +0 -26
  167. package/dist/otel/config.js.map +0 -1
  168. package/dist/otel/console.d.ts +0 -33
  169. package/dist/otel/console.d.ts.map +0 -1
  170. package/dist/otel/console.js +0 -86
  171. package/dist/otel/console.js.map +0 -1
  172. package/dist/otel/exporters/index.d.ts +0 -4
  173. package/dist/otel/exporters/index.d.ts.map +0 -1
  174. package/dist/otel/exporters/index.js +0 -4
  175. package/dist/otel/exporters/index.js.map +0 -1
  176. package/dist/otel/exporters/jsonl-log-exporter.d.ts +0 -36
  177. package/dist/otel/exporters/jsonl-log-exporter.d.ts.map +0 -1
  178. package/dist/otel/exporters/jsonl-log-exporter.js +0 -103
  179. package/dist/otel/exporters/jsonl-log-exporter.js.map +0 -1
  180. package/dist/otel/exporters/jsonl-metric-exporter.d.ts +0 -40
  181. package/dist/otel/exporters/jsonl-metric-exporter.d.ts.map +0 -1
  182. package/dist/otel/exporters/jsonl-metric-exporter.js +0 -104
  183. package/dist/otel/exporters/jsonl-metric-exporter.js.map +0 -1
  184. package/dist/otel/exporters/jsonl-trace-exporter.d.ts +0 -36
  185. package/dist/otel/exporters/jsonl-trace-exporter.d.ts.map +0 -1
  186. package/dist/otel/exporters/jsonl-trace-exporter.js +0 -111
  187. package/dist/otel/exporters/jsonl-trace-exporter.js.map +0 -1
  188. package/dist/otel/fetch.d.ts +0 -12
  189. package/dist/otel/fetch.d.ts.map +0 -1
  190. package/dist/otel/fetch.js +0 -82
  191. package/dist/otel/fetch.js.map +0 -1
  192. package/dist/otel/http.d.ts +0 -16
  193. package/dist/otel/http.d.ts.map +0 -1
  194. package/dist/otel/http.js +0 -44
  195. package/dist/otel/http.js.map +0 -1
  196. package/dist/otel/logger.d.ts +0 -37
  197. package/dist/otel/logger.d.ts.map +0 -1
  198. package/dist/otel/logger.js +0 -265
  199. package/dist/otel/logger.js.map +0 -1
  200. package/dist/otel/otel.d.ts +0 -68
  201. package/dist/otel/otel.d.ts.map +0 -1
  202. package/dist/otel/otel.js +0 -245
  203. package/dist/otel/otel.js.map +0 -1
  204. package/dist/otel/tracestate.d.ts +0 -44
  205. package/dist/otel/tracestate.d.ts.map +0 -1
  206. package/dist/otel/tracestate.js +0 -84
  207. package/dist/otel/tracestate.js.map +0 -1
  208. package/dist/router.d.ts +0 -66
  209. package/dist/router.d.ts.map +0 -1
  210. package/dist/router.js +0 -44
  211. package/dist/router.js.map +0 -1
  212. package/dist/services/evalrun/composite.d.ts +0 -21
  213. package/dist/services/evalrun/composite.d.ts.map +0 -1
  214. package/dist/services/evalrun/composite.js +0 -26
  215. package/dist/services/evalrun/composite.js.map +0 -1
  216. package/dist/services/evalrun/http.d.ts +0 -24
  217. package/dist/services/evalrun/http.d.ts.map +0 -1
  218. package/dist/services/evalrun/http.js +0 -115
  219. package/dist/services/evalrun/http.js.map +0 -1
  220. package/dist/services/evalrun/index.d.ts +0 -5
  221. package/dist/services/evalrun/index.d.ts.map +0 -1
  222. package/dist/services/evalrun/index.js +0 -5
  223. package/dist/services/evalrun/index.js.map +0 -1
  224. package/dist/services/evalrun/json.d.ts +0 -21
  225. package/dist/services/evalrun/json.d.ts.map +0 -1
  226. package/dist/services/evalrun/json.js +0 -38
  227. package/dist/services/evalrun/json.js.map +0 -1
  228. package/dist/services/evalrun/local.d.ts +0 -19
  229. package/dist/services/evalrun/local.d.ts.map +0 -1
  230. package/dist/services/evalrun/local.js +0 -22
  231. package/dist/services/evalrun/local.js.map +0 -1
  232. package/dist/services/local/_db.d.ts +0 -4
  233. package/dist/services/local/_db.d.ts.map +0 -1
  234. package/dist/services/local/_db.js +0 -281
  235. package/dist/services/local/_db.js.map +0 -1
  236. package/dist/services/local/_router.d.ts +0 -3
  237. package/dist/services/local/_router.d.ts.map +0 -1
  238. package/dist/services/local/_router.js +0 -28
  239. package/dist/services/local/_router.js.map +0 -1
  240. package/dist/services/local/_util.d.ts +0 -18
  241. package/dist/services/local/_util.d.ts.map +0 -1
  242. package/dist/services/local/_util.js +0 -44
  243. package/dist/services/local/_util.js.map +0 -1
  244. package/dist/services/local/email.d.ts +0 -24
  245. package/dist/services/local/email.d.ts.map +0 -1
  246. package/dist/services/local/email.js +0 -58
  247. package/dist/services/local/email.js.map +0 -1
  248. package/dist/services/local/index.d.ts +0 -10
  249. package/dist/services/local/index.d.ts.map +0 -1
  250. package/dist/services/local/index.js +0 -10
  251. package/dist/services/local/index.js.map +0 -1
  252. package/dist/services/local/keyvalue.d.ts +0 -17
  253. package/dist/services/local/keyvalue.d.ts.map +0 -1
  254. package/dist/services/local/keyvalue.js +0 -133
  255. package/dist/services/local/keyvalue.js.map +0 -1
  256. package/dist/services/local/queue.d.ts +0 -10
  257. package/dist/services/local/queue.d.ts.map +0 -1
  258. package/dist/services/local/queue.js +0 -96
  259. package/dist/services/local/queue.js.map +0 -1
  260. package/dist/services/local/stream.d.ts +0 -12
  261. package/dist/services/local/stream.d.ts.map +0 -1
  262. package/dist/services/local/stream.js +0 -266
  263. package/dist/services/local/stream.js.map +0 -1
  264. package/dist/services/local/task.d.ts +0 -55
  265. package/dist/services/local/task.d.ts.map +0 -1
  266. package/dist/services/local/task.js +0 -1248
  267. package/dist/services/local/task.js.map +0 -1
  268. package/dist/services/local/vector.d.ts +0 -17
  269. package/dist/services/local/vector.d.ts.map +0 -1
  270. package/dist/services/local/vector.js +0 -303
  271. package/dist/services/local/vector.js.map +0 -1
  272. package/dist/services/sandbox/http.d.ts +0 -23
  273. package/dist/services/sandbox/http.d.ts.map +0 -1
  274. package/dist/services/sandbox/http.js +0 -327
  275. package/dist/services/sandbox/http.js.map +0 -1
  276. package/dist/services/sandbox/index.d.ts +0 -2
  277. package/dist/services/sandbox/index.d.ts.map +0 -1
  278. package/dist/services/sandbox/index.js +0 -2
  279. package/dist/services/sandbox/index.js.map +0 -1
  280. package/dist/services/session/composite.d.ts +0 -21
  281. package/dist/services/session/composite.d.ts.map +0 -1
  282. package/dist/services/session/composite.js +0 -26
  283. package/dist/services/session/composite.js.map +0 -1
  284. package/dist/services/session/http.d.ts +0 -34
  285. package/dist/services/session/http.d.ts.map +0 -1
  286. package/dist/services/session/http.js +0 -124
  287. package/dist/services/session/http.js.map +0 -1
  288. package/dist/services/session/index.d.ts +0 -5
  289. package/dist/services/session/index.d.ts.map +0 -1
  290. package/dist/services/session/index.js +0 -5
  291. package/dist/services/session/index.js.map +0 -1
  292. package/dist/services/session/json.d.ts +0 -22
  293. package/dist/services/session/json.d.ts.map +0 -1
  294. package/dist/services/session/json.js +0 -35
  295. package/dist/services/session/json.js.map +0 -1
  296. package/dist/services/session/local.d.ts +0 -19
  297. package/dist/services/session/local.d.ts.map +0 -1
  298. package/dist/services/session/local.js +0 -23
  299. package/dist/services/session/local.js.map +0 -1
  300. package/dist/services/thread/local.d.ts +0 -20
  301. package/dist/services/thread/local.d.ts.map +0 -1
  302. package/dist/services/thread/local.js +0 -158
  303. package/dist/services/thread/local.js.map +0 -1
  304. package/dist/session.d.ts +0 -734
  305. package/dist/session.d.ts.map +0 -1
  306. package/dist/session.js +0 -1140
  307. package/dist/session.js.map +0 -1
  308. package/dist/signature.d.ts +0 -22
  309. package/dist/signature.d.ts.map +0 -1
  310. package/dist/signature.js +0 -63
  311. package/dist/signature.js.map +0 -1
  312. package/dist/validator.d.ts +0 -142
  313. package/dist/validator.d.ts.map +0 -1
  314. package/dist/validator.js +0 -149
  315. package/dist/validator.js.map +0 -1
  316. package/dist/version-check.d.ts +0 -20
  317. package/dist/version-check.d.ts.map +0 -1
  318. package/dist/version-check.js +0 -157
  319. package/dist/version-check.js.map +0 -1
  320. package/dist/web.d.ts +0 -8
  321. package/dist/web.d.ts.map +0 -1
  322. package/dist/web.js +0 -67
  323. package/dist/web.js.map +0 -1
  324. package/dist/webrtc-signaling.d.ts +0 -80
  325. package/dist/webrtc-signaling.d.ts.map +0 -1
  326. package/dist/webrtc-signaling.js +0 -237
  327. package/dist/webrtc-signaling.js.map +0 -1
  328. package/dist/workbench.d.ts +0 -17
  329. package/dist/workbench.d.ts.map +0 -1
  330. package/dist/workbench.js +0 -605
  331. package/dist/workbench.js.map +0 -1
  332. package/src/_config.ts +0 -163
  333. package/src/_context.ts +0 -240
  334. package/src/_events.ts +0 -142
  335. package/src/_globals.ts +0 -92
  336. package/src/_idle.ts +0 -10
  337. package/src/_metadata.ts +0 -407
  338. package/src/_process-protection.ts +0 -71
  339. package/src/_server.ts +0 -109
  340. package/src/_services.ts +0 -379
  341. package/src/_standalone.ts +0 -710
  342. package/src/_tokens.ts +0 -114
  343. package/src/_util.ts +0 -62
  344. package/src/_validation.ts +0 -119
  345. package/src/_waituntil.ts +0 -188
  346. package/src/agent.ts +0 -2739
  347. package/src/app.ts +0 -769
  348. package/src/bootstrap.ts +0 -321
  349. package/src/bun-s3-patch.ts +0 -224
  350. package/src/cors.ts +0 -137
  351. package/src/dev-patches/aisdk.ts +0 -169
  352. package/src/dev-patches/gateway.ts +0 -68
  353. package/src/dev-patches/index.ts +0 -37
  354. package/src/dev-patches/otel-llm.ts +0 -405
  355. package/src/devmode.ts +0 -171
  356. package/src/eval.ts +0 -109
  357. package/src/globals.d.ts +0 -28
  358. package/src/handlers/_route-meta.ts +0 -33
  359. package/src/handlers/cron.ts +0 -141
  360. package/src/handlers/index.ts +0 -18
  361. package/src/handlers/sse.ts +0 -358
  362. package/src/handlers/stream.ts +0 -121
  363. package/src/handlers/webrtc.ts +0 -125
  364. package/src/handlers/websocket.ts +0 -203
  365. package/src/logger/console.ts +0 -323
  366. package/src/logger/index.ts +0 -2
  367. package/src/logger/internal.ts +0 -165
  368. package/src/logger/logger.ts +0 -44
  369. package/src/logger/user.ts +0 -15
  370. package/src/logger/util.ts +0 -80
  371. package/src/middleware.ts +0 -1095
  372. package/src/otel/config.ts +0 -47
  373. package/src/otel/console.ts +0 -91
  374. package/src/otel/exporters/README.md +0 -217
  375. package/src/otel/exporters/index.ts +0 -3
  376. package/src/otel/exporters/jsonl-log-exporter.ts +0 -113
  377. package/src/otel/exporters/jsonl-metric-exporter.ts +0 -120
  378. package/src/otel/exporters/jsonl-trace-exporter.ts +0 -121
  379. package/src/otel/fetch.ts +0 -105
  380. package/src/otel/http.ts +0 -53
  381. package/src/otel/logger.ts +0 -293
  382. package/src/otel/otel.ts +0 -354
  383. package/src/otel/tracestate.ts +0 -108
  384. package/src/router.ts +0 -75
  385. package/src/services/evalrun/composite.ts +0 -34
  386. package/src/services/evalrun/http.ts +0 -167
  387. package/src/services/evalrun/index.ts +0 -4
  388. package/src/services/evalrun/json.ts +0 -46
  389. package/src/services/evalrun/local.ts +0 -28
  390. package/src/services/local/README.md +0 -1576
  391. package/src/services/local/_db.ts +0 -353
  392. package/src/services/local/_router.ts +0 -40
  393. package/src/services/local/_util.ts +0 -55
  394. package/src/services/local/email.ts +0 -91
  395. package/src/services/local/index.ts +0 -9
  396. package/src/services/local/keyvalue.ts +0 -174
  397. package/src/services/local/queue.ts +0 -145
  398. package/src/services/local/stream.ts +0 -358
  399. package/src/services/local/task.ts +0 -1711
  400. package/src/services/local/vector.ts +0 -438
  401. package/src/services/sandbox/http.ts +0 -522
  402. package/src/services/sandbox/index.ts +0 -1
  403. package/src/services/session/composite.ts +0 -33
  404. package/src/services/session/http.ts +0 -167
  405. package/src/services/session/index.ts +0 -4
  406. package/src/services/session/json.ts +0 -42
  407. package/src/services/session/local.ts +0 -33
  408. package/src/services/thread/local.ts +0 -199
  409. package/src/session.ts +0 -1960
  410. package/src/signature.ts +0 -82
  411. package/src/validator.ts +0 -283
  412. package/src/version-check.ts +0 -184
  413. package/src/web.ts +0 -76
  414. package/src/webrtc-signaling.ts +0 -288
  415. package/src/workbench.ts +0 -725
package/dist/agent.js DELETED
@@ -1,981 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { StructuredError, toCamelCase, } from '@agentuity/core';
3
- import { context, SpanStatusCode, trace } from '@opentelemetry/api';
4
- import { enrichContextWithTraceState } from './otel/tracestate';
5
- import { validator } from 'hono/validator';
6
- import { AGENT_RUNTIME, INTERNAL_AGENT, CURRENT_AGENT, AGENT_IDS } from './_config';
7
- import { getAgentContext, inHTTPContext, getHTTPContext, setupRequestAgentContext, getAgentAsyncLocalStorage, } from './_context';
8
- import { internal } from './logger/internal';
9
- import { fireEvent } from './_events';
10
- import { privateContext } from './_server';
11
- import { generateId } from './session';
12
- import { getEvalRunEventProvider } from './_services';
13
- import * as runtimeConfig from './_config';
14
- import { validateSchema, formatValidationIssues } from './_validation';
15
- import { getAgentMetadataByName, getEvalMetadata } from './_metadata';
16
- // Will be populated at runtime with strongly typed agents
17
- const agents = new Map();
18
- // WeakMap to store event listeners for each agent instance (truly private)
19
- const agentEventListeners = new WeakMap();
20
- // Map to store agent configs returned from setup (keyed by agent name)
21
- const agentConfigs = new Map();
22
- /**
23
- * Get the global runtime state (for production use).
24
- * In tests, use TestAgentContext which has isolated runtime state.
25
- */
26
- export function getGlobalRuntimeState() {
27
- return {
28
- agents,
29
- agentConfigs,
30
- agentEventListeners,
31
- };
32
- }
33
- /**
34
- * Get the runtime state from an AgentContext.
35
- * @internal
36
- */
37
- export function getAgentRuntime(ctx) {
38
- return ctx[AGENT_RUNTIME];
39
- }
40
- async function fireAgentEvent(runtime, agent, eventName, context, data) {
41
- // Fire agent-level listeners
42
- const listeners = runtime.agentEventListeners.get(agent);
43
- if (listeners) {
44
- const callbacks = listeners.get(eventName);
45
- if (callbacks && callbacks.size > 0) {
46
- for (const callback of callbacks) {
47
- try {
48
- if (eventName === 'errored' && data) {
49
- await callback(eventName, agent, context, data);
50
- }
51
- else if (eventName === 'started' || eventName === 'completed') {
52
- await callback(eventName, agent, context);
53
- }
54
- }
55
- catch (error) {
56
- // Log but don't re-throw - event listener errors should not crash the server
57
- internal.error(`Error in agent event listener for '${eventName}':`, error);
58
- }
59
- }
60
- }
61
- }
62
- // Fire global app-level events
63
- if (eventName === 'errored' && data) {
64
- await fireEvent('agent.errored', agent, context, data);
65
- }
66
- else if (eventName === 'started') {
67
- await fireEvent('agent.started', agent, context);
68
- }
69
- else if (eventName === 'completed') {
70
- await fireEvent('agent.completed', agent, context);
71
- }
72
- }
73
- export const registerAgent = (name, agent) => {
74
- agents.set(name, agent);
75
- };
76
- export const setAgentConfig = (name, config) => {
77
- agentConfigs.set(name, config);
78
- };
79
- export const getAgentConfig = (name) => {
80
- return agentConfigs.get(name);
81
- };
82
- const ValidationError = StructuredError('ValidationError')();
83
- // Implementation
84
- export function createAgent(name, config) {
85
- const inputSchema = config.schema?.input;
86
- const outputSchema = config.schema?.output;
87
- // Initialize evals array before handler so it can be captured in closure
88
- // Evals should only be added via agent.createEval() after agent creation
89
- const evalsArray = [];
90
- const handler = async (input) => {
91
- let validatedInput = undefined;
92
- if (inputSchema) {
93
- const inputResult = await inputSchema['~standard'].validate(input);
94
- if (inputResult.issues) {
95
- throw new ValidationError({
96
- issues: inputResult.issues,
97
- message: `Input validation failed: ${inputResult.issues.map((i) => i.message).join(', ')}`,
98
- });
99
- }
100
- validatedInput = inputResult.value;
101
- }
102
- const agentCtx = getAgentContext();
103
- // Store current agent for telemetry (using Symbol to keep it internal)
104
- agentCtx[CURRENT_AGENT] = agent;
105
- // Expose current agent metadata on the context
106
- agentCtx.current = agent.metadata;
107
- // Update ctx.config with this agent's setup() return value.
108
- // This ensures correct config when:
109
- // - Agent is called via user router (createAgentMiddleware(''))
110
- // - Agent A calls Agent B (agentB.run() inside handler)
111
- // - Agent is called via runInAgentContext() in tests
112
- const agentConfig = getAgentConfig(agent.metadata.name);
113
- if (agentConfig !== undefined) {
114
- agentCtx.config = agentConfig;
115
- }
116
- const attrs = {
117
- '@agentuity/agentId': agent.metadata.agentId, // stable ID (agent_*) - consistent across deployments
118
- '@agentuity/agentInstanceId': agent.metadata.id, // deployment-specific ID (agentid_*) - changes per deployment
119
- '@agentuity/agentDescription': agent.metadata.description,
120
- '@agentuity/agentName': agent.metadata.name,
121
- '@agentuity/threadId': agentCtx.thread.id,
122
- };
123
- // Set agent attributes on the current active span
124
- const activeSpan = trace.getActiveSpan();
125
- if (activeSpan) {
126
- activeSpan.setAttributes(attrs);
127
- }
128
- if (inHTTPContext()) {
129
- const honoCtx = privateContext(getHTTPContext());
130
- if (honoCtx.var.agentIds) {
131
- if (agent.metadata.id)
132
- honoCtx.var.agentIds.add(agent.metadata.id);
133
- if (agent.metadata.agentId)
134
- honoCtx.var.agentIds.add(agent.metadata.agentId);
135
- }
136
- }
137
- else {
138
- // For standalone contexts, check for AGENT_IDS symbol
139
- const agentIds = agentCtx[AGENT_IDS];
140
- if (agentIds) {
141
- if (agent.metadata.id)
142
- agentIds.add(agent.metadata.id);
143
- if (agent.metadata.agentId)
144
- agentIds.add(agent.metadata.agentId);
145
- }
146
- }
147
- agentCtx.logger = agentCtx.logger.child(attrs);
148
- // Get the agent instance from the runtime state to fire events
149
- const runtime = getAgentRuntime(agentCtx);
150
- // Fire 'started' event
151
- await fireAgentEvent(runtime, agent, 'started', agentCtx);
152
- try {
153
- // Execute the handler directly - span creation is handled by the caller (AgentRunner.run)
154
- // This avoids duplicate spans when agents call other agents
155
- const result = await (async () => {
156
- if (agent.metadata.id && !inHTTPContext()) {
157
- // For standalone contexts, wrap with agent context to set aid in trace state
158
- return runWithAgentContext(agent.metadata.id, () => inputSchema
159
- ? config.handler(agentCtx, validatedInput)
160
- : config.handler(agentCtx));
161
- }
162
- else {
163
- // HTTP context or no agent ID - invoke handler directly
164
- // Span is created by AgentRunner.run or createAgentRunner
165
- return inputSchema
166
- ? config.handler(agentCtx, validatedInput)
167
- : config.handler(agentCtx);
168
- }
169
- })();
170
- let validatedOutput = result;
171
- // Skip output validation for streaming agents (they return ReadableStream)
172
- if (outputSchema && !config.schema?.stream) {
173
- const outputResult = await outputSchema['~standard'].validate(result);
174
- if (outputResult.issues) {
175
- throw new ValidationError({
176
- issues: outputResult.issues,
177
- message: `Output validation failed: ${outputResult.issues.map((i) => i.message).join(', ')}`,
178
- });
179
- }
180
- validatedOutput = outputResult.value;
181
- }
182
- // Store validated input/output in context state for event listeners
183
- agentCtx.state.set('_evalInput', validatedInput);
184
- agentCtx.state.set('_evalOutput', validatedOutput);
185
- // Fire 'completed' event - evals will run via event listener
186
- await fireAgentEvent(runtime, agent, 'completed', agentCtx);
187
- return validatedOutput;
188
- }
189
- catch (error) {
190
- // Fire 'errored' event
191
- await fireAgentEvent(runtime, agent, 'errored', agentCtx, error);
192
- throw error;
193
- }
194
- };
195
- // Create createEval method that infers types from agent and automatically adds to agent
196
- const createEval = ((evalNameOrConfig, evalConfig) => {
197
- // Handle preset eval config (single argument with name property)
198
- if (typeof evalNameOrConfig !== 'string' && 'name' in evalNameOrConfig) {
199
- const presetConfig = evalNameOrConfig;
200
- const evalName = presetConfig.name;
201
- internal.debug(`createEval called for agent "${name || 'unknown'}": registering preset eval "${evalName}"`);
202
- const evalType = {
203
- metadata: {
204
- identifier: evalName,
205
- name: evalName,
206
- description: presetConfig.description || '',
207
- },
208
- handler: presetConfig.handler,
209
- };
210
- if (inputSchema) {
211
- evalType.inputSchema = inputSchema;
212
- }
213
- if (outputSchema) {
214
- evalType.outputSchema = outputSchema;
215
- }
216
- evalsArray.push(evalType);
217
- internal.debug(`Added preset eval "${evalName}" to agent "${name || 'unknown'}". Total evals: ${evalsArray.length}`);
218
- return evalType;
219
- }
220
- // Handle custom eval config (name + config)
221
- if (typeof evalNameOrConfig !== 'string' || !evalConfig) {
222
- throw new Error('Invalid arguments: expected (name: string, config) or (config: PresetEvalConfig)');
223
- }
224
- const evalName = evalNameOrConfig;
225
- // Trace log to verify evals file is imported
226
- internal.debug(`createEval called for agent "${name || 'unknown'}": registering eval "${evalName}"`);
227
- // Use build-time injected metadata if available (same pattern as agents)
228
- const evalMetadata = evalConfig.metadata || {};
229
- // Build eval metadata - merge injected metadata with defaults
230
- const evalType = {
231
- metadata: {
232
- // Use build-time injected metadata if available, otherwise fallback to empty/undefined
233
- id: evalMetadata.id || undefined,
234
- identifier: evalMetadata.identifier || undefined,
235
- version: evalMetadata.version || undefined,
236
- filename: evalMetadata.filename || '',
237
- name: evalName,
238
- description: evalConfig.description || '',
239
- },
240
- handler: evalConfig.handler,
241
- };
242
- if (inputSchema) {
243
- evalType.inputSchema = inputSchema;
244
- }
245
- if (outputSchema) {
246
- evalType.outputSchema = outputSchema;
247
- }
248
- // Automatically add eval to agent's evals array
249
- evalsArray.push(evalType);
250
- internal.debug(`Added eval "${evalName}" to agent "${name || 'unknown'}". Total evals: ${evalsArray.length}`);
251
- return evalType;
252
- });
253
- // Build metadata - merge user-provided metadata with defaults
254
- // The build plugin injects metadata via config.metadata during AST transformation
255
- let metadata = {
256
- // Defaults (used when running without build, e.g., dev mode)
257
- name,
258
- description: config.description,
259
- id: '',
260
- agentId: '',
261
- filename: '',
262
- version: '',
263
- inputSchemaCode: '',
264
- outputSchemaCode: '',
265
- // Merge in build-time injected metadata (overrides defaults)
266
- ...config.metadata,
267
- };
268
- // If id/agentId are empty, try to load from agentuity.metadata.json
269
- if (!metadata.id || !metadata.agentId) {
270
- const fileMetadata = getAgentMetadataByName(name);
271
- if (fileMetadata) {
272
- internal.info('[agent] loaded metadata for "%s" from file: id=%s, agentId=%s', name, fileMetadata.id, fileMetadata.agentId);
273
- metadata = {
274
- ...metadata,
275
- id: fileMetadata.id || metadata.id,
276
- agentId: fileMetadata.agentId || metadata.agentId,
277
- filename: fileMetadata.filename || metadata.filename,
278
- version: fileMetadata.version || metadata.version,
279
- };
280
- }
281
- }
282
- // Error if agent has no metadata IDs in production - this causes agent_ids to be empty in sessions
283
- // which affects analytics, billing attribution, and session filtering
284
- // Only enforce in production (when AGENTUITY_CLOUD_PROJECT_ID is set) to allow dev/test without metadata
285
- if (!metadata.id && !metadata.agentId && runtimeConfig.getProjectId()) {
286
- throw new Error(`Agent "${name}" has no metadata IDs (id and agentId are empty). ` +
287
- `This will result in empty agent_ids in session events. ` +
288
- `Ensure agentuity.metadata.json exists in the runtime directory ` +
289
- `(checked: ${process.cwd()}/agentuity.metadata.json and ${process.cwd()}/.agentuity/agentuity.metadata.json). ` +
290
- `Run 'agentuity build' to generate the metadata file.`);
291
- }
292
- const agent = {
293
- handler,
294
- metadata,
295
- evals: evalsArray,
296
- createEval,
297
- setup: config.setup,
298
- shutdown: config.shutdown,
299
- };
300
- // Add event listener methods
301
- agent.addEventListener = (eventName, callback) => {
302
- const agentForListeners = agent;
303
- const callbackForListeners = callback;
304
- let listeners = agentEventListeners.get(agentForListeners);
305
- if (!listeners) {
306
- listeners = new Map();
307
- agentEventListeners.set(agentForListeners, listeners);
308
- }
309
- let callbacks = listeners.get(eventName);
310
- if (!callbacks) {
311
- callbacks = new Set();
312
- listeners.set(eventName, callbacks);
313
- }
314
- callbacks.add(callbackForListeners);
315
- };
316
- // Automatically add event listener for 'completed' event to run evals
317
- agent.addEventListener('completed', async (_event, _agent, ctx) => {
318
- // Use the agent instance passed to event listener to access its evals array
319
- // This ensures we get evals that were added via agent.createEval() after agent creation
320
- const agentEvals = _agent?.evals || evalsArray;
321
- internal.debug(`Checking evals: agent=${_agent.metadata?.name}, evalsArray.length=${evalsArray?.length || 0}, agent.evals.length=${_agent?.evals?.length || 0}`);
322
- if (agentEvals && agentEvals.length > 0) {
323
- internal.info(`Executing ${agentEvals.length} evaluations after agent run`);
324
- // Get validated input/output from context state
325
- const validatedInput = ctx.state.get('_evalInput');
326
- const validatedOutput = ctx.state.get('_evalOutput');
327
- // Capture agentRunSpanId synchronously before waitUntil (which may run outside AsyncLocalStorage)
328
- let agentRunSpanId;
329
- try {
330
- const httpCtx = getHTTPContext();
331
- const _httpCtx = privateContext(httpCtx);
332
- agentRunSpanId = _httpCtx.var.agentRunSpanId;
333
- }
334
- catch {
335
- // HTTP context may not be available, spanId will be undefined
336
- }
337
- // Capture the agent span context so eval spans are parented to the agent
338
- const agentSpanContext = context.active();
339
- // Execute each eval using waitUntil to avoid blocking the response
340
- for (const evalItem of agentEvals) {
341
- const evalName = evalItem.metadata.name || 'unnamed';
342
- const agentName = _agent?.metadata?.name || name;
343
- const evalRunId = generateId('evalrun');
344
- // Look up eval metadata synchronously before async execution
345
- const evalMeta = getEvalMetadata(agentName, evalName);
346
- const evalId = evalMeta?.id || '';
347
- const evalIdentifier = evalMeta?.identifier || '';
348
- // Create eval span FIRST, parented to agent, then call waitUntil inside it
349
- // This makes waitUntil a child of the eval span
350
- const tracer = ctx.tracer;
351
- if (tracer) {
352
- const evalSpan = tracer.startSpan(evalName, {}, agentSpanContext);
353
- evalSpan.setAttributes({
354
- '@agentuity/evalId': evalId,
355
- '@agentuity/evalIdentifier': evalIdentifier,
356
- '@agentuity/evalName': evalName,
357
- '@agentuity/evalRunId': evalRunId,
358
- '@agentuity/agentName': agentName,
359
- '@agentuity/evalDescription': evalMeta?.description || evalItem.metadata.description || '',
360
- '@agentuity/evalFilename': evalMeta?.filename || evalItem.metadata.filename || '',
361
- });
362
- const evalSpanContext = trace.setSpan(agentSpanContext, evalSpan);
363
- // Run waitUntil INSIDE the eval span context - this makes waitUntil a child of eval
364
- // Pass a function (not an already-executing promise) so waitUntil executes it
365
- // AFTER setting up its span context, making operations children of waitUntil
366
- context.with(evalSpanContext, () => {
367
- ctx.waitUntil(async () => {
368
- const orgId = runtimeConfig.getOrganizationId();
369
- const projectId = runtimeConfig.getProjectId();
370
- const devMode = runtimeConfig.isDevMode() ?? false;
371
- const evalRunEventProvider = getEvalRunEventProvider();
372
- const shouldSendEvalRunEvents = orgId && projectId && evalId !== '' && evalIdentifier !== '';
373
- try {
374
- internal.info(`[EVALRUN] Starting eval run tracking for '${evalName}'`);
375
- // Send eval run start event
376
- if (shouldSendEvalRunEvents && evalRunEventProvider) {
377
- try {
378
- const deploymentId = runtimeConfig.getDeploymentId();
379
- await evalRunEventProvider.start({
380
- id: evalRunId,
381
- sessionId: ctx.sessionId,
382
- evalId,
383
- evalIdentifier,
384
- orgId: orgId,
385
- projectId: projectId,
386
- devmode: Boolean(devMode),
387
- deploymentId: deploymentId || undefined,
388
- spanId: agentRunSpanId,
389
- });
390
- }
391
- catch (error) {
392
- internal.error(`[EVALRUN] Error sending start event for '${evalName}'`, { error });
393
- }
394
- }
395
- // Validate eval input/output if schemas exist
396
- let evalValidatedInput = validatedInput;
397
- let evalValidatedOutput = validatedOutput;
398
- if (evalItem.inputSchema) {
399
- const result = await evalItem.inputSchema['~standard'].validate(validatedInput);
400
- if (result.issues) {
401
- throw new ValidationError({
402
- issues: result.issues,
403
- message: `Eval input validation failed`,
404
- });
405
- }
406
- evalValidatedInput = result.value;
407
- }
408
- if (evalItem.outputSchema) {
409
- const result = await evalItem.outputSchema['~standard'].validate(validatedOutput);
410
- if (result.issues) {
411
- throw new ValidationError({
412
- issues: result.issues,
413
- message: `Eval output validation failed`,
414
- });
415
- }
416
- evalValidatedOutput = result.value;
417
- }
418
- // Execute the eval handler
419
- let handlerResult;
420
- if (inputSchema && outputSchema) {
421
- handlerResult = await evalItem.handler(ctx, evalValidatedInput, evalValidatedOutput);
422
- }
423
- else if (inputSchema) {
424
- handlerResult = await evalItem.handler(ctx, evalValidatedInput);
425
- }
426
- else if (outputSchema) {
427
- handlerResult = await evalItem.handler(ctx, evalValidatedOutput);
428
- }
429
- else {
430
- handlerResult = await evalItem.handler(ctx);
431
- }
432
- const result = { success: true, ...handlerResult };
433
- // Send eval run complete event
434
- if (shouldSendEvalRunEvents && evalRunEventProvider) {
435
- try {
436
- await evalRunEventProvider.complete({ id: evalRunId, result });
437
- }
438
- catch (error) {
439
- internal.error(`[EVALRUN] Error sending complete event for '${evalName}'`, { error });
440
- }
441
- }
442
- internal.debug(`Eval '${evalName}' completed successfully`);
443
- }
444
- catch (error) {
445
- const errorMessage = error instanceof Error ? error.message : String(error);
446
- evalSpan.recordException(error);
447
- evalSpan.setStatus({
448
- code: SpanStatusCode.ERROR,
449
- message: errorMessage,
450
- });
451
- internal.error(`Error executing eval '${evalName}'`, { error });
452
- // Send error event
453
- if (shouldSendEvalRunEvents && evalRunEventProvider) {
454
- try {
455
- await evalRunEventProvider.complete({
456
- id: evalRunId,
457
- error: errorMessage,
458
- result: {
459
- success: false,
460
- passed: false,
461
- error: errorMessage,
462
- metadata: {},
463
- },
464
- });
465
- }
466
- catch (e) {
467
- internal.debug('Failed to send eval run complete event', {
468
- evalRunId,
469
- errorMessage,
470
- error: e instanceof Error ? e.message : String(e),
471
- });
472
- }
473
- }
474
- }
475
- finally {
476
- evalSpan.end();
477
- }
478
- });
479
- });
480
- }
481
- else {
482
- // No tracer - execute without span
483
- ctx.waitUntil(async () => {
484
- const orgId = runtimeConfig.getOrganizationId();
485
- const projectId = runtimeConfig.getProjectId();
486
- const devMode = runtimeConfig.isDevMode() ?? false;
487
- const evalRunEventProvider = getEvalRunEventProvider();
488
- const shouldSendEvalRunEvents = orgId && projectId && evalId !== '' && evalIdentifier !== '';
489
- try {
490
- if (shouldSendEvalRunEvents && evalRunEventProvider) {
491
- try {
492
- await evalRunEventProvider.start({
493
- id: evalRunId,
494
- sessionId: ctx.sessionId,
495
- evalId,
496
- evalIdentifier,
497
- orgId: orgId,
498
- projectId: projectId,
499
- devmode: Boolean(devMode),
500
- deploymentId: runtimeConfig.getDeploymentId() || undefined,
501
- spanId: agentRunSpanId,
502
- });
503
- }
504
- catch (e) {
505
- internal.debug('Failed to send eval run start event', {
506
- evalRunId,
507
- evalId,
508
- evalIdentifier,
509
- sessionId: ctx.sessionId,
510
- error: e instanceof Error ? e.message : String(e),
511
- });
512
- }
513
- }
514
- let evalValidatedInput = validatedInput;
515
- let evalValidatedOutput = validatedOutput;
516
- if (evalItem.inputSchema) {
517
- const result = await evalItem.inputSchema['~standard'].validate(validatedInput);
518
- if (result.issues) {
519
- throw new ValidationError({
520
- issues: result.issues,
521
- message: `Eval input validation failed`,
522
- });
523
- }
524
- evalValidatedInput = result.value;
525
- }
526
- if (evalItem.outputSchema) {
527
- const result = await evalItem.outputSchema['~standard'].validate(validatedOutput);
528
- if (result.issues) {
529
- throw new ValidationError({
530
- issues: result.issues,
531
- message: `Eval output validation failed`,
532
- });
533
- }
534
- evalValidatedOutput = result.value;
535
- }
536
- let handlerResult;
537
- if (inputSchema && outputSchema) {
538
- handlerResult = await evalItem.handler(ctx, evalValidatedInput, evalValidatedOutput);
539
- }
540
- else if (inputSchema) {
541
- handlerResult = await evalItem.handler(ctx, evalValidatedInput);
542
- }
543
- else if (outputSchema) {
544
- handlerResult = await evalItem.handler(ctx, evalValidatedOutput);
545
- }
546
- else {
547
- handlerResult = await evalItem.handler(ctx);
548
- }
549
- if (shouldSendEvalRunEvents && evalRunEventProvider) {
550
- try {
551
- await evalRunEventProvider.complete({
552
- id: evalRunId,
553
- result: { success: true, ...handlerResult },
554
- });
555
- }
556
- catch (e) {
557
- internal.debug('Failed to send eval run complete event', {
558
- evalRunId,
559
- error: e instanceof Error ? e.message : String(e),
560
- });
561
- }
562
- }
563
- }
564
- catch (error) {
565
- const errorMessage = error instanceof Error ? error.message : String(error);
566
- internal.error(`Error executing eval '${evalName}'`, { error });
567
- // Send error event to match traced branch behavior
568
- if (shouldSendEvalRunEvents && evalRunEventProvider) {
569
- try {
570
- await evalRunEventProvider.complete({
571
- id: evalRunId,
572
- error: errorMessage,
573
- result: {
574
- success: false,
575
- passed: false,
576
- error: errorMessage,
577
- metadata: {},
578
- },
579
- });
580
- }
581
- catch (e) {
582
- internal.debug('Failed to send eval run complete event', {
583
- evalRunId,
584
- errorMessage,
585
- error: e instanceof Error ? e.message : String(e),
586
- });
587
- }
588
- }
589
- }
590
- });
591
- }
592
- }
593
- }
594
- });
595
- agent.removeEventListener = (eventName, callback) => {
596
- const agentForListeners = agent;
597
- const callbackForListeners = callback;
598
- const listeners = agentEventListeners.get(agentForListeners);
599
- if (!listeners)
600
- return;
601
- const callbacks = listeners.get(eventName);
602
- if (!callbacks)
603
- return;
604
- callbacks.delete(callbackForListeners);
605
- };
606
- if (inputSchema) {
607
- agent.inputSchema = inputSchema;
608
- }
609
- if (outputSchema) {
610
- agent.outputSchema = outputSchema;
611
- }
612
- if (config.schema?.stream) {
613
- agent.stream = config.schema.stream;
614
- }
615
- // Add validator method with overloads
616
- agent.validator = ((override) => {
617
- const effectiveInputSchema = override?.input ?? inputSchema;
618
- // Only use agent's output schema if no override was provided at all.
619
- // If override is provided (even with just input), don't auto-apply agent's output schema
620
- // unless the override explicitly includes output.
621
- const effectiveOutputSchema = override ? override.output : outputSchema;
622
- // Helper to build the standard Hono input validator so types flow
623
- const buildInputValidator = (schema) => validator('json', async (value, c) => {
624
- if (schema) {
625
- const result = await validateSchema(schema, value);
626
- if (!result.success) {
627
- return c.json({
628
- error: 'Validation failed',
629
- message: formatValidationIssues(result.issues),
630
- issues: result.issues,
631
- }, 400);
632
- }
633
- return result.data;
634
- }
635
- return value;
636
- });
637
- // If no output schema, preserve existing behavior: pure input validation
638
- if (!effectiveOutputSchema) {
639
- return buildInputValidator(effectiveInputSchema);
640
- }
641
- // Output validation middleware (runs after handler)
642
- const outputValidator = async (c, next) => {
643
- await next();
644
- const res = c.res;
645
- if (!res)
646
- return;
647
- // Skip output validation for streaming agents
648
- if (config.schema?.stream) {
649
- return;
650
- }
651
- // Only validate JSON responses
652
- const contentType = res.headers.get('Content-Type') ?? '';
653
- if (!contentType.toLowerCase().includes('application/json')) {
654
- return;
655
- }
656
- // Clone so we don't consume the body that will be sent
657
- let responseBody;
658
- try {
659
- const cloned = res.clone();
660
- responseBody = await cloned.json();
661
- }
662
- catch {
663
- const OutputValidationError = StructuredError('OutputValidationError')();
664
- throw new OutputValidationError({
665
- message: 'Output validation failed: response is not valid JSON',
666
- issues: [],
667
- });
668
- }
669
- const result = await validateSchema(effectiveOutputSchema, responseBody);
670
- if (!result.success) {
671
- const OutputValidationError = StructuredError('OutputValidationError')();
672
- throw new OutputValidationError({
673
- message: `Output validation failed: ${formatValidationIssues(result.issues)}`,
674
- issues: result.issues,
675
- });
676
- }
677
- // Replace response with validated/sanitized JSON
678
- c.res = new Response(JSON.stringify(result.data), {
679
- status: res.status,
680
- headers: res.headers,
681
- });
682
- };
683
- // If we have no input schema, we only do output validation
684
- if (!effectiveInputSchema) {
685
- return outputValidator;
686
- }
687
- // Compose: input validator → output validator
688
- const inputMiddleware = buildInputValidator(effectiveInputSchema);
689
- const composed = async (c, next) => {
690
- // Run the validator first; its next() runs the output validator,
691
- // whose next() runs the actual handler(s)
692
- const result = await inputMiddleware(c, async () => {
693
- await outputValidator(c, next);
694
- });
695
- // If inputMiddleware returned early (validation failed), return that response
696
- return result;
697
- };
698
- return composed;
699
- });
700
- // Register the agent for runtime use
701
- // @ts-expect-error - metadata might be incomplete until build plugin injects InternalAgentMetadata
702
- agents.set(name, agent);
703
- // Create and return AgentRunner
704
- const runner = {
705
- metadata: metadata,
706
- validator: agent.validator,
707
- inputSchema: inputSchema,
708
- outputSchema: outputSchema,
709
- stream: config.schema?.stream || false,
710
- evals: agent.evals,
711
- createEval,
712
- addEventListener: agent.addEventListener,
713
- removeEventListener: agent.removeEventListener,
714
- run: inputSchema
715
- ? async (input) => {
716
- // Wrap with span if in HTTP context with tracer
717
- if (inHTTPContext()) {
718
- const honoCtx = getHTTPContext();
719
- const tracer = honoCtx.var.tracer;
720
- if (tracer) {
721
- return runWithSpan(tracer, agent, honoCtx, async () => await agent.handler(input));
722
- }
723
- }
724
- return await agent.handler(input);
725
- }
726
- : async () => {
727
- // Wrap with span if in HTTP context with tracer
728
- if (inHTTPContext()) {
729
- const honoCtx = getHTTPContext();
730
- const tracer = honoCtx.var.tracer;
731
- if (tracer) {
732
- return runWithSpan(tracer, agent, honoCtx, async () => await agent.handler());
733
- }
734
- }
735
- return await agent.handler();
736
- },
737
- [INTERNAL_AGENT]: agent, // Store reference to internal agent for testing
738
- };
739
- return runner;
740
- }
741
- /**
742
- * Run a handler with the agent identifier set in trace state.
743
- * Used for non-HTTP contexts (standalone) where we still want to propagate
744
- * the agent ID to downstream API calls.
745
- */
746
- const runWithAgentContext = async (agentId, handler) => {
747
- const currentContext = context.active();
748
- const activeSpan = trace.getSpan(currentContext);
749
- if (!activeSpan) {
750
- // No active span, just run the handler
751
- return handler();
752
- }
753
- // Enrich the context's traceState with the agent ID so it propagates
754
- // to downstream calls. Note: this does NOT affect the active recording
755
- // span's exported traceState (that was set at span creation). This only
756
- // affects propagation context for outbound requests.
757
- const contextWithAgentId = enrichContextWithTraceState(currentContext, {
758
- aid: agentId,
759
- });
760
- return context.with(contextWithAgentId, handler);
761
- };
762
- const runWithSpan = async (tracer, agent, ctx, handler) => {
763
- const currentContext = context.active();
764
- // Build enriched traceState BEFORE span creation so the recording span
765
- // inherits it and it gets exported to OTLP. This ensures the agent ID
766
- // and other metadata appear in ClickHouse TraceState column.
767
- const deploymentId = runtimeConfig.getDeploymentId();
768
- const projectId = runtimeConfig.getProjectId();
769
- const orgId = runtimeConfig.getOrganizationId();
770
- const isDevMode = runtimeConfig.isDevMode();
771
- const enrichedContext = enrichContextWithTraceState(currentContext, {
772
- aid: agent.metadata.id,
773
- did: deploymentId,
774
- pid: projectId,
775
- oid: orgId,
776
- d: isDevMode ? '1' : undefined,
777
- });
778
- const span = tracer.startSpan('agent.run', {}, enrichedContext);
779
- // Set agent attributes on the span immediately after creation
780
- span.setAttributes({
781
- '@agentuity/agentId': agent.metadata.agentId, // stable ID (agent_*) - consistent across deployments
782
- '@agentuity/agentInstanceId': agent.metadata.id, // deployment-specific ID (agentid_*) - changes per deployment
783
- '@agentuity/agentDescription': agent.metadata.description,
784
- '@agentuity/agentName': agent.metadata.name,
785
- '@agentuity/threadId': ctx.var.thread.id,
786
- });
787
- const spanId = span.spanContext().spanId;
788
- // Store span ID in PrivateVariables
789
- const _ctx = privateContext(ctx);
790
- _ctx.set('agentRunSpanId', spanId);
791
- try {
792
- // Create a new context with the span active.
793
- // The span already carries the enriched traceState (inherited from
794
- // enrichedContext), so downstream API calls via propagation.inject()
795
- // will see aid/pid/oid/did/d.
796
- const spanContext = trace.setSpan(currentContext, span);
797
- return await context.with(spanContext, handler);
798
- }
799
- catch (error) {
800
- span.recordException(error);
801
- span.setStatus({ code: SpanStatusCode.ERROR });
802
- throw error;
803
- }
804
- finally {
805
- span.end();
806
- }
807
- };
808
- const createAgentRunner = (agent, ctx) => {
809
- const tracer = ctx.var.tracer;
810
- if (agent.inputSchema) {
811
- return {
812
- metadata: agent.metadata,
813
- run: async (input) => {
814
- return runWithSpan(tracer, agent, ctx, async () => await agent.handler(input));
815
- },
816
- };
817
- }
818
- else {
819
- return {
820
- metadata: agent.metadata,
821
- run: async () => {
822
- return runWithSpan(tracer, agent, ctx, async () => await agent.handler());
823
- },
824
- };
825
- }
826
- };
827
- /**
828
- * Populate the agents object with all registered agents
829
- * Keys are converted to camelCase to match the generated TypeScript types
830
- */
831
- export const populateAgentsRegistry = (ctx) => {
832
- const agentsObj = {};
833
- // Track ownership of camelCase keys to detect collisions between different raw names
834
- const ownershipMap = new Map();
835
- // Build flat registry of agents
836
- for (const [name, agentFn] of agents) {
837
- const runner = createAgentRunner(agentFn, ctx);
838
- const key = toCamelCase(name);
839
- // Validate key is non-empty
840
- if (!key) {
841
- internal.warn(`Agent name "${name}" converts to empty camelCase key. Skipping.`);
842
- continue;
843
- }
844
- // Detect collision on key - check ownership
845
- const existingOwner = ownershipMap.get(key);
846
- if (existingOwner && existingOwner !== name) {
847
- internal.error(`Agent registry collision: "${name}" conflicts with "${existingOwner}" (both map to camelCase key "${key}")`);
848
- throw new Error(`Agent registry collision detected for key "${key}"`);
849
- }
850
- agentsObj[key] = runner;
851
- // Record ownership
852
- ownershipMap.set(key, name);
853
- }
854
- return agentsObj;
855
- };
856
- export const createAgentMiddleware = (agentName) => {
857
- return async (ctx, next) => {
858
- // Populate agents object with strongly-typed keys
859
- const agentsObj = populateAgentsRegistry(ctx);
860
- // Track agent ID for session telemetry
861
- if (agentName) {
862
- const agentKey = toCamelCase(agentName);
863
- const agent = agentsObj[agentKey];
864
- const _ctx = privateContext(ctx);
865
- // we add both so that you can query by either
866
- if (agent?.metadata?.id) {
867
- _ctx.var.agentIds.add(agent.metadata.id);
868
- }
869
- if (agent?.metadata?.agentId) {
870
- _ctx.var.agentIds.add(agent.metadata.agentId);
871
- }
872
- }
873
- const sessionId = ctx.var.sessionId;
874
- const thread = ctx.var.thread;
875
- const session = ctx.var.session;
876
- const config = agentName ? getAgentConfig(agentName) : undefined;
877
- const app = ctx.var.app;
878
- const args = {
879
- agent: agentsObj,
880
- logger: ctx.var.logger,
881
- tracer: ctx.var.tracer,
882
- sessionId,
883
- session,
884
- thread,
885
- handler: ctx.var.waitUntilHandler,
886
- config: config || {},
887
- app: app || {},
888
- runtime: getGlobalRuntimeState(),
889
- auth: ctx.var.auth ?? null,
890
- };
891
- return setupRequestAgentContext(ctx, args, next);
892
- };
893
- };
894
- export const getAgents = () => agents;
895
- export const runAgentSetups = async (appState) => {
896
- for (const [name, agent] of agents.entries()) {
897
- if (agent.setup) {
898
- const config = await agent.setup(appState);
899
- setAgentConfig(name, config);
900
- }
901
- }
902
- // Note: Server readiness is managed by Vite (dev) or Bun.serve (prod)
903
- };
904
- export const runAgentShutdowns = async (appState) => {
905
- const runtime = getGlobalRuntimeState();
906
- for (const [name, agent] of runtime.agents.entries()) {
907
- if (agent.shutdown) {
908
- const config = runtime.agentConfigs.get(name);
909
- await agent.shutdown(appState, config);
910
- }
911
- }
912
- };
913
- /**
914
- * Run an agent within a specific AgentContext.
915
- * Sets up AsyncLocalStorage with the provided context and executes the agent.
916
- *
917
- * This is the recommended way to test agents in unit tests. It automatically:
918
- * - Registers the agent in the runtime state so event listeners fire
919
- * - Sets up AsyncLocalStorage so getAgentContext() works inside the agent
920
- * - Handles both agents with input and agents without input
921
- *
922
- * **Use cases:**
923
- * - Unit testing agents with TestAgentContext
924
- * - Running agents outside HTTP request flow
925
- * - Custom agent execution environments
926
- * - Testing event listeners and evaluations
927
- *
928
- * @template TInput - Type of the input parameter
929
- * @template TOutput - Type of the return value
930
- *
931
- * @param ctx - The AgentContext to use (typically TestAgentContext in tests)
932
- * @param agent - The AgentRunner to execute (returned from createAgent)
933
- * @param input - Input data (required if agent has input schema, omit otherwise)
934
- *
935
- * @returns Promise resolving to the agent's output
936
- *
937
- * @example
938
- * ```typescript
939
- * import { runInAgentContext, TestAgentContext } from '@agentuity/runtime/test';
940
- *
941
- * test('greeting agent', async () => {
942
- * const ctx = new TestAgentContext();
943
- * const result = await runInAgentContext(ctx, greetingAgent, {
944
- * name: 'Alice',
945
- * age: 30
946
- * });
947
- * expect(result).toBe('Hello, Alice! You are 30 years old.');
948
- * });
949
- *
950
- * test('no-input agent', async () => {
951
- * const ctx = new TestAgentContext();
952
- * const result = await runInAgentContext(ctx, statusAgent);
953
- * expect(result).toEqual({ status: 'ok' });
954
- * });
955
- * ```
956
- */
957
- export async function runInAgentContext(ctx, agent, input) {
958
- const storage = getAgentAsyncLocalStorage();
959
- // Register agent in runtime state so events fire (lookup by metadata.name)
960
- const agentName = agent.metadata.name;
961
- const runtime = getAgentRuntime(ctx);
962
- // Get internal agent from runner (stored via symbol) or global registry
963
- const internalAgent = agent[INTERNAL_AGENT] || agents.get(agentName);
964
- if (internalAgent && agentName) {
965
- runtime.agents.set(agentName, internalAgent);
966
- // Copy event listeners from global to context runtime
967
- const globalListeners = agentEventListeners.get(internalAgent);
968
- if (globalListeners) {
969
- runtime.agentEventListeners.set(internalAgent, globalListeners);
970
- }
971
- }
972
- return storage.run(ctx, async () => {
973
- if (input !== undefined) {
974
- return await agent.run(input);
975
- }
976
- else {
977
- return await agent.run();
978
- }
979
- });
980
- }
981
- //# sourceMappingURL=agent.js.map