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,190 @@
1
+ """errors — list errored events, or --aggregate them into a summary card.
2
+
3
+ Read-only; talks to the dashboard `/api/events/summary` (the light, payload-free errored
4
+ rows) and `/api/events/error_summary` (the aggregate). The list view renders the server's
5
+ precomputed `summary` column — the CLI never returns the fat payload for an errors read.
6
+ Free-text `--search` remains the exception at the database layer: it scans payload to match.
7
+ Emits the server payload verbatim under `--json`.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from typing import List, Optional
13
+
14
+ import typer
15
+
16
+ from .. import client as api
17
+ from .. import dates, output
18
+ from .._context import (
19
+ GLOBALS_EPILOG,
20
+ AppState,
21
+ require_auth,
22
+ resolve_dates,
23
+ resolve_fields,
24
+ validate_choice,
25
+ validate_limit,
26
+ )
27
+ from ..models import AgentEvent
28
+
29
+
30
+ def errors(
31
+ ctx: typer.Context,
32
+ aggregate: bool = typer.Option(False, "--aggregate", help="Summarise the matching errors into a card (count + sessions/agents/last seen) instead of listing them."),
33
+ limit: int = typer.Option(50, "--limit", "-n", help="Max rows in total (list mode). Use --all to auto-paginate beyond the server's single-request cap."),
34
+ since: Optional[str] = typer.Option(None, "--since", help=f"Relative window from now (dashboard presets): {', '.join(dates.SINCE_CHOICES)}."),
35
+ ts_from: Optional[str] = typer.Option(None, "--from", help="Custom-range start, ISO-8601 UTC (e.g. 2026-05-01T00:00:00Z). Overrides --since."),
36
+ ts_to: Optional[str] = typer.Option(None, "--to", help="Custom-range end, ISO-8601 UTC. Overrides --since."),
37
+ environment: Optional[str] = typer.Option(None, "--env", help="Filter to one environment (exact match). e.g. `prod`."),
38
+ error_type: Optional[str] = typer.Option(None, "--error-type", help="Filter to one error type (exact match). e.g. `TimeoutError`."),
39
+ event_type: Optional[str] = typer.Option(None, "--event-type", help="Filter to one event type (exact match). e.g. `error`."),
40
+ agent_id: Optional[str] = typer.Option(None, "--agent-id", help="Filter to one agent id (exact match)."),
41
+ session_id: Optional[str] = typer.Option(None, "--session-id", help="Filter to one session id (exact match)."),
42
+ search: Optional[List[str]] = typer.Option(None, "--search", help="Free-text term to match in the payload (repeatable; an event matches if it contains ANY of the terms)."),
43
+ order: Optional[str] = typer.Option(None, "--order", help="Sort order by time: `asc` or `desc` (default newest-first; list mode)."),
44
+ fetch_all: bool = typer.Option(False, "--all", help="Auto-paginate through all pages, up to --limit (list mode)."),
45
+ cursor: Optional[str] = typer.Option(None, "--cursor", help="Resume after this cursor (a prior next_cursor; opaque token; list mode)."),
46
+ page_size: Optional[int] = typer.Option(None, "--page-size", help="Rows per request when --all (max 200; list mode)."),
47
+ fields: Optional[str] = typer.Option(None, "--fields", help="Comma-separated subset of fields to output (list mode). e.g. `ts,event_type,session_id`."),
48
+ full_ids: bool = typer.Option(False, "--full-ids", help="Show full session ids in the table instead of truncating them (list mode; --json always has the full id)."),
49
+ ) -> None:
50
+ """List **errored events**, newest first — or roll them up with **`--aggregate`**.
51
+
52
+ Errored events are the failures across your agents' runs (the dashboard's `/errors` view).
53
+ Two modes, same filters:
54
+
55
+ * **list** (default) — one row per errored event: `time · event · env · agent · session ·
56
+ summary` (the summary is derived from the event payload).
57
+ * **`--aggregate`** — a summary card: the total error count plus how many sessions and agents
58
+ are affected and how recent the last error is.
59
+
60
+ Each filter — `--env`, `--error-type`, `--event-type`, `--agent-id`, `--session-id` — takes a
61
+ **single** value; combine them to narrow to one slice (they AND together). `--search` matches
62
+ a free-text term in the event payload (repeatable — an event matches ANY of the terms). Scope
63
+ time with `--since` or `--from`/`--to`. Every filter applies to both modes.
64
+
65
+ Needs `events:read`. List `--json`: `{"errors": [...], "next_cursor": …}` — each row is a
66
+ light, payload-free event (`id, session_id, agent_id, event_type, ts, environment,
67
+ summary, is_error, error_type, output_tokens`, also the valid `--fields` names). The
68
+ rendered `summary` is the server-computed `summary` field (no client-side payload
69
+ parsing). Aggregate `--json`: `{total, sessions, agents, last_ts, bins}`. For the raw
70
+ payload of an errored run, use `fp events --full --session-id <id>`.
71
+
72
+ Examples:
73
+
74
+ * `fp errors --env prod --since 24h` — recent production errors
75
+ * `fp errors --error-type TimeoutError --agent-id agent-orderbot` — one agent's timeouts
76
+ * `fp errors --aggregate --env prod --since 7d` — how many prod errors this week, and where
77
+ * `fp --json errors --session-id sess-001 --all | jq '.errors[].summary'` — one session's error summaries as JSON
78
+ """
79
+ state: AppState = ctx.obj
80
+ cctx = require_auth(state)
81
+ validate_limit(limit)
82
+ order = validate_choice(order, ("asc", "desc"), flag="--order")
83
+ frm, to = resolve_dates(since, ts_from, ts_to)
84
+
85
+ # Which narrowing filters did the user set? Used to word the empty message and to nudge them
86
+ # to re-check those values when nothing matches (a value matching nothing returns empty, not
87
+ # an error — so a typo reads as "no errors"). Applies to both modes.
88
+ active_filters = [
89
+ flag for flag, val in (
90
+ ("--env", environment),
91
+ ("--event-type", event_type),
92
+ ("--error-type", error_type),
93
+ ("--agent-id", agent_id),
94
+ ("--session-id", session_id),
95
+ ("--search", search),
96
+ ("--since/--from/--to", since or ts_from or ts_to),
97
+ ) if val
98
+ ]
99
+
100
+ # ── aggregate mode: one summary payload, no pagination ──
101
+ if aggregate:
102
+ data = api.event_error_summary(
103
+ cctx,
104
+ session_id=session_id,
105
+ agent_id=agent_id,
106
+ event_type=event_type,
107
+ error_type=error_type,
108
+ environment=environment,
109
+ search=search,
110
+ ts_from=frm,
111
+ ts_to=to,
112
+ )
113
+ if state.json:
114
+ output.emit_json(data)
115
+ else:
116
+ output.render_error_aggregate(data)
117
+ if not int(data.get("total", 0) or 0):
118
+ output.recheck_filters_hint(active_filters)
119
+ return
120
+
121
+ # ── list mode: errored events (errored=true, like the dashboard /errors view) ──
122
+ # `errors` ALWAYS reads the light, payload-free `/api/events/summary` feed —
123
+ # there is no `--full` here and no feed switch. So validating `--fields`
124
+ # against the whole `AgentEvent` dataclass accepted `payload`, whose
125
+ # dataclass default is `{}`, and the projection emitted that empty dict as if
126
+ # it were data: `fp --json errors --fields payload` exited 0 printing
127
+ # `{"payload": {}}` per row, and a caller piping it into `jq` reasonably
128
+ # concluded the errored events carried no payload. `events` gets this right
129
+ # by switching feeds; here the honest answer is a usage error naming the
130
+ # command that can serve it. The docstring above already lists the valid
131
+ # names and `payload` is deliberately not among them.
132
+ if fields and "payload" in {f.strip() for f in fields.split(",")}:
133
+ raise typer.BadParameter(
134
+ "`payload` is not available on `fp errors` — it reads the light, "
135
+ "payload-free feed. Use `fp events --full --session-id <id>` (or "
136
+ "`fp events --fields payload`) to get event payloads."
137
+ )
138
+ cols = resolve_fields(fields, AgentEvent)
139
+ common = dict(
140
+ session_id=session_id,
141
+ agent_id=agent_id,
142
+ event_type=event_type,
143
+ error_type=error_type,
144
+ environment=environment,
145
+ errored=True,
146
+ order=order,
147
+ search=search,
148
+ ts_from=frm,
149
+ ts_to=to,
150
+ )
151
+
152
+ if fetch_all:
153
+ walk = api.Walk()
154
+ items = list(
155
+ api.paginate(
156
+ lambda cursor, limit: api.list_event_summaries(cctx, cursor=cursor, limit=limit, **common),
157
+ limit=limit,
158
+ page_size=page_size,
159
+ start_cursor=cursor,
160
+ walk=walk,
161
+ )
162
+ )
163
+ # NOT `None`. `--limit` defaults to 50, so `--all` without an explicit
164
+ # limit stops at 50 rows — and hard-coding the cursor to null told the
165
+ # caller the feed was exhausted, on the one output a script or an agent
166
+ # reads. `walk` carries the cursor the walk actually stopped on.
167
+ next_cursor = walk.next_cursor
168
+ else:
169
+ page = api.list_event_summaries(cctx, cursor=cursor, limit=limit, **common)
170
+ items = page.items
171
+ next_cursor = page.next_cursor
172
+
173
+ if state.json:
174
+ payload = output.project_dicts(items, cols) if cols else items
175
+ output.emit_json({"errors": payload, "next_cursor": next_cursor})
176
+ return
177
+
178
+ if cols:
179
+ # `--fields` asks for specific raw columns → the generic table (no bespoke styling).
180
+ output.print_table(list(cols), output.project_rows(items, cols), title=f"Errors ({len(items)})")
181
+ else:
182
+ empty_message = "no errors match these filters" if active_filters else "no errors"
183
+ output.render_errors(items, order=order, full_ids=full_ids, empty_message=empty_message)
184
+ output.errors_footer(len(items), more=next_cursor is not None)
185
+ if not items:
186
+ output.recheck_filters_hint(active_filters)
187
+
188
+
189
+ def register(app: typer.Typer) -> None:
190
+ app.command("errors", epilog=GLOBALS_EPILOG)(errors)
@@ -0,0 +1,161 @@
1
+ """evals — list evaluation results (with scores), or roll them up with --aggregate."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import List, Optional
6
+
7
+ import typer
8
+
9
+ from .. import client as api
10
+ from .. import dates, output
11
+ from .._context import (
12
+ GLOBALS_EPILOG,
13
+ AppState,
14
+ require_auth,
15
+ resolve_dates,
16
+ resolve_fields,
17
+ validate_choice,
18
+ validate_limit,
19
+ validate_score_filters,
20
+ )
21
+ from ..models import Evaluation
22
+
23
+
24
+ def evals(
25
+ ctx: typer.Context,
26
+ aggregate: bool = typer.Option(False, "--aggregate", help="Roll the matching evaluations up into a totals card + per-metric score stats, instead of listing rows."),
27
+ limit: int = typer.Option(50, "--limit", "-n", help="Max rows in total (list mode). Use --all to auto-paginate beyond the server's single-request cap."),
28
+ since: Optional[str] = typer.Option(None, "--since", help=f"Relative window from now (dashboard presets): {', '.join(dates.SINCE_CHOICES)}."),
29
+ ts_from: Optional[str] = typer.Option(None, "--from", help="Custom-range start, ISO-8601 UTC (e.g. 2026-05-01T00:00:00Z). Overrides --since."),
30
+ ts_to: Optional[str] = typer.Option(None, "--to", help="Custom-range end, ISO-8601 UTC. Overrides --since."),
31
+ environment: Optional[str] = typer.Option(None, "--env", help="Filter to one environment (exact match). e.g. `prod`."),
32
+ status: Optional[str] = typer.Option(None, "--status", help="Filter to one evaluation status: `done`, `error`, or `timeout`."),
33
+ agent_id: Optional[str] = typer.Option(None, "--agent-id", help="Filter to one agent id (exact match)."),
34
+ session_id: Optional[str] = typer.Option(None, "--session-id", help="Filter to one session id (exact match)."),
35
+ score: Optional[List[str]] = typer.Option(None, "--score", help="Score range filter `KEY:MIN..MAX` (either bound optional). Repeatable; all must match. e.g. `helpfulness:0.5..0.8`."),
36
+ fetch_all: bool = typer.Option(False, "--all", help="Auto-paginate through all pages, up to --limit (list mode)."),
37
+ cursor: Optional[str] = typer.Option(None, "--cursor", help="Resume after this cursor (a prior next_cursor; opaque token; list mode)."),
38
+ page_size: Optional[int] = typer.Option(None, "--page-size", help="Rows per request when --all (max 200; list mode)."),
39
+ fields: Optional[str] = typer.Option(None, "--fields", help="Comma-separated subset of fields to output (list mode). e.g. `session_id,status,scores`."),
40
+ full_ids: bool = typer.Option(False, "--full-ids", help="Show full session ids in the table instead of truncating them (list mode; --json always has the full id)."),
41
+ scores_full: bool = typer.Option(False, "--scores-full", help="Show every score pair in the table instead of the first few + `+N` (list mode; may wrap)."),
42
+ ) -> None:
43
+ """List **evaluation results** with their scores, newest first — or roll them up with
44
+ **`--aggregate`**. An evaluation is one scored judgement of an agent run.
45
+
46
+ Two modes, same filters:
47
+
48
+ * **list** (default) — one row per evaluation: `time · env · agent · session · status · scores`.
49
+ * **`--aggregate`** — a totals card (run-health mix + success rate) and a per-metric
50
+ score-stats table (count, average + bar, min/max/p50) over the whole matching set, worst
51
+ average first. Point it at one slice — an agent, env, session, or status — to read that
52
+ slice's score performance.
53
+
54
+ The filters `--env`, `--status`, `--agent-id`, and `--session-id` each take a **single**
55
+ value; combine them to narrow a slice (they AND together). `--score KEY:MIN..MAX` filters by
56
+ score range — either bound optional (`helpfulness:0.5..0.8`, `tool_efficiency:..0.3`,
57
+ `factuality:0.9..`) — and is **repeatable**, with **all** ranges required (AND). Scope time
58
+ with `--since` or `--from`/`--to`. Every filter applies to both modes.
59
+
60
+ Needs `evaluations:read`. List `--json`: `{"evaluations": [...], "next_cursor": …}`.
61
+ Aggregate `--json`: `{total, status_counts, score_stats[], timeline}`.
62
+
63
+ Examples:
64
+
65
+ * `fp evals --agent-id agent-orderbot --aggregate` — one agent's score performance, rolled up
66
+ * `fp evals --aggregate --env prod --status error` — score stats for prod runs that failed
67
+ * `fp evals --score helpfulness:0.8.. --since 7d` — recent evaluations scoring ≥0.8 on helpfulness
68
+ * `fp --json evals --aggregate --session-id sess-001 | jq '.score_stats'` — one session's metric stats as JSON
69
+ """
70
+ state: AppState = ctx.obj
71
+ cctx = require_auth(state)
72
+ validate_score_filters(score)
73
+ validate_limit(limit)
74
+ status = validate_choice(status, ("done", "error", "timeout"), flag="--status")
75
+ frm, to = resolve_dates(since, ts_from, ts_to)
76
+ score_filters = ",".join(score) if score else None
77
+
78
+ # Which narrowing filters did the user set? Used to word the empty message and to nudge
79
+ # them to re-check those values when nothing matches (a value matching nothing returns an
80
+ # empty set, not an error — so a typo looks like "no evals"). Applies to both modes.
81
+ active_filters = [
82
+ flag for flag, val in (
83
+ ("--env", environment),
84
+ ("--status", status),
85
+ ("--agent-id", agent_id),
86
+ ("--session-id", session_id),
87
+ ("--score", score),
88
+ ("--since/--from/--to", since or ts_from or ts_to),
89
+ ) if val
90
+ ]
91
+
92
+ # ── aggregate mode: one rolled-up payload, no pagination ──
93
+ if aggregate:
94
+ data = api.evaluation_aggregate(
95
+ cctx,
96
+ session_id=session_id,
97
+ agent_id=agent_id,
98
+ environment=environment,
99
+ status=status,
100
+ score_filters=score_filters,
101
+ ts_from=frm,
102
+ ts_to=to,
103
+ )
104
+ if state.json:
105
+ output.emit_json(data)
106
+ else:
107
+ output.render_eval_aggregate(data)
108
+ if not int(data.get("total", 0) or 0):
109
+ output.recheck_filters_hint(active_filters)
110
+ return
111
+
112
+ # ── list mode ──
113
+ cols = resolve_fields(fields, Evaluation)
114
+
115
+ def fetch(cursor: Optional[int], limit: Optional[int]):
116
+ return api.list_evaluations(
117
+ cctx,
118
+ session_id=session_id,
119
+ agent_id=agent_id,
120
+ environment=environment,
121
+ status=status,
122
+ score_filters=score_filters,
123
+ ts_from=frm,
124
+ ts_to=to,
125
+ cursor=cursor,
126
+ limit=limit,
127
+ )
128
+
129
+ if fetch_all:
130
+ walk = api.Walk()
131
+ items = list(
132
+ api.paginate(fetch, limit=limit, page_size=page_size, start_cursor=cursor, walk=walk)
133
+ )
134
+ # NOT `None`. `--limit` defaults to 50, so `--all` without an explicit
135
+ # limit stops at 50 rows — and hard-coding the cursor to null told the
136
+ # caller the feed was exhausted, on the one output a script or an agent
137
+ # reads. `walk` carries the cursor the walk actually stopped on.
138
+ next_cursor = walk.next_cursor
139
+ else:
140
+ page = fetch(cursor, limit)
141
+ items = page.items
142
+ next_cursor = page.next_cursor
143
+
144
+ if state.json:
145
+ payload = output.project_dicts(items, cols) if cols else items
146
+ output.emit_json({"evaluations": payload, "next_cursor": next_cursor})
147
+ return
148
+
149
+ if cols:
150
+ # `--fields` asks for specific columns → the generic table (no bespoke styling).
151
+ output.print_table(list(cols), output.project_rows(items, cols), title=f"Evaluations ({len(items)})")
152
+ else:
153
+ empty_message = "no evals match these filters" if active_filters else "no evals"
154
+ output.render_evals(items, full_ids=full_ids, scores_full=scores_full, empty_message=empty_message)
155
+ output.evals_footer(len(items), more=next_cursor is not None)
156
+ if not items:
157
+ output.recheck_filters_hint(active_filters)
158
+
159
+
160
+ def register(app: typer.Typer) -> None:
161
+ app.command("evals", epilog=GLOBALS_EPILOG)(evals)
@@ -0,0 +1,159 @@
1
+ """events — list raw agent events."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import List, Optional
6
+
7
+ import typer
8
+
9
+ from .. import client as api
10
+ from .. import dates, output
11
+ from .._context import (
12
+ GLOBALS_EPILOG,
13
+ AppState,
14
+ collect_multi,
15
+ require_auth,
16
+ resolve_dates,
17
+ resolve_fields,
18
+ validate_limit,
19
+ )
20
+ from ..models import AgentEvent
21
+
22
+
23
+ def events(
24
+ ctx: typer.Context,
25
+ limit: int = typer.Option(50, "--limit", "-n", help="Max rows in total. Use --all to auto-paginate beyond the server's single-request cap."),
26
+ since: Optional[str] = typer.Option(None, "--since", help=f"Relative window from now (dashboard presets): {', '.join(dates.SINCE_CHOICES)}."),
27
+ ts_from: Optional[str] = typer.Option(None, "--from", help="Custom-range start, ISO-8601 UTC (e.g. 2026-05-01T00:00:00Z). Overrides --since."),
28
+ ts_to: Optional[str] = typer.Option(None, "--to", help="Custom-range end, ISO-8601 UTC. Overrides --since."),
29
+ environment: Optional[List[str]] = typer.Option(None, "--env", help="Filter by environment. Accepts multiple — repeat the flag or comma-separate: `--env prod --env staging` or `--env prod,staging` (matches any)."),
30
+ event_type: Optional[List[str]] = typer.Option(None, "--event-type", help="Filter by event type. Accepts multiple — repeat the flag or comma-separate: `--event-type tool_use,tool_result` (matches any). Discover values with `fp list event_types`."),
31
+ agent_id: Optional[List[str]] = typer.Option(None, "--agent-id", help="Filter by agent id. Accepts multiple — repeat the flag or comma-separate: `--agent-id a,b` (matches any). Discover values with `fp list agents`."),
32
+ session_id: Optional[List[str]] = typer.Option(None, "--session-id", help="Filter by session id. Accepts multiple — repeat the flag or comma-separate: `--session-id a,b` (matches any)."),
33
+ search: Optional[List[str]] = typer.Option(None, "--search", help="Free-text term to match in the payload (repeatable; an event matches if it contains ANY of the terms)."),
34
+ order: Optional[str] = typer.Option(None, "--order", help="Sort order by time: `asc` or `desc` (default newest-first)."),
35
+ fetch_all: bool = typer.Option(False, "--all", help="Auto-paginate through all pages, up to --limit."),
36
+ cursor: Optional[str] = typer.Option(None, "--cursor", help="Resume after this cursor (a prior next_cursor; opaque token)."),
37
+ page_size: Optional[int] = typer.Option(None, "--page-size", help="Rows per request when --all (max 200)."),
38
+ full: bool = typer.Option(False, "--full", help="Fetch the FULL event rows incl. the raw `payload` (the heavy feed). Off by default — the light payload-free feed is used unless you pass this or request `--fields payload`. The full feed is slow at scale, so keep it bounded (e.g. to one `--session-id`)."),
39
+ fields: Optional[str] = typer.Option(None, "--fields", help="Comma-separated subset of fields to output (applies to --json and the table). e.g. `ts,event_type,summary`. Requesting `payload` auto-switches to the full feed."),
40
+ ) -> None:
41
+ """List **event logs** — the raw, per-step trail your agents emit (tool calls, model
42
+ requests/responses, hooks, results), newest first.
43
+
44
+ Narrow the feed with the filters below. `--env`, `--event-type`, `--agent-id`, and
45
+ `--session-id` each accept **multiple values** — repeat the flag or comma-separate
46
+ (`--env prod,staging` is the same as `--env prod --env staging`). Values within one
47
+ filter match **any** of them; different filters are combined (an event must satisfy all
48
+ of them). Scope by time with `--since` (a preset window) or `--from`/`--to` (a custom
49
+ UTC range), and walk large result sets with `--all` (or resume with `--cursor`).
50
+
51
+ Discover valid filter values with `fp list` — e.g. `fp list event_types`,
52
+ `fp list agents`, `fp list envs`.
53
+
54
+ Needs `events:read`. With `--json`: `{"events": [...], "next_cursor": <cursor or null>}`.
55
+
56
+ By **default** this reads the light, payload-free feed — each event has `id, session_id,
57
+ agent_id, event_type, ts, environment, summary, is_error, error_type, output_tokens,
58
+ context_window, context_fill` (a server-computed one-line `summary`, never the raw
59
+ payload). This is the fast path for structured filters, `--session-id`, and `--all`.
60
+ `--search` keeps the response payload-free but still scans payload server-side, so broad
61
+ searches may be expensive. To get
62
+ the raw `payload`, opt into the **full feed** with `--full` (or `--fields payload`), which
63
+ hits the heavy `/events` endpoint — slow at scale, so keep it bounded (pair `--full` with a
64
+ single `--session-id`). All listed keys are valid `--fields` names (`payload` too, in full
65
+ mode).
66
+
67
+ Examples:
68
+
69
+ * `fp events --env prod,staging --event-type tool_use,error --limit 100` — recent prod/staging events (light)
70
+ * `fp --json events --session-id run-001 --all` — a run's full timeline: event types + summaries (light, fast)
71
+ * `fp --json events --full --session-id run-001 --all | jq '.events[].payload'` — that run's raw payloads (full feed, bounded to one run)
72
+ """
73
+ state: AppState = ctx.obj
74
+ cctx = require_auth(state)
75
+ frm, to = resolve_dates(since, ts_from, ts_to)
76
+ cols = resolve_fields(fields, AgentEvent)
77
+ if order is not None and order not in ("asc", "desc"):
78
+ raise typer.BadParameter("--order must be 'asc' or 'desc'.")
79
+ validate_limit(limit)
80
+
81
+ # Multi-value filters: merge repeated flags + comma-separated values into one flat,
82
+ # de-duplicated list each (the server UNIONs within a filter via `IN`, ANDs across them).
83
+ session_id = collect_multi(session_id)
84
+ agent_id = collect_multi(agent_id)
85
+ event_type = collect_multi(event_type)
86
+ environment = collect_multi(environment)
87
+
88
+ # Default to the light, payload-free feed (/api/events/summary). Only reach for the heavy
89
+ # full feed (/api/events, with `payload`) when the caller EXPLICITLY asks for the raw
90
+ # payload: --full, or --fields payload. Everything else — including --session-id — stays
91
+ # on the light feed: the full feed is slow/timeout-prone at scale, a single-session read
92
+ # wants the summaries/timeline (not the fat payload), and payload is a deliberate opt-in.
93
+ use_full = full or (cols is not None and "payload" in cols)
94
+ fetch = api.list_events if use_full else api.list_event_summaries
95
+
96
+ common = dict(
97
+ session_id=session_id,
98
+ agent_id=agent_id,
99
+ event_type=event_type,
100
+ environment=environment,
101
+ order=order,
102
+ search=search,
103
+ ts_from=frm,
104
+ ts_to=to,
105
+ )
106
+
107
+ if fetch_all:
108
+ walk = api.Walk()
109
+ items = list(
110
+ api.paginate(
111
+ lambda cursor, limit: fetch(cctx, cursor=cursor, limit=limit, **common),
112
+ limit=limit,
113
+ page_size=page_size,
114
+ start_cursor=cursor,
115
+ walk=walk,
116
+ )
117
+ )
118
+ # NOT `None`. `--limit` defaults to 50, so `--all` without an explicit
119
+ # limit stops at 50 rows — and hard-coding the cursor to null told the
120
+ # caller the feed was exhausted, on the one output a script or an agent
121
+ # reads. `walk` carries the cursor the walk actually stopped on.
122
+ next_cursor = walk.next_cursor
123
+ else:
124
+ page = fetch(cctx, cursor=cursor, limit=limit, **common)
125
+ items = page.items
126
+ next_cursor = page.next_cursor
127
+
128
+ if state.json:
129
+ payload = output.project_dicts(items, cols) if cols else items
130
+ output.emit_json({"events": payload, "next_cursor": next_cursor})
131
+ return
132
+
133
+ # Which narrowing filters did the user actually set? Used to (a) word the empty-box
134
+ # message and (b) nudge them to re-check those values when 0 rows come back — the server
135
+ # returns an empty set for any value that matches nothing, so a typo looks like "no data".
136
+ active_filters = [
137
+ flag for flag, val in (
138
+ ("--env", environment),
139
+ ("--event-type", event_type),
140
+ ("--agent-id", agent_id),
141
+ ("--session-id", session_id),
142
+ ("--search", search),
143
+ ("--since/--from/--to", since or ts_from or ts_to),
144
+ ) if val
145
+ ]
146
+
147
+ if cols:
148
+ # `--fields` asks for specific columns → the generic table (no bespoke styling).
149
+ output.print_table(list(cols), output.project_rows(items, cols), title=f"Events ({len(items)})")
150
+ else:
151
+ empty_message = "no events match these filters" if active_filters else "no events in this window"
152
+ output.render_events(items, order=order, empty_message=empty_message)
153
+ output.events_footer(len(items), more=next_cursor is not None)
154
+ if not items:
155
+ output.recheck_filters_hint(active_filters)
156
+
157
+
158
+ def register(app: typer.Typer) -> None:
159
+ app.command("events", epilog=GLOBALS_EPILOG)(events)