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,249 @@
1
+ # failproofai-sdk — integration guide
2
+
3
+ Plug your agent into Failproof AI. One call, no call-site changes, no ids
4
+ threaded through your code.
5
+
6
+ ```bash
7
+ pip install 'failproofai-sdk[langgraph]'
8
+ ```
9
+
10
+ ```python
11
+ import failproofai_sdk
12
+
13
+ failproofai_sdk.instrument() # auto-detects the frameworks you imported
14
+
15
+ with failproofai_sdk.session():
16
+ graph.invoke(...) # recorded
17
+ ```
18
+
19
+ That is the whole integration.
20
+
21
+ ---
22
+
23
+ ## pick your framework
24
+
25
+ | framework | guide | runnable code |
26
+ |---|---|---|
27
+ | LangChain / LangGraph | [langgraph/](langgraph/) | [langgraph/examples/](langgraph/examples/) |
28
+ | CrewAI | [crewai/](crewai/) | [crewai/examples/](crewai/examples/) |
29
+ | LlamaIndex | [llama_index/](llama_index/) | [llama_index/examples/](llama_index/examples/) |
30
+ | Pydantic AI | [pydantic_ai/](pydantic_ai/) | [pydantic_ai/examples/](pydantic_ai/examples/) |
31
+ | **no framework** (your own agent) | [manual/](manual/) | [manual/examples/](manual/examples/) |
32
+
33
+ Using something else — AutoGen, Haystack, Semantic Kernel, your own loop? Read
34
+ [manual/](manual/). It is the same fidelity, it just costs you the call sites,
35
+ and it explains why AutoGen has no adapter.
36
+
37
+ ---
38
+
39
+ ## what you get
40
+
41
+ Here is a real trace, printed by `langgraph/examples/quickstart.py`. This is
42
+ captured output, not an illustration:
43
+
44
+ ```
45
+ ━━ failproof_ai · langgraph quickstart
46
+ session faf3a02d64464e34809eae95fa244230
47
+ events 14 · agents 1 · types 8
48
+
49
+ № offset event detail
50
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
51
+ 1 +0.000s agent_start LangGraph
52
+ 2 +0.001s hook_triggered agent
53
+ 3 +0.002s model_request gpt-5.6-terra
54
+ 4 +3.023s model_response gpt-5.6-terra · 21 out-tok
55
+ 5 +3.024s hook_completed agent
56
+ 6 +3.024s hook_triggered tools
57
+ 7 +3.025s tool_use word_count
58
+ 8 +3.025s tool_result word_count · ok
59
+ 9 +3.025s hook_completed tools
60
+ 10 +3.026s hook_triggered agent
61
+ 11 +3.027s model_request gpt-5.6-terra
62
+ 12 +5.717s model_response gpt-5.6-terra · 5 out-tok
63
+ 13 +5.720s hook_completed agent
64
+ 14 +5.721s agent_end LangGraph · success
65
+ ```
66
+
67
+ One `graph.invoke()` from the outside. Fourteen events with timings, token
68
+ counts and the tool call, from the inside.
69
+
70
+ ---
71
+
72
+ ## the three calls
73
+
74
+ ### 1. `configure()` — optional
75
+
76
+ ```python
77
+ failproofai_sdk.configure(
78
+ environment="production", # label on every event; default "dev"
79
+ flush_interval=0.5, # seconds between disk flushes
80
+ base_dir=None, # spool root; default ~/.failproofai/custom-agents
81
+ )
82
+ ```
83
+
84
+ Defaults are usually right. Set `environment` so you can tell prod from staging
85
+ on the dashboard.
86
+
87
+ ### 2. `instrument()` — the one that does the work
88
+
89
+ ```python
90
+ failproofai_sdk.instrument() # every framework already imported
91
+ failproofai_sdk.instrument("crewai") # exactly one
92
+ failproofai_sdk.uninstrument() # put everything back
93
+ ```
94
+
95
+ Auto-detection reads `sys.modules` — a framework you have installed but are not
96
+ using is never imported on your behalf.
97
+
98
+ ### 3. `session()` — group one run
99
+
100
+ ```python
101
+ with failproofai_sdk.session():
102
+ ...
103
+ ```
104
+
105
+ A session is one run. Without it, each top-level call becomes its own session,
106
+ which is almost never what you want.
107
+
108
+ ---
109
+
110
+ ## the fifteen event types
111
+
112
+ | group | events | what they mean |
113
+ |---|---|---|
114
+ | agents | `agent_start` `agent_end` | a unit of work begins / ends |
115
+ | | `agent_pause` `agent_resume` | it is blocked / unblocked (feeds paused time) |
116
+ | models | `model_request` `model_response` | one LLM round trip, with tokens |
117
+ | tools | `tool_use` `tool_result` | one tool call, with args and output |
118
+ | hooks | `hook_triggered` `hook_completed` | a node / step / task boundary |
119
+ | humans | `human_wait` `human_input` | you asked a person / they answered |
120
+ | | `human_pause` `human_interrupt` | a person paused / stopped the agent |
121
+ | failures | `error` | something went wrong |
122
+
123
+ **Events come in pairs.** The closing event carries a `duration_ms` measured
124
+ from the matching opening one. An opening event with no close renders as a span
125
+ that never finishes.
126
+
127
+ ---
128
+
129
+ ## what each framework emits
130
+
131
+ Measured from the real runs in this directory, not declared.
132
+
133
+ | event | langgraph | crewai | llama_index | pydantic ai | your own |
134
+ |---|:--:|:--:|:--:|:--:|:--:|
135
+ | `agent_start` / `agent_end` | yes | yes | yes | yes | you |
136
+ | `model_request` / `model_response` | yes | yes | yes | yes | you |
137
+ | `tool_use` / `tool_result` | yes | yes | yes | yes | you |
138
+ | `hook_triggered` / `hook_completed` | node | task | step | — | you |
139
+ | `error` | yes | yes | yes | yes | automatic |
140
+ | `human_wait` / `human_input` | yes | yes | yes | — | you |
141
+ | `agent_pause` / `agent_resume` | yes | yes | yes | — | you |
142
+ | `human_pause` / `human_interrupt` | — | — | — | — | you |
143
+
144
+ A dash means the framework has no such concept, not that it is missing.
145
+ Pydantic AI has no node boundary and no built-in human pause, so there is
146
+ nothing to map. `human_pause` and `human_interrupt` describe a *person* acting
147
+ on the agent — a stop button — which no framework signals; emit those yourself.
148
+
149
+ ---
150
+
151
+ ## running the examples
152
+
153
+ Every example in this tree was executed against a live model before it shipped.
154
+
155
+ ```bash
156
+ pip install 'failproofai-sdk[langgraph]'
157
+ export OPENAI_API_KEY=sk-...
158
+ export FPAI_MODEL=gpt-4o-mini # optional, this is the default
159
+
160
+ python docs/langgraph/examples/quickstart.py
161
+ ```
162
+
163
+ Each one prints the event stream it produced when it finishes. That printer
164
+ lives in [`_shared/`](_shared/) and is **cosmetics only** — the two bootstrap
165
+ lines at the top of each example exist just to import it. Delete them and the
166
+ example still instruments correctly.
167
+
168
+ ---
169
+
170
+ ## instrumentation cannot break your agent
171
+
172
+ Every callback goes through a wrapper whose only job is to re-raise. Your call
173
+ sits in exactly one `try`; everything the SDK does happens outside it.
174
+
175
+ - a hook that raises is logged once, with its traceback, and your call is
176
+ unaffected;
177
+ - a hook that raises three times at the same site is disabled for the rest of
178
+ the process, with one error line saying so.
179
+
180
+ That firewall is the right default in production and the wrong one when you are
181
+ debugging. To make failures loud instead:
182
+
183
+ ```bash
184
+ export FAILPROOFAI_SDK_STRICT=1
185
+ ```
186
+
187
+ Without it you can only ever prove "it did not crash", never "it swallowed the
188
+ right thing".
189
+
190
+ ---
191
+
192
+ ## zero dependencies
193
+
194
+ `import failproofai_sdk` pulls in nothing outside the standard library. That is
195
+ enforced, not asserted: one test installs the built wheel with `--no-deps`,
196
+ another launches a fresh interpreter and proves no framework reaches
197
+ `sys.modules`.
198
+
199
+ The extras install the **framework**, not the adapter — the adapter code always
200
+ ships in the base wheel and is imported only when `instrument()` asks for it.
201
+ Most people already have the framework and never need an extra.
202
+
203
+ | extra | installs |
204
+ |---|---|
205
+ | `failproofai-sdk[langchain]` | `langchain-core>=1.4.7,<2` |
206
+ | `failproofai-sdk[langgraph]` | `langgraph>=1.2,<2` |
207
+ | `failproofai-sdk[crewai]` | `crewai>=1.13,<2` |
208
+ | `failproofai-sdk[llamaindex]` | `llama-index-core>=0.14.23,<0.15` |
209
+ | `failproofai-sdk[pydantic-ai]` | `pydantic-ai-slim>=2.0,<3` |
210
+
211
+ There is deliberately no `[all]` — an extra that installs four agent frameworks
212
+ at once is a resolver problem handed to somebody who wanted a telemetry library.
213
+
214
+ ---
215
+
216
+ ## verifying it works
217
+
218
+ Look at the dashboard, or query the store.
219
+
220
+ **Do not read the spool directory to check.** When `failproofaid` is running it
221
+ collects and deletes each batch file within milliseconds of it appearing, so a
222
+ read races the collector and returns only what has not shipped yet — which looks
223
+ exactly like an adapter that emitted nothing but its closing events. This is a
224
+ real thing that happened while writing these docs.
225
+
226
+ To inspect events in-process instead, tap the writer:
227
+
228
+ ```python
229
+ captured = []
230
+ _original = failproofai_sdk._writer.submit
231
+ failproofai_sdk._writer.submit = lambda e: (captured.append(e), _original(e))[1]
232
+ ```
233
+
234
+ Every example here does exactly that.
235
+
236
+ ---
237
+
238
+ ## troubleshooting
239
+
240
+ | symptom | most likely cause |
241
+ |---|---|
242
+ | no events at all | `instrument()` never ran, or ran after you built the agent (Pydantic AI) |
243
+ | events, but no session | no `with failproofai_sdk.session():` — each call became its own session |
244
+ | `TypeError: ... missing session_id` | you emitted from a new thread; wrap it in `failproofai_sdk.propagate()` |
245
+ | spans that never finish | an opening event with no closing one — emit the pairs |
246
+ | null token counts on LlamaIndex | streaming has no usage; see [llama_index/](llama_index/) |
247
+ | `agent_id` full of uuids | keep it low-cardinality — a role or node name, never a run id |
248
+ | duplicated events on LangChain | you registered a second callback handler as well as `instrument()` |
249
+ | adapter seems to do nothing | set `FAILPROOFAI_SDK_STRICT=1` and run again |
@@ -0,0 +1,43 @@
1
+ # _shared
2
+
3
+ Cosmetics for the runnable examples. **Nothing here is part of the SDK**, and no
4
+ example needs it to instrument correctly.
5
+
6
+ Two helpers:
7
+
8
+ - `model()` — reads `FPAI_MODEL` / `MODEL`, defaults to `gpt-4o-mini`, so one
9
+ export drives every example.
10
+ - `trace(session_id)` — prints the event stream the run produced.
11
+
12
+ `trace()` is why the examples are worth running rather than reading. An adapter
13
+ that "works" is one whose event stream you can see, so every example ends by
14
+ printing its own instead of asserting in a comment that events happened.
15
+
16
+ ## why it taps the writer instead of reading the spool
17
+
18
+ When `failproofaid` is running it collects and **deletes** each batch file
19
+ within milliseconds of it appearing. A spool read therefore races the collector
20
+ and returns only whatever has not shipped yet — which looks exactly like an
21
+ adapter that emitted nothing but its closing events.
22
+
23
+ That is not hypothetical: it is what happened the first time these examples were
24
+ run, and it read as three adapter bugs that did not exist.
25
+
26
+ So `capture()` wraps `failproofai_sdk._writer.submit` and appends every entry to
27
+ a list first. Same dict that goes to disk, race-free, and it works whether or not
28
+ a daemon is running. `banner()` calls it, so every example is tapped from its
29
+ first line.
30
+
31
+ ## removing it
32
+
33
+ Each example starts with two bootstrap lines that exist only to import this
34
+ package:
35
+
36
+ ```python
37
+ sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
38
+ ...
39
+ from _shared import banner, model, trace
40
+ ```
41
+
42
+ Delete those and the `banner()` / `trace()` calls, and the example still
43
+ instruments correctly. It just stops printing.
@@ -0,0 +1,195 @@
1
+ """Cosmetics shared by the examples. No SDK behaviour lives here.
2
+
3
+ Two helpers, both deliberately boring:
4
+
5
+ * `model()` — the model id, from `FPAI_MODEL` / `MODEL`, so one export drives
6
+ every example instead of a dozen edits.
7
+ * `trace()` — reads the spool back and prints what the run actually recorded.
8
+
9
+ `trace()` is the point of these examples. An adapter that "works" is one whose
10
+ event stream you can read, so every example ends by printing its own trace
11
+ rather than asserting in a comment that events were produced. It reads the same
12
+ JSONL the daemon collects, filtered to the session just run.
13
+
14
+ Nothing here is required to use the SDK. Delete this folder and the examples
15
+ still instrument correctly; they just stop printing.
16
+ """
17
+ from __future__ import annotations
18
+
19
+ import json
20
+ import os
21
+ import pathlib
22
+ import sys
23
+
24
+ import failproofai_sdk
25
+
26
+ # ── brand ────────────────────────────────────────────────────────────────────
27
+ # Exact hex from the design system: pink #e4587d, mint #66d1b5, ink #d8d6d2.
28
+ # Truecolor, and only when stdout is a terminal — a piped log gets clean text.
29
+ _TTY = sys.stdout.isatty()
30
+
31
+
32
+ def _c(code: str, text: str) -> str:
33
+ return f"\033[{code}m{text}\033[0m" if _TTY else text
34
+
35
+
36
+ def pink(t: str) -> str:
37
+ return _c("38;2;228;88;125", t)
38
+
39
+
40
+ def mint(t: str) -> str:
41
+ return _c("38;2;102;209;181", t)
42
+
43
+
44
+ def dim(t: str) -> str:
45
+ return _c("38;2;120;120;130", t)
46
+
47
+
48
+ def bold(t: str) -> str:
49
+ return _c("1", t)
50
+
51
+
52
+ RULE = "━" * 68
53
+
54
+
55
+ def model() -> str:
56
+ """The model id every example runs against."""
57
+ return os.environ.get("FPAI_MODEL") or os.environ.get("MODEL") or "gpt-4o-mini"
58
+
59
+
60
+ def banner(title: str, subtitle: str = "") -> None:
61
+ """Print the example's header and start capturing events."""
62
+ capture()
63
+ print()
64
+ print(pink("━━ ") + bold(title.lower()))
65
+ if subtitle:
66
+ print(dim(" " + subtitle))
67
+ print()
68
+
69
+
70
+ # ── capturing what the run emitted ───────────────────────────────────────────
71
+ # NOT by reading the spool. When `failproofaid` is running it collects and
72
+ # DELETES each batch file within milliseconds of it appearing, so a spool read
73
+ # races the daemon and returns whatever happens to be left — which looks exactly
74
+ # like an adapter that only emitted its closing events. (That is a real thing
75
+ # that happened while writing these examples.)
76
+ #
77
+ # So the tap sits on the writer instead: the same dict that goes to disk is
78
+ # appended to a list first. Race-free, and it works whether or not a daemon is
79
+ # running.
80
+ _CAPTURED: list[dict] = []
81
+ _TAPPED = False
82
+
83
+
84
+ def capture() -> None:
85
+ """Start recording every event this process emits. Idempotent."""
86
+ global _TAPPED
87
+ if _TAPPED:
88
+ return
89
+ writer = failproofai_sdk._writer
90
+ original = writer.submit
91
+
92
+ def _tee(entry: dict) -> None:
93
+ _CAPTURED.append(entry)
94
+ return original(entry)
95
+
96
+ writer.submit = _tee # instance attribute; the real method is untouched
97
+ _TAPPED = True
98
+
99
+
100
+ def events(session_id: str | None = None) -> list[dict]:
101
+ """Everything captured, optionally narrowed to one session."""
102
+ rows = [r for r in _CAPTURED if session_id is None or r.get("session_id") == session_id]
103
+ return sorted(rows, key=lambda r: r.get("timestamp", ""))
104
+
105
+
106
+ _LEAF = {
107
+ "tool_use": "tool_result",
108
+ "model_request": "model_response",
109
+ "hook_triggered": "hook_completed",
110
+ "agent_start": "agent_end",
111
+ "human_wait": "human_input",
112
+ "agent_pause": "agent_resume",
113
+ }
114
+ _CLOSERS = set(_LEAF.values())
115
+
116
+
117
+ def _detail(row: dict) -> str:
118
+ t = row["type"]
119
+ if t in ("tool_use", "tool_result"):
120
+ bits = [row.get("tool_name") or "?"]
121
+ if row.get("error"):
122
+ bits.append(pink("error"))
123
+ elif t == "tool_result":
124
+ bits.append(mint("ok"))
125
+ return " · ".join(bits)
126
+ if t in ("model_request", "model_response"):
127
+ bits = [row.get("model") or "?"]
128
+ tok = row.get("output_tokens")
129
+ if tok:
130
+ bits.append(f"{tok} out-tok")
131
+ if row.get("error"):
132
+ bits.append(pink("error"))
133
+ return " · ".join(bits)
134
+ if t in ("agent_start", "agent_end"):
135
+ bits = [row.get("agent_id") or "?"]
136
+ if row.get("parent_id"):
137
+ bits.append(dim("under " + row["parent_id"]))
138
+ if row.get("outcome"):
139
+ good = row["outcome"] == "success"
140
+ bits.append((mint if good else pink)(row["outcome"]))
141
+ return " · ".join(bits)
142
+ if t in ("hook_triggered", "hook_completed"):
143
+ return " · ".join(x for x in (row.get("hook_name"), row.get("status")) if x)
144
+ if t == "error":
145
+ return pink(str(row.get("message", ""))[:48])
146
+ for key in ("prompt", "reason", "response", "summary", "goal"):
147
+ if row.get(key):
148
+ return dim(str(row[key])[:48])
149
+ return ""
150
+
151
+
152
+ def trace(session_id: str, *, title: str = "trace") -> list[dict]:
153
+ """Print the event stream this run produced. Returns the rows."""
154
+ rows = events(session_id)
155
+ if not rows:
156
+ print(pink(" no events — is the spool configured?"))
157
+ return rows
158
+
159
+ kinds = sorted({r["type"] for r in rows})
160
+ agents = sorted({r.get("agent_id") for r in rows if r.get("agent_id")})
161
+ t0 = rows[0]["timestamp"]
162
+
163
+ print(pink("━━ ") + bold(f"failproof_ai · {title}"))
164
+ print(dim(f" session {session_id}"))
165
+ print(dim(f" events {len(rows)} · agents {len(agents)} · types {len(kinds)}"))
166
+ print()
167
+ print(dim(f" {'№':>3} {'offset':>8} {'event':<16} detail"))
168
+ print(dim(" " + RULE))
169
+
170
+ depth = 0
171
+ for i, row in enumerate(rows, 1):
172
+ t = row["type"]
173
+ if t in _CLOSERS:
174
+ depth = max(depth - 1, 0)
175
+ indent = " " * depth
176
+ offset = _offset(t0, row["timestamp"])
177
+ name = f"{indent}{t}"
178
+ print(f" {i:>3} {dim(offset):>8} {name:<16} {_detail(row)}")
179
+ if t in _LEAF:
180
+ depth += 1
181
+ print(dim(" " + RULE))
182
+ print(dim(" " + " ".join(kinds)))
183
+ print()
184
+ return rows
185
+
186
+
187
+ def _offset(first: str, ts: str) -> str:
188
+ from datetime import datetime
189
+
190
+ try:
191
+ a = datetime.fromisoformat(first.replace("Z", "+00:00"))
192
+ b = datetime.fromisoformat(ts.replace("Z", "+00:00"))
193
+ return f"+{(b - a).total_seconds():.3f}s"
194
+ except Exception:
195
+ return ""