failproofai 1.0.1 → 1.0.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (389) 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 +6 -6
  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 +2 -2
  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 +2 -2
  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 +3 -2
  24. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/audit/run/route.js +5 -4
  26. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/auth/login-request/route.js +2 -2
  29. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +4 -3
  31. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/auth/logout/route.js +4 -4
  33. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/auth/status/route.js +4 -4
  35. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  38. package/.next/standalone/.next/server/app/audit/page.js +2 -2
  39. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  41. package/.next/standalone/.next/server/app/index.html +1 -1
  42. package/.next/standalone/.next/server/app/index.rsc +15 -15
  43. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
  44. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  45. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  46. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  47. package/.next/standalone/.next/server/app/page.js +2 -2
  48. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +66 -22
  51. package/.next/standalone/.next/server/app/policies/page.js +5 -4
  52. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  55. package/.next/standalone/.next/server/app/project/[name]/page.js +2 -2
  56. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  59. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  60. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +2 -2
  61. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  62. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  64. package/.next/standalone/.next/server/app/projects/page.js +2 -2
  65. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -4
  68. package/.next/standalone/.next/server/app/settings/page.js +1 -1
  69. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/chunks/{[externals]__1qzqcio._.js → [externals]__0e32-7c._.js} +1 -1
  72. package/.next/standalone/.next/server/chunks/[externals]__1s462yl._.js +3 -0
  73. package/.next/standalone/.next/server/chunks/[root-of-the-server]__01eqny5._.js +3 -0
  74. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0xu5z._.js +1 -1
  75. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1p8poxd._.js → [root-of-the-server]__0igxt32._.js} +2 -2
  76. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0neqlu-._.js +3 -0
  77. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +3 -0
  78. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t9oqnn._.js +3 -0
  79. package/.next/standalone/.next/server/chunks/_0bs-v8p._.js +3 -0
  80. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +3 -0
  81. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +3 -0
  82. package/.next/standalone/.next/server/chunks/_185gyk9._.js +3 -0
  83. package/.next/standalone/.next/server/chunks/_1ek68ln._.js +5 -6
  84. package/.next/standalone/.next/server/chunks/lib_telemetry-id_ts_1k8gj9o._.js +3 -0
  85. package/.next/standalone/.next/server/chunks/{node_modules_posthog-node_dist_entrypoints_index_node_mjs_09d5c79._.js → node_modules_posthog-node_dist_entrypoints_index_node_mjs_04op_ou._.js} +1 -1
  86. package/.next/standalone/.next/server/chunks/{node_modules_posthog-node_dist_entrypoints_index_node_mjs_1d2g73o._.js → node_modules_posthog-node_dist_entrypoints_index_node_mjs_0dr20uz._.js} +1 -1
  87. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  88. package/.next/standalone/.next/server/chunks/src_hooks_0xbw3bu._.js +12 -0
  89. package/.next/standalone/.next/server/chunks/src_hooks_fp-home_ts_09kv0bn._.js +1 -1
  90. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +4 -0
  91. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +4 -0
  92. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +4 -0
  93. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0spkm68._.js → [root-of-the-server]__07gm3zl._.js} +21 -20
  94. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +4 -0
  95. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +4 -0
  96. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +1 -1
  97. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +4 -0
  98. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +6 -0
  99. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__07tbbf3._.js → [root-of-the-server]__0zig5sv._.js} +2 -2
  100. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__192nhvh._.js +5 -0
  101. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +4 -0
  102. package/.next/standalone/.next/server/chunks/ssr/{_0lvyuv4._.js → _00e9tnf._.js} +2 -2
  103. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  104. package/.next/standalone/.next/server/chunks/ssr/{_0u5zauv._.js → _12l4a_k._.js} +1 -1
  105. package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +1 -1
  106. package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
  107. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +13 -13
  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 +1 -1
  111. package/.next/standalone/.next/server/chunks/ssr/src_hooks_08o7bqo._.js +10 -0
  112. package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +1 -1
  113. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-home_ts_0je3xkv._.js +1 -1
  114. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  115. package/.next/standalone/.next/server/middleware.js +1 -1
  116. package/.next/standalone/.next/server/pages/404.html +1 -1
  117. package/.next/standalone/.next/server/pages/500.html +1 -1
  118. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  119. package/.next/standalone/.next/server/server-reference-manifest.json +71 -27
  120. package/.next/standalone/.next/static/chunks/{37fcpc36x9gpe.js → 0eqky-7n7dgdm.js} +1 -1
  121. package/.next/standalone/.next/static/chunks/{1ide1wl2f7zi1.js → 0sa9v5mhc8861.js} +13 -13
  122. package/.next/standalone/.next/static/chunks/1mfzsja6ftim5.css +2 -0
  123. package/.next/standalone/.next/static/chunks/{3k7mxbp9hiom0.js → 1nuqytbta44af.js} +1 -1
  124. package/.next/standalone/.next/static/chunks/1sl2xmn9inx3y.js +6 -0
  125. package/.next/standalone/.next/static/chunks/{2_2lhuojq2xop.js → 2aawsjld9ied_.js} +1 -1
  126. package/.next/standalone/.next/static/chunks/2gn7ut4svofm2.js +1 -0
  127. package/.next/standalone/.next/static/chunks/{31s1smp-g7gks.js → 2hs7ycvsav7v2.js} +1 -1
  128. package/.next/standalone/.next/static/chunks/{0k5050ezjvv49.js → 2i2yt3hzjredm.js} +1 -1
  129. package/.next/standalone/.next/static/chunks/{3c808qrfcq0im.js → 35xg6retpe6rp.js} +1 -1
  130. package/.next/standalone/.next/static/chunks/{2zpp1we2jv6tb.js → 3y54nw0i7dsjl.js} +1 -1
  131. package/.next/standalone/SECURITY.md +5 -4
  132. package/.next/standalone/app/actions/get-hooks-config.ts +108 -17
  133. package/.next/standalone/app/actions/pack-actions.ts +153 -0
  134. package/.next/standalone/app/audit/_components/run-progress.tsx +1 -1
  135. package/.next/standalone/app/audit/_components/share-templates.ts +13 -13
  136. package/.next/standalone/app/policies/hooks-client.tsx +320 -14
  137. package/.next/standalone/components/navbar.tsx +2 -28
  138. package/.next/standalone/components/reach-developers.tsx +8 -1
  139. package/.next/standalone/docs-old/agenteye/python-sdk-skill.mdx +1 -1
  140. package/.next/standalone/docs-old/agenteye/python-sdk.mdx +59 -35
  141. package/.next/standalone/docs-old/i18n/README.ar.md +1 -0
  142. package/.next/standalone/docs-old/i18n/README.de.md +1 -0
  143. package/.next/standalone/docs-old/i18n/README.es.md +1 -0
  144. package/.next/standalone/docs-old/i18n/README.fr.md +1 -0
  145. package/.next/standalone/docs-old/i18n/README.he.md +1 -0
  146. package/.next/standalone/docs-old/i18n/README.hi.md +1 -0
  147. package/.next/standalone/docs-old/i18n/README.it.md +1 -0
  148. package/.next/standalone/docs-old/i18n/README.ja.md +1 -0
  149. package/.next/standalone/docs-old/i18n/README.ko.md +1 -0
  150. package/.next/standalone/docs-old/i18n/README.pt-br.md +1 -0
  151. package/.next/standalone/docs-old/i18n/README.ru.md +1 -0
  152. package/.next/standalone/docs-old/i18n/README.tr.md +1 -0
  153. package/.next/standalone/docs-old/i18n/README.vi.md +1 -0
  154. package/.next/standalone/docs-old/i18n/README.zh.md +1 -0
  155. package/.next/standalone/fp-cloud-cli/CHANGELOG.md +431 -0
  156. package/.next/standalone/fp-cloud-cli/LICENSE +42 -0
  157. package/.next/standalone/fp-cloud-cli/MANIFEST.in +10 -0
  158. package/.next/standalone/fp-cloud-cli/README.md +259 -0
  159. package/.next/standalone/fp-cloud-cli/fp_cli/__init__.py +10 -0
  160. package/.next/standalone/fp-cloud-cli/fp_cli/__main__.py +4 -0
  161. package/.next/standalone/fp-cloud-cli/fp_cli/_click_compat.py +64 -0
  162. package/.next/standalone/fp-cloud-cli/fp_cli/_context.py +332 -0
  163. package/.next/standalone/fp-cloud-cli/fp_cli/_version.py +1 -0
  164. package/.next/standalone/fp-cloud-cli/fp_cli/analytics.py +432 -0
  165. package/.next/standalone/fp-cloud-cli/fp_cli/analytics_config.py +77 -0
  166. package/.next/standalone/fp-cloud-cli/fp_cli/analytics_registry.py +83 -0
  167. package/.next/standalone/fp-cloud-cli/fp_cli/app.py +492 -0
  168. package/.next/standalone/fp-cloud-cli/fp_cli/auth.py +160 -0
  169. package/.next/standalone/fp-cloud-cli/fp_cli/client.py +1694 -0
  170. package/.next/standalone/fp-cloud-cli/fp_cli/commands/__init__.py +0 -0
  171. package/.next/standalone/fp-cloud-cli/fp_cli/commands/_write.py +214 -0
  172. package/.next/standalone/fp-cloud-cli/fp_cli/commands/agent_cmds.py +407 -0
  173. package/.next/standalone/fp-cloud-cli/fp_cli/commands/alerts_cmds.py +445 -0
  174. package/.next/standalone/fp-cloud-cli/fp_cli/commands/audits_cmds.py +1054 -0
  175. package/.next/standalone/fp-cloud-cli/fp_cli/commands/auth_cmds.py +512 -0
  176. package/.next/standalone/fp-cloud-cli/fp_cli/commands/errors_cmds.py +190 -0
  177. package/.next/standalone/fp-cloud-cli/fp_cli/commands/evals_cmds.py +161 -0
  178. package/.next/standalone/fp-cloud-cli/fp_cli/commands/events_cmds.py +159 -0
  179. package/.next/standalone/fp-cloud-cli/fp_cli/commands/fleet_cmds.py +416 -0
  180. package/.next/standalone/fp-cloud-cli/fp_cli/commands/guardrails_cmds.py +148 -0
  181. package/.next/standalone/fp-cloud-cli/fp_cli/commands/incidents_cmds.py +472 -0
  182. package/.next/standalone/fp-cloud-cli/fp_cli/commands/keys_cmds.py +407 -0
  183. package/.next/standalone/fp-cloud-cli/fp_cli/commands/list_cmds.py +63 -0
  184. package/.next/standalone/fp-cloud-cli/fp_cli/commands/orgs_cmds.py +319 -0
  185. package/.next/standalone/fp-cloud-cli/fp_cli/commands/policies_cmds.py +499 -0
  186. package/.next/standalone/fp-cloud-cli/fp_cli/commands/queries_cmds.py +378 -0
  187. package/.next/standalone/fp-cloud-cli/fp_cli/commands/sessions_cmds.py +151 -0
  188. package/.next/standalone/fp-cloud-cli/fp_cli/commands/settings_cmds.py +150 -0
  189. package/.next/standalone/fp-cloud-cli/fp_cli/commands/usage_cmds.py +35 -0
  190. package/.next/standalone/fp-cloud-cli/fp_cli/commands/users_cmds.py +404 -0
  191. package/.next/standalone/fp-cloud-cli/fp_cli/config.py +330 -0
  192. package/.next/standalone/fp-cloud-cli/fp_cli/dates.py +78 -0
  193. package/.next/standalone/fp-cloud-cli/fp_cli/enforcement.py +345 -0
  194. package/.next/standalone/fp-cloud-cli/fp_cli/errors.py +98 -0
  195. package/.next/standalone/fp-cloud-cli/fp_cli/models.py +891 -0
  196. package/.next/standalone/fp-cloud-cli/fp_cli/orgs.py +30 -0
  197. package/.next/standalone/fp-cloud-cli/fp_cli/output.py +6593 -0
  198. package/.next/standalone/fp-cloud-cli/fp_cli/permissions.py +208 -0
  199. package/.next/standalone/fp-cloud-cli/fp_cli/policy_check.py +290 -0
  200. package/.next/standalone/fp-cloud-cli/fp_cli/py.typed +0 -0
  201. package/.next/standalone/fp-cloud-cli/fp_cli/select.py +322 -0
  202. package/.next/standalone/fp-cloud-cli/fp_cli/theme.py +53 -0
  203. package/.next/standalone/fp-cloud-cli/pyproject.toml +106 -0
  204. package/.next/standalone/fp-cloud-cli/skill/SKILL.md +302 -0
  205. package/.next/standalone/fp-cloud-cli/skill/agents/openai.yaml +8 -0
  206. package/.next/standalone/fp-cloud-cli/skill/references/commands.md +254 -0
  207. package/.next/standalone/fp-cloud-cli/tests/__init__.py +0 -0
  208. package/.next/standalone/fp-cloud-cli/tests/conftest.py +92 -0
  209. package/.next/standalone/fp-cloud-cli/tests/test_alerting.py +644 -0
  210. package/.next/standalone/fp-cloud-cli/tests/test_analytics.py +385 -0
  211. package/.next/standalone/fp-cloud-cli/tests/test_audits.py +950 -0
  212. package/.next/standalone/fp-cloud-cli/tests/test_auth.py +98 -0
  213. package/.next/standalone/fp-cloud-cli/tests/test_auth_mode.py +272 -0
  214. package/.next/standalone/fp-cloud-cli/tests/test_click_compat.py +118 -0
  215. package/.next/standalone/fp-cloud-cli/tests/test_client.py +299 -0
  216. package/.next/standalone/fp-cloud-cli/tests/test_commands.py +814 -0
  217. package/.next/standalone/fp-cloud-cli/tests/test_config.py +99 -0
  218. package/.next/standalone/fp-cloud-cli/tests/test_dashboards_agent.py +340 -0
  219. package/.next/standalone/fp-cloud-cli/tests/test_dates.py +76 -0
  220. package/.next/standalone/fp-cloud-cli/tests/test_enforcement_logic.py +481 -0
  221. package/.next/standalone/fp-cloud-cli/tests/test_facets.py +170 -0
  222. package/.next/standalone/fp-cloud-cli/tests/test_failproofai_home.py +722 -0
  223. package/.next/standalone/fp-cloud-cli/tests/test_fp_home_contract.py +198 -0
  224. package/.next/standalone/fp-cloud-cli/tests/test_hardening.py +186 -0
  225. package/.next/standalone/fp-cloud-cli/tests/test_help_table_coverage.py +127 -0
  226. package/.next/standalone/fp-cloud-cli/tests/test_keys_queries.py +496 -0
  227. package/.next/standalone/fp-cloud-cli/tests/test_list.py +59 -0
  228. package/.next/standalone/fp-cloud-cli/tests/test_multivalue.py +183 -0
  229. package/.next/standalone/fp-cloud-cli/tests/test_no_customer_identifiers.py +168 -0
  230. package/.next/standalone/fp-cloud-cli/tests/test_operator.py +492 -0
  231. package/.next/standalone/fp-cloud-cli/tests/test_orgs.py +692 -0
  232. package/.next/standalone/fp-cloud-cli/tests/test_output.py +1732 -0
  233. package/.next/standalone/fp-cloud-cli/tests/test_policy_check.py +191 -0
  234. package/.next/standalone/fp-cloud-cli/tests/test_readme_matches_reality.py +125 -0
  235. package/.next/standalone/fp-cloud-cli/tests/test_review_fixes.py +161 -0
  236. package/.next/standalone/fp-cloud-cli/tests/test_telemetry_completeness.py +90 -0
  237. package/.next/standalone/fp-cloud-cli/tests/test_usage.py +115 -0
  238. package/.next/standalone/fp-cloud-cli/tests/test_v1_origin_diagnostic.py +70 -0
  239. package/.next/standalone/fp-cloud-cli/tests/test_v1_routing.py +214 -0
  240. package/.next/standalone/fp-cloud-cli/tests/test_whoami.py +104 -0
  241. package/.next/standalone/fp-cloud-cli/uv.lock +552 -0
  242. package/.next/standalone/package.json +29 -22
  243. package/.next/standalone/sdk/python/CHANGELOG.md +70 -0
  244. package/.next/standalone/sdk/python/LICENSE +42 -0
  245. package/.next/standalone/sdk/python/MANIFEST.in +21 -0
  246. package/.next/standalone/sdk/python/README.md +466 -0
  247. package/.next/standalone/sdk/python/docs/README.md +249 -0
  248. package/.next/standalone/sdk/python/docs/_shared/README.md +43 -0
  249. package/.next/standalone/sdk/python/docs/_shared/__init__.py +195 -0
  250. package/.next/standalone/sdk/python/docs/crewai/README.md +328 -0
  251. package/.next/standalone/sdk/python/docs/crewai/examples/quickstart.py +61 -0
  252. package/.next/standalone/sdk/python/docs/crewai/examples/research_crew.py +92 -0
  253. package/.next/standalone/sdk/python/docs/langgraph/README.md +481 -0
  254. package/.next/standalone/sdk/python/docs/langgraph/examples/quickstart.py +51 -0
  255. package/.next/standalone/sdk/python/docs/langgraph/examples/research_agent.py +86 -0
  256. package/.next/standalone/sdk/python/docs/langgraph/examples/supervisor_handoff.py +83 -0
  257. package/.next/standalone/sdk/python/docs/llama_index/README.md +332 -0
  258. package/.next/standalone/sdk/python/docs/llama_index/examples/quickstart.py +62 -0
  259. package/.next/standalone/sdk/python/docs/llama_index/examples/research_agent.py +93 -0
  260. package/.next/standalone/sdk/python/docs/manual/README.md +491 -0
  261. package/.next/standalone/sdk/python/docs/manual/examples/quickstart.py +57 -0
  262. package/.next/standalone/sdk/python/docs/manual/examples/research_agent.py +133 -0
  263. package/.next/standalone/sdk/python/docs/pydantic_ai/README.md +323 -0
  264. package/.next/standalone/sdk/python/docs/pydantic_ai/examples/quickstart.py +48 -0
  265. package/.next/standalone/sdk/python/docs/pydantic_ai/examples/research_agent.py +94 -0
  266. package/.next/standalone/sdk/python/failproofai_sdk/__init__.py +131 -0
  267. package/.next/standalone/sdk/python/failproofai_sdk/_context.py +218 -0
  268. package/.next/standalone/sdk/python/failproofai_sdk/_environment.py +78 -0
  269. package/.next/standalone/sdk/python/failproofai_sdk/_events.py +752 -0
  270. package/.next/standalone/sdk/python/failproofai_sdk/_resolver.py +118 -0
  271. package/.next/standalone/sdk/python/failproofai_sdk/_runtime.py +21 -0
  272. package/.next/standalone/sdk/python/failproofai_sdk/_schema.py +317 -0
  273. package/.next/standalone/sdk/python/failproofai_sdk/_scopes.py +422 -0
  274. package/.next/standalone/sdk/python/failproofai_sdk/_version.py +1 -0
  275. package/.next/standalone/sdk/python/failproofai_sdk/_writer.py +750 -0
  276. package/.next/standalone/sdk/python/failproofai_sdk/integrations/__init__.py +274 -0
  277. package/.next/standalone/sdk/python/failproofai_sdk/integrations/_compat.py +247 -0
  278. package/.next/standalone/sdk/python/failproofai_sdk/integrations/_core.py +1076 -0
  279. package/.next/standalone/sdk/python/failproofai_sdk/integrations/crewai.py +1669 -0
  280. package/.next/standalone/sdk/python/failproofai_sdk/integrations/langchain.py +2151 -0
  281. package/.next/standalone/sdk/python/failproofai_sdk/integrations/llama_index.py +1588 -0
  282. package/.next/standalone/sdk/python/failproofai_sdk/integrations/pydantic_ai.py +977 -0
  283. package/.next/standalone/sdk/python/failproofai_sdk/py.typed +0 -0
  284. package/.next/standalone/sdk/python/pyproject.toml +92 -0
  285. package/.next/standalone/sdk/python/skill/SKILL.md +399 -0
  286. package/.next/standalone/sdk/python/skill/agents/openai.yaml +8 -0
  287. package/.next/standalone/sdk/python/skill/references/events.md +234 -0
  288. package/.next/standalone/sdk/python/skill/references/frameworks.md +314 -0
  289. package/.next/standalone/sdk/python/skill/references/install.md +100 -0
  290. package/.next/standalone/sdk/python/skill/references/integration.md +352 -0
  291. package/.next/standalone/sdk/python/tests/__init__.py +0 -0
  292. package/.next/standalone/sdk/python/tests/conftest.py +169 -0
  293. package/.next/standalone/sdk/python/tests/integrations/__init__.py +6 -0
  294. package/.next/standalone/sdk/python/tests/integrations/test_crewai.py +1299 -0
  295. package/.next/standalone/sdk/python/tests/integrations/test_langchain.py +2338 -0
  296. package/.next/standalone/sdk/python/tests/integrations/test_llama_index.py +1576 -0
  297. package/.next/standalone/sdk/python/tests/integrations/test_pydantic_ai.py +1102 -0
  298. package/.next/standalone/sdk/python/tests/test_context.py +410 -0
  299. package/.next/standalone/sdk/python/tests/test_docs.py +411 -0
  300. package/.next/standalone/sdk/python/tests/test_durability.py +1352 -0
  301. package/.next/standalone/sdk/python/tests/test_encoding.py +571 -0
  302. package/.next/standalone/sdk/python/tests/test_integrations.py +1127 -0
  303. package/.next/standalone/sdk/python/tests/test_no_customer_identifiers.py +214 -0
  304. package/.next/standalone/sdk/python/tests/test_packaging.py +185 -0
  305. package/.next/standalone/sdk/python/tests/test_resolver_umbrella.py +178 -0
  306. package/.next/standalone/sdk/python/tests/test_scopes.py +487 -0
  307. package/.next/standalone/sdk/python/tests/test_sdk.py +923 -0
  308. package/.next/standalone/sdk/python/tests/test_server_contract.py +650 -0
  309. package/.next/standalone/sdk/python/tests/test_site_docs.py +371 -0
  310. package/.next/standalone/sdk/python/tests/test_skill_snippets.py +165 -0
  311. package/.next/standalone/sdk/python/tests/test_spool_contract.py +287 -0
  312. package/.next/standalone/sdk/python/tests/test_spool_creation.py +360 -0
  313. package/.next/standalone/sdk/python/tests/test_wire_format.py +279 -0
  314. package/.next/standalone/sdk/python/tests/test_zero_dependencies.py +378 -0
  315. package/.next/standalone/sdk/python/uv.lock +6005 -0
  316. package/.next/standalone/server.js +1 -1
  317. package/README.md +77 -21
  318. package/bin/failproofai.mjs +145 -11
  319. package/dist/cli.mjs +4482 -2205
  320. package/dist/index.js +5 -5
  321. package/dist/worker.mjs +2399 -1978
  322. package/package.json +29 -22
  323. package/policy-pack/SHA256SUMS +2 -0
  324. package/policy-pack/failproofai-pack.json +732 -0
  325. package/policy-pack/failproofai-pack.mjs +2017 -0
  326. package/scripts/build-policy-pack.mjs +121 -0
  327. package/scripts/changelog-section.py +77 -0
  328. package/scripts/prune-standalone.mjs +3 -0
  329. package/scripts/python-version.py +232 -0
  330. package/scripts/translate-docs/cli.ts +21 -0
  331. package/scripts/translate-docs/mintlify-nav.ts +85 -13
  332. package/scripts/translate-docs/translator.ts +66 -11
  333. package/src/audit/cache.ts +40 -3
  334. package/src/audit/cli.ts +1 -1
  335. package/src/audit/index.ts +1 -1
  336. package/src/audit/replay.ts +89 -3
  337. package/src/audit/report.ts +5 -5
  338. package/src/audit/schedule-cli.ts +49 -53
  339. package/src/hooks/builtin-policies.ts +217 -579
  340. package/src/hooks/cloud-enrollment-cli.ts +66 -27
  341. package/src/hooks/cloud-managed-policies.ts +6 -1
  342. package/src/hooks/configure-wizard.ts +1 -1
  343. package/src/hooks/custom-hooks-loader.ts +89 -6
  344. package/src/hooks/fp-home.ts +92 -4
  345. package/src/hooks/fp-reset.ts +26 -2
  346. package/src/hooks/handler.ts +181 -11
  347. package/src/hooks/harness-cli.ts +79 -25
  348. package/src/hooks/hook-activity-store.ts +13 -3
  349. package/src/hooks/install-prompt.ts +25 -3
  350. package/src/hooks/manager.ts +418 -172
  351. package/src/hooks/migrations.ts +2 -2
  352. package/src/hooks/pack-cli.ts +505 -0
  353. package/src/hooks/pack-failclosed.ts +189 -0
  354. package/src/hooks/pack-manifest.ts +344 -0
  355. package/src/hooks/pack-store.ts +930 -0
  356. package/src/hooks/policy-catalog.ts +535 -0
  357. package/src/hooks/policy-evaluator.ts +24 -16
  358. package/src/hooks/policy-presets.ts +4 -2
  359. package/src/hooks/policy-registry.ts +8 -2
  360. package/src/hooks/policy-types.ts +26 -0
  361. package/src/hooks/session-pause-cli.ts +33 -9
  362. package/src/hooks/tui.ts +570 -0
  363. package/src/hooks/types.ts +15 -1
  364. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_usx0j._.js +0 -3
  365. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_zk340._.js +0 -3
  366. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0agdw2a._.js +0 -3
  367. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d1u_na._.js +0 -3
  368. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0oy4kxb._.js +0 -3
  369. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zf034w._.js +0 -3
  370. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tvn4wf._.js +0 -3
  371. package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +0 -3
  372. package/.next/standalone/.next/server/chunks/_1ger0a2._.js +0 -3
  373. package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +0 -3
  374. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_1iiwm5e._.js +0 -3
  375. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kc8_v5._.js +0 -4
  376. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kgy9da._.js +0 -4
  377. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0mhqk5a._.js +0 -4
  378. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0pltpn8._.js +0 -4
  379. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qkcyf-._.js +0 -4
  380. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w0x_ok._.js +0 -4
  381. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1_dfocn._.js +0 -4
  382. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1bfex62._.js +0 -5
  383. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1kzapg5._.js +0 -6
  384. package/.next/standalone/.next/static/chunks/36fw6yk1s6x_f.js +0 -1
  385. package/.next/standalone/.next/static/chunks/3tzq0260n17ae.js +0 -6
  386. package/.next/standalone/.next/static/chunks/3wq9x0c-7ld5d.css +0 -2
  387. /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → nwbyWT06Ud0XdXOrVJyvS}/_buildManifest.js +0 -0
  388. /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → nwbyWT06Ud0XdXOrVJyvS}/_clientMiddlewareManifest.js +0 -0
  389. /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → nwbyWT06Ud0XdXOrVJyvS}/_ssgManifest.js +0 -0
@@ -0,0 +1,481 @@
1
+ # LangChain / LangGraph
2
+
3
+ One adapter serves both — LangGraph runs on `langchain-core`'s callback manager,
4
+ so instrumenting one instruments the other.
5
+
6
+ - [Install](#install)
7
+ - [The integration](#the-integration)
8
+ - [How it attaches](#how-it-attaches)
9
+ - [What gets recorded](#what-gets-recorded)
10
+ - [A complete example](#a-complete-example)
11
+ - [Naming your agents](#naming-your-agents)
12
+ - [Controlling the session](#controlling-the-session)
13
+ - [Options](#options)
14
+ - [What an event actually looks like](#what-an-event-actually-looks-like)
15
+ - [Human in the loop](#human-in-the-loop)
16
+ - [Pitfalls](#pitfalls)
17
+ - [Runnable examples](#runnable-examples)
18
+
19
+ ---
20
+
21
+ ## Install
22
+
23
+ ```bash
24
+ pip install 'failproofai-sdk[langgraph]' # pins langgraph >=1.2,<2
25
+ ```
26
+
27
+ Using plain LangChain without LangGraph:
28
+
29
+ ```bash
30
+ pip install 'failproofai-sdk[langchain]' # pins langchain-core >=1.4.7,<2
31
+ ```
32
+
33
+ You almost certainly have the framework already. The extras exist to state the
34
+ supported range; the adapter itself ships in the base wheel.
35
+
36
+ **Supported:** `langchain-core` 1.4.7 → 2.0, `langgraph` 1.2 → 2.0. Outside
37
+ that range the adapter still installs and warns once, because a version we have
38
+ not tested is a better bet than no telemetry.
39
+
40
+ ---
41
+
42
+ ## The integration
43
+
44
+ ```python
45
+ import failproofai_sdk
46
+
47
+ failproofai_sdk.configure(environment="production")
48
+ failproofai_sdk.instrument()
49
+
50
+ with failproofai_sdk.session():
51
+ graph.invoke({"messages": [HumanMessage("...")]})
52
+ ```
53
+
54
+ Three lines, and nothing else in your codebase changes. No decorators on your
55
+ nodes, no callback passed to `.invoke()`, no ids threaded through your
56
+ functions.
57
+
58
+ `instrument()` with no argument auto-detects every supported framework already
59
+ imported. To be explicit:
60
+
61
+ ```python
62
+ failproofai_sdk.instrument("langchain") # "langgraph" is an alias
63
+ ```
64
+
65
+ ---
66
+
67
+ ## How it attaches
68
+
69
+ `instrument()` registers a tracer through
70
+ `langchain_core.tracers.context.register_configure_hook`. LangChain injects it
71
+ into **every callback manager it builds**, which means:
72
+
73
+ - every graph, node, tool, retriever and model call is captured;
74
+ - so is anything inside a library you did not write, as long as it goes through
75
+ LangChain;
76
+ - there is nothing to pass to `.invoke()` and no call site to change.
77
+
78
+ The tracer subclasses `BaseTracer`, so LangChain assembles the run tree and
79
+ hands over `Run` objects with inputs, outputs, metadata and timings already
80
+ collected — two override points instead of twenty hand-correlated callbacks.
81
+
82
+ <details>
83
+ <summary><b>Why we do not patch <code>BaseCallbackManager.__init__</code></b></summary>
84
+
85
+ Some other integrations do, and it double-records.
86
+ `BaseCallbackManager.merge()` builds a new manager with handlers already passed
87
+ in, so their `isinstance` dedup misses and the handler is added twice. MLflow
88
+ patches `merge` as well to work around it. The configure hook has no such hole.
89
+
90
+ This is also why you must **not** pass a Failproof handler in
91
+ `config={"callbacks": [...]}` yourself — see [Pitfalls](#pitfalls).
92
+ </details>
93
+
94
+ <details>
95
+ <summary><b>Why the handler runs inline</b></summary>
96
+
97
+ `run_inline = True` is not optional. `AsyncCallbackManager` dispatches sync
98
+ handlers through `run_in_executor` unless a handler opts out, and that hop can
99
+ **reorder callbacks** — which scrambles timestamp order and breaks every pairing.
100
+ Writing an event is a `deque.append`, so running inline on the event loop is
101
+ safe.
102
+ </details>
103
+
104
+ ---
105
+
106
+ ## What gets recorded
107
+
108
+ | LangChain / LangGraph | Failproof event | When |
109
+ |---|---|---|
110
+ | root run | `agent_start` / `agent_end` | the outermost `.invoke()` / `.stream()` |
111
+ | LangGraph node | `hook_triggered` / `hook_completed` | each node entry and exit |
112
+ | compiled subgraph | nested `agent_start` / `agent_end` | a subgraph run, named `root/node` |
113
+ | tool run | `tool_use` / `tool_result` | each tool call, with args and output |
114
+ | retriever run | `tool_use` / `tool_result` | output summarised, not dumped |
115
+ | chat model / LLM run | `model_request` / `model_response` | each model call, with token usage |
116
+ | streamed tokens | *nothing* | folded into `fw_chunks`, `fw_ttft_ms` on the response |
117
+ | `interrupt()` | `human_wait` + `agent_pause` | the graph suspends for a person |
118
+ | `Command(resume=...)` | `agent_resume` + `human_input` | the graph continues |
119
+ | unhandled exception | `error` + `agent_end(outcome="failed")` | the run raises |
120
+ | intermediate chains | *nothing* | unless named in `include_chains` |
121
+
122
+ ### Why a node is a hook and not a nested agent
123
+
124
+ `agent_id` is a `LowCardinality(String)` column and the primary facet on every
125
+ dashboard surface. Promoting `retrieve`, `grade_documents` and `should_continue`
126
+ to agents would:
127
+
128
+ - drown that facet with one entry per node, and
129
+ - label the whole session after whichever node happened to run first.
130
+
131
+ Hook spans render structurally identically in the timeline, and you get a
132
+ per-node latency page for free. Subgraphs *do* become nested agents, because a
133
+ compiled subgraph is a genuine unit of work.
134
+
135
+ ### Why streamed tokens emit nothing
136
+
137
+ A 500-token response would otherwise be 500 stored rows against a five-lane
138
+ rail. The chunk count, time-to-first-token and a `fw_streamed` flag land on the
139
+ single `model_response` instead.
140
+
141
+ ---
142
+
143
+ ## A complete example
144
+
145
+ Copy-pasteable, no helpers:
146
+
147
+ ```python
148
+ import failproofai_sdk
149
+ from langchain_core.messages import HumanMessage
150
+ from langchain_core.tools import tool
151
+ from langchain_openai import ChatOpenAI
152
+ from langgraph.prebuilt import ToolNode, create_react_agent
153
+
154
+ failproofai_sdk.configure(environment="production")
155
+ failproofai_sdk.instrument()
156
+
157
+
158
+ @tool
159
+ def price_of(item: str) -> float:
160
+ """Return the unit price of an item in USD."""
161
+ return {"widget": 42.0, "gadget": 17.5}[item.lower().strip()]
162
+
163
+
164
+ @tool
165
+ def stock_of(item: str) -> int:
166
+ """Return the units of an item currently in stock."""
167
+ return {"widget": 120, "gadget": 0}[item.lower().strip()]
168
+
169
+
170
+ # handle_tool_errors=True feeds a raised exception back to the model as a tool
171
+ # message instead of aborting the graph. The failure is recorded either way.
172
+ tools = ToolNode([price_of, stock_of], handle_tool_errors=True)
173
+ graph = create_react_agent(ChatOpenAI(model="gpt-4o-mini"), tools)
174
+
175
+ with failproofai_sdk.session():
176
+ with failproofai_sdk.agent("analyst", goal="price and stock report"):
177
+ result = graph.invoke({
178
+ "messages": [HumanMessage("Price and stock for widget and gadget?")]
179
+ })
180
+
181
+ print(result["messages"][-1].content)
182
+ ```
183
+
184
+ Running the fuller version of this
185
+ ([`examples/research_agent.py`](examples/research_agent.py)) produces **36
186
+ events across 8 types**: the `analyst` span, the graph nested inside it, a hook
187
+ pair per node, a model pair per turn with token counts, and a tool pair per call
188
+ — including one that failed:
189
+
190
+ ```
191
+ 1 +0.000s agent_start analyst
192
+ 2 +0.001s agent_start LangGraph · under analyst
193
+ 3 +0.002s hook_triggered agent
194
+ 4 +0.003s model_request gpt-5.6-terra
195
+ 5 +3.690s model_response gpt-5.6-terra · 99 out-tok
196
+ ...
197
+ 28 +5.830s tool_use restock_eta
198
+ 29 +5.834s tool_result restock_eta · error
199
+ ...
200
+ 36 +9.209s agent_end analyst · success
201
+ ```
202
+
203
+ Note event 29: a failed tool is a `tool_result` carrying `error`. The run still
204
+ ends `success`, because the agent recovered — the trace preserves both facts.
205
+
206
+ ---
207
+
208
+ ## Naming your agents
209
+
210
+ By default the root span takes the graph's own name (`LangGraph`, or whatever
211
+ you passed to `.compile(name=...)`). Wrap it to get something meaningful:
212
+
213
+ ```python
214
+ with failproofai_sdk.session():
215
+ with failproofai_sdk.agent("analyst", goal="price and stock report"):
216
+ graph.invoke(...)
217
+ ```
218
+
219
+ Everything inside now carries `parent_id="analyst"`, and the dashboard groups by
220
+ `analyst` rather than by a framework class name.
221
+
222
+ For multi-agent setups, nest the scopes — each worker becomes a child span:
223
+
224
+ ```python
225
+ with failproofai_sdk.session():
226
+ with failproofai_sdk.agent("supervisor"):
227
+ with failproofai_sdk.agent("researcher"):
228
+ research_graph.invoke(...)
229
+ with failproofai_sdk.agent("writer"):
230
+ writer_graph.invoke(...)
231
+ ```
232
+
233
+ See [`examples/supervisor_handoff.py`](examples/supervisor_handoff.py) — 38
234
+ events, 5 agents, correctly nested.
235
+
236
+ > **Keep `agent_id` low-cardinality.** It is a facet column. Use a role or node
237
+ > name (`analyst`, `researcher`), never a UUID or a per-run string. Put the real
238
+ > id in a payload field instead.
239
+
240
+ ---
241
+
242
+ ## Controlling the session
243
+
244
+ The session id is resolved in this order — first match wins:
245
+
246
+ 1. `failproofai_sdk.instrument("langchain", session_id="...")` — pins every run
247
+ 2. `config={"metadata": {"failproofai_sdk_session_id": "..."}}` — per call
248
+ 3. the ambient `failproofai_sdk.session()` / `agent()` scope
249
+ 4. `metadata["session_id"]`, `metadata["conversation_id"]`, `metadata["thread_id"]`
250
+ 5. the root run id
251
+
252
+ It is **never synthesised from scratch**, because a made-up id splits one run
253
+ into many sessions — a silent wrong answer rather than a loud one.
254
+
255
+ Per-call override:
256
+
257
+ ```python
258
+ graph.invoke(
259
+ {"messages": [...]},
260
+ config={"metadata": {"failproofai_sdk_session_id": f"chat-{user_id}"}},
261
+ )
262
+ ```
263
+
264
+ > `thread_id` **is** available to callbacks on this stack, despite what you may
265
+ > have read. Reports that it is `None` are about `langchain-core` dropping
266
+ > `configurable` from `metadata`; LangGraph 1.2 re-adds it. It is still only the
267
+ > fourth resolution step, because a thread is a conversation, not necessarily a
268
+ > single run.
269
+
270
+ ---
271
+
272
+ ## Options
273
+
274
+ ```python
275
+ failproofai_sdk.instrument(
276
+ "langchain",
277
+ session_id=None, # pin every run to one session id
278
+ include_chains=set(), # allowlist intermediate chains as hook pairs
279
+ capture_content=True, # False drops prompts and completions from payloads
280
+ graph_callbacks=True, # first-class interrupt/resume (needs langgraph >= 1.2)
281
+ )
282
+ ```
283
+
284
+ **`capture_content=False`** is the switch for regulated data. Structure,
285
+ timings, token counts, tool names and outcomes are all still recorded; the
286
+ message bodies and completions are not.
287
+
288
+ **`include_chains`** takes a set of runnable names. Use it sparingly — it exists
289
+ for a chain that is genuinely a step in your pipeline, not to surface
290
+ `RunnableSequence`.
291
+
292
+ It applies to **nested** runs only. A runnable you invoke at the top level is
293
+ the session's root, so it becomes the agent span rather than a hook pair, and
294
+ naming it here has no effect.
295
+
296
+ ---
297
+
298
+ ## What an event actually looks like
299
+
300
+ A real `model_response`, captured from `examples/quickstart.py`:
301
+
302
+ ```json
303
+ {
304
+ "timestamp": "2026-08-19T19:50:56.241974Z",
305
+ "session_id": "7e5de1571fa14424aa1a5bbd88cb420d",
306
+ "agent_id": "LangGraph",
307
+ "type": "model_response",
308
+ "environment": "production",
309
+ "model": "gpt-5.6-terra",
310
+ "stop_reason": "tool_calls",
311
+ "input_tokens": 139,
312
+ "output_tokens": 21,
313
+ "content": "",
314
+ "role": "assistant",
315
+ "request_id": "01a01b93-91a0-7c92-bf45-3857ee43d3ff",
316
+ "usage": { "input_tokens": 139, "output_tokens": 21, "total_tokens": 160 },
317
+ "duration_ms": 5202,
318
+ "framework": "langchain",
319
+ "framework_version": "1.5.6",
320
+ "integration_version": "0.0.1b1",
321
+ "fw_langgraph_version": "1.2.11",
322
+ "fw_run_id": "01a01b93-91a0-7c92-bf45-3857ee43d3ff",
323
+ "fw_node": "agent",
324
+ "fw_step": 1
325
+ }
326
+ ```
327
+
328
+ Everything prefixed `fw_` is framework-specific detail, namespaced so it can
329
+ never collide with — and silently overwrite — a first-class field like
330
+ `model` or `output_tokens`. `request_id` is what pairs this response with its
331
+ request; without it the dashboard falls back to FIFO pairing and concurrent
332
+ calls mis-pair.
333
+
334
+ ---
335
+
336
+ ## Human in the loop
337
+
338
+ LangGraph's `interrupt()` produces **four** events, and neither pair is
339
+ redundant:
340
+
341
+ ```python
342
+ from langgraph.types import interrupt, Command
343
+
344
+ def approve(state):
345
+ decision = interrupt({"prompt": "Ship it?", "options": ["yes", "no"]})
346
+ return {"approved": decision == "yes"}
347
+
348
+ with failproofai_sdk.session():
349
+ graph.invoke(state, config) # human_wait + agent_pause
350
+ # ... minutes pass ...
351
+ graph.invoke(Command(resume="yes"), config) # agent_resume + human_input
352
+ ```
353
+
354
+ - `human_wait` → `human_input` carries the prompt, the options, the answer and
355
+ the pending-human count;
356
+ - `agent_pause` → `agent_resume` is the **only** thing that feeds paused time.
357
+ Without it the whole human wait is billed as active agent time.
358
+
359
+ The root agent span deliberately stays **open** across the gap, so the two
360
+ `.invoke()` calls are one session and one run.
361
+
362
+ ---
363
+
364
+ ## Pitfalls
365
+
366
+ ### A raising tool aborts the whole graph
367
+
368
+ **Symptom:** your run dies on the first tool exception instead of recovering.
369
+
370
+ **Cause:** `create_react_agent` propagates it by default.
371
+
372
+ **Fix:** build the tool node explicitly.
373
+
374
+ ```python
375
+ from langgraph.prebuilt import ToolNode, create_react_agent
376
+
377
+ tools = ToolNode([price_of, stock_of], handle_tool_errors=True)
378
+ graph = create_react_agent(model, tools)
379
+ ```
380
+
381
+ The failure is recorded as `tool_result` with `error` either way — this only
382
+ decides whether the run survives it.
383
+
384
+ ---
385
+
386
+ ### A bare `llm.invoke()` shows up as an agent named after the model class
387
+
388
+ **Symptom:** an `agent_id` of `ChatOpenAI` in your trace.
389
+
390
+ **Cause:** a direct model call outside any graph has no parent run, so it opens
391
+ a root agent span **and** emits its own `model_request` / `model_response` pair
392
+ inside it. The dashboard parents leaves to an open agent and synthesises a
393
+ never-ending root span when there is none, so the span is deliberate.
394
+
395
+ **Fix:** name it.
396
+
397
+ ```python
398
+ with failproofai_sdk.agent("summariser"):
399
+ summary = ChatOpenAI(model="gpt-4o-mini").invoke([HumanMessage(text)])
400
+ ```
401
+
402
+ > Before v1.0.1-beta.2 this case emitted the agent span and **nothing else** —
403
+ > no model name, no token counts, no latency. If you are on an older build,
404
+ > upgrade.
405
+
406
+ ---
407
+
408
+ ### Interrupts look like errors and are not
409
+
410
+ **Symptom:** you expect a red error on every human approval.
411
+
412
+ **Cause:** LangGraph's runnable does `except BaseException: on_chain_error(e);
413
+ raise` with no special case for interrupts, so every HITL pause reaches the
414
+ tracer as an error callback.
415
+
416
+ **Fix:** none needed. Any `GraphBubbleUp` subclass — `GraphInterrupt`,
417
+ `NodeInterrupt`, `ParentCommand`, `GraphDrained` — is treated as control flow.
418
+ Without that, every approval would paint a red error plus
419
+ `agent_end(outcome="failed")`.
420
+
421
+ ---
422
+
423
+ ### Everything is recorded twice
424
+
425
+ **Symptom:** every event appears two times.
426
+
427
+ **Cause:** you passed a Failproof handler in `config={"callbacks": [...]}` *as
428
+ well as* calling `instrument()`.
429
+
430
+ **Fix:** remove it. The configure hook already covers every callback manager in
431
+ the process. There is never a reason to register a handler by hand.
432
+
433
+ ---
434
+
435
+ ### Nothing is recorded at all
436
+
437
+ Work through these in order:
438
+
439
+ 1. Did `instrument()` actually run before the graph executed?
440
+ 2. Is there a `with failproofai_sdk.session():` around the call? Without one,
441
+ every `.invoke()` becomes its own session — you will have events, but
442
+ scattered.
443
+ 3. Set `FAILPROOFAI_SDK_STRICT=1` and run again. A silently degraded hook will
444
+ now raise instead of being swallowed.
445
+ 4. Are you reading the spool directory to check? Do not — a running
446
+ `failproofaid` deletes each batch within milliseconds. Check the dashboard.
447
+
448
+ ---
449
+
450
+ ### Events from a worker thread raise `TypeError`
451
+
452
+ **Symptom:** `TypeError` naming `session_id` from inside a thread pool.
453
+
454
+ **Cause:** contextvars propagate into asyncio tasks automatically but **not**
455
+ into new threads — a thread starts with an empty context.
456
+
457
+ **Fix:**
458
+
459
+ ```python
460
+ pool.submit(failproofai_sdk.propagate(work), x)
461
+ threading.Thread(target=failproofai_sdk.propagate(work)).start()
462
+ ```
463
+
464
+ ---
465
+
466
+ ## Runnable examples
467
+
468
+ | file | what it shows | events |
469
+ |---|---|---|
470
+ | [`examples/quickstart.py`](examples/quickstart.py) | one tool, one turn — the smallest real trace | 14 |
471
+ | [`examples/research_agent.py`](examples/research_agent.py) | 3 tools, several turns, one tool that fails and recovers | 36 |
472
+ | [`examples/supervisor_handoff.py`](examples/supervisor_handoff.py) | a supervisor delegating to 2 workers, nested spans | 38 |
473
+
474
+ ```bash
475
+ export OPENAI_API_KEY=sk-...
476
+ export FPAI_MODEL=gpt-4o-mini
477
+ python docs/langgraph/examples/quickstart.py
478
+ ```
479
+
480
+ Each prints the event stream it produced. All three were run against a live
481
+ model before shipping.
@@ -0,0 +1,51 @@
1
+ """langgraph — the smallest thing that produces a trace.
2
+
3
+ pip install 'failproofai-sdk[langgraph]'
4
+ python docs/langgraph/examples/quickstart.py
5
+
6
+ `instrument()` installs a tracer on langchain's global callback manager, so
7
+ every graph, node, tool and model call in the process is recorded — including
8
+ ones inside libraries you did not write. Nothing below passes an id by hand.
9
+ """
10
+ import sys
11
+ from pathlib import Path
12
+
13
+ # Only so this file can import the shared trace printer from docs/_shared/.
14
+ # Delete these two lines and the `_shared` import below and the example still
15
+ # instruments correctly — it just stops printing its own trace at the end.
16
+ sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
17
+
18
+ import failproofai_sdk
19
+ from _shared import banner, model, trace
20
+ from langchain_core.messages import HumanMessage
21
+ from langchain_core.tools import tool
22
+ from langchain_openai import ChatOpenAI
23
+ from langgraph.prebuilt import create_react_agent
24
+
25
+ failproofai_sdk.configure(environment="examples")
26
+ failproofai_sdk.instrument()
27
+
28
+
29
+ @tool
30
+ def word_count(text: str) -> int:
31
+ """Count the words in a piece of text."""
32
+ return len(text.split())
33
+
34
+
35
+ def main() -> None:
36
+ banner("langgraph quickstart", "one tool, one turn")
37
+ graph = create_react_agent(ChatOpenAI(model=model()), [word_count])
38
+
39
+ # A session groups everything below into one run. Without it each
40
+ # `.invoke()` becomes its own session, which is rarely what you want.
41
+ with failproofai_sdk.session() as sid:
42
+ result = graph.invoke(
43
+ {"messages": [HumanMessage("How many words in 'hello brave new world'?")]}
44
+ )
45
+
46
+ print(" answer:", result["messages"][-1].content.strip()[:120])
47
+ trace(sid, title="langgraph quickstart")
48
+
49
+
50
+ if __name__ == "__main__":
51
+ main()
@@ -0,0 +1,86 @@
1
+ """langgraph — a real multi-step run: three tools, several turns.
2
+
3
+ pip install 'failproofai-sdk[langgraph]'
4
+ python docs/langgraph/examples/research_agent.py
5
+
6
+ What this demonstrates that the quickstart does not:
7
+
8
+ * several model turns in one session, each paired `model_request`/`model_response`
9
+ with real token counts and latency;
10
+ * three distinct tools, each a `tool_use`/`tool_result` pair carrying arguments
11
+ and output;
12
+ * a tool that raises — recorded as `tool_result` with `error` set, and the run
13
+ keeps going, because a failed tool is data, not a crash;
14
+ * a named `agent()` scope, so the trace is labelled `analyst` rather than the
15
+ graph's generated id.
16
+ """
17
+ import sys
18
+ from pathlib import Path
19
+
20
+ # Only so this file can import the shared trace printer from docs/_shared/.
21
+ # Delete these two lines and the `_shared` import below and the example still
22
+ # instruments correctly — it just stops printing its own trace at the end.
23
+ sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
24
+
25
+ import failproofai_sdk
26
+ from _shared import banner, model, trace
27
+ from langchain_core.messages import HumanMessage
28
+ from langchain_core.tools import tool
29
+ from langchain_openai import ChatOpenAI
30
+ from langgraph.prebuilt import ToolNode, create_react_agent
31
+
32
+ failproofai_sdk.configure(environment="examples")
33
+ failproofai_sdk.instrument()
34
+
35
+ _PRICES = {"widget": 42.0, "gadget": 17.5, "sprocket": 3.25}
36
+ _STOCK = {"widget": 120, "gadget": 0, "sprocket": 8}
37
+
38
+
39
+ @tool
40
+ def price_of(item: str) -> float:
41
+ """Return the unit price of an item in USD."""
42
+ return _PRICES[item.lower().strip()]
43
+
44
+
45
+ @tool
46
+ def stock_of(item: str) -> int:
47
+ """Return the units of an item currently in stock."""
48
+ return _STOCK[item.lower().strip()]
49
+
50
+
51
+ @tool
52
+ def restock_eta(item: str) -> str:
53
+ """Return the restock ETA. Raises for items that are not tracked."""
54
+ # Deliberately unhandled: the trace should show a failed tool call and the
55
+ # agent recovering from it, which is the interesting case to observe.
56
+ raise LookupError(f"no restock schedule for {item!r}")
57
+
58
+
59
+ def main() -> None:
60
+ banner("langgraph research agent", "3 tools · multi-turn · one failing call")
61
+
62
+ # `handle_tool_errors=True` feeds the exception back to the model as a tool
63
+ # message instead of raising out of `.invoke()`. The failproof trace records
64
+ # the failure either way — this just lets the run continue so you can watch
65
+ # the model recover from it.
66
+ tools = ToolNode([price_of, stock_of, restock_eta], handle_tool_errors=True)
67
+ graph = create_react_agent(ChatOpenAI(model=model()), tools)
68
+
69
+ question = (
70
+ "For 'widget' and 'gadget': give me the unit price and the stock level. "
71
+ "For anything out of stock, try to look up the restock ETA. "
72
+ "Finish with a two-line summary."
73
+ )
74
+
75
+ # `agent("analyst")` names the span. Without it the adapter falls back to the
76
+ # graph's own label, which is stable but not meaningful on a dashboard.
77
+ with failproofai_sdk.session() as sid:
78
+ with failproofai_sdk.agent("analyst", goal="price and stock report"):
79
+ result = graph.invoke({"messages": [HumanMessage(question)]})
80
+
81
+ print(" answer:", result["messages"][-1].content.strip()[:200], "\n")
82
+ trace(sid, title="langgraph research agent")
83
+
84
+
85
+ if __name__ == "__main__":
86
+ main()
@@ -0,0 +1,83 @@
1
+ """langgraph — a supervisor delegating to two workers.
2
+
3
+ pip install 'failproofai-sdk[langgraph]'
4
+ python docs/langgraph/examples/supervisor_handoff.py
5
+
6
+ Multi-agent is where a flat event log stops being readable, so this is the
7
+ example to run if you want to see what the parent/child structure buys you.
8
+
9
+ Each worker runs inside its own `agent()` scope nested in the supervisor's, so
10
+ every event a worker emits carries `parent_id="supervisor"` and `depth=2`. The
11
+ dashboard renders that as a tree; a flat log cannot tell you which agent made
12
+ which model call.
13
+ """
14
+ import sys
15
+ from pathlib import Path
16
+
17
+ # Only so this file can import the shared trace printer from docs/_shared/.
18
+ # Delete these two lines and the `_shared` import below and the example still
19
+ # instruments correctly — it just stops printing its own trace at the end.
20
+ sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
21
+
22
+ import failproofai_sdk
23
+ from _shared import banner, model, trace
24
+ from langchain_core.messages import HumanMessage
25
+ from langchain_core.tools import tool
26
+ from langchain_openai import ChatOpenAI
27
+ from langgraph.prebuilt import create_react_agent
28
+
29
+ failproofai_sdk.configure(environment="examples")
30
+ failproofai_sdk.instrument()
31
+
32
+
33
+ @tool
34
+ def fetch_incidents(service: str) -> str:
35
+ """List recent incidents for a service."""
36
+ return {
37
+ "checkout": "2 incidents: 503 spike (12m), payment timeout (4m)",
38
+ "search": "1 incident: index lag (31m)",
39
+ }.get(service, "no incidents on record")
40
+
41
+
42
+ @tool
43
+ def oncall_for(service: str) -> str:
44
+ """Return who is on call for a service."""
45
+ return {"checkout": "dana", "search": "kim"}.get(service, "unassigned")
46
+
47
+
48
+ def worker(name: str, tools: list, prompt: str) -> str:
49
+ """One delegated unit of work, bracketed as its own child agent."""
50
+ graph = create_react_agent(ChatOpenAI(model=model()), tools)
51
+ with failproofai_sdk.agent(name, goal=prompt[:60]):
52
+ out = graph.invoke({"messages": [HumanMessage(prompt)]})
53
+ return out["messages"][-1].content
54
+
55
+
56
+ def main() -> None:
57
+ banner("langgraph supervisor handoff", "1 supervisor → 2 workers · nested spans")
58
+
59
+ with failproofai_sdk.session() as sid:
60
+ with failproofai_sdk.agent("supervisor", goal="incident brief for checkout"):
61
+ incidents = worker(
62
+ "incident_worker",
63
+ [fetch_incidents],
64
+ "Use the tool to list recent incidents for the 'checkout' service.",
65
+ )
66
+ owner = worker(
67
+ "roster_worker",
68
+ [oncall_for],
69
+ "Use the tool to say who is on call for the 'checkout' service.",
70
+ )
71
+
72
+ # The supervisor's own model turn, at depth 1 — the two worker turns
73
+ # above are at depth 2 and carry parent_id="supervisor".
74
+ summary = ChatOpenAI(model=model()).invoke(
75
+ [HumanMessage(f"In two lines, brief the on-call.\n{incidents}\n{owner}")]
76
+ )
77
+
78
+ print(" brief:", summary.content.strip()[:200], "\n")
79
+ trace(sid, title="langgraph supervisor handoff")
80
+
81
+
82
+ if __name__ == "__main__":
83
+ main()