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
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
# Pydantic AI
|
|
2
|
+
|
|
3
|
+
- [Install](#install)
|
|
4
|
+
- [The integration](#the-integration)
|
|
5
|
+
- [Read this first: construction order](#read-this-first-construction-order)
|
|
6
|
+
- [How it attaches](#how-it-attaches)
|
|
7
|
+
- [What gets recorded](#what-gets-recorded)
|
|
8
|
+
- [A complete example](#a-complete-example)
|
|
9
|
+
- [Options](#options)
|
|
10
|
+
- [Errors, retries and control flow](#errors-retries-and-control-flow)
|
|
11
|
+
- [Pitfalls](#pitfalls)
|
|
12
|
+
- [Runnable examples](#runnable-examples)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install 'failproofai-sdk[pydantic-ai]' # pins pydantic-ai-slim >=2.0,<3
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Supported:** `pydantic-ai-slim` 2.0 → 3.0. 2.0 is a capability floor: it is the
|
|
23
|
+
release that removed `Agent(instrument=...)` and introduced `AbstractCapability`,
|
|
24
|
+
which is the entire surface this adapter is built on. There is no way to
|
|
25
|
+
instrument 1.x with this adapter.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## The integration
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
import failproofai_sdk
|
|
33
|
+
from pydantic_ai import Agent
|
|
34
|
+
|
|
35
|
+
failproofai_sdk.configure(environment="production")
|
|
36
|
+
failproofai_sdk.instrument() # <- BEFORE constructing any Agent
|
|
37
|
+
|
|
38
|
+
agent = Agent("openai:gpt-4o-mini", system_prompt="Be terse.")
|
|
39
|
+
|
|
40
|
+
with failproofai_sdk.session():
|
|
41
|
+
result = agent.run_sync("...")
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Read this first: construction order
|
|
47
|
+
|
|
48
|
+
**`instrument()` must run before you construct an `Agent`.**
|
|
49
|
+
|
|
50
|
+
The capability is appended at construction time. An `Agent` built before
|
|
51
|
+
`instrument()` ran carries no capability and records **nothing** — and there is
|
|
52
|
+
no error, because nothing went wrong. This is the single most common way to get
|
|
53
|
+
an empty trace with this adapter.
|
|
54
|
+
|
|
55
|
+
This bites hardest at module scope:
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
# agents.py
|
|
59
|
+
from pydantic_ai import Agent
|
|
60
|
+
agent = Agent("openai:gpt-4o-mini") # constructed at import time
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
# main.py
|
|
64
|
+
import agents # <- agent built HERE, uninstrumented
|
|
65
|
+
import failproofai_sdk
|
|
66
|
+
failproofai_sdk.instrument() # too late for agents.agent
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Fix it by instrumenting first:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
# main.py
|
|
73
|
+
import failproofai_sdk
|
|
74
|
+
failproofai_sdk.instrument()
|
|
75
|
+
|
|
76
|
+
import agents # now the agent gets the capability
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Or construct agents inside a function rather than at import time.
|
|
80
|
+
|
|
81
|
+
Agents built **while** instrumented keep the capability object, so
|
|
82
|
+
`uninstrument()` flips a flag the capability reads rather than trying to reach
|
|
83
|
+
back into agents it no longer owns. That means you can safely uninstrument and
|
|
84
|
+
re-instrument without rebuilding your agents.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## How it attaches
|
|
89
|
+
|
|
90
|
+
`instrument()` wraps `Agent.__init__` so that every agent constructed afterwards
|
|
91
|
+
gets a `FailproofAI` capability appended to its capability list.
|
|
92
|
+
|
|
93
|
+
The capability implements the middleware protocol Pydantic AI 2.0 introduced, so
|
|
94
|
+
it sees:
|
|
95
|
+
|
|
96
|
+
- run start and end,
|
|
97
|
+
- each model request and response, with usage,
|
|
98
|
+
- each tool call and its result.
|
|
99
|
+
|
|
100
|
+
It composes with your own capabilities — it is appended, not substituted, and it
|
|
101
|
+
declares an ordering so it wraps the outside of the stack rather than
|
|
102
|
+
interfering with middleware you added.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## What gets recorded
|
|
107
|
+
|
|
108
|
+
| Pydantic AI | Failproof event | When |
|
|
109
|
+
|---|---|---|
|
|
110
|
+
| agent run | `agent_start` / `agent_end` | `run` / `run_sync` / `run_stream` |
|
|
111
|
+
| model request | `model_request` / `model_response` | each model call, with `usage` |
|
|
112
|
+
| tool call | `tool_use` / `tool_result` | each tool call, with the args the model sent |
|
|
113
|
+
| `ModelRetry` from a tool | `tool_result` with `error` | the tool asked for a retry |
|
|
114
|
+
| unhandled exception | `error` + `agent_end(outcome="failed")` | the run raises |
|
|
115
|
+
|
|
116
|
+
There is **no** `hook_triggered` / `hook_completed` pair here, and no
|
|
117
|
+
human-in-the-loop pair. That is not a gap — Pydantic AI has no node or step
|
|
118
|
+
boundary to bracket, and no built-in human pause. If you build either, emit the
|
|
119
|
+
events yourself; see [`../manual/`](../manual/).
|
|
120
|
+
|
|
121
|
+
`output_type` makes no difference to the trace. A typed run and a string run
|
|
122
|
+
produce the same events.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## A complete example
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
import failproofai_sdk
|
|
130
|
+
from pydantic import BaseModel
|
|
131
|
+
from pydantic_ai import Agent, ModelRetry
|
|
132
|
+
|
|
133
|
+
failproofai_sdk.configure(environment="production")
|
|
134
|
+
failproofai_sdk.instrument()
|
|
135
|
+
|
|
136
|
+
PRICE = {"widget": 42.0, "gadget": 17.5}
|
|
137
|
+
STOCK = {"widget": 120, "gadget": 0}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class Report(BaseModel):
|
|
141
|
+
"""What the run must produce. Validated by pydantic_ai, not by us."""
|
|
142
|
+
|
|
143
|
+
headline: str
|
|
144
|
+
out_of_stock: list[str]
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
agent = Agent(
|
|
148
|
+
"openai:gpt-4o-mini",
|
|
149
|
+
output_type=Report,
|
|
150
|
+
system_prompt="Use the tools for every number. If a tool fails, note it and continue.",
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@agent.tool_plain
|
|
155
|
+
def price_of(item: str) -> float:
|
|
156
|
+
"""Unit price of an item. Valid: widget, gadget."""
|
|
157
|
+
return PRICE[item.lower().strip()]
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
@agent.tool_plain
|
|
161
|
+
def stock_of(item: str) -> int:
|
|
162
|
+
"""Units in stock. Valid: widget, gadget."""
|
|
163
|
+
return STOCK[item.lower().strip()]
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@agent.tool_plain
|
|
167
|
+
def restock_eta(item: str) -> str:
|
|
168
|
+
"""Restock ETA. Not available for anything."""
|
|
169
|
+
# ModelRetry hands the failure back to the model instead of raising out of
|
|
170
|
+
# run_sync. Recorded as an errored tool_result either way.
|
|
171
|
+
raise ModelRetry(f"no restock schedule for {item!r} — answer without it")
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
with failproofai_sdk.session():
|
|
175
|
+
with failproofai_sdk.agent("inventory", goal="stock report"):
|
|
176
|
+
result = agent.run_sync(
|
|
177
|
+
"For 'widget' and 'gadget', get price and stock. "
|
|
178
|
+
"For anything out of stock, try the restock ETA. Then produce the report."
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
print(result.output.headline)
|
|
182
|
+
print(result.output.out_of_stock)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Produces **20 events across 6 types**:
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
1 +0.000s agent_start inventory
|
|
189
|
+
2 +0.005s agent_start agent · under inventory
|
|
190
|
+
3 +0.006s model_request gpt-5.6-terra
|
|
191
|
+
4 +4.036s model_response gpt-5.6-terra · 90 out-tok
|
|
192
|
+
5 +4.039s tool_use price_of
|
|
193
|
+
...
|
|
194
|
+
15 +7.028s tool_use restock_eta
|
|
195
|
+
16 +7.029s tool_result restock_eta · error
|
|
196
|
+
17 +7.032s model_request gpt-5.6-terra
|
|
197
|
+
18 +10.411s model_response gpt-5.6-terra · 101 out-tok
|
|
198
|
+
19 +10.416s agent_end agent · success
|
|
199
|
+
20 +10.417s agent_end inventory · success
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Note events 16–18: the tool failed, the model was told, it made another call and
|
|
203
|
+
recovered. The run ends `success` and the failure is still on the record.
|
|
204
|
+
|
|
205
|
+
The nested `agent` span at depth 2 is Pydantic AI's own run, sitting inside the
|
|
206
|
+
`inventory` scope you opened. That is where the model and tool events hang.
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Options
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
failproofai_sdk.instrument(
|
|
214
|
+
"pydantic_ai",
|
|
215
|
+
session_id=None, # pin every run to one session id
|
|
216
|
+
capture_content=True, # False drops prompts and completions from payloads
|
|
217
|
+
)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Errors, retries and control flow
|
|
223
|
+
|
|
224
|
+
Pydantic AI raises exceptions for three genuinely different things, and the
|
|
225
|
+
adapter distinguishes them:
|
|
226
|
+
|
|
227
|
+
| exception | treated as | result |
|
|
228
|
+
|---|---|---|
|
|
229
|
+
| `ModelRetry`, `ToolRetryError`, `ToolFailedError` | **a real tool failure** | `tool_result` with `error`; run can still end `success` |
|
|
230
|
+
| `SkipToolExecution`, `SkipToolValidation`, `SkipModelRequest`, `CallDeferred`, `ApprovalRequired` | **control flow** | not an error; the run is being steered |
|
|
231
|
+
| anything else | **a failure** | `error` + `agent_end(outcome="failed")` |
|
|
232
|
+
|
|
233
|
+
`ModelRetry` is deliberately in the first group, not the second. It means an
|
|
234
|
+
attempt genuinely failed and the model was asked to try again — which is exactly
|
|
235
|
+
what a tool span's `error` field is for. Classifying it as control flow would
|
|
236
|
+
hide real tool failures behind a green run.
|
|
237
|
+
|
|
238
|
+
The control-flow list is resolved by name at import time and tolerates every one
|
|
239
|
+
of them being absent: a minor release renaming one degrades to "treat it as an
|
|
240
|
+
error" rather than raising an `AttributeError` inside your run.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Pitfalls
|
|
245
|
+
|
|
246
|
+
### An empty trace, no errors anywhere
|
|
247
|
+
|
|
248
|
+
**Symptom:** the run works, no warnings, and no events.
|
|
249
|
+
|
|
250
|
+
**Cause:** the `Agent` was constructed before `instrument()` ran. See
|
|
251
|
+
[construction order](#read-this-first-construction-order).
|
|
252
|
+
|
|
253
|
+
**Check it:**
|
|
254
|
+
|
|
255
|
+
```python
|
|
256
|
+
agent = Agent("openai:gpt-4o-mini")
|
|
257
|
+
print([type(c).__name__ for c in agent.root_capability.capabilities])
|
|
258
|
+
# ['FailproofAI', 'ToolSearch', 'PendingMessageDrainCapability']
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Pydantic AI merges the list you pass into one `root_capability`, so there is no
|
|
262
|
+
`agent.capabilities` attribute — reading that raises `AttributeError`.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
### A plain exception in a tool kills the run
|
|
267
|
+
|
|
268
|
+
**Symptom:** `run_sync` raises instead of the model working around a failed tool.
|
|
269
|
+
|
|
270
|
+
**Cause:** a bare `raise` propagates. That is Pydantic AI's design.
|
|
271
|
+
|
|
272
|
+
**Fix:** raise `ModelRetry` with a message the model can act on.
|
|
273
|
+
|
|
274
|
+
```python
|
|
275
|
+
@agent.tool_plain
|
|
276
|
+
def restock_eta(item: str) -> str:
|
|
277
|
+
"""Restock ETA."""
|
|
278
|
+
raise ModelRetry(f"no schedule for {item!r} — answer without it")
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
The failure is recorded as an errored `tool_result` either way; this only
|
|
282
|
+
decides whether the run survives it.
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
### There is a nested agent span I did not create
|
|
287
|
+
|
|
288
|
+
**Symptom:** wrapping in `failproofai_sdk.agent("inventory")` gives you
|
|
289
|
+
`inventory` **and** a child called `agent`.
|
|
290
|
+
|
|
291
|
+
**Cause:** that child is Pydantic AI's own run span, and it is where the model
|
|
292
|
+
and tool events hang. It is correct.
|
|
293
|
+
|
|
294
|
+
**Fix:** if you want one span instead of two, drop your own scope and let the
|
|
295
|
+
framework's span be the root — you lose the custom name.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
### Tracebacks look truncated at the top
|
|
300
|
+
|
|
301
|
+
**Symptom:** the `traceback` field starts with `[older frames truncated]…`.
|
|
302
|
+
|
|
303
|
+
**Cause:** Pydantic AI's async graph stack is comfortably longer than the 8KB
|
|
304
|
+
field limit. A traceback's last line is the exception itself, so this one field
|
|
305
|
+
is trimmed from the **front**, not the back — keeping the head like every other
|
|
306
|
+
field would ship 8KB of framework frames and drop the one line anybody reads.
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## Runnable examples
|
|
311
|
+
|
|
312
|
+
| file | what it shows | events |
|
|
313
|
+
|---|---|---|
|
|
314
|
+
| [`examples/quickstart.py`](examples/quickstart.py) | one tool, one turn | 8 |
|
|
315
|
+
| [`examples/research_agent.py`](examples/research_agent.py) | 3 tools, typed output, one tool that retries | 20 |
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
export OPENAI_API_KEY=sk-...
|
|
319
|
+
export FPAI_MODEL=gpt-4o-mini
|
|
320
|
+
python docs/pydantic_ai/examples/quickstart.py
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Both were run against a live model before shipping.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""pydantic_ai — the smallest thing that produces a trace.
|
|
2
|
+
|
|
3
|
+
pip install 'failproofai-sdk[pydantic-ai]'
|
|
4
|
+
python docs/pydantic_ai/examples/quickstart.py
|
|
5
|
+
|
|
6
|
+
`instrument()` appends a capability to every `Agent` constructed afterwards, so
|
|
7
|
+
runs, tools and model calls are captured without touching the call sites.
|
|
8
|
+
|
|
9
|
+
Order matters here and nowhere else: an `Agent` built BEFORE `instrument()` does
|
|
10
|
+
not carry the capability. Construct agents after instrumenting, or at import
|
|
11
|
+
time in a module imported after it.
|
|
12
|
+
"""
|
|
13
|
+
import sys
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
# Only so this file can import the shared trace printer from docs/_shared/.
|
|
17
|
+
# Delete these two lines and the `_shared` import below and the example still
|
|
18
|
+
# instruments correctly — it just stops printing its own trace at the end.
|
|
19
|
+
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
|
|
20
|
+
|
|
21
|
+
import failproofai_sdk
|
|
22
|
+
from _shared import banner, model, trace
|
|
23
|
+
from pydantic_ai import Agent
|
|
24
|
+
|
|
25
|
+
failproofai_sdk.configure(environment="examples")
|
|
26
|
+
failproofai_sdk.instrument()
|
|
27
|
+
|
|
28
|
+
agent = Agent(f"openai:{model()}", system_prompt="Be terse.")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@agent.tool_plain
|
|
32
|
+
def population(city: str) -> str:
|
|
33
|
+
"""Population of a city."""
|
|
34
|
+
return {"tokyo": "37M", "delhi": "33M"}.get(city.lower(), "unknown")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def main() -> None:
|
|
38
|
+
banner("pydantic_ai quickstart", "one tool, one turn")
|
|
39
|
+
|
|
40
|
+
with failproofai_sdk.session() as sid:
|
|
41
|
+
result = agent.run_sync("Population of Tokyo? Use the tool.")
|
|
42
|
+
|
|
43
|
+
print(" answer:", str(result.output).strip()[:120])
|
|
44
|
+
trace(sid, title="pydantic_ai quickstart")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
if __name__ == "__main__":
|
|
48
|
+
main()
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""pydantic_ai — a typed multi-tool run, plus a tool that raises.
|
|
2
|
+
|
|
3
|
+
pip install 'failproofai-sdk[pydantic-ai]'
|
|
4
|
+
python docs/pydantic_ai/examples/research_agent.py
|
|
5
|
+
|
|
6
|
+
What this demonstrates that the quickstart does not:
|
|
7
|
+
|
|
8
|
+
* three tools over several turns, each a `tool_use`/`tool_result` pair carrying
|
|
9
|
+
the arguments the model actually sent;
|
|
10
|
+
* a tool that raises `ModelRetry`, recorded as `tool_result` with `error` set
|
|
11
|
+
while the run still finishes `success` — the adapter deliberately does NOT
|
|
12
|
+
treat a retry as control flow, because an attempt really did fail and that is
|
|
13
|
+
what a tool span's `error` field is for;
|
|
14
|
+
* a typed `output_type`, so the run ends with a validated object and the trace
|
|
15
|
+
still reads the same — instrumentation does not care about your result type;
|
|
16
|
+
* `usage` on `model_response`, which is where per-run token spend comes from.
|
|
17
|
+
"""
|
|
18
|
+
import sys
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
# Only so this file can import the shared trace printer from docs/_shared/.
|
|
22
|
+
# Delete these two lines and the `_shared` import below and the example still
|
|
23
|
+
# instruments correctly — it just stops printing its own trace at the end.
|
|
24
|
+
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
|
|
25
|
+
|
|
26
|
+
import failproofai_sdk
|
|
27
|
+
from _shared import banner, model, trace
|
|
28
|
+
from pydantic import BaseModel
|
|
29
|
+
from pydantic_ai import Agent, ModelRetry
|
|
30
|
+
|
|
31
|
+
failproofai_sdk.configure(environment="examples")
|
|
32
|
+
failproofai_sdk.instrument()
|
|
33
|
+
|
|
34
|
+
_PRICE = {"widget": 42.0, "gadget": 17.5}
|
|
35
|
+
_STOCK = {"widget": 120, "gadget": 0}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Report(BaseModel):
|
|
39
|
+
"""What the run must produce. Validated by pydantic_ai, not by us."""
|
|
40
|
+
|
|
41
|
+
headline: str
|
|
42
|
+
out_of_stock: list[str]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
agent = Agent(
|
|
46
|
+
f"openai:{model()}",
|
|
47
|
+
output_type=Report,
|
|
48
|
+
system_prompt=(
|
|
49
|
+
"Use the tools for every number. If a tool fails, note it and continue."
|
|
50
|
+
),
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@agent.tool_plain
|
|
55
|
+
def price_of(item: str) -> float:
|
|
56
|
+
"""Unit price of an item. Valid: widget, gadget."""
|
|
57
|
+
return _PRICE[item.lower().strip()]
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@agent.tool_plain
|
|
61
|
+
def stock_of(item: str) -> int:
|
|
62
|
+
"""Units in stock. Valid: widget, gadget."""
|
|
63
|
+
return _STOCK[item.lower().strip()]
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@agent.tool_plain
|
|
67
|
+
def restock_eta(item: str) -> str:
|
|
68
|
+
"""Restock ETA. Not available for anything."""
|
|
69
|
+
# `ModelRetry` is how pydantic_ai hands a failure back to the model instead
|
|
70
|
+
# of raising out of `run_sync`. The failproof trace records it as an errored
|
|
71
|
+
# tool_result either way; this just lets the run finish so you can watch the
|
|
72
|
+
# model work around it.
|
|
73
|
+
raise ModelRetry(f"no restock schedule for {item!r} — answer without it")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def main() -> None:
|
|
77
|
+
banner("pydantic_ai research agent", "3 tools · typed output · one failing call")
|
|
78
|
+
|
|
79
|
+
prompt = (
|
|
80
|
+
"For 'widget' and 'gadget', get price and stock. For anything out of "
|
|
81
|
+
"stock, try the restock ETA. Then produce the report."
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
with failproofai_sdk.session() as sid:
|
|
85
|
+
with failproofai_sdk.agent("inventory", goal="stock report"):
|
|
86
|
+
result = agent.run_sync(prompt)
|
|
87
|
+
|
|
88
|
+
print(" headline: ", result.output.headline[:120])
|
|
89
|
+
print(" out of stock: ", result.output.out_of_stock, "\n")
|
|
90
|
+
trace(sid, title="pydantic_ai research agent")
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
if __name__ == "__main__":
|
|
94
|
+
main()
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""Telemetry for AI agents: emit events, spool them, let the daemon ship them.
|
|
2
|
+
|
|
3
|
+
Three surfaces, in the order most people meet them:
|
|
4
|
+
|
|
5
|
+
* **Scopes** — `session()`, `agent()`, `tool_call()`. Context managers that bind
|
|
6
|
+
run identity and, for the latter two, bracket a run with its own events. Work
|
|
7
|
+
under `with` and `async with`.
|
|
8
|
+
* **Adapters** — `instrument()`. Auto-detects LangChain/LangGraph, CrewAI,
|
|
9
|
+
LlamaIndex and Pydantic AI in the process and wires them to the scopes above.
|
|
10
|
+
* **`event.*`** — the 15 event methods, for anything the adapters do not cover.
|
|
11
|
+
|
|
12
|
+
`session_id` and `agent_id` are optional on every event method: omitted, they
|
|
13
|
+
resolve from the enclosing scope. Nothing bound and nothing passed is an error,
|
|
14
|
+
never a silent drop — ingest skips an event with no session and answers 200.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
19
|
+
from failproofai_sdk._version import __version__
|
|
20
|
+
from failproofai_sdk._environment import set_environment
|
|
21
|
+
from failproofai_sdk._resolver import set_base_dir
|
|
22
|
+
from failproofai_sdk._context import Identity, current, propagate
|
|
23
|
+
from failproofai_sdk._runtime import event
|
|
24
|
+
from failproofai_sdk._scopes import agent, session, tool_call
|
|
25
|
+
from failproofai_sdk._environment import _reject_comma
|
|
26
|
+
from failproofai_sdk._writer import _validated_interval
|
|
27
|
+
from failproofai_sdk import _runtime
|
|
28
|
+
|
|
29
|
+
__all__ = [
|
|
30
|
+
"__version__",
|
|
31
|
+
"configure",
|
|
32
|
+
"event",
|
|
33
|
+
"session",
|
|
34
|
+
"agent",
|
|
35
|
+
"tool_call",
|
|
36
|
+
"current",
|
|
37
|
+
"Identity",
|
|
38
|
+
"propagate",
|
|
39
|
+
"instrument",
|
|
40
|
+
"uninstrument",
|
|
41
|
+
"_writer",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def configure(
|
|
46
|
+
*,
|
|
47
|
+
base_dir=None,
|
|
48
|
+
flush_interval: float = 0.5,
|
|
49
|
+
environment: str | None = None,
|
|
50
|
+
) -> None:
|
|
51
|
+
"""Configure the SDK. Call once at startup before any event.* calls.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
base_dir: Override the spool root. Pass None to resolve it to
|
|
55
|
+
~/.failproofai/custom-agents (honouring $FAILPROOFAI_HOME,
|
|
56
|
+
which moves the umbrella but cannot take the spool outside
|
|
57
|
+
it — the `custom-agents` segment is always appended).
|
|
58
|
+
|
|
59
|
+
This is the ONLY way to spool anywhere else. No environment
|
|
60
|
+
variable redirects it; $AGENTEYE_HOME used to and no longer
|
|
61
|
+
does, because exporting it for the one component that still
|
|
62
|
+
reads it (the older `agenteye-collector`) moved this SDK's
|
|
63
|
+
spool as an unasked-for side effect.
|
|
64
|
+
|
|
65
|
+
The default moved here from ~/.agenteye. `failproofaid`
|
|
66
|
+
watches both roots, so on a host running it this only
|
|
67
|
+
changes which directory the files appear in, and batches
|
|
68
|
+
already spooled under the old root are still collected.
|
|
69
|
+
On a host running only `agenteye-collector`, give that
|
|
70
|
+
collector AGENTEYE_HOME=~/.failproofai/custom-agents so it
|
|
71
|
+
watches where this SDK writes — or pass base_dir here.
|
|
72
|
+
flush_interval: Seconds between flush cycles. Default 0.5 (500ms).
|
|
73
|
+
environment: Deployment environment label (e.g. "production", "staging").
|
|
74
|
+
Can also be set via the AGENTEYE_ENVIRONMENT env var.
|
|
75
|
+
Defaults to "dev" when neither is set.
|
|
76
|
+
|
|
77
|
+
Raises:
|
|
78
|
+
ValueError: if `flush_interval` is not a finite number greater than zero.
|
|
79
|
+
Checked here, before anything is applied, so a rejected call leaves
|
|
80
|
+
the SDK exactly as it was rather than with a new base_dir and the old
|
|
81
|
+
interval.
|
|
82
|
+
"""
|
|
83
|
+
# BOTH validations before ANY application. `set_environment` raises on a
|
|
84
|
+
# comma, and it used to run last — so `configure(base_dir=..., environment=
|
|
85
|
+
# "prod,eu")` raised having already moved the spool and the flush interval,
|
|
86
|
+
# which is precisely the half-applied state the docstring above promises is
|
|
87
|
+
# impossible. A caller who wraps startup in `except ValueError` (a reasonable
|
|
88
|
+
# thing to do for a telemetry library that must not crash the agent) was left
|
|
89
|
+
# shipping from a directory they did not choose.
|
|
90
|
+
flush_interval = _validated_interval(flush_interval)
|
|
91
|
+
if environment:
|
|
92
|
+
_reject_comma(environment, "configure(environment=...)")
|
|
93
|
+
set_base_dir(base_dir)
|
|
94
|
+
_runtime.writer.set_flush_interval(flush_interval)
|
|
95
|
+
set_environment(environment)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def instrument(framework: str | None = None, **options: Any):
|
|
99
|
+
"""Install the framework adapters.
|
|
100
|
+
|
|
101
|
+
With no argument, auto-detects the frameworks already imported in this
|
|
102
|
+
process. Pass a name (`"langchain"`, `"crewai"`, `"llama_index"`,
|
|
103
|
+
`"pydantic_ai"`) to install exactly one.
|
|
104
|
+
|
|
105
|
+
The import is inside the function on purpose: `failproofai_sdk.integrations`
|
|
106
|
+
reaches for framework packages, and `import failproofai_sdk` is
|
|
107
|
+
contractually zero-dependency — a promise `tests/test_zero_dependencies.py`
|
|
108
|
+
enforces both by scanning the core modules and by launching a fresh
|
|
109
|
+
interpreter to prove no framework lands in `sys.modules`.
|
|
110
|
+
"""
|
|
111
|
+
from failproofai_sdk.integrations import instrument as _impl
|
|
112
|
+
|
|
113
|
+
return _impl(framework, **options)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def uninstrument(framework: str | None = None):
|
|
117
|
+
"""Reverse `instrument()`, restoring the original attributes.
|
|
118
|
+
|
|
119
|
+
Lazy-imported for the same reason as `instrument()`.
|
|
120
|
+
"""
|
|
121
|
+
from failproofai_sdk.integrations import uninstrument as _impl
|
|
122
|
+
|
|
123
|
+
return _impl(framework)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# MUST be last: any `import failproofai_sdk.<sub>` binds the *module* onto this
|
|
127
|
+
# package as `failproofai_sdk._writer`. Rebinding it here to the instance is what
|
|
128
|
+
# keeps the published `failproofai_sdk._writer.flush_now()` recipe working — and
|
|
129
|
+
# is why a test reaching for the MODULE has to go through
|
|
130
|
+
# `sys.modules["failproofai_sdk._writer"]`.
|
|
131
|
+
_writer = _runtime.writer
|