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.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +6 -6
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js +2 -2
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js +2 -2
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/audit/invite/route.js +3 -2
- package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route.js +5 -4
- package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js +2 -2
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +4 -3
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route.js +4 -4
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route.js +4 -4
- package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page.js +2 -2
- package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js +2 -2
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +66 -22
- package/.next/standalone/.next/server/app/policies/page.js +5 -4
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js +2 -2
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js +2 -2
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -4
- package/.next/standalone/.next/server/app/settings/page.js +1 -1
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__1qzqcio._.js → [externals]__0e32-7c._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[externals]__1s462yl._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__01eqny5._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0xu5z._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1p8poxd._.js → [root-of-the-server]__0igxt32._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0neqlu-._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t9oqnn._.js +3 -0
- package/.next/standalone/.next/server/chunks/_0bs-v8p._.js +3 -0
- package/.next/standalone/.next/server/chunks/_0tovk6q._.js +3 -0
- package/.next/standalone/.next/server/chunks/_0trp3yc._.js +3 -0
- package/.next/standalone/.next/server/chunks/_185gyk9._.js +3 -0
- package/.next/standalone/.next/server/chunks/_1ek68ln._.js +5 -6
- package/.next/standalone/.next/server/chunks/lib_telemetry-id_ts_1k8gj9o._.js +3 -0
- 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
- 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
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_hooks_0xbw3bu._.js +12 -0
- package/.next/standalone/.next/server/chunks/src_hooks_fp-home_ts_09kv0bn._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0spkm68._.js → [root-of-the-server]__07gm3zl._.js} +21 -20
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +6 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__07tbbf3._.js → [root-of-the-server]__0zig5sv._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__192nhvh._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/{_0lvyuv4._.js → _00e9tnf._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_0u5zauv._.js → _12l4a_k._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +13 -13
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_08o7bqo._.js +10 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-home_ts_0je3xkv._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/middleware.js +1 -1
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +71 -27
- package/.next/standalone/.next/static/chunks/{37fcpc36x9gpe.js → 0eqky-7n7dgdm.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1ide1wl2f7zi1.js → 0sa9v5mhc8861.js} +13 -13
- package/.next/standalone/.next/static/chunks/1mfzsja6ftim5.css +2 -0
- package/.next/standalone/.next/static/chunks/{3k7mxbp9hiom0.js → 1nuqytbta44af.js} +1 -1
- package/.next/standalone/.next/static/chunks/1sl2xmn9inx3y.js +6 -0
- package/.next/standalone/.next/static/chunks/{2_2lhuojq2xop.js → 2aawsjld9ied_.js} +1 -1
- package/.next/standalone/.next/static/chunks/2gn7ut4svofm2.js +1 -0
- package/.next/standalone/.next/static/chunks/{31s1smp-g7gks.js → 2hs7ycvsav7v2.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0k5050ezjvv49.js → 2i2yt3hzjredm.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3c808qrfcq0im.js → 35xg6retpe6rp.js} +1 -1
- package/.next/standalone/.next/static/chunks/{2zpp1we2jv6tb.js → 3y54nw0i7dsjl.js} +1 -1
- package/.next/standalone/SECURITY.md +5 -4
- package/.next/standalone/app/actions/get-hooks-config.ts +108 -17
- package/.next/standalone/app/actions/pack-actions.ts +153 -0
- package/.next/standalone/app/audit/_components/run-progress.tsx +1 -1
- package/.next/standalone/app/audit/_components/share-templates.ts +13 -13
- package/.next/standalone/app/policies/hooks-client.tsx +320 -14
- package/.next/standalone/components/navbar.tsx +2 -28
- package/.next/standalone/components/reach-developers.tsx +8 -1
- package/.next/standalone/docs-old/agenteye/python-sdk-skill.mdx +1 -1
- package/.next/standalone/docs-old/agenteye/python-sdk.mdx +59 -35
- package/.next/standalone/docs-old/i18n/README.ar.md +1 -0
- package/.next/standalone/docs-old/i18n/README.de.md +1 -0
- package/.next/standalone/docs-old/i18n/README.es.md +1 -0
- package/.next/standalone/docs-old/i18n/README.fr.md +1 -0
- package/.next/standalone/docs-old/i18n/README.he.md +1 -0
- package/.next/standalone/docs-old/i18n/README.hi.md +1 -0
- package/.next/standalone/docs-old/i18n/README.it.md +1 -0
- package/.next/standalone/docs-old/i18n/README.ja.md +1 -0
- package/.next/standalone/docs-old/i18n/README.ko.md +1 -0
- package/.next/standalone/docs-old/i18n/README.pt-br.md +1 -0
- package/.next/standalone/docs-old/i18n/README.ru.md +1 -0
- package/.next/standalone/docs-old/i18n/README.tr.md +1 -0
- package/.next/standalone/docs-old/i18n/README.vi.md +1 -0
- package/.next/standalone/docs-old/i18n/README.zh.md +1 -0
- package/.next/standalone/fp-cloud-cli/CHANGELOG.md +431 -0
- package/.next/standalone/fp-cloud-cli/LICENSE +42 -0
- package/.next/standalone/fp-cloud-cli/MANIFEST.in +10 -0
- package/.next/standalone/fp-cloud-cli/README.md +259 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/__init__.py +10 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/__main__.py +4 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/_click_compat.py +64 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/_context.py +332 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/_version.py +1 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/analytics.py +432 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/analytics_config.py +77 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/analytics_registry.py +83 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/app.py +492 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/auth.py +160 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/client.py +1694 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/__init__.py +0 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/_write.py +214 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/agent_cmds.py +407 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/alerts_cmds.py +445 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/audits_cmds.py +1054 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/auth_cmds.py +512 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/errors_cmds.py +190 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/evals_cmds.py +161 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/events_cmds.py +159 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/fleet_cmds.py +416 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/guardrails_cmds.py +148 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/incidents_cmds.py +472 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/keys_cmds.py +407 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/list_cmds.py +63 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/orgs_cmds.py +319 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/policies_cmds.py +499 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/queries_cmds.py +378 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/sessions_cmds.py +151 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/settings_cmds.py +150 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/usage_cmds.py +35 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/users_cmds.py +404 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/config.py +330 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/dates.py +78 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/enforcement.py +345 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/errors.py +98 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/models.py +891 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/orgs.py +30 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/output.py +6593 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/permissions.py +208 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/policy_check.py +290 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/py.typed +0 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/select.py +322 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/theme.py +53 -0
- package/.next/standalone/fp-cloud-cli/pyproject.toml +106 -0
- package/.next/standalone/fp-cloud-cli/skill/SKILL.md +302 -0
- package/.next/standalone/fp-cloud-cli/skill/agents/openai.yaml +8 -0
- package/.next/standalone/fp-cloud-cli/skill/references/commands.md +254 -0
- package/.next/standalone/fp-cloud-cli/tests/__init__.py +0 -0
- package/.next/standalone/fp-cloud-cli/tests/conftest.py +92 -0
- package/.next/standalone/fp-cloud-cli/tests/test_alerting.py +644 -0
- package/.next/standalone/fp-cloud-cli/tests/test_analytics.py +385 -0
- package/.next/standalone/fp-cloud-cli/tests/test_audits.py +950 -0
- package/.next/standalone/fp-cloud-cli/tests/test_auth.py +98 -0
- package/.next/standalone/fp-cloud-cli/tests/test_auth_mode.py +272 -0
- package/.next/standalone/fp-cloud-cli/tests/test_click_compat.py +118 -0
- package/.next/standalone/fp-cloud-cli/tests/test_client.py +299 -0
- package/.next/standalone/fp-cloud-cli/tests/test_commands.py +814 -0
- package/.next/standalone/fp-cloud-cli/tests/test_config.py +99 -0
- package/.next/standalone/fp-cloud-cli/tests/test_dashboards_agent.py +340 -0
- package/.next/standalone/fp-cloud-cli/tests/test_dates.py +76 -0
- package/.next/standalone/fp-cloud-cli/tests/test_enforcement_logic.py +481 -0
- package/.next/standalone/fp-cloud-cli/tests/test_facets.py +170 -0
- package/.next/standalone/fp-cloud-cli/tests/test_failproofai_home.py +722 -0
- package/.next/standalone/fp-cloud-cli/tests/test_fp_home_contract.py +198 -0
- package/.next/standalone/fp-cloud-cli/tests/test_hardening.py +186 -0
- package/.next/standalone/fp-cloud-cli/tests/test_help_table_coverage.py +127 -0
- package/.next/standalone/fp-cloud-cli/tests/test_keys_queries.py +496 -0
- package/.next/standalone/fp-cloud-cli/tests/test_list.py +59 -0
- package/.next/standalone/fp-cloud-cli/tests/test_multivalue.py +183 -0
- package/.next/standalone/fp-cloud-cli/tests/test_no_customer_identifiers.py +168 -0
- package/.next/standalone/fp-cloud-cli/tests/test_operator.py +492 -0
- package/.next/standalone/fp-cloud-cli/tests/test_orgs.py +692 -0
- package/.next/standalone/fp-cloud-cli/tests/test_output.py +1732 -0
- package/.next/standalone/fp-cloud-cli/tests/test_policy_check.py +191 -0
- package/.next/standalone/fp-cloud-cli/tests/test_readme_matches_reality.py +125 -0
- package/.next/standalone/fp-cloud-cli/tests/test_review_fixes.py +161 -0
- package/.next/standalone/fp-cloud-cli/tests/test_telemetry_completeness.py +90 -0
- package/.next/standalone/fp-cloud-cli/tests/test_usage.py +115 -0
- package/.next/standalone/fp-cloud-cli/tests/test_v1_origin_diagnostic.py +70 -0
- package/.next/standalone/fp-cloud-cli/tests/test_v1_routing.py +214 -0
- package/.next/standalone/fp-cloud-cli/tests/test_whoami.py +104 -0
- package/.next/standalone/fp-cloud-cli/uv.lock +552 -0
- package/.next/standalone/package.json +29 -22
- package/.next/standalone/sdk/python/CHANGELOG.md +70 -0
- package/.next/standalone/sdk/python/LICENSE +42 -0
- package/.next/standalone/sdk/python/MANIFEST.in +21 -0
- package/.next/standalone/sdk/python/README.md +466 -0
- package/.next/standalone/sdk/python/docs/README.md +249 -0
- package/.next/standalone/sdk/python/docs/_shared/README.md +43 -0
- package/.next/standalone/sdk/python/docs/_shared/__init__.py +195 -0
- package/.next/standalone/sdk/python/docs/crewai/README.md +328 -0
- package/.next/standalone/sdk/python/docs/crewai/examples/quickstart.py +61 -0
- package/.next/standalone/sdk/python/docs/crewai/examples/research_crew.py +92 -0
- package/.next/standalone/sdk/python/docs/langgraph/README.md +481 -0
- package/.next/standalone/sdk/python/docs/langgraph/examples/quickstart.py +51 -0
- package/.next/standalone/sdk/python/docs/langgraph/examples/research_agent.py +86 -0
- package/.next/standalone/sdk/python/docs/langgraph/examples/supervisor_handoff.py +83 -0
- package/.next/standalone/sdk/python/docs/llama_index/README.md +332 -0
- package/.next/standalone/sdk/python/docs/llama_index/examples/quickstart.py +62 -0
- package/.next/standalone/sdk/python/docs/llama_index/examples/research_agent.py +93 -0
- package/.next/standalone/sdk/python/docs/manual/README.md +491 -0
- package/.next/standalone/sdk/python/docs/manual/examples/quickstart.py +57 -0
- package/.next/standalone/sdk/python/docs/manual/examples/research_agent.py +133 -0
- package/.next/standalone/sdk/python/docs/pydantic_ai/README.md +323 -0
- package/.next/standalone/sdk/python/docs/pydantic_ai/examples/quickstart.py +48 -0
- package/.next/standalone/sdk/python/docs/pydantic_ai/examples/research_agent.py +94 -0
- package/.next/standalone/sdk/python/failproofai_sdk/__init__.py +131 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_context.py +218 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_environment.py +78 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_events.py +752 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_resolver.py +118 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_runtime.py +21 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_schema.py +317 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_scopes.py +422 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_version.py +1 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_writer.py +750 -0
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/__init__.py +274 -0
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/_compat.py +247 -0
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/_core.py +1076 -0
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/crewai.py +1669 -0
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/langchain.py +2151 -0
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/llama_index.py +1588 -0
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/pydantic_ai.py +977 -0
- package/.next/standalone/sdk/python/failproofai_sdk/py.typed +0 -0
- package/.next/standalone/sdk/python/pyproject.toml +92 -0
- package/.next/standalone/sdk/python/skill/SKILL.md +399 -0
- package/.next/standalone/sdk/python/skill/agents/openai.yaml +8 -0
- package/.next/standalone/sdk/python/skill/references/events.md +234 -0
- package/.next/standalone/sdk/python/skill/references/frameworks.md +314 -0
- package/.next/standalone/sdk/python/skill/references/install.md +100 -0
- package/.next/standalone/sdk/python/skill/references/integration.md +352 -0
- package/.next/standalone/sdk/python/tests/__init__.py +0 -0
- package/.next/standalone/sdk/python/tests/conftest.py +169 -0
- package/.next/standalone/sdk/python/tests/integrations/__init__.py +6 -0
- package/.next/standalone/sdk/python/tests/integrations/test_crewai.py +1299 -0
- package/.next/standalone/sdk/python/tests/integrations/test_langchain.py +2338 -0
- package/.next/standalone/sdk/python/tests/integrations/test_llama_index.py +1576 -0
- package/.next/standalone/sdk/python/tests/integrations/test_pydantic_ai.py +1102 -0
- package/.next/standalone/sdk/python/tests/test_context.py +410 -0
- package/.next/standalone/sdk/python/tests/test_docs.py +411 -0
- package/.next/standalone/sdk/python/tests/test_durability.py +1352 -0
- package/.next/standalone/sdk/python/tests/test_encoding.py +571 -0
- package/.next/standalone/sdk/python/tests/test_integrations.py +1127 -0
- package/.next/standalone/sdk/python/tests/test_no_customer_identifiers.py +214 -0
- package/.next/standalone/sdk/python/tests/test_packaging.py +185 -0
- package/.next/standalone/sdk/python/tests/test_resolver_umbrella.py +178 -0
- package/.next/standalone/sdk/python/tests/test_scopes.py +487 -0
- package/.next/standalone/sdk/python/tests/test_sdk.py +923 -0
- package/.next/standalone/sdk/python/tests/test_server_contract.py +650 -0
- package/.next/standalone/sdk/python/tests/test_site_docs.py +371 -0
- package/.next/standalone/sdk/python/tests/test_skill_snippets.py +165 -0
- package/.next/standalone/sdk/python/tests/test_spool_contract.py +287 -0
- package/.next/standalone/sdk/python/tests/test_spool_creation.py +360 -0
- package/.next/standalone/sdk/python/tests/test_wire_format.py +279 -0
- package/.next/standalone/sdk/python/tests/test_zero_dependencies.py +378 -0
- package/.next/standalone/sdk/python/uv.lock +6005 -0
- package/.next/standalone/server.js +1 -1
- package/README.md +77 -21
- package/bin/failproofai.mjs +145 -11
- package/dist/cli.mjs +4482 -2205
- package/dist/index.js +5 -5
- package/dist/worker.mjs +2399 -1978
- package/package.json +29 -22
- package/policy-pack/SHA256SUMS +2 -0
- package/policy-pack/failproofai-pack.json +732 -0
- package/policy-pack/failproofai-pack.mjs +2017 -0
- package/scripts/build-policy-pack.mjs +121 -0
- package/scripts/changelog-section.py +77 -0
- package/scripts/prune-standalone.mjs +3 -0
- package/scripts/python-version.py +232 -0
- package/scripts/translate-docs/cli.ts +21 -0
- package/scripts/translate-docs/mintlify-nav.ts +85 -13
- package/scripts/translate-docs/translator.ts +66 -11
- package/src/audit/cache.ts +40 -3
- package/src/audit/cli.ts +1 -1
- package/src/audit/index.ts +1 -1
- package/src/audit/replay.ts +89 -3
- package/src/audit/report.ts +5 -5
- package/src/audit/schedule-cli.ts +49 -53
- package/src/hooks/builtin-policies.ts +217 -579
- package/src/hooks/cloud-enrollment-cli.ts +66 -27
- package/src/hooks/cloud-managed-policies.ts +6 -1
- package/src/hooks/configure-wizard.ts +1 -1
- package/src/hooks/custom-hooks-loader.ts +89 -6
- package/src/hooks/fp-home.ts +92 -4
- package/src/hooks/fp-reset.ts +26 -2
- package/src/hooks/handler.ts +181 -11
- package/src/hooks/harness-cli.ts +79 -25
- package/src/hooks/hook-activity-store.ts +13 -3
- package/src/hooks/install-prompt.ts +25 -3
- package/src/hooks/manager.ts +418 -172
- package/src/hooks/migrations.ts +2 -2
- package/src/hooks/pack-cli.ts +505 -0
- package/src/hooks/pack-failclosed.ts +189 -0
- package/src/hooks/pack-manifest.ts +344 -0
- package/src/hooks/pack-store.ts +930 -0
- package/src/hooks/policy-catalog.ts +535 -0
- package/src/hooks/policy-evaluator.ts +24 -16
- package/src/hooks/policy-presets.ts +4 -2
- package/src/hooks/policy-registry.ts +8 -2
- package/src/hooks/policy-types.ts +26 -0
- package/src/hooks/session-pause-cli.ts +33 -9
- package/src/hooks/tui.ts +570 -0
- package/src/hooks/types.ts +15 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_usx0j._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_zk340._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0agdw2a._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d1u_na._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0oy4kxb._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zf034w._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tvn4wf._.js +0 -3
- package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +0 -3
- package/.next/standalone/.next/server/chunks/_1ger0a2._.js +0 -3
- package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +0 -3
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_1iiwm5e._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kc8_v5._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kgy9da._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0mhqk5a._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0pltpn8._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qkcyf-._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w0x_ok._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1_dfocn._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1bfex62._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1kzapg5._.js +0 -6
- package/.next/standalone/.next/static/chunks/36fw6yk1s6x_f.js +0 -1
- package/.next/standalone/.next/static/chunks/3tzq0260n17ae.js +0 -6
- package/.next/standalone/.next/static/chunks/3wq9x0c-7ld5d.css +0 -2
- /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → nwbyWT06Ud0XdXOrVJyvS}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → nwbyWT06Ud0XdXOrVJyvS}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → nwbyWT06Ud0XdXOrVJyvS}/_ssgManifest.js +0 -0
|
File without changes
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "failproofai-sdk"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
requires-python = ">=3.10"
|
|
9
|
+
description = "Emit agent telemetry to FailproofAI Cloud — zero-dependency, stdlib only"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
license = { file = "LICENSE" }
|
|
12
|
+
authors = [{ name = "Failproof AI", email = "failproofai@exosphere.host" }]
|
|
13
|
+
keywords = ["agents", "observability", "ai", "monitoring", "failproofai", "telemetry", "sdk"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Programming Language :: Python :: 3.14",
|
|
23
|
+
"Typing :: Typed",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
# There is deliberately NO `dependencies` key. This SDK imports nothing outside the
|
|
27
|
+
# standard library, and that is a load-bearing property rather than a happy accident:
|
|
28
|
+
# it is installed into other people's agent processes, where any dependency of ours is
|
|
29
|
+
# a version constraint on their application. `tests/test_zero_dependencies.py` fails if
|
|
30
|
+
# a runtime dependency is ever declared or imported, and the CI job installs the built
|
|
31
|
+
# wheel with `--no-deps` to prove the claim against the artifact.
|
|
32
|
+
|
|
33
|
+
# No [project.scripts] either — this is a library, not a command. The command is `fp`,
|
|
34
|
+
# which ships from ../../fp-cloud-cli.
|
|
35
|
+
|
|
36
|
+
[project.urls]
|
|
37
|
+
Homepage = "https://befailproof.ai"
|
|
38
|
+
# The live route. `/agenteye/python-sdk` is a 404 — see fp-cloud-cli's pyproject for
|
|
39
|
+
# the full reasoning; PyPI bakes this into published metadata.
|
|
40
|
+
Documentation = "https://docs.befailproof.ai/reference/custom-agents"
|
|
41
|
+
Source = "https://github.com/FailproofAI/failproofai"
|
|
42
|
+
# PyPI gives "Changelog" its own sidebar slot and icon. Without it the only
|
|
43
|
+
# thing a visitor to the project page can read is the README, and there is no
|
|
44
|
+
# route at all from an installed version to what changed in it.
|
|
45
|
+
Changelog = "https://github.com/FailproofAI/failproofai/blob/main/sdk/python/CHANGELOG.md"
|
|
46
|
+
|
|
47
|
+
[project.optional-dependencies]
|
|
48
|
+
# Test-only, and it stays that way — `dependencies` above is empty and
|
|
49
|
+
# `tests/test_zero_dependencies.py` fails if anything lands here without a reason.
|
|
50
|
+
# `tomli` is `tomllib`'s backport: 3.10 has no stdlib TOML parser, and that test
|
|
51
|
+
# reads this file to prove the promise, so on 3.10 it needs one rather than
|
|
52
|
+
# skipping the check on the oldest interpreter we advertise.
|
|
53
|
+
dev = ["pytest>=7", "tomli>=2; python_version<'3.11'", "pytest-asyncio>=1.3,<2"]
|
|
54
|
+
|
|
55
|
+
# Convenience aliases that pull the FRAMEWORK in. The adapter code always ships
|
|
56
|
+
# in the base wheel and lazy-imports, so these gate nothing on our side — most
|
|
57
|
+
# users already have the framework and will never install an extra.
|
|
58
|
+
#
|
|
59
|
+
# Each floor is a CAPABILITY floor with a stated reason, not a guess, and each
|
|
60
|
+
# ceiling is deliberate: without one, a clean build a year from now pulls the
|
|
61
|
+
# next major, the callback API shifts, and the adapter stops receiving events
|
|
62
|
+
# while raising nothing.
|
|
63
|
+
#
|
|
64
|
+
# NEVER write `failproofai-sdk[...]` inside an extra, and there is deliberately
|
|
65
|
+
# no `[all]`: an extra that installs four agent frameworks at once is a resolver
|
|
66
|
+
# problem handed to somebody who wanted a telemetry library.
|
|
67
|
+
langchain = ["langchain-core>=1.4.7,<2"] # langgraph 1.2's own floor
|
|
68
|
+
langgraph = ["langgraph>=1.2,<2"] # first release with GraphCallbackHandler
|
|
69
|
+
crewai = [
|
|
70
|
+
"crewai>=1.13,<2", # started_event_id + normalized usage
|
|
71
|
+
"onnxruntime>=1.14,<1.24; python_version < '3.11'", # 1.24+ dropped CPython 3.10 wheels
|
|
72
|
+
]
|
|
73
|
+
llamaindex = ["llama-index-core>=0.14.23,<0.15"]
|
|
74
|
+
pydantic-ai = ["pydantic-ai-slim>=2.0,<3"] # 2.0 removed Agent(instrument=...)
|
|
75
|
+
|
|
76
|
+
[tool.setuptools.dynamic]
|
|
77
|
+
version = { attr = "failproofai_sdk._version.__version__" }
|
|
78
|
+
|
|
79
|
+
[tool.setuptools.packages.find]
|
|
80
|
+
where = ["."]
|
|
81
|
+
include = ["failproofai_sdk*"]
|
|
82
|
+
|
|
83
|
+
[tool.setuptools.package-data]
|
|
84
|
+
failproofai_sdk = ["py.typed"]
|
|
85
|
+
|
|
86
|
+
[tool.pytest.ini_options]
|
|
87
|
+
testpaths = ["tests"]
|
|
88
|
+
# `framework` marks a suite that needs a real agent framework installed. Those
|
|
89
|
+
# skip on a plain `pytest` run and are exercised in an environment that has the
|
|
90
|
+
# frameworks — registering it here is what keeps an unknown-mark warning from
|
|
91
|
+
# training everyone to ignore warnings.
|
|
92
|
+
markers = ["framework: needs a real agent framework installed"]
|
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: failproofai-sdk
|
|
3
|
+
description: |-
|
|
4
|
+
The way to make an AI agent report what it did to Failproof AI — planning what to record, writing the instrumentation, and proving the events land. Reach for it on vague phrasing too: "add observability to my agent", "why isn't my agent showing up?"
|
|
5
|
+
|
|
6
|
+
Trigger when the user wants to:
|
|
7
|
+
• plan an integration — which points in their agent loop to record, and what the platform must see before sessions, errors, and evals work at all;
|
|
8
|
+
• write or fix instrumentation — add the `failproofai_sdk` Python SDK to an agent codebase, thread session/agent identity through it, emit tool, model, hook, or human events;
|
|
9
|
+
• verify it — confirm events are being written, or debug an integration that looks correct and produces nothing.
|
|
10
|
+
|
|
11
|
+
Served by the `failproofai_sdk` Python SDK, inside the user's own agent.
|
|
12
|
+
|
|
13
|
+
NOT for reading telemetry that already landed or operating a deployment (that's `fp-cloud-cli`), or building the evaluator service that scores runs (that's `agenteye-evaluator`).
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Failproof AI Python SDK
|
|
17
|
+
|
|
18
|
+
The SDK records what your agent did, from inside your agent. You call it at points
|
|
19
|
+
you choose; it appends structured events to local `.jsonl` files. A separate
|
|
20
|
+
collector ships those files to the platform.
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
your agent calls failproofai_sdk.event.*
|
|
24
|
+
→ SDK queues it in memory
|
|
25
|
+
→ flush thread writes <base_dir>/events/event-<timestamp>.jsonl
|
|
26
|
+
→ collector picks the file up and ships it
|
|
27
|
+
→ visible as sessions / events / errors / evals
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**The SDK's job ends at the file.** That boundary is the most useful thing to know
|
|
31
|
+
about it: everything up to the `.jsonl` is yours to get right and yours to verify,
|
|
32
|
+
and it is verifiable on a laptop with no server, no API key, and no network.
|
|
33
|
+
|
|
34
|
+
The API is small — 15 event methods, all keyword-only. The hard parts are
|
|
35
|
+
**deciding where to call them** and **knowing which silences are bugs**, because
|
|
36
|
+
this SDK does not raise when you get it wrong. Sections 1-3 are the plan, 4 is the
|
|
37
|
+
code, 5-6 are the proof.
|
|
38
|
+
|
|
39
|
+
## 1. Install it
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install failproofai-sdk # or: uv add failproofai-sdk
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The distribution is `failproofai-sdk` and the import is `failproofai_sdk`. Public
|
|
46
|
+
PyPI, no token, no dependencies.
|
|
47
|
+
|
|
48
|
+
**One command to never run: `pip install agenteye`.** That name belongs to a
|
|
49
|
+
stranded release of an old CLI — a different product that shipped under it before
|
|
50
|
+
moving to `fp-cloud-cli`. PyPI versions cannot be withdrawn, so the name still resolves
|
|
51
|
+
to that build forever. You get the CLI, `import failproofai_sdk` raises
|
|
52
|
+
`ModuleNotFoundError`, and on a codebase still using the pre-rename SDK (which
|
|
53
|
+
published under `agenteye` too) pip treats it as an upgrade and **removes the SDK**.
|
|
54
|
+
|
|
55
|
+
> **Tell:** if a coding agent proposes `pip install agenteye` to install the SDK,
|
|
56
|
+
> this skill never loaded. Stop and re-read it.
|
|
57
|
+
|
|
58
|
+
The CLI is a fine thing to want — it is what reads the telemetry back. Install it
|
|
59
|
+
separately, never with `pip` into your agent's environment:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pipx install fp-cloud-cli # the command is `fp`
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Confirm what you actually have before writing a line of instrumentation:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
python -c "import failproofai_sdk; print(failproofai_sdk.__version__)"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
A version like `0.0.1b1` is the SDK. `ModuleNotFoundError` means it is not
|
|
72
|
+
installed — check `pip show agenteye`, which returning anything means the wrong
|
|
73
|
+
name was installed. `references/install.md` covers migrating an existing
|
|
74
|
+
`import agenteye` integration.
|
|
75
|
+
|
|
76
|
+
## 2. Plan before you instrument
|
|
77
|
+
|
|
78
|
+
Instrumentation lands in code that already exists and already works. Read it
|
|
79
|
+
first, then decide. Two questions settle most of the design, and only the user can
|
|
80
|
+
answer the first:
|
|
81
|
+
|
|
82
|
+
> **What is one run of this agent?** That is your `session_id` — one value for the
|
|
83
|
+
> whole run, generated by you at the point the run starts. A chat turn, a job, a
|
|
84
|
+
> request, a workflow execution. If the agent handles concurrent runs, this must
|
|
85
|
+
> be per-run, not per-process.
|
|
86
|
+
>
|
|
87
|
+
> **What are the distinguishable actors in a run?** That is your `agent_id` — a
|
|
88
|
+
> stable *label*, not a unique id. `"planner"`, `"researcher"`, `"main"`. It is how
|
|
89
|
+
> the platform tells sub-agents apart, so reuse the same string across runs.
|
|
90
|
+
|
|
91
|
+
Get these two named and agreed before writing code. They are the axes every
|
|
92
|
+
surface groups by, and changing them later splits the history: old runs keep the
|
|
93
|
+
old labels and the trends break.
|
|
94
|
+
|
|
95
|
+
### The two events everything else hangs off
|
|
96
|
+
|
|
97
|
+
Most of the catalog is optional and incremental. These two are not:
|
|
98
|
+
|
|
99
|
+
| Event | Without it |
|
|
100
|
+
|---|---|
|
|
101
|
+
| `agent_start` | **The session does not exist.** No row on Sessions, no timeline, no evaluation — while every other event you emit still lands fine and shows up in the event stream. |
|
|
102
|
+
| `agent_end` | The run never closes, and it is not handed to the evaluator at the normal time. |
|
|
103
|
+
|
|
104
|
+
That first row is the single most common integration failure, and it is
|
|
105
|
+
completely silent: a run emitting 500 tool calls and no `agent_start` produces a
|
|
106
|
+
busy event stream and **zero sessions**. Sessions are *defined* as "something that
|
|
107
|
+
emitted `agent_start`". So:
|
|
108
|
+
|
|
109
|
+
**Emit `agent_start` at the top of the run and `agent_end` at every exit, and get
|
|
110
|
+
those two working end-to-end before you instrument anything else.** One event at
|
|
111
|
+
each end proves the whole path — install, identity, base dir, collector — with
|
|
112
|
+
almost no code to be wrong. Add tools, models, and hooks after that path is green.
|
|
113
|
+
|
|
114
|
+
### Then map the rest onto the agent's shape
|
|
115
|
+
|
|
116
|
+
Walk the agent loop and pick the points that exist in *this* codebase. Skip what
|
|
117
|
+
doesn't apply; there is no requirement to emit every type.
|
|
118
|
+
|
|
119
|
+
| In the code | Emit | Buys you |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| every exit path of a run — success, exception, early return | `agent_start` / `agent_end` | the session itself |
|
|
122
|
+
| the tool dispatcher, both sides of the call | `tool_use` / `tool_result` | what ran, in what order, how long |
|
|
123
|
+
| the LLM client wrapper, both sides | `model_request` / `model_response` | model mix, token spend, stop reasons |
|
|
124
|
+
| your `except` blocks | `error` | the Errors surface |
|
|
125
|
+
| a policy/guard/middleware layer | `hook_triggered` / `hook_completed` | hook behaviour |
|
|
126
|
+
| an approval gate or human handoff | `human_wait` / `human_input`, `human_pause`, `human_interrupt` | where runs sit waiting on people |
|
|
127
|
+
| a run that suspends and resumes — waiting for a human, throttled, user-paused | `agent_pause` / `agent_resume` | a real "paused" state: the agent isn't ended, the resume isn't a new agent, and wait time is excluded from active work |
|
|
128
|
+
|
|
129
|
+
If the codebase has one tool dispatcher and one LLM wrapper, you have two edit
|
|
130
|
+
sites for the bulk of the value. If tool calls are scattered inline across the
|
|
131
|
+
codebase, say so — a wrapper (§4) is worth more than 40 call sites.
|
|
132
|
+
|
|
133
|
+
Full field-by-field catalog: `references/events.md`.
|
|
134
|
+
|
|
135
|
+
## 3. The contract
|
|
136
|
+
|
|
137
|
+
Work with these; none of them raise, so none of them show up in testing.
|
|
138
|
+
|
|
139
|
+
- **There IS an ambient session, and it is the ergonomic path.** `session()`,
|
|
140
|
+
`agent()` and `tool_call()` bind identity on contextvars, so `session_id` and
|
|
141
|
+
`agent_id` are optional on all 15 event methods — omitted, they resolve from
|
|
142
|
+
the enclosing scope. `current()` reads it; `propagate(fn)` carries it into a
|
|
143
|
+
new thread, which contextvars do NOT do on their own.
|
|
144
|
+
|
|
145
|
+
This section said the opposite until the scopes existed, and the reference
|
|
146
|
+
integration shipped a contextvars wrapper as markdown for customers to paste
|
|
147
|
+
into their own code. That is now in the package.
|
|
148
|
+
|
|
149
|
+
Nothing bound and nothing passed raises `TypeError` naming the fix — never a
|
|
150
|
+
silent emit, because ingest skips an event with no session and answers `200`.
|
|
151
|
+
|
|
152
|
+
Two more shapes raise, for the same reason:
|
|
153
|
+
|
|
154
|
+
| You pass | Raises | Why it cannot be allowed through |
|
|
155
|
+
| --- | --- | --- |
|
|
156
|
+
| A non-`str` id | `TypeError` | Ingest skips the event and still answers `200` |
|
|
157
|
+
| `""` or `" "` | `ValueError` | Worse — ingest *accepts* it, and every event merges under one blank id |
|
|
158
|
+
|
|
159
|
+
- **`configure()` is optional, and every call restates all of it.** It is
|
|
160
|
+
keyword-only with exactly three settings:
|
|
161
|
+
|
|
162
|
+
| arg | default resolution |
|
|
163
|
+
|---|---|
|
|
164
|
+
| `base_dir` | `~/.failproofai/custom-agents` (honours `$FAILPROOFAI_HOME`) |
|
|
165
|
+
| `environment` | `$AGENTEYE_ENVIRONMENT`, else `"dev"` |
|
|
166
|
+
| `flush_interval` | `0.5` (seconds) |
|
|
167
|
+
|
|
168
|
+
**No environment variable can move the spool out of the umbrella.**
|
|
169
|
+
`$FAILPROOFAI_HOME` relocates the umbrella itself, but `custom-agents` is
|
|
170
|
+
appended unconditionally, so the spool is always inside it. `base_dir` is the
|
|
171
|
+
only way to write anywhere else, and it is an explicit argument at the call
|
|
172
|
+
site rather than something inherited from the environment.
|
|
173
|
+
|
|
174
|
+
The default root moved here from `~/.agenteye`. `failproofaid` watches both,
|
|
175
|
+
so on a host running it nothing changes but the directory name, and batches
|
|
176
|
+
already in `~/.agenteye/events` still get collected. On a host running the
|
|
177
|
+
older `agenteye-collector` — which resolves `$AGENTEYE_HOME` or `~/.agenteye`
|
|
178
|
+
and nothing else — point **the collector** at this SDK with
|
|
179
|
+
`AGENTEYE_HOME=~/.failproofai/custom-agents`, or pass `base_dir` here.
|
|
180
|
+
Setting `AGENTEYE_HOME` no longer moves the SDK: it used to, which meant
|
|
181
|
+
exporting it for the collector silently relocated the SDK too.
|
|
182
|
+
`AGENTEYE_SPOOL_TO_FAILPROOFAI` is retired; it required a directory nothing
|
|
183
|
+
created, so it never fired.
|
|
184
|
+
|
|
185
|
+
Each call *sets all three* — omitted arguments are **reset to default
|
|
186
|
+
resolution**, not left alone. So a later `configure(flush_interval=1.0)`
|
|
187
|
+
silently moves your events back to the default directory and re-resolves the
|
|
188
|
+
environment. An explicit `configure(environment=...)` beats the env var; omit it
|
|
189
|
+
and the env var applies again. Call it **once**, at startup, before the first
|
|
190
|
+
event, passing every argument you care about.
|
|
191
|
+
|
|
192
|
+
- **`environment` defaults to `"dev"`.** An unconfigured production agent reports
|
|
193
|
+
its runs as `dev` and they are invisible wherever the team filters on
|
|
194
|
+
`production`. Set it explicitly via `configure(environment=...)` or the
|
|
195
|
+
`AGENTEYE_ENVIRONMENT` env var. This is a favourite: everything works, in the
|
|
196
|
+
wrong bucket.
|
|
197
|
+
|
|
198
|
+
**A comma raises `ValueError`.** `configure(environment="prod,eu")` is rejected
|
|
199
|
+
at the call site: ingest splits this field on commas to build filter facets, so
|
|
200
|
+
a comma would discard the whole event server-side with nothing said.
|
|
201
|
+
|
|
202
|
+
- **Non-JSON payload leaves are stringified.** Events are serialized on a
|
|
203
|
+
background thread. Ordinary structured JSON retains its types; unsupported
|
|
204
|
+
leaves such as `datetime`, `UUID`, `Decimal`, `set`, `bytes`, or a Pydantic
|
|
205
|
+
model are converted with `str(value)` so one awkward tool result cannot stop
|
|
206
|
+
recording. Prefer plain JSON values when downstream queries need their
|
|
207
|
+
structure; use explicit custom serialization when a string would be ambiguous.
|
|
208
|
+
|
|
209
|
+
- **Field *names* are unvalidated — but only the optional ones.** Every method
|
|
210
|
+
takes arbitrary `**fields` and stores them as-is, so a typo'd *optional* name
|
|
211
|
+
(`inpt=` for `input=`) is not an error, it is a new field, and nothing will tell
|
|
212
|
+
you. Typos in *required* names raise `TypeError` (they're real parameters), and
|
|
213
|
+
five reserved names — `timestamp`, `session_id`, `agent_id`, `type`,
|
|
214
|
+
`environment` — raise `ValueError`.
|
|
215
|
+
|
|
216
|
+
- **`outcome="failed"`, not `"failure"`.** A run counts as failed only when
|
|
217
|
+
`outcome` (or `status`) is one of `error`, `failed`, `timeout`, `rejected`
|
|
218
|
+
(case-insensitive). `"failure"` is the natural antonym of the `"success"` in
|
|
219
|
+
every example — and it silently counts as *not a failure*. The run shows green.
|
|
220
|
+
|
|
221
|
+
- **You own correlation, and ids are scoped per session AND per kind.**
|
|
222
|
+
Pending spans are keyed `tool:<session_id>:<tool_call_id>` and
|
|
223
|
+
`hook:<session_id>:<hook_id>`, so a `hook_completed(hook_id="x")` cannot pair
|
|
224
|
+
with a pending `tool_use(tool_call_id="x")`, and two concurrent sessions both
|
|
225
|
+
using `call_1` cannot cross-pair either. `input_id` and `pause_id` are scoped
|
|
226
|
+
the same way.
|
|
227
|
+
|
|
228
|
+
What must still be unique is an id **within one session, for one kind**. The
|
|
229
|
+
pending map is a plain assignment, so emitting `tool_use(tool_call_id="call_1")`
|
|
230
|
+
twice in one session overwrites the first entry and the first `tool_result`
|
|
231
|
+
measures from the wrong start. Reusing your framework's id is always safe
|
|
232
|
+
(Anthropic and OpenAI ids are globally unique); a per-run counter is safe only
|
|
233
|
+
if you do not reset it inside a session.
|
|
234
|
+
|
|
235
|
+
If you have read older guidance describing one flat, process-wide map shared
|
|
236
|
+
between tools and hooks: that was true, and is not any more.
|
|
237
|
+
|
|
238
|
+
- **`duration_ms` is computed for you on four methods only** — `tool_result`,
|
|
239
|
+
`hook_completed`, `human_input`, `agent_resume` — from the matching earlier event.
|
|
240
|
+
Passing it to those four raises `ValueError`. Passing it to any of the other
|
|
241
|
+
eleven is **silently accepted as a custom field**.
|
|
242
|
+
|
|
243
|
+
- **Events are fire-and-forget.** `event.*` queues in memory and returns; a daemon
|
|
244
|
+
thread writes every 0.5s, plus once at interpreter exit. A clean exit flushes.
|
|
245
|
+
A hard kill (`SIGKILL`, `os._exit`, a container OOM) drops whatever is queued,
|
|
246
|
+
silently.
|
|
247
|
+
|
|
248
|
+
**`SIGTERM` deserves its own line, because it is not exotic — it is every
|
|
249
|
+
rolling deploy**, every `docker stop`, every Kubernetes eviction, and every
|
|
250
|
+
plain `kill`. CPython installs **no** handler for it: `signal.getsignal(SIGTERM)`
|
|
251
|
+
is `SIG_DFL`, the OS terminates the process where it stands, and **`atexit`
|
|
252
|
+
does not run**. Whatever is queued is gone — and what is in flight at shutdown
|
|
253
|
+
is disproportionately `agent_end`, so runs never close and never reach the
|
|
254
|
+
evaluator. The 0.5s flush interval is what bounds the loss, not the exit path.
|
|
255
|
+
|
|
256
|
+
So if your process can receive `SIGTERM`, handle it — the SDK will not install
|
|
257
|
+
a handler in your process behind your back:
|
|
258
|
+
|
|
259
|
+
import signal, sys, failproofai_sdk
|
|
260
|
+
|
|
261
|
+
def _flush_and_exit(signum, frame):
|
|
262
|
+
failproofai_sdk._writer.flush_now()
|
|
263
|
+
sys.exit(128 + signum)
|
|
264
|
+
|
|
265
|
+
signal.signal(signal.SIGTERM, _flush_and_exit)
|
|
266
|
+
|
|
267
|
+
(`sys.exit` here rather than `os._exit`: it unwinds, so any `agent()` scope
|
|
268
|
+
still open emits its `agent_end` before the flush. That scope closes
|
|
269
|
+
`outcome="failed"` with an `error` naming `SystemExit`, because an evicted run
|
|
270
|
+
did not finish — which is the thing you want to be able to see.) `SIGKILL`,
|
|
271
|
+
`os._exit` and a container OOM cannot be handled by anything, and drop the
|
|
272
|
+
queue silently.
|
|
273
|
+
|
|
274
|
+
## 4. Write it
|
|
275
|
+
|
|
276
|
+
Threading `session_id` and `agent_id` through every call site by hand is the thing
|
|
277
|
+
that makes integrations ugly and abandoned. Don't. Bind identity once per run and
|
|
278
|
+
let the call sites read it.
|
|
279
|
+
|
|
280
|
+
`references/frameworks.md` covers the four adapters. `references/integration.md` has the hand-written wrapper — one small
|
|
281
|
+
module, correct under `asyncio` and threads, adaptable to any codebase — plus
|
|
282
|
+
worked shapes for a tool dispatcher, an LLM client wrapper, and framework-specific
|
|
283
|
+
callback layers. Read it before writing your own; the naive version (a module
|
|
284
|
+
global, or a plain attribute) breaks the moment two runs overlap, and it breaks by
|
|
285
|
+
mixing two runs' events together rather than by failing.
|
|
286
|
+
|
|
287
|
+
Match the codebase you're in. If it's async, the wrapper is async. If it already
|
|
288
|
+
has a request context or a trace id, bind to that instead of inventing one.
|
|
289
|
+
|
|
290
|
+
## 5. Verify — watch the files
|
|
291
|
+
|
|
292
|
+
**This is the whole point of the file boundary: you can prove the integration
|
|
293
|
+
without a server.** Run the agent and look.
|
|
294
|
+
|
|
295
|
+
Resolve the spool the way the SDK does, rather than guessing at a path:
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
python -c "import failproofai_sdk._resolver as r; print(r.get_base_dir() / 'events')"
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
That prints `~/.failproofai/custom-agents/events` unless the application called
|
|
302
|
+
`configure(base_dir=...)`. `$FAILPROOFAI_HOME` moves the `~/.failproofai` part
|
|
303
|
+
and nothing else. `$AGENTEYE_HOME` does **not** affect it — that variable belongs
|
|
304
|
+
to the older `agenteye-collector`, which reads it to decide what to WATCH.
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
ls -la ~/.failproofai/custom-agents/events/
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
You are looking for `event-<UTC timestamp>-<pid>-<seq>.jsonl` files — the pid and
|
|
311
|
+
sequence number are what keep two processes flushing in the same millisecond from
|
|
312
|
+
overwriting each other. Each line is one event. Read them with a JSON parser, not
|
|
313
|
+
`grep` — the exact spacing is not a contract, and a grep for `"type":"agent_start"`
|
|
314
|
+
returns nothing on a perfectly healthy integration:
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
cat ~/.failproofai/custom-agents/events/*.jsonl | python -m json.tool --json-lines | head -20
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Then check, in this order — the first failure explains everything downstream:
|
|
321
|
+
|
|
322
|
+
1. **Any files at all — or do they stop mid-run?** Look at stderr for
|
|
323
|
+
`Exception in thread failproofai-sdk-flush`. **This is the first thing to check and
|
|
324
|
+
the worst thing to miss**: one non-JSON-serializable value killed the writer,
|
|
325
|
+
and everything after it — including the at-exit flush — is gone (§3). The tell
|
|
326
|
+
is that events stop for *every* type at once, and nothing raised. If instead
|
|
327
|
+
there were never any files: did `import failproofai_sdk` succeed (§1)? Is the base dir
|
|
328
|
+
writable? Did the process die hard (`SIGKILL`, `docker stop`, an OOM) before a
|
|
329
|
+
flush?
|
|
330
|
+
2. **Is `agent_start` there, once per run?** No → you will see events on the
|
|
331
|
+
platform and no sessions, and you will spend an afternoon on it (§2).
|
|
332
|
+
3. **Sessions but no tool or model events?** Your emit path is dropping them
|
|
333
|
+
before the SDK ever sees them — nearly always because they're emitted from a
|
|
334
|
+
thread the identity never reached. See `references/integration.md` → *"Threads
|
|
335
|
+
will drop your events"*. The SDK is silent here; only your own wrapper can warn.
|
|
336
|
+
4. **Is `environment` what you expect?** It is `"dev"` unless you set it (§3).
|
|
337
|
+
5. **Is `outcome` on `agent_end` a word that counts?** `failed`/`error`/`timeout`/
|
|
338
|
+
`rejected` — not `"failure"` (§3). Failed runs showing green is this, every
|
|
339
|
+
time.
|
|
340
|
+
6. **Run two overlapping runs.** Confirm two `session_id`s with **no events
|
|
341
|
+
crossing between them**. Do not check this with one run: a single run passes
|
|
342
|
+
even when identity is a module global, and mixing only appears once two runs
|
|
343
|
+
overlap — which is production, not your laptop (§4).
|
|
344
|
+
7. **Do `tool_use` and `tool_result` share a `tool_call_id`?** Unpaired means no
|
|
345
|
+
duration. Also confirm your ids are unique *process-wide* — a collision pairs
|
|
346
|
+
the wrong two events and reports a confident wrong duration (§3).
|
|
347
|
+
|
|
348
|
+
A test-mode loop that costs nothing:
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
export FAILPROOFAI_HOME=/tmp/failproofai-sdk-test
|
|
352
|
+
rm -rf /tmp/failproofai-sdk-test && python your_agent.py
|
|
353
|
+
cat /tmp/failproofai-sdk-test/custom-agents/events/*.jsonl | python -m json.tool --json-lines
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
`FAILPROOFAI_HOME` sends events somewhere disposable, so you can iterate on the
|
|
357
|
+
integration without touching the real directory or shipping test runs to the
|
|
358
|
+
platform. Note the `custom-agents` segment in the read path — the SDK appends it
|
|
359
|
+
unconditionally. Note too that the SDK reads the variable late, per flush, so set
|
|
360
|
+
it before you start the process, not halfway through.
|
|
361
|
+
|
|
362
|
+
`AGENTEYE_HOME` used to do this job and no longer does anything to the SDK; using
|
|
363
|
+
it here would write to your REAL spool while you read an empty temp directory.
|
|
364
|
+
|
|
365
|
+
**Do not verify by installing the CLI into your agent's environment.** It will
|
|
366
|
+
uninstall the SDK you just integrated (§1). Reading back what landed on the
|
|
367
|
+
platform is the `fp-cloud-cli` skill's job, from a separate environment.
|
|
368
|
+
|
|
369
|
+
## 6. Production — the collector has to agree with you
|
|
370
|
+
|
|
371
|
+
The SDK writes files. It never talks to the network, so from its point of view a
|
|
372
|
+
completely unshipped integration looks perfect.
|
|
373
|
+
|
|
374
|
+
In production, the collector must be **running** and reading the **same directory
|
|
375
|
+
the SDK is writing to**. That is the whole contract, and both halves fail
|
|
376
|
+
silently:
|
|
377
|
+
|
|
378
|
+
- Collector not running → files pile up in `events/` forever. The SDK is fine.
|
|
379
|
+
- Collector reading a different base dir than the agent writes to — the
|
|
380
|
+
collector's own `AGENTEYE_HOME` pointing somewhere else, a different user's
|
|
381
|
+
`~`, a container path that isn't mounted → files pile up in a directory nobody
|
|
382
|
+
reads. The SDK is fine. (`failproofaid` watches both
|
|
383
|
+
`~/.failproofai/custom-agents/events` and `~/.agenteye/events`, so it is the
|
|
384
|
+
half of this pair least likely to be misconfigured.)
|
|
385
|
+
|
|
386
|
+
So when events are on disk but not on the platform, the SDK is not the suspect.
|
|
387
|
+
Compare the two paths first: print the directory your agent is actually writing to
|
|
388
|
+
(`python -c "import failproofai_sdk._resolver as r; print(r.get_base_dir())"` in the
|
|
389
|
+
agent's own environment, with the agent's own env vars) and check the collector is
|
|
390
|
+
running and pointed at the same one. A `.jsonl` count that only grows is the tell.
|
|
391
|
+
|
|
392
|
+
Confirming events arrived on the *platform* is deliberately not this skill's job —
|
|
393
|
+
that is the `fp-cloud-cli` skill, from a **separate environment** (§1). Collector
|
|
394
|
+
setup and deployment are your platform's own documentation.
|
|
395
|
+
|
|
396
|
+
If the files look right (§5) and the collector is running against the same
|
|
397
|
+
directory, the integration is done.
|
|
398
|
+
|
|
399
|
+
<!-- ci: no-op touch to exercise the skill-sync trigger (safe to remove) -->
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Codex skill configuration (optional). See https://developers.openai.com/codex/skills
|
|
2
|
+
#
|
|
3
|
+
# Codex reads SKILL.md's `name`/`description` the same way Claude Code does.
|
|
4
|
+
# This file only tunes Codex-specific behavior.
|
|
5
|
+
|
|
6
|
+
# Let Codex auto-select this skill when a task matches the description
|
|
7
|
+
# (set to false to require explicit `$failproofai-sdk` invocation).
|
|
8
|
+
allow_implicit_invocation: true
|