failproofai 1.0.7-beta.1 → 1.0.7

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 (429) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +4 -4
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  6. package/.next/standalone/.next/server/app/_global-error/page.js +4 -4
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page.js +4 -4
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -14
  22. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  23. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/audit/run/route.js +7 -8
  25. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  33. package/.next/standalone/.next/server/app/audit/page.js +5 -7
  34. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  36. package/.next/standalone/.next/server/app/index.html +1 -1
  37. package/.next/standalone/.next/server/app/index.rsc +15 -15
  38. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
  39. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  40. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  41. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  42. package/.next/standalone/.next/server/app/page.js +6 -6
  43. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  46. package/.next/standalone/.next/server/app/policies/page.js +11 -13
  47. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  50. package/.next/standalone/.next/server/app/project/[name]/page.js +7 -8
  51. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  53. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  54. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  55. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +7 -7
  56. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  59. package/.next/standalone/.next/server/app/projects/page.js +6 -7
  60. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  61. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +8 -41
  63. package/.next/standalone/.next/server/app/settings/page.js +9 -12
  64. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  65. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/chunks/{[externals]__1j-zsg5._.js → [externals]__1_bftcl._.js} +1 -1
  67. package/.next/standalone/.next/server/chunks/{[externals]__19_pzeq._.js → [externals]__1msfs-h._.js} +1 -1
  68. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
  69. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1bf34x4._.js → [root-of-the-server]__1_r2rbg._.js} +7 -5
  70. package/.next/standalone/.next/server/chunks/_09dz7xv._.js +21 -21
  71. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
  72. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
  73. package/.next/standalone/.next/server/chunks/{_1q5i8mb._.js → _1c3k-8x._.js} +2 -2
  74. package/.next/standalone/.next/server/chunks/_1ek68ln._.js +16 -16
  75. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +1 -1
  76. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  77. package/.next/standalone/.next/server/chunks/src_hooks_0iu54mz._.js +3 -0
  78. package/.next/standalone/.next/server/chunks/src_hooks_custom-hooks-loader_ts_0lnb3n3._.js +2 -4
  79. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-_ki57._.js +4 -0
  80. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +4 -0
  81. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +4 -0
  82. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +4 -0
  83. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0yxwl6j._.js → [root-of-the-server]__0bd3mje._.js} +2 -2
  84. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cg-bgc._.js +5 -0
  85. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cpu_mj._.js +3 -0
  86. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1mf3zp6._.js → [root-of-the-server]__0cxe_2_._.js} +3 -3
  87. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +4 -0
  88. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +4 -0
  89. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +4 -0
  90. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u3w0ll._.js +22 -0
  91. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17d_ffl._.js +3 -0
  92. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__19d9tgz._.js +5 -0
  93. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ctpynv._.js +3 -0
  94. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1jiwfsj._.js +3 -0
  95. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +4 -0
  96. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1phc187._.js +3 -0
  97. package/.next/standalone/.next/server/chunks/ssr/_06imw3p._.js +5 -0
  98. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  99. package/.next/standalone/.next/server/chunks/ssr/{_1w_5l7t._.js → _0h_douw._.js} +1 -1
  100. package/.next/standalone/.next/server/chunks/ssr/{_214wgrp._.js → _1-i_gzc._.js} +2 -2
  101. package/.next/standalone/.next/server/chunks/ssr/{_0bn2oo8._.js → _166t73i._.js} +1 -1
  102. package/.next/standalone/.next/server/chunks/ssr/{_1q46vxx._.js → _1_qswah._.js} +2 -2
  103. package/.next/standalone/.next/server/chunks/ssr/{_1gb0ifp._.js → _1es2j7i._.js} +5 -5
  104. package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +3 -0
  105. package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
  106. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +2 -2
  107. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  108. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  109. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
  110. package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +3 -0
  111. package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_18_d8l1._.js → node_modules_next_dist_0drixxt._.js} +4 -4
  112. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1cv9_c4._.js +10 -0
  113. package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +1 -1
  114. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-home_ts_0je3xkv._.js +1 -1
  115. package/.next/standalone/.next/server/chunks/ssr/src_hooks_pack-cli_ts_0t7me65._.js +1 -1
  116. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  117. package/.next/standalone/.next/server/pages/404.html +1 -1
  118. package/.next/standalone/.next/server/pages/500.html +1 -1
  119. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  120. package/.next/standalone/.next/server/server-reference-manifest.json +23 -56
  121. package/.next/standalone/.next/static/chunks/094xgi4owxaqf.js +1 -0
  122. package/.next/standalone/.next/static/chunks/0__8a7m868fvf.js +1 -0
  123. package/.next/standalone/.next/static/chunks/{12tvm75t5ffui.js → 0o6qlkgubtoex.js} +1 -1
  124. package/.next/standalone/.next/static/chunks/13i7-9is-vhys.js +1 -0
  125. package/.next/standalone/.next/static/chunks/1rz20_pz828f3.js +6 -0
  126. package/.next/standalone/.next/static/chunks/2k9f4tyv04809.css +1 -0
  127. package/.next/standalone/.next/static/chunks/{0vmd180qfntfb.js → 2klitrtzpaoe0.js} +1 -1
  128. package/.next/standalone/.next/static/chunks/{258668t68du6b.js → 2mdh397ghgnvv.js} +1 -1
  129. package/.next/standalone/.next/static/chunks/2rshywgeqsyzk.css +2 -0
  130. package/.next/standalone/.next/static/chunks/3pzx4chkhko9k.js +1 -0
  131. package/.next/standalone/.next/static/chunks/{0qrbdkv9qmvli.js → 3rh5o7e16irrm.js} +1 -1
  132. package/.next/standalone/.next/static/chunks/{29fql3nbnfc9q.js → 43ufqrz8qo3h-.js} +1 -1
  133. package/.next/standalone/SECURITY.md +53 -0
  134. package/.next/standalone/app/actions/pack-actions.ts +0 -12
  135. package/.next/standalone/app/policies/hooks-client.tsx +0 -9
  136. package/.next/standalone/app/settings/page.tsx +1 -20
  137. package/.next/standalone/app/settings/settings-client.tsx +1 -27
  138. package/.next/standalone/app/settings/settings.css +0 -79
  139. package/.next/standalone/package.json +9 -9
  140. package/.next/standalone/sdk/python/skill/SKILL.md +60 -14
  141. package/.next/standalone/sdk/python/skill/agents/openai.yaml +2 -1
  142. package/.next/standalone/sdk/python/skill/references/evaluator.md +255 -0
  143. package/.next/standalone/sdk/python/skill/references/events.md +17 -8
  144. package/.next/standalone/sdk/python/skill/references/frameworks.md +3 -0
  145. package/.next/standalone/sdk/python/skill/references/install.md +3 -0
  146. package/.next/standalone/sdk/python/skill/references/integration.md +6 -2
  147. package/.next/standalone/sdk/python/skill/references/typescript.md +568 -0
  148. package/.next/standalone/sdk/typescript/CHANGELOG.md +133 -0
  149. package/.next/standalone/sdk/typescript/LICENSE +42 -0
  150. package/.next/standalone/sdk/typescript/README.md +552 -0
  151. package/.next/standalone/sdk/typescript/eslint.config.mjs +59 -0
  152. package/.next/standalone/sdk/typescript/examples/research-agent.ts +197 -0
  153. package/.next/standalone/sdk/typescript/integration/ai.test.ts +920 -0
  154. package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/agent.ts +337 -0
  155. package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package-lock.json +261 -0
  156. package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package.json +16 -0
  157. package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/surfaces.ts +605 -0
  158. package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/tsconfig.json +12 -0
  159. package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/tsconfig.surfaces.json +4 -0
  160. package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/agent.ts +342 -0
  161. package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package-lock.json +156 -0
  162. package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package.json +16 -0
  163. package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/surfaces.ts +628 -0
  164. package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/tsconfig.json +12 -0
  165. package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/tsconfig.surfaces.json +4 -0
  166. package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/agent.ts +346 -0
  167. package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package-lock.json +156 -0
  168. package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package.json +13 -0
  169. package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/surfaces.ts +651 -0
  170. package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/tsconfig.json +12 -0
  171. package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/tsconfig.surfaces.json +4 -0
  172. package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/agent.ts +350 -0
  173. package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package-lock.json +153 -0
  174. package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package.json +13 -0
  175. package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/surfaces.ts +651 -0
  176. package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/tsconfig.json +12 -0
  177. package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/tsconfig.surfaces.json +4 -0
  178. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/agent.ts +623 -0
  179. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package-lock.json +344 -0
  180. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package.json +19 -0
  181. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/tsconfig.json +12 -0
  182. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/agent-v1.ts +99 -0
  183. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/agent.ts +623 -0
  184. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package-lock.json +336 -0
  185. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package.json +15 -0
  186. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/tsconfig.json +12 -0
  187. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/agent.ts +96 -0
  188. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package-lock.json +441 -0
  189. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package.json +19 -0
  190. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/tsconfig.json +12 -0
  191. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/index.cjs +53 -0
  192. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/index.mjs +55 -0
  193. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/package.json +18 -0
  194. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/agent.ts +659 -0
  195. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package-lock.json +635 -0
  196. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package.json +15 -0
  197. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/tsconfig.json +12 -0
  198. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/agent.ts +659 -0
  199. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package-lock.json +553 -0
  200. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package.json +15 -0
  201. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/tsconfig.json +12 -0
  202. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/agent.ts +877 -0
  203. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/mcp-server.mjs +66 -0
  204. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package-lock.json +6797 -0
  205. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package.json +24 -0
  206. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/tsconfig.json +12 -0
  207. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/agent.ts +872 -0
  208. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/mcp-server.mjs +66 -0
  209. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package-lock.json +2540 -0
  210. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package.json +15 -0
  211. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/tsconfig.json +12 -0
  212. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/actions.ts +18 -0
  213. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/ai/route.ts +42 -0
  214. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/edge/route.ts +29 -0
  215. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/langgraph/route.ts +21 -0
  216. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/llamaindex/route.ts +11 -0
  217. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/mastra/route.ts +19 -0
  218. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/status/route.ts +7 -0
  219. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/layout.tsx +9 -0
  220. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/page.tsx +15 -0
  221. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/instrumentation.ts +15 -0
  222. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/ai.ts +61 -0
  223. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/langgraph.ts +68 -0
  224. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/llamaindex.ts +98 -0
  225. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/mastra.ts +90 -0
  226. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/next.config.ts +52 -0
  227. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package-lock.json +4343 -0
  228. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package.json +28 -0
  229. package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/agent.ts +51 -0
  230. package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/deno-npm.ts +76 -0
  231. package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package-lock.json +484 -0
  232. package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package.json +15 -0
  233. package/.next/standalone/sdk/typescript/integration/fixtures/types/agent.ts +79 -0
  234. package/.next/standalone/sdk/typescript/integration/fixtures/types/package-lock.json +740 -0
  235. package/.next/standalone/sdk/typescript/integration/fixtures/types/package.json +11 -0
  236. package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/agent.ts +197 -0
  237. package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/package-lock.json +70 -0
  238. package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/package.json +12 -0
  239. package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/tsconfig.json +12 -0
  240. package/.next/standalone/sdk/typescript/integration/global-setup.ts +29 -0
  241. package/.next/standalone/sdk/typescript/integration/harness.ts +451 -0
  242. package/.next/standalone/sdk/typescript/integration/langchain.test.ts +682 -0
  243. package/.next/standalone/sdk/typescript/integration/llamaindex.test.ts +709 -0
  244. package/.next/standalone/sdk/typescript/integration/mastra-coverage.test.ts +386 -0
  245. package/.next/standalone/sdk/typescript/integration/mastra.test.ts +311 -0
  246. package/.next/standalone/sdk/typescript/integration/nextjs.test.ts +341 -0
  247. package/.next/standalone/sdk/typescript/integration/runtime-parity.ts +180 -0
  248. package/.next/standalone/sdk/typescript/integration/runtimes.bun.test.ts +15 -0
  249. package/.next/standalone/sdk/typescript/integration/runtimes.core.test.ts +113 -0
  250. package/.next/standalone/sdk/typescript/integration/runtimes.deno.test.ts +19 -0
  251. package/.next/standalone/sdk/typescript/integration/types.test.ts +141 -0
  252. package/.next/standalone/sdk/typescript/integration/vanilla.test.ts +255 -0
  253. package/.next/standalone/sdk/typescript/package-lock.json +2640 -0
  254. package/.next/standalone/sdk/typescript/package.json +401 -0
  255. package/.next/standalone/sdk/typescript/scripts/finalize-build.mjs +123 -0
  256. package/.next/standalone/sdk/typescript/scripts/release.mjs +177 -0
  257. package/.next/standalone/sdk/typescript/src/clock.ts +58 -0
  258. package/.next/standalone/sdk/typescript/src/context.ts +214 -0
  259. package/.next/standalone/sdk/typescript/src/edge/adapter.ts +18 -0
  260. package/.next/standalone/sdk/typescript/src/edge/ai.ts +116 -0
  261. package/.next/standalone/sdk/typescript/src/edge/index.ts +238 -0
  262. package/.next/standalone/sdk/typescript/src/edge/langchain.ts +18 -0
  263. package/.next/standalone/sdk/typescript/src/edge/llamaindex.ts +12 -0
  264. package/.next/standalone/sdk/typescript/src/edge/mastra.ts +17 -0
  265. package/.next/standalone/sdk/typescript/src/edge/notice.ts +33 -0
  266. package/.next/standalone/sdk/typescript/src/environment.ts +75 -0
  267. package/.next/standalone/sdk/typescript/src/evaluator/authoring.ts +480 -0
  268. package/.next/standalone/sdk/typescript/src/evaluator/cli.ts +96 -0
  269. package/.next/standalone/sdk/typescript/src/evaluator/client.ts +421 -0
  270. package/.next/standalone/sdk/typescript/src/evaluator/expression.ts +1292 -0
  271. package/.next/standalone/sdk/typescript/src/evaluator/index.ts +144 -0
  272. package/.next/standalone/sdk/typescript/src/evaluator/protocol.ts +747 -0
  273. package/.next/standalone/sdk/typescript/src/evaluator/runtime.ts +930 -0
  274. package/.next/standalone/sdk/typescript/src/evaluator/sandbox-worker.ts +171 -0
  275. package/.next/standalone/sdk/typescript/src/evaluator/source-limits.ts +27 -0
  276. package/.next/standalone/sdk/typescript/src/evaluator/source.ts +509 -0
  277. package/.next/standalone/sdk/typescript/src/events.ts +879 -0
  278. package/.next/standalone/sdk/typescript/src/exit.ts +117 -0
  279. package/.next/standalone/sdk/typescript/src/index.ts +186 -0
  280. package/.next/standalone/sdk/typescript/src/integrations/ai.ts +1566 -0
  281. package/.next/standalone/sdk/typescript/src/integrations/compat.ts +322 -0
  282. package/.next/standalone/sdk/typescript/src/integrations/core.ts +1321 -0
  283. package/.next/standalone/sdk/typescript/src/integrations/index.ts +355 -0
  284. package/.next/standalone/sdk/typescript/src/integrations/langchain.ts +2340 -0
  285. package/.next/standalone/sdk/typescript/src/integrations/llamaindex.ts +2111 -0
  286. package/.next/standalone/sdk/typescript/src/integrations/mastra.ts +1802 -0
  287. package/.next/standalone/sdk/typescript/src/logger.ts +98 -0
  288. package/.next/standalone/sdk/typescript/src/next.ts +115 -0
  289. package/.next/standalone/sdk/typescript/src/node-require.ts +446 -0
  290. package/.next/standalone/sdk/typescript/src/redact.ts +305 -0
  291. package/.next/standalone/sdk/typescript/src/resolver.ts +120 -0
  292. package/.next/standalone/sdk/typescript/src/runtime.ts +29 -0
  293. package/.next/standalone/sdk/typescript/src/schema.ts +410 -0
  294. package/.next/standalone/sdk/typescript/src/scopes.ts +701 -0
  295. package/.next/standalone/sdk/typescript/src/shared.ts +33 -0
  296. package/.next/standalone/sdk/typescript/src/version.ts +5 -0
  297. package/.next/standalone/sdk/typescript/src/writer.ts +934 -0
  298. package/.next/standalone/sdk/typescript/test/adapters.test.ts +397 -0
  299. package/.next/standalone/sdk/typescript/test/ai.test.ts +1076 -0
  300. package/.next/standalone/sdk/typescript/test/copies.test.ts +204 -0
  301. package/.next/standalone/sdk/typescript/test/edge.test.ts +183 -0
  302. package/.next/standalone/sdk/typescript/test/evaluator-client.test.ts +234 -0
  303. package/.next/standalone/sdk/typescript/test/evaluator-protocol.test.ts +225 -0
  304. package/.next/standalone/sdk/typescript/test/events.test.ts +193 -0
  305. package/.next/standalone/sdk/typescript/test/expression.test.ts +181 -0
  306. package/.next/standalone/sdk/typescript/test/global-setup.ts +26 -0
  307. package/.next/standalone/sdk/typescript/test/helpers.ts +130 -0
  308. package/.next/standalone/sdk/typescript/test/integrations.test.ts +369 -0
  309. package/.next/standalone/sdk/typescript/test/langchain-copies.test.ts +204 -0
  310. package/.next/standalone/sdk/typescript/test/langchain.test.ts +999 -0
  311. package/.next/standalone/sdk/typescript/test/llamaindex.test.ts +1760 -0
  312. package/.next/standalone/sdk/typescript/test/mastra-coverage.test.ts +501 -0
  313. package/.next/standalone/sdk/typescript/test/mastra-lifecycle.test.ts +479 -0
  314. package/.next/standalone/sdk/typescript/test/mastra.test.ts +285 -0
  315. package/.next/standalone/sdk/typescript/test/next.test.ts +109 -0
  316. package/.next/standalone/sdk/typescript/test/packaging.test.ts +312 -0
  317. package/.next/standalone/sdk/typescript/test/redaction.test.ts +171 -0
  318. package/.next/standalone/sdk/typescript/test/runtimes.test.ts +101 -0
  319. package/.next/standalone/sdk/typescript/test/sandbox.test.ts +189 -0
  320. package/.next/standalone/sdk/typescript/test/scopes.test.ts +271 -0
  321. package/.next/standalone/sdk/typescript/test/setup.ts +19 -0
  322. package/.next/standalone/sdk/typescript/test/skill-snippets.test.ts +73 -0
  323. package/.next/standalone/sdk/typescript/test/spool-contract.test.ts +124 -0
  324. package/.next/standalone/sdk/typescript/test/tracker-bounds.test.ts +191 -0
  325. package/.next/standalone/sdk/typescript/test/wire-format.test.ts +214 -0
  326. package/.next/standalone/sdk/typescript/test/writer.test.ts +407 -0
  327. package/.next/standalone/sdk/typescript/tsconfig.build.json +15 -0
  328. package/.next/standalone/sdk/typescript/tsconfig.cjs.json +19 -0
  329. package/.next/standalone/sdk/typescript/tsconfig.json +28 -0
  330. package/.next/standalone/sdk/typescript/vitest.config.ts +33 -0
  331. package/.next/standalone/sdk/typescript/vitest.integration.config.ts +23 -0
  332. package/.next/standalone/server.js +1 -1
  333. package/bin/failproofai.mjs +2 -115
  334. package/dist/cli.mjs +6538 -13686
  335. package/dist/index.js +1 -19
  336. package/dist/worker.mjs +2085 -8012
  337. package/package.json +9 -9
  338. package/pi-extension/index.ts +0 -11
  339. package/scripts/build-policy-pack.mjs +2 -39
  340. package/src/hooks/builtin-policies.ts +3 -21
  341. package/src/hooks/cloud-enrollment-cli.ts +1 -1
  342. package/src/hooks/cloud-managed-policies.ts +0 -22
  343. package/src/hooks/custom-hooks-loader.ts +7 -45
  344. package/src/hooks/custom-hooks-registry.ts +1 -45
  345. package/src/hooks/first-run-gate.ts +0 -5
  346. package/src/hooks/fp-home.ts +0 -23
  347. package/src/hooks/handler.ts +6 -265
  348. package/src/hooks/hook-activity-store.ts +1 -105
  349. package/src/hooks/hook-telemetry.ts +0 -41
  350. package/src/hooks/loader-utils.ts +0 -6
  351. package/src/hooks/pack-cli.ts +17 -278
  352. package/src/hooks/pack-manifest.ts +7 -479
  353. package/src/hooks/pack-store.ts +10 -156
  354. package/src/hooks/policy-catalog.ts +0 -65
  355. package/src/hooks/policy-evaluator.ts +796 -940
  356. package/src/hooks/policy-registry.ts +0 -25
  357. package/src/hooks/policy-types.ts +0 -126
  358. package/src/hooks/worker-server.ts +26 -119
  359. package/src/index.ts +0 -6
  360. package/.next/standalone/.next/server/chunks/src_hooks_01frwmb._.js +0 -5
  361. package/.next/standalone/.next/server/chunks/src_hooks_18qtd42._.js +0 -3
  362. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01bmjsj._.js +0 -3
  363. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +0 -4
  364. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__056wjo4._.js +0 -4
  365. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__059yza8._.js +0 -3
  366. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0eip4_k._.js +0 -22
  367. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n0xg95._.js +0 -4
  368. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qcb0mg._.js +0 -3
  369. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qxnccm._.js +0 -5
  370. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rwtwpm._.js +0 -4
  371. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s_yomn._.js +0 -4
  372. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0soxz2z._.js +0 -3
  373. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0yrsbd_._.js +0 -3
  374. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11mayhe._.js +0 -4
  375. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13d-wb6._.js +0 -3
  376. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1dinjii._.js +0 -3
  377. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pprgri._.js +0 -4
  378. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1q4p5b8._.js +0 -4
  379. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qiz0e4._.js +0 -3
  380. package/.next/standalone/.next/server/chunks/ssr/_042cgl1._.js +0 -3
  381. package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +0 -3
  382. package/.next/standalone/.next/server/chunks/ssr/_0uyu3jf._.js +0 -3
  383. package/.next/standalone/.next/server/chunks/ssr/_1feuvhb._.js +0 -5
  384. package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9sni._.js +0 -3
  385. package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +0 -3
  386. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_0w6mzq5._.js +0 -151
  387. package/.next/standalone/.next/server/chunks/ssr/src_hooks_095a_79._.js +0 -5
  388. package/.next/standalone/.next/server/chunks/ssr/src_hooks_15t8kqj._.js +0 -3
  389. package/.next/standalone/.next/server/chunks/ssr/src_hooks_18k8rl0._.js +0 -12
  390. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1fm2w5z._.js +0 -3
  391. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1j0zy3v._.js +0 -3
  392. package/.next/standalone/.next/static/chunks/0cd-_8-c-m1ea.js +0 -6
  393. package/.next/standalone/.next/static/chunks/0uldbut9y2-e8.js +0 -1
  394. package/.next/standalone/.next/static/chunks/1u5zsejmgrir_.js +0 -1
  395. package/.next/standalone/.next/static/chunks/285spx855h_3r.css +0 -2
  396. package/.next/standalone/.next/static/chunks/2qv4hshejedtx.css +0 -1
  397. package/.next/standalone/.next/static/chunks/2vkvu9-opa_1z.js +0 -1
  398. package/.next/standalone/.next/static/chunks/37lhv7wa3ywt6.js +0 -1
  399. package/.next/standalone/app/actions/get-jev-config.ts +0 -409
  400. package/.next/standalone/app/actions/update-jev-config.ts +0 -420
  401. package/.next/standalone/app/components/jev-notices.tsx +0 -96
  402. package/.next/standalone/app/settings/jev-panel.tsx +0 -469
  403. package/src/hooks/effective-reviewers.ts +0 -79
  404. package/src/hooks/jev-activity.ts +0 -385
  405. package/src/hooks/jev-cli.ts +0 -1193
  406. package/src/hooks/policy-authority.ts +0 -333
  407. package/src/hooks/policy-reviewability.ts +0 -229
  408. package/src/hooks/semantic/combine.ts +0 -541
  409. package/src/hooks/semantic/compile.ts +0 -176
  410. package/src/hooks/semantic/decide.ts +0 -392
  411. package/src/hooks/semantic/envelope.ts +0 -1296
  412. package/src/hooks/semantic/evaluator.ts +0 -547
  413. package/src/hooks/semantic/facts.ts +0 -292
  414. package/src/hooks/semantic/intent.ts +0 -1190
  415. package/src/hooks/semantic/jev-client.ts +0 -643
  416. package/src/hooks/semantic/jev-config.ts +0 -594
  417. package/src/hooks/semantic/jev-review.ts +0 -374
  418. package/src/hooks/semantic/jev-stats.ts +0 -289
  419. package/src/hooks/semantic/jev-throttle.ts +0 -421
  420. package/src/hooks/semantic/pack-policies.ts +0 -251
  421. package/src/hooks/semantic/policies.ts +0 -596
  422. package/src/hooks/semantic/precondition-names.ts +0 -60
  423. package/src/hooks/semantic/preconditions.ts +0 -58
  424. package/src/hooks/semantic/redact.ts +0 -2910
  425. package/src/hooks/semantic/types.ts +0 -145
  426. package/src/hooks/semver-precedence.ts +0 -128
  427. /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → PgeWCHmyVbjRznv2VO7KF}/_buildManifest.js +0 -0
  428. /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → PgeWCHmyVbjRznv2VO7KF}/_clientMiddlewareManifest.js +0 -0
  429. /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → PgeWCHmyVbjRznv2VO7KF}/_ssgManifest.js +0 -0
@@ -0,0 +1,877 @@
1
+ // Mastra 0.x consumer (the last 0.x line). Run as `node agent.{mjs,cjs} <case>`.
2
+ //
3
+ // The same program as `../mastra-1/agent.ts`, differing only where the 0.x API
4
+ // does: a tool's `execute` receives `{ context }` rather than the input itself,
5
+ // a workflow run is created with `createRunAsync()`, and an MCPClient lists its
6
+ // tools with `getTools()` / `getToolsets()`.
7
+ //
8
+ // Deliberately the shape a customer writes: import the framework, instrument,
9
+ // run. The model is a hand-written AI SDK `LanguageModelV2` — Mastra's own
10
+ // model interface, so nothing here reaches a network — scripted per agent:
11
+ // the first call asks for a tool, the next one answers. Every agent gets its
12
+ // own script so the token counts in the trace say which call they came from.
13
+ import * as failproofai from "@failproofai/sdk";
14
+ import { wrapTool } from "@failproofai/sdk/mastra";
15
+ import { Agent } from "@mastra/core/agent";
16
+ import { createTool } from "@mastra/core/tools";
17
+ import { createStep, createWorkflow } from "@mastra/core/workflows";
18
+ import { Mastra } from "@mastra/core/mastra";
19
+ import { InMemoryStore } from "@mastra/core/storage";
20
+ import { MCPClient } from "@mastra/mcp";
21
+ import { Memory } from "@mastra/memory";
22
+ import { createServer } from "node:http";
23
+ import type { AddressInfo } from "node:net";
24
+ import { join } from "node:path";
25
+ import { z } from "zod";
26
+
27
+ type Turn = { tool: string; input: Record<string, unknown>; usage: [number, number] } | { text: string; usage: [number, number] };
28
+
29
+ /**
30
+ * Holds the FIRST streamed step open after its response metadata: `reached`
31
+ * fires once the stream is parked there, and it moves on when `wait` settles.
32
+ */
33
+ type Gate = { reached: () => void; wait: Promise<void> };
34
+
35
+ function barrier(): { wait: Promise<void>; open: () => void } {
36
+ let open!: () => void;
37
+ const wait = new Promise<void>((resolve) => (open = resolve));
38
+ return { wait, open };
39
+ }
40
+
41
+ /**
42
+ * A scripted `LanguageModelV2`: `turns` alternate per call, so a two-step tool
43
+ * loop is turn 0 (tool call) then turn 1 (answer). `fail` makes every call
44
+ * throw, which is how a provider error reaches Mastra. Tool call ids are
45
+ * `<callPrefix>_<n>`, so two models in one session never reuse an id.
46
+ */
47
+ function scriptedModel(turns: Turn[], options: { fail?: boolean; callPrefix?: string; gate?: Gate } = {}) {
48
+ let calls = 0;
49
+ const next = (): Turn => turns[calls++ % turns.length]!;
50
+ const usage = ([input, output]: [number, number]) => ({
51
+ inputTokens: input,
52
+ outputTokens: output,
53
+ totalTokens: input + output,
54
+ });
55
+ return {
56
+ specificationVersion: "v2" as const,
57
+ provider: "scripted",
58
+ modelId: "scripted-model",
59
+ supportedUrls: {},
60
+ async doGenerate() {
61
+ if (options.fail) throw new Error("model exploded");
62
+ const turn = next();
63
+ return "tool" in turn
64
+ ? {
65
+ content: [
66
+ { type: "tool-call" as const, toolCallId: `${options.callPrefix ?? "call"}_${calls}`, toolName: turn.tool, input: JSON.stringify(turn.input) },
67
+ ],
68
+ finishReason: "tool-calls" as const,
69
+ usage: usage(turn.usage),
70
+ warnings: [],
71
+ }
72
+ : {
73
+ content: [{ type: "text" as const, text: turn.text }],
74
+ finishReason: "stop" as const,
75
+ usage: usage(turn.usage),
76
+ warnings: [],
77
+ };
78
+ },
79
+ async doStream() {
80
+ if (options.fail) throw new Error("model exploded");
81
+ const turn = next();
82
+ const parts: unknown[] = [
83
+ { type: "stream-start", warnings: [] },
84
+ { type: "response-metadata", id: `resp_${calls}`, modelId: "scripted-model", timestamp: new Date(0) },
85
+ ];
86
+ if ("tool" in turn) {
87
+ parts.push({ type: "tool-call", toolCallId: `${options.callPrefix ?? "call"}_${calls}`, toolName: turn.tool, input: JSON.stringify(turn.input) });
88
+ parts.push({ type: "finish", finishReason: "tool-calls", usage: usage(turn.usage) });
89
+ } else {
90
+ parts.push({ type: "text-start", id: "t" });
91
+ // Two deltas, so a step's content has to be assembled from the stream.
92
+ // (Not one per word: Mastra 0.24's textStream drops the third of five
93
+ // such deltas on its own, instrumented or not.)
94
+ const cut = turn.text.indexOf(" ", turn.text.length / 2) + 1;
95
+ for (const delta of [turn.text.slice(0, cut), turn.text.slice(cut)]) {
96
+ parts.push({ type: "text-delta", id: "t", delta });
97
+ }
98
+ parts.push({ type: "text-end", id: "t" });
99
+ parts.push({ type: "finish", finishReason: "stop", usage: usage(turn.usage) });
100
+ }
101
+ const gate = calls === 1 ? options.gate : undefined;
102
+ if (gate) {
103
+ let index = 0;
104
+ return {
105
+ stream: new ReadableStream({
106
+ async pull(controller) {
107
+ if (index === 2) {
108
+ gate.reached();
109
+ await gate.wait;
110
+ }
111
+ if (index >= parts.length) controller.close();
112
+ else controller.enqueue(parts[index++]);
113
+ },
114
+ }),
115
+ };
116
+ }
117
+ return {
118
+ stream: new ReadableStream({
119
+ start(controller) {
120
+ for (const part of parts) controller.enqueue(part);
121
+ controller.close();
122
+ },
123
+ }),
124
+ };
125
+ },
126
+ };
127
+ }
128
+
129
+ const WEATHER_TURNS: Turn[] = [
130
+ { tool: "weather", input: { city: "Paris" }, usage: [11, 7] },
131
+ { text: "It is sunny in Paris.", usage: [23, 9] },
132
+ ];
133
+
134
+ const weather = createTool({
135
+ id: "weather",
136
+ description: "Current weather for a city",
137
+ inputSchema: z.object({ city: z.string() }),
138
+ execute: async ({ context }: { context: { city: string } }) => ({ city: context.city, forecast: "sunny" }),
139
+ });
140
+
141
+ const brokenWeather = createTool({
142
+ id: "weather",
143
+ description: "Current weather for a city",
144
+ inputSchema: z.object({ city: z.string() }),
145
+ execute: async (): Promise<{ city: string }> => {
146
+ throw new Error("tool exploded");
147
+ },
148
+ });
149
+
150
+ const weatherAgent = (options: { fail?: boolean; tool?: typeof weather; gate?: Gate } = {}) =>
151
+ new Agent({
152
+ id: "weather-agent",
153
+ name: "weather-agent",
154
+ instructions: "Answer weather questions.",
155
+ model: scriptedModel(WEATHER_TURNS, options) as never,
156
+ tools: { weather: options.tool ?? weather },
157
+ });
158
+
159
+ function buildWorkflow(fail = false) {
160
+ const fetchCity = createStep({
161
+ id: "fetch-city",
162
+ inputSchema: z.object({ question: z.string() }),
163
+ outputSchema: z.object({ city: z.string() }),
164
+ execute: async () => ({ city: "Paris" }),
165
+ });
166
+ const ask = createStep({
167
+ id: "ask-agent",
168
+ inputSchema: z.object({ city: z.string() }),
169
+ outputSchema: z.object({ answer: z.string() }),
170
+ execute: async ({ inputData }) => {
171
+ if (fail) throw new Error("step exploded");
172
+ const out = await weatherAgent().generate(`Weather in ${inputData.city}?`);
173
+ return { answer: out.text };
174
+ },
175
+ });
176
+ return createWorkflow({
177
+ id: "weather-flow",
178
+ inputSchema: z.object({ question: z.string() }),
179
+ outputSchema: z.object({ answer: z.string() }),
180
+ })
181
+ .then(fetchCity)
182
+ .then(ask)
183
+ .commit();
184
+ }
185
+
186
+ const report = (value: unknown) => console.log(JSON.stringify(value));
187
+ const question = "What is the weather in Paris?";
188
+
189
+ // ---------------------------------------------------------------------------
190
+ // The coverage cases below need a model that answers from what it is ASKED
191
+ // rather than from how often it has been called: concurrent runs share one
192
+ // model, and memory, networks and structured output change what a call sees.
193
+ // ---------------------------------------------------------------------------
194
+
195
+ type Prompt = Array<{ role: string; content: unknown }>;
196
+ type CallOptions = { prompt: Prompt; responseFormat?: { type?: string; schema?: { properties?: Record<string, unknown> } } };
197
+
198
+ /** The text of the LAST user message — the question this call answers. */
199
+ function lastUserText(prompt: Prompt): string {
200
+ for (let i = prompt.length - 1; i >= 0; i -= 1) {
201
+ const message = prompt[i]!;
202
+ if (message.role !== "user") continue;
203
+ if (typeof message.content === "string") return message.content;
204
+ if (Array.isArray(message.content)) {
205
+ return message.content
206
+ .map((part: { type?: string; text?: string }) => (part.type === "text" ? (part.text ?? "") : ""))
207
+ .join("");
208
+ }
209
+ }
210
+ return "";
211
+ }
212
+
213
+ const cityOf = (text: string): string => /in ([A-Z][a-z]+)/.exec(text)?.[1] ?? "Paris";
214
+
215
+ /** Every text a call's prompt carries, system included, for routing on. */
216
+ const promptText = (prompt: Prompt): string => JSON.stringify(prompt);
217
+
218
+ let decidedCalls = 0;
219
+
220
+ /**
221
+ * A `LanguageModelV2` whose every answer is `decide(options)`. Tool call ids
222
+ * are `<prefix>_<n>` over one process-wide counter, so no two calls anywhere
223
+ * reuse one — the concurrency case needs that to tell runs apart.
224
+ */
225
+ function decidingModel(modelId: string, decide: (options: CallOptions) => Turn, prefix = "call") {
226
+ const usage = ([input, output]: [number, number]) => ({ inputTokens: input, outputTokens: output, totalTokens: input + output });
227
+ const answer = (options: CallOptions) => {
228
+ decidedCalls += 1;
229
+ return { turn: decide(options), id: `${prefix}_${decidedCalls}` };
230
+ };
231
+ return {
232
+ specificationVersion: "v2" as const,
233
+ provider: "scripted",
234
+ modelId,
235
+ supportedUrls: {},
236
+ async doGenerate(options: CallOptions) {
237
+ const { turn, id } = answer(options);
238
+ return "tool" in turn
239
+ ? {
240
+ content: [{ type: "tool-call" as const, toolCallId: id, toolName: turn.tool, input: JSON.stringify(turn.input) }],
241
+ finishReason: "tool-calls" as const,
242
+ usage: usage(turn.usage),
243
+ warnings: [],
244
+ }
245
+ : {
246
+ content: [{ type: "text" as const, text: turn.text }],
247
+ finishReason: "stop" as const,
248
+ usage: usage(turn.usage),
249
+ warnings: [],
250
+ };
251
+ },
252
+ async doStream(options: CallOptions) {
253
+ const { turn, id } = answer(options);
254
+ const parts: unknown[] = [
255
+ { type: "stream-start", warnings: [] },
256
+ { type: "response-metadata", id: `resp_${id}`, modelId, timestamp: new Date(0) },
257
+ ];
258
+ if ("tool" in turn) {
259
+ parts.push({ type: "tool-call", toolCallId: id, toolName: turn.tool, input: JSON.stringify(turn.input) });
260
+ parts.push({ type: "finish", finishReason: "tool-calls", usage: usage(turn.usage) });
261
+ } else {
262
+ parts.push({ type: "text-start", id: "t" });
263
+ parts.push({ type: "text-delta", id: "t", delta: turn.text });
264
+ parts.push({ type: "text-end", id: "t" });
265
+ parts.push({ type: "finish", finishReason: "stop", usage: usage(turn.usage) });
266
+ }
267
+ return {
268
+ stream: new ReadableStream({
269
+ start(controller) {
270
+ for (const part of parts) controller.enqueue(part);
271
+ controller.close();
272
+ },
273
+ }),
274
+ };
275
+ },
276
+ };
277
+ }
278
+
279
+ /** Ask `tool` for the city in the question, then answer from its result. */
280
+ const toolThenAnswer = (tool: string) => (options: CallOptions): Turn => {
281
+ // Memory titling a new thread (on by default in 0.x) asks the agent's model.
282
+ if (promptText(options.prompt).includes("short title")) return { text: "Weather", usage: [5, 3] };
283
+ const city = cityOf(lastUserText(options.prompt));
284
+ return options.prompt.at(-1)?.role === "tool"
285
+ ? { text: `It is sunny in ${city}.`, usage: [23, 9] }
286
+ : { tool, input: { city }, usage: [11, 7] };
287
+ };
288
+
289
+ const routedAgent = (name: string, tools: Record<string, unknown> = { weather }, extra: Record<string, unknown> = {}) =>
290
+ new Agent({
291
+ id: name,
292
+ name,
293
+ instructions: "Answer weather questions.",
294
+ model: decidingModel("routed-model", toolThenAnswer(Object.keys(tools)[0] ?? "weather")) as never,
295
+ tools: tools as never,
296
+ ...extra,
297
+ } as never);
298
+
299
+ const CITIES = ["Paris", "Rome", "Oslo", "Lima", "Cairo", "Tokyo", "Quito", "Dakar", "Hanoi", "Perth"];
300
+
301
+ const answerStep = createStep({
302
+ id: "answer",
303
+ inputSchema: z.object({ city: z.string() }),
304
+ outputSchema: z.object({ answer: z.string() }),
305
+ execute: async ({ inputData }) => ({ answer: `sunny in ${inputData.city}` }),
306
+ });
307
+
308
+ /** A two-step workflow, used on its own and nested inside another. */
309
+ function innerWorkflow() {
310
+ const pick = createStep({
311
+ id: "pick-city",
312
+ inputSchema: z.object({ question: z.string() }),
313
+ outputSchema: z.object({ city: z.string() }),
314
+ execute: async ({ inputData }) => ({ city: cityOf(inputData.question) }),
315
+ });
316
+ return createWorkflow({
317
+ id: "inner-flow",
318
+ inputSchema: z.object({ question: z.string() }),
319
+ outputSchema: z.object({ answer: z.string() }),
320
+ })
321
+ .then(pick)
322
+ .then(answerStep)
323
+ .commit();
324
+ }
325
+
326
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- one entry point for differently-typed workflows
327
+ function workflowCase(name: string): { createRunAsync(): Promise<any> } {
328
+ const input = z.object({ question: z.string() });
329
+ const out = z.object({ answer: z.string() });
330
+ const city = createStep({
331
+ id: "city",
332
+ inputSchema: input,
333
+ outputSchema: z.object({ city: z.string() }),
334
+ execute: async ({ inputData }) => ({ city: cityOf(inputData.question) }),
335
+ });
336
+ switch (name) {
337
+ case "branch": {
338
+ const sunny = createStep({ id: "sunny", inputSchema: z.object({ city: z.string() }), outputSchema: out, execute: async () => ({ answer: "sunny" }) });
339
+ const rainy = createStep({ id: "rainy", inputSchema: z.object({ city: z.string() }), outputSchema: out, execute: async () => ({ answer: "rainy" }) });
340
+ return createWorkflow({ id: "branch-flow", inputSchema: input, outputSchema: z.any() })
341
+ .then(city)
342
+ .branch([
343
+ [async ({ inputData }) => inputData.city === "Paris", sunny],
344
+ [async ({ inputData }) => inputData.city !== "Paris", rainy],
345
+ ])
346
+ .commit();
347
+ }
348
+ case "parallel": {
349
+ const high = createStep({ id: "high", inputSchema: z.object({ city: z.string() }), outputSchema: z.object({ t: z.number() }), execute: async () => ({ t: 25 }) });
350
+ const low = createStep({ id: "low", inputSchema: z.object({ city: z.string() }), outputSchema: z.object({ t: z.number() }), execute: async () => ({ t: 12 }) });
351
+ return createWorkflow({ id: "parallel-flow", inputSchema: input, outputSchema: z.any() }).then(city).parallel([high, low]).commit();
352
+ }
353
+ case "loop": {
354
+ const count = createStep({
355
+ id: "count",
356
+ inputSchema: z.object({ n: z.number() }),
357
+ outputSchema: z.object({ n: z.number() }),
358
+ execute: async ({ inputData }) => ({ n: inputData.n + 1 }),
359
+ });
360
+ const cities = createStep({
361
+ id: "cities",
362
+ inputSchema: z.object({ n: z.number() }),
363
+ outputSchema: z.array(z.object({ city: z.string() })),
364
+ execute: async () => [{ city: "Paris" }, { city: "Rome" }],
365
+ });
366
+ return createWorkflow({ id: "loop-flow", inputSchema: z.object({ n: z.number() }), outputSchema: z.any() })
367
+ .dowhile(count, async ({ inputData }) => inputData.n < 3)
368
+ .then(cities)
369
+ .foreach(answerStep)
370
+ .commit();
371
+ }
372
+ case "nested":
373
+ return createWorkflow({ id: "outer-flow", inputSchema: input, outputSchema: out }).then(innerWorkflow()).commit();
374
+ case "agent-step": {
375
+ const toPrompt = createStep({
376
+ id: "to-prompt",
377
+ inputSchema: input,
378
+ outputSchema: z.object({ prompt: z.string() }),
379
+ execute: async ({ inputData }) => ({ prompt: inputData.question }),
380
+ });
381
+ return createWorkflow({ id: "agent-step-flow", inputSchema: input, outputSchema: z.any() })
382
+ .then(toPrompt)
383
+ .then(createStep(routedAgent("weather-agent")))
384
+ .commit();
385
+ }
386
+ case "suspend": {
387
+ const approve = createStep({
388
+ id: "approve",
389
+ inputSchema: z.object({ city: z.string() }),
390
+ outputSchema: z.object({ city: z.string(), approved: z.boolean() }),
391
+ suspendSchema: z.object({ prompt: z.string() }),
392
+ resumeSchema: z.object({ approved: z.boolean() }),
393
+ execute: async ({ inputData, resumeData, suspend }) => {
394
+ if (resumeData === undefined) return (await suspend({ prompt: `Look up ${inputData.city}?` })) as never;
395
+ return { city: inputData.city, approved: resumeData.approved };
396
+ },
397
+ });
398
+ const done = createStep({
399
+ id: "done",
400
+ inputSchema: z.object({ city: z.string(), approved: z.boolean() }),
401
+ outputSchema: out,
402
+ execute: async ({ inputData }) => ({ answer: inputData.approved ? `sunny in ${inputData.city}` : "declined" }),
403
+ });
404
+ return createWorkflow({ id: "approval-flow", inputSchema: input, outputSchema: out }).then(city).then(approve).then(done).commit();
405
+ }
406
+ default:
407
+ throw new Error(`unknown workflow ${name}`);
408
+ }
409
+ }
410
+
411
+ const mcpServer = () => ({ command: process.execPath, args: [join(process.cwd(), "mcp-server.mjs")] });
412
+
413
+ async function main(scenario: string): Promise<void> {
414
+ report({ instrumented: await failproofai.instrument("mastra") });
415
+
416
+ switch (scenario) {
417
+ case "generate": {
418
+ const out = await weatherAgent().generate(question);
419
+ report({ answer: out.text });
420
+ break;
421
+ }
422
+ case "stream": {
423
+ const out = await weatherAgent().stream(question);
424
+ let text = "";
425
+ for await (const chunk of out.textStream) text += chunk;
426
+ report({ answer: text });
427
+ break;
428
+ }
429
+ case "subagent": {
430
+ const helper = new Agent({
431
+ id: "helper",
432
+ name: "helper",
433
+ description: "Looks up the weather.",
434
+ instructions: "Answer weather questions.",
435
+ model: scriptedModel(WEATHER_TURNS) as never,
436
+ tools: { weather },
437
+ });
438
+ const boss = new Agent({
439
+ id: "boss",
440
+ name: "boss",
441
+ instructions: "Delegate weather questions.",
442
+ model: scriptedModel([
443
+ { tool: "agent-helper", input: { prompt: "Weather in Paris?" }, usage: [40, 12] },
444
+ { text: "The helper says it is sunny.", usage: [60, 8] },
445
+ ], { callPrefix: "delegate" }) as never,
446
+ agents: { helper },
447
+ });
448
+ const out = await boss.generate(question);
449
+ report({ answer: out.text });
450
+ break;
451
+ }
452
+ case "workflow": {
453
+ const run = await buildWorkflow().createRunAsync();
454
+ const out = await run.start({ inputData: { question } });
455
+ report({ status: out.status });
456
+ break;
457
+ }
458
+ case "workflow-error": {
459
+ const run = await buildWorkflow(true).createRunAsync();
460
+ const out = await run.start({ inputData: { question } });
461
+ report({ status: out.status });
462
+ break;
463
+ }
464
+ case "wraptool": {
465
+ const tool = wrapTool(weather);
466
+ report({ out: await tool.execute!({ context: { city: "Rome" } } as never) });
467
+ break;
468
+ }
469
+ case "tool-error": {
470
+ const out = await weatherAgent({ tool: brokenWeather as never }).generate(question);
471
+ report({ answer: out.text });
472
+ break;
473
+ }
474
+ case "model-error": {
475
+ try {
476
+ await weatherAgent({ fail: true }).generate(question);
477
+ report({ threw: false });
478
+ } catch (error) {
479
+ report({ threw: (error as Error).message });
480
+ }
481
+ break;
482
+ }
483
+ case "stream-model-error": {
484
+ const out = await weatherAgent({ fail: true }).stream(question);
485
+ let chunks = 0;
486
+ for await (const _ of out.fullStream) chunks += 1;
487
+ report({ chunks, error: String(out.error) });
488
+ break;
489
+ }
490
+ case "scope": {
491
+ await failproofai.session({ sessionId: "req-1" }, () =>
492
+ failproofai.agent("planner", { goal: "plan" }, () => weatherAgent().generate(question)),
493
+ );
494
+ break;
495
+ }
496
+ case "uninstrument": {
497
+ report({ removed: failproofai.uninstrument() });
498
+ await weatherAgent().generate(question);
499
+ break;
500
+ }
501
+ case "uninstrument-midstream": {
502
+ // uninstrument() lands while the first model step's stream is parked
503
+ // mid-flight; the caller then reads the run to the end regardless.
504
+ const reached = barrier();
505
+ const gate = barrier();
506
+ await failproofai.session({ sessionId: "req-1" }, async () => {
507
+ const out = await weatherAgent({ gate: { reached: reached.open, wait: gate.wait } }).stream(question);
508
+ const reading = (async () => {
509
+ let text = "";
510
+ for await (const chunk of out.textStream) text += chunk;
511
+ return text;
512
+ })();
513
+ await reached.wait;
514
+ report({ removed: failproofai.uninstrument() });
515
+ gate.open();
516
+ report({ answer: await reading });
517
+ });
518
+ break;
519
+ }
520
+ case "uninstrument-reuse": {
521
+ // One Agent instance: run while instrumented, then again (both ways)
522
+ // after uninstrument().
523
+ await failproofai.session({ sessionId: "req-1" }, async () => {
524
+ const agent = weatherAgent();
525
+ await agent.generate(question);
526
+ report({ removed: failproofai.uninstrument() });
527
+ const again = await agent.generate(question);
528
+ const streamed = await agent.stream(question);
529
+ let text = "";
530
+ for await (const chunk of streamed.textStream) text += chunk;
531
+ report({ answers: [again.text, text] });
532
+ });
533
+ break;
534
+ }
535
+ case "reinstrument": {
536
+ report({ removed: failproofai.uninstrument() });
537
+ report({ instrumented: await failproofai.instrument("mastra") });
538
+ const out = await weatherAgent().generate(question);
539
+ report({ answer: out.text });
540
+ break;
541
+ }
542
+ case "reinstrument-reuse": {
543
+ // The same Agent instance across an uninstrument()/instrument() cycle.
544
+ const agent = weatherAgent();
545
+ await agent.generate(question);
546
+ report({ removed: failproofai.uninstrument() });
547
+ report({ instrumented: await failproofai.instrument("mastra") });
548
+ const out = await agent.generate(question);
549
+ report({ answer: out.text });
550
+ break;
551
+ }
552
+ case "mastra-instance": {
553
+ // Registered on a Mastra instance and fetched back through it — the
554
+ // shape `mastra dev` and every deployer use.
555
+ const mastra = new Mastra({
556
+ agents: { weatherAgent: weatherAgent() },
557
+ workflows: { weatherFlow: buildWorkflow() },
558
+ logger: false,
559
+ });
560
+ const out = await mastra.getAgent("weatherAgent").generate(question);
561
+ const run = await mastra.getWorkflow("weatherFlow").createRunAsync();
562
+ const flow = await run.start({ inputData: { question } });
563
+ report({ answer: out.text, status: flow.status });
564
+ break;
565
+ }
566
+ case "concurrent": {
567
+ // Ten runs of ONE Agent instance at once, in one session.
568
+ const agent = routedAgent("weather-agent");
569
+ await failproofai.session({ sessionId: "req-1" }, async () => {
570
+ const outs = await Promise.all(CITIES.map((city) => agent.generate(`What is the weather in ${city}?`)));
571
+ report({ answers: outs.map((out) => out.text) });
572
+ });
573
+ break;
574
+ }
575
+ case "concurrent-sessions": {
576
+ // The same, with no scope: every run is its own session, so a leaked
577
+ // event would land in the wrong one where the test can see it.
578
+ const agent = routedAgent("weather-agent");
579
+ const outs = await Promise.all(
580
+ CITIES.map((city, i) =>
581
+ i % 2 === 0
582
+ ? agent.generate(`What is the weather in ${city}?`).then((out) => out.text)
583
+ : agent.stream(`What is the weather in ${city}?`).then(async (out) => {
584
+ let text = "";
585
+ for await (const chunk of out.textStream) text += chunk;
586
+ return text;
587
+ }),
588
+ ),
589
+ );
590
+ report({ answers: outs });
591
+ break;
592
+ }
593
+ case "memory": {
594
+ // Two turns of one conversation (thread) through @mastra/memory.
595
+ const agent = routedAgent("weather-agent", { weather }, {
596
+ memory: new Memory({ storage: new InMemoryStore(), options: { lastMessages: 10 } }),
597
+ });
598
+ const memory = { thread: "thread-42", resource: "user-7" };
599
+ const first = await agent.generate("What is the weather in Paris?", { memory });
600
+ const second = await agent.stream("And what is the weather in Rome?", { memory });
601
+ let text = "";
602
+ for await (const chunk of second.textStream) text += chunk;
603
+ report({ answers: [first.text, text] });
604
+ break;
605
+ }
606
+ case "memory-scoped": {
607
+ // An enclosing session scope wins over the thread.
608
+ const agent = routedAgent("weather-agent", { weather }, {
609
+ memory: new Memory({ storage: new InMemoryStore(), options: { lastMessages: 10 } }),
610
+ });
611
+ await failproofai.session({ sessionId: "req-1" }, () =>
612
+ agent.generate(question, { memory: { thread: "thread-42", resource: "user-7" } }),
613
+ );
614
+ break;
615
+ }
616
+ case "wf-branch":
617
+ case "wf-parallel":
618
+ case "wf-loop":
619
+ case "wf-nested":
620
+ case "wf-agent-step": {
621
+ const name = scenario.slice(3);
622
+ const run = await workflowCase(name).createRunAsync();
623
+ const out = await run.start({ inputData: (name === "loop" ? { n: 0 } : { question }) as never });
624
+ report({ status: out.status, result: out.status === "success" ? out.result : undefined });
625
+ break;
626
+ }
627
+ case "wf-stream": {
628
+ // A workflow run streamed rather than awaited.
629
+ const run = await workflowCase("agent-step").createRunAsync();
630
+ const streamed = await run.stream({ inputData: { question } });
631
+ let chunks = 0;
632
+ for await (const _ of streamed.fullStream) chunks += 1;
633
+ report({ chunks, status: await streamed.status });
634
+ break;
635
+ }
636
+ case "wf-suspend": {
637
+ // A resume reads the suspended run's snapshot back from storage.
638
+ const mastra = new Mastra({ workflows: { approval: workflowCase("suspend") as never }, storage: new InMemoryStore(), logger: false });
639
+ const run = await (mastra.getWorkflow("approval") as unknown as ReturnType<typeof workflowCase>).createRunAsync();
640
+ const first = await run.start({ inputData: { question } });
641
+ report({ status: first.status });
642
+ const second = await run.resume({ step: "approve", resumeData: { approved: true } });
643
+ report({ status: second.status, result: second.status === "success" ? second.result : undefined });
644
+ break;
645
+ }
646
+ case "processors": {
647
+ // An input processor that rewrites the prompt and an output processor
648
+ // that rewrites the answer: neither may add or lose an event.
649
+ const agent = routedAgent("weather-agent", { weather }, {
650
+ inputProcessors: [
651
+ {
652
+ id: "tag-input",
653
+ processInput: ({ messages }: { messages: unknown[] }) => messages,
654
+ },
655
+ ],
656
+ outputProcessors: [
657
+ {
658
+ id: "shout",
659
+ processOutputResult: ({ messages }: { messages: unknown[] }) => messages,
660
+ },
661
+ ],
662
+ });
663
+ const out = await agent.generate(question);
664
+ const streamed = await agent.stream(question);
665
+ let text = "";
666
+ for await (const chunk of streamed.textStream) text += chunk;
667
+ report({ answers: [out.text, text] });
668
+ break;
669
+ }
670
+ case "tripwire": {
671
+ // A guardrail that blocks the prompt: no model call, the run rejected.
672
+ const agent = routedAgent("weather-agent", { weather }, {
673
+ inputProcessors: [
674
+ {
675
+ id: "block-paris",
676
+ processInput: ({ messages, abort }: { messages: unknown[]; abort: (reason: string) => never }) =>
677
+ JSON.stringify(messages).includes("Paris") ? abort("Paris is blocked") : messages,
678
+ },
679
+ ],
680
+ });
681
+ const out = await agent.generate(question);
682
+ const streamed = await agent.stream(question);
683
+ for await (const _ of streamed.fullStream) void _;
684
+ report({ tripwire: Boolean((out as { tripwire?: unknown }).tripwire), text: out.text });
685
+ break;
686
+ }
687
+ case "tripwire-output": {
688
+ // A guardrail on the OUTPUT stream: the model answers, the processor
689
+ // blocks the answer mid-stream.
690
+ const agent = new Agent({
691
+ id: "weather-agent",
692
+ name: "weather-agent",
693
+ instructions: "Answer weather questions.",
694
+ model: decidingModel("routed-model", () => ({ text: "It is sunny in Paris.", usage: [9, 4] })) as never,
695
+ outputProcessors: [
696
+ {
697
+ id: "block-answer",
698
+ processOutputStream: ({ part, abort }: { part: { type: string }; abort: (reason: string) => never }) =>
699
+ part.type === "text-delta" ? abort("answer blocked") : part,
700
+ },
701
+ ],
702
+ } as never);
703
+ const streamed = await agent.stream(question);
704
+ let chunks = 0;
705
+ for await (const _ of streamed.fullStream) chunks += 1;
706
+ report({ chunks, tripwire: Boolean((streamed as { tripwire?: unknown }).tripwire) });
707
+ break;
708
+ }
709
+ case "usage-openai-compatible": {
710
+ // Mastra's own model for an OpenAI-compatible endpoint (`{ id, url }`),
711
+ // against a loopback server that — like OpenAI — sends a streamed
712
+ // step's usage only when the request asks for it, or always when
713
+ // USAGE_ALWAYS=1 (as some compatible servers do).
714
+ const requests: Array<{ stream?: boolean; streamOptions?: unknown }> = [];
715
+ const usage = { prompt_tokens: 17, completion_tokens: 5, total_tokens: 22 };
716
+ const server = createServer((req, res) => {
717
+ let raw = "";
718
+ req.on("data", (chunk: Buffer) => (raw += chunk.toString()));
719
+ req.on("end", () => {
720
+ const body = JSON.parse(raw || "{}") as { stream?: boolean; stream_options?: { include_usage?: boolean } };
721
+ requests.push({ stream: body.stream, streamOptions: body.stream_options });
722
+ const base = { id: "c1", created: 0, model: "compat-model" };
723
+ if (!body.stream) {
724
+ res.setHeader("content-type", "application/json");
725
+ res.end(JSON.stringify({ ...base, object: "chat.completion", choices: [{ index: 0, message: { role: "assistant", content: "Sunny." }, finish_reason: "stop" }], usage }));
726
+ return;
727
+ }
728
+ res.setHeader("content-type", "text/event-stream");
729
+ const send = (chunk: unknown) => res.write(`data: ${JSON.stringify(chunk)}\n\n`);
730
+ send({ ...base, object: "chat.completion.chunk", choices: [{ index: 0, delta: { role: "assistant", content: "Sunny." }, finish_reason: null }] });
731
+ send({ ...base, object: "chat.completion.chunk", choices: [{ index: 0, delta: {}, finish_reason: "stop" }] });
732
+ if (process.env.USAGE_ALWAYS === "1" || body.stream_options?.include_usage) {
733
+ send({ ...base, object: "chat.completion.chunk", choices: [], usage });
734
+ }
735
+ res.end("data: [DONE]\n\n");
736
+ });
737
+ });
738
+ await new Promise<void>((resolve) => server.listen(0, "127.0.0.1", resolve));
739
+ try {
740
+ const url = `http://127.0.0.1:${(server.address() as AddressInfo).port}/v1`;
741
+ const agent = new Agent({ id: "compat-agent", name: "compat-agent", instructions: "Be brief.", model: { id: "custom/compat-model", url, apiKey: "test-key" } as never });
742
+ const streamed = await agent.stream(question);
743
+ let text = "";
744
+ for await (const chunk of streamed.textStream) text += chunk;
745
+ const streamedUsage = await streamed.usage;
746
+ const generated = await agent.generate(question);
747
+ report({ text, mastraStreamTokens: streamedUsage.inputTokens ?? 0, mastraGenerateTokens: generated.usage.inputTokens ?? 0, requests });
748
+ } finally {
749
+ // Deno's node:http keeps idle keep-alive sockets open through close(),
750
+ // so the process would outlive the test; Node closes idle ones itself.
751
+ server.closeAllConnections();
752
+ server.close();
753
+ }
754
+ break;
755
+ }
756
+ case "mcp":
757
+ case "mcp-toolsets": {
758
+ const mcp = new MCPClient({ id: `mcp-${process.pid}`, servers: { weatherServer: mcpServer() } });
759
+ try {
760
+ if (scenario === "mcp") {
761
+ const tools = await mcp.getTools();
762
+ const agent = routedAgent("weather-agent", tools);
763
+ const out = await agent.generate(question);
764
+ report({ tools: Object.keys(tools), answer: out.text });
765
+ } else {
766
+ const agent = new Agent({
767
+ id: "weather-agent",
768
+ name: "weather-agent",
769
+ instructions: "Answer weather questions.",
770
+ model: decidingModel("routed-model", toolThenAnswer("forecast")) as never,
771
+ });
772
+ const out = await agent.generate(question, { toolsets: await mcp.getToolsets() });
773
+ report({ answer: out.text });
774
+ }
775
+ } finally {
776
+ await mcp.disconnect();
777
+ }
778
+ break;
779
+ }
780
+ case "structured": {
781
+ const agent = new Agent({
782
+ id: "weather-agent",
783
+ name: "weather-agent",
784
+ instructions: "Answer weather questions.",
785
+ model: decidingModel("routed-model", (options) => ({
786
+ text: JSON.stringify({ city: cityOf(lastUserText(options.prompt)), forecast: "sunny" }),
787
+ usage: [15, 6],
788
+ })) as never,
789
+ });
790
+ const schema = z.object({ city: z.string(), forecast: z.string() });
791
+ const out = await agent.generate(question, { structuredOutput: { schema } });
792
+ const streamed = await agent.stream(question, { structuredOutput: { schema } });
793
+ report({ object: out.object, streamed: await streamed.object });
794
+ break;
795
+ }
796
+ case "structured-model": {
797
+ // Structuring by a SECOND model: Mastra runs it through an agent of
798
+ // its own, after the main loop.
799
+ const agent = routedAgent("weather-agent");
800
+ const structurer = decidingModel("structuring-model", () => ({ text: JSON.stringify({ city: "Paris", forecast: "sunny" }), usage: [30, 5] }));
801
+ const out = await agent.generate(question, {
802
+ structuredOutput: { schema: z.object({ city: z.string(), forecast: z.string() }), model: structurer as never },
803
+ });
804
+ report({ object: out.object });
805
+ break;
806
+ }
807
+ case "maxsteps-tool-error": {
808
+ // One step only, and the tool it calls throws.
809
+ const agent = routedAgent("weather-agent", { weather: brokenWeather });
810
+ const out = await agent.generate(question, { maxSteps: 1 });
811
+ report({ finishReason: out.finishReason, text: out.text });
812
+ break;
813
+ }
814
+ case "network": {
815
+ // An agent network: the planner's model routes to `helper` once, the
816
+ // helper answers with its tool, the planner's model judges it complete.
817
+ const helper = new Agent({
818
+ id: "helper",
819
+ name: "helper",
820
+ description: "Looks up the weather.",
821
+ instructions: "Answer weather questions.",
822
+ model: decidingModel("routed-model", toolThenAnswer("weather")) as never,
823
+ tools: { weather },
824
+ });
825
+ const planner = new Agent({
826
+ id: "planner",
827
+ name: "planner",
828
+ instructions: "Coordinate the specialists.",
829
+ model: decidingModel("router-model", (options) => {
830
+ // Tell the calls apart by the schema they ask for, falling back to
831
+ // the prompt when a release injects the schema as text instead. The
832
+ // completion check comes first: its prompt quotes the routing answer.
833
+ const fields = options.responseFormat?.schema?.properties ?? {};
834
+ const asked = lastUserText(options.prompt);
835
+ if ("isComplete" in fields || (asked.includes("evaluate") && asked.includes("complete"))) {
836
+ return { text: JSON.stringify({ isComplete: true, completionReason: "answered", finalResult: "It is sunny in Paris." }), usage: [40, 6] };
837
+ }
838
+ if ("primitiveId" in fields || promptText(options.prompt).includes("primitiveId")) {
839
+ return {
840
+ text: JSON.stringify({ primitiveId: "helper", primitiveType: "agent", prompt: question, selectionReason: "weather" }),
841
+ usage: [50, 10],
842
+ };
843
+ }
844
+ return { text: "Weather in Paris", usage: [5, 3] };
845
+ }) as never,
846
+ agents: { helper },
847
+ memory: new Memory({ storage: new InMemoryStore(), options: { lastMessages: 10 } }),
848
+ });
849
+ const stream = await planner.network(question, { memory: { thread: "thread-net", resource: "user-7" } });
850
+ for await (const _ of stream) void _;
851
+ report({ status: await stream.status });
852
+ break;
853
+ }
854
+ case "agent-in-tool": {
855
+ // Delegation by hand: a tool whose body runs another agent.
856
+ const helper = routedAgent("helper");
857
+ const ask = createTool({
858
+ id: "ask-helper",
859
+ description: "Ask the helper",
860
+ inputSchema: z.object({ city: z.string() }),
861
+ execute: async ({ context }: { context: { city: string } }) => ({ answer: (await helper.generate(`What is the weather in ${context.city}?`)).text }),
862
+ });
863
+ const boss = routedAgent("boss", { "ask-helper": ask });
864
+ const out = await boss.generate(question);
865
+ report({ answer: out.text });
866
+ break;
867
+ }
868
+ default:
869
+ throw new Error(`unknown scenario ${scenario}`);
870
+ }
871
+ await failproofai.flush();
872
+ }
873
+
874
+ main(process.argv[2] ?? "generate").catch((error: unknown) => {
875
+ console.error("FATAL", error);
876
+ process.exit(1);
877
+ });