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,422 @@
|
|
|
1
|
+
"""Context-manager scopes: `session()`, `agent()`, `tool_call()`.
|
|
2
|
+
|
|
3
|
+
These are the ergonomic surface over `failproofai_sdk.event.*`. Each one binds run
|
|
4
|
+
identity onto the contextvars in `failproofai_sdk._context` so that everything emitted
|
|
5
|
+
inside the block — including code that has never heard of the SDK's identity
|
|
6
|
+
arguments — lands on the right session and agent.
|
|
7
|
+
|
|
8
|
+
Why classes and not `@contextlib.contextmanager`
|
|
9
|
+
------------------------------------------------
|
|
10
|
+
A `@contextmanager` generator supports `with` only. An agent framework is
|
|
11
|
+
half-async, so the same scope has to work under `async with` too, and
|
|
12
|
+
`@asynccontextmanager` would mean a second, separately-maintained copy of the
|
|
13
|
+
body. These are plain classes with `__enter__`/`__exit__` **and**
|
|
14
|
+
`__aenter__`/`__aexit__`, where the async pair delegates to the sync pair. No
|
|
15
|
+
scope awaits anything — `writer.submit()` is a `deque.append` — so the delegation
|
|
16
|
+
is not a lie, and `async with` provably produces byte-identical events.
|
|
17
|
+
|
|
18
|
+
The namespace is reached as `_runtime.event` (attribute lookup at call time, not
|
|
19
|
+
a `from ... import event` binding) both to avoid importing `failproofai_sdk` from inside
|
|
20
|
+
`failproofai_sdk` and so tests can swap in a recording namespace.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import contextvars
|
|
24
|
+
import sys
|
|
25
|
+
import traceback as _traceback
|
|
26
|
+
import uuid
|
|
27
|
+
from typing import Any, Literal
|
|
28
|
+
|
|
29
|
+
from failproofai_sdk import _context
|
|
30
|
+
from failproofai_sdk import _runtime
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class _Auto:
|
|
34
|
+
"""Sentinel for `agent(parent_id=...)`.
|
|
35
|
+
|
|
36
|
+
`parent_id` has three states and `None` is a meaningful one of them, so the
|
|
37
|
+
default cannot be `None`:
|
|
38
|
+
|
|
39
|
+
* `AUTO` — infer the enclosing agent from the context stack (the default);
|
|
40
|
+
* `None` — force a root span, emitting no `parent_id` at all;
|
|
41
|
+
* `"str"` — use this id verbatim.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
__slots__ = ()
|
|
45
|
+
|
|
46
|
+
def __repr__(self) -> str: # pragma: no cover - debugging aid
|
|
47
|
+
return "AUTO"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
AUTO = _Auto()
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _is_cancellation(exc_type: type) -> bool:
|
|
54
|
+
"""True for `asyncio.CancelledError` / `GeneratorExit`.
|
|
55
|
+
|
|
56
|
+
A cancellation is not a failure: it must not emit an `error` event, or every
|
|
57
|
+
cancelled run pollutes the Errors surface. `asyncio` is looked up through
|
|
58
|
+
`sys.modules` rather than imported, so `import failproofai_sdk` stays cheap — if
|
|
59
|
+
`asyncio` was never imported, nothing in the process can have raised its
|
|
60
|
+
`CancelledError`.
|
|
61
|
+
"""
|
|
62
|
+
if issubclass(exc_type, GeneratorExit):
|
|
63
|
+
return True
|
|
64
|
+
asyncio = sys.modules.get("asyncio")
|
|
65
|
+
return asyncio is not None and issubclass(exc_type, asyncio.CancelledError)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _describe(exc_type: type, exc: BaseException | None) -> str:
|
|
69
|
+
text = str(exc) if exc is not None else ""
|
|
70
|
+
return f"{exc_type.__name__}: {text}" if text else exc_type.__name__
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class session:
|
|
74
|
+
"""Bind a session id (and optionally an agent id) for the enclosing block.
|
|
75
|
+
|
|
76
|
+
with failproofai_sdk.session() as sid:
|
|
77
|
+
failproofai_sdk.event.agent_start(agent_id="main", goal="...")
|
|
78
|
+
|
|
79
|
+
Emits **no events** — it is identity only. `agent()` is what brackets a run
|
|
80
|
+
with `agent_start`/`agent_end`.
|
|
81
|
+
|
|
82
|
+
`session_id=None` reuses an already-bound session if there is one, and
|
|
83
|
+
otherwise generates `uuid4().hex`. That inheritance is what lets a nested
|
|
84
|
+
scope stay inside one run instead of splitting it into two sessions.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
__slots__ = (
|
|
88
|
+
"_requested",
|
|
89
|
+
"_agent_id",
|
|
90
|
+
"id",
|
|
91
|
+
"_sid_token",
|
|
92
|
+
"_agent_token",
|
|
93
|
+
"_entry_session_id",
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
def __init__(self, session_id: str | None = None, *, agent_id: str | None = None) -> None:
|
|
97
|
+
self._requested = session_id
|
|
98
|
+
self._agent_id = agent_id
|
|
99
|
+
self.id: str | None = None
|
|
100
|
+
self._sid_token: "contextvars.Token | None" = None
|
|
101
|
+
self._agent_token: "contextvars.Token | None" = None
|
|
102
|
+
self._entry_session_id: str | None = None
|
|
103
|
+
|
|
104
|
+
def _enter(self) -> str:
|
|
105
|
+
sid = self._requested or _context.session_id() or uuid.uuid4().hex
|
|
106
|
+
self.id = sid
|
|
107
|
+
self._entry_session_id = _context.session_id()
|
|
108
|
+
self._sid_token = _context.bind_session(sid)
|
|
109
|
+
if self._agent_id is not None:
|
|
110
|
+
self._agent_token = _context.push_agent(self._agent_id)
|
|
111
|
+
return sid
|
|
112
|
+
|
|
113
|
+
def _exit(self) -> None:
|
|
114
|
+
# Unwind in reverse, and unconditionally: a scope that leaks an agent
|
|
115
|
+
# frame misattributes every later event in the process. Repair by value
|
|
116
|
+
# when the token is foreign — see `agent._unwind` for why that happens
|
|
117
|
+
# to ordinary code.
|
|
118
|
+
if not _context.reset(self._agent_token) and self._agent_id is not None:
|
|
119
|
+
_context.discard_agent(self._agent_id)
|
|
120
|
+
if not _context.reset(self._sid_token):
|
|
121
|
+
_context.restore_session(self._entry_session_id)
|
|
122
|
+
self._agent_token = None
|
|
123
|
+
self._sid_token = None
|
|
124
|
+
|
|
125
|
+
def __enter__(self) -> str:
|
|
126
|
+
return self._enter()
|
|
127
|
+
|
|
128
|
+
# `Literal[False]`, not `bool`: a `__exit__` typed `bool` tells every caller's
|
|
129
|
+
# type checker this scope MIGHT swallow the exception. It never does.
|
|
130
|
+
def __exit__(self, exc_type, exc, tb) -> Literal[False]:
|
|
131
|
+
self._exit()
|
|
132
|
+
return False
|
|
133
|
+
|
|
134
|
+
async def __aenter__(self) -> str:
|
|
135
|
+
return self._enter()
|
|
136
|
+
|
|
137
|
+
async def __aexit__(self, exc_type, exc, tb) -> Literal[False]:
|
|
138
|
+
self._exit()
|
|
139
|
+
return False
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class agent:
|
|
143
|
+
"""Bracket a run (or a sub-run) with `agent_start` / `agent_end`.
|
|
144
|
+
|
|
145
|
+
with failproofai_sdk.agent("planner", goal=question):
|
|
146
|
+
...
|
|
147
|
+
|
|
148
|
+
`agent_id` is positional on purpose. It is the one argument integrators type
|
|
149
|
+
on every single call site, and the rest of the SDK's keyword-only discipline
|
|
150
|
+
exists to stop *identity* arguments being passed by accident — which is not a
|
|
151
|
+
risk here.
|
|
152
|
+
|
|
153
|
+
Keep `agent_id` low-cardinality (a node/role name, never a UUID): it is a
|
|
154
|
+
`LowCardinality(String)` column and the primary facet across every session.
|
|
155
|
+
|
|
156
|
+
`**fields` are attached to `agent_start` only; `agent_end` carries `outcome`
|
|
157
|
+
and `summary`.
|
|
158
|
+
|
|
159
|
+
Exit semantics, which are the whole point of the class:
|
|
160
|
+
|
|
161
|
+
| exception | events | outcome |
|
|
162
|
+
|---------------------------------|-------------------|-------------|
|
|
163
|
+
| none | `agent_end` | `outcome=` |
|
|
164
|
+
| `Exception` | `error`, then end | `"failed"` |
|
|
165
|
+
| `KeyboardInterrupt`/`SystemExit`| `error`, then end | `"failed"` |
|
|
166
|
+
| `CancelledError`/`GeneratorExit`| `agent_end` only | `"cancelled"`|
|
|
167
|
+
|
|
168
|
+
`error` strictly *before* `agent_end`, because the dashboard closes the agent
|
|
169
|
+
span at `agent_end` and anything after it is attributed to nothing. The
|
|
170
|
+
literal is `"failed"`, never `"failure"` — only `error|failed|timeout|rejected`
|
|
171
|
+
count as a failure server-side. The exception is always re-raised.
|
|
172
|
+
|
|
173
|
+
**Do not span a `yield` in an async generator with this.** Async generators
|
|
174
|
+
have no context of their own, so the identity binds in the CONSUMER's
|
|
175
|
+
context — and when the consumer stops early (`break` out of `async for`)
|
|
176
|
+
asyncio finalizes the generator from a separate task, so `__aexit__` runs
|
|
177
|
+
somewhere the binding is unreachable. `agent_end` is still emitted correctly,
|
|
178
|
+
but the consumer keeps a frame for a span that has already closed, and the
|
|
179
|
+
library cannot remove it from there: `ContextVar.set` in the finalizer's task
|
|
180
|
+
does not reach the context the value lives in. `_context.reset` warns once
|
|
181
|
+
when it happens. Pass `session_id=`/`agent_id=` explicitly on the events
|
|
182
|
+
inside a streaming generator instead of wrapping the `yield` in a scope.
|
|
183
|
+
"""
|
|
184
|
+
|
|
185
|
+
__slots__ = (
|
|
186
|
+
"agent_id",
|
|
187
|
+
"_requested_sid",
|
|
188
|
+
"_goal",
|
|
189
|
+
"_parent_id",
|
|
190
|
+
"_outcome",
|
|
191
|
+
"_summary",
|
|
192
|
+
"_fields",
|
|
193
|
+
"session_id",
|
|
194
|
+
"_sid_token",
|
|
195
|
+
"_agent_token",
|
|
196
|
+
"_entry_session_id",
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
def __init__(
|
|
200
|
+
self,
|
|
201
|
+
agent_id: str = "main",
|
|
202
|
+
*,
|
|
203
|
+
session_id: str | None = None,
|
|
204
|
+
goal: str | None = None,
|
|
205
|
+
parent_id: "str | None | _Auto" = AUTO,
|
|
206
|
+
outcome: str | None = "success",
|
|
207
|
+
summary: str | None = None,
|
|
208
|
+
**fields: Any,
|
|
209
|
+
) -> None:
|
|
210
|
+
self.agent_id = agent_id
|
|
211
|
+
self._requested_sid = session_id
|
|
212
|
+
self._goal = goal
|
|
213
|
+
self._parent_id = parent_id
|
|
214
|
+
self._outcome = outcome
|
|
215
|
+
self._summary = summary
|
|
216
|
+
self._fields = fields
|
|
217
|
+
self.session_id: str | None = None
|
|
218
|
+
self._sid_token: "contextvars.Token | None" = None
|
|
219
|
+
self._agent_token: "contextvars.Token | None" = None
|
|
220
|
+
self._entry_session_id: str | None = None
|
|
221
|
+
|
|
222
|
+
def _enter(self) -> _context.Identity:
|
|
223
|
+
sid = self._requested_sid or _context.session_id() or uuid.uuid4().hex
|
|
224
|
+
self.session_id = sid
|
|
225
|
+
|
|
226
|
+
if isinstance(self._parent_id, _Auto):
|
|
227
|
+
# Only inherit within the SAME session. An explicit `session_id=`
|
|
228
|
+
# that differs from the ambient one is the documented way to start a
|
|
229
|
+
# NEW run, and the enclosing agent does not exist in it — the span
|
|
230
|
+
# tree is keyed by session, so the child rendered as a root with a
|
|
231
|
+
# dangling parent, or got grafted onto whatever agent in its own
|
|
232
|
+
# session happened to share the id. The ordinary long-lived-server
|
|
233
|
+
# shape reached it directly:
|
|
234
|
+
#
|
|
235
|
+
# with agent("server", session_id="boot"):
|
|
236
|
+
# for rid in requests:
|
|
237
|
+
# with agent("handler", session_id=rid): # parent="server"
|
|
238
|
+
#
|
|
239
|
+
# A caller who genuinely wants a cross-session link can still pass
|
|
240
|
+
# `parent_id=` explicitly.
|
|
241
|
+
parent = _context.current().agent_id if sid == _context.session_id() else None
|
|
242
|
+
else:
|
|
243
|
+
parent = self._parent_id
|
|
244
|
+
|
|
245
|
+
self._entry_session_id = _context.session_id()
|
|
246
|
+
self._sid_token = _context.bind_session(sid)
|
|
247
|
+
self._agent_token = _context.push_agent(self.agent_id)
|
|
248
|
+
try:
|
|
249
|
+
_runtime.event.agent_start(
|
|
250
|
+
session_id=sid,
|
|
251
|
+
agent_id=self.agent_id,
|
|
252
|
+
goal=self._goal,
|
|
253
|
+
parent_id=parent,
|
|
254
|
+
**self._fields,
|
|
255
|
+
)
|
|
256
|
+
except BaseException:
|
|
257
|
+
# A rejected agent_start (a reserved **field, say) must not leave a
|
|
258
|
+
# half-entered scope behind: `__exit__` never runs if `__enter__`
|
|
259
|
+
# raises.
|
|
260
|
+
self._unwind()
|
|
261
|
+
raise
|
|
262
|
+
return _context.current()
|
|
263
|
+
|
|
264
|
+
def _unwind(self) -> None:
|
|
265
|
+
# `reset` tolerates a cross-context token, but tolerating it is not the
|
|
266
|
+
# same as undoing it: the frame this scope pushed stays on the caller's
|
|
267
|
+
# stack forever. An `agent()` scope inside an ASYNC GENERATOR reaches
|
|
268
|
+
# that without anyone doing anything unusual — async generators have no
|
|
269
|
+
# context of their own, so the binding lands in the CONSUMER's context,
|
|
270
|
+
# and when the consumer stops early (`break` out of `async for`) asyncio
|
|
271
|
+
# finalizes the generator from a SEPARATE task. `__aexit__` therefore
|
|
272
|
+
# runs somewhere the token is foreign, the reset is swallowed with a
|
|
273
|
+
# debug line, and the consumer is left holding a span that has already
|
|
274
|
+
# closed: the next unrelated request is emitted as its child, in a
|
|
275
|
+
# different session, and the stack grows by one on every repetition.
|
|
276
|
+
#
|
|
277
|
+
# So fall back to repairing the values directly. `reset` reports whether
|
|
278
|
+
# it managed the token-based restore; when it did not, remove exactly
|
|
279
|
+
# this scope's own frame and put the session back to what it was.
|
|
280
|
+
if not _context.reset(self._agent_token):
|
|
281
|
+
_context.discard_agent(self.agent_id)
|
|
282
|
+
if not _context.reset(self._sid_token):
|
|
283
|
+
_context.restore_session(self._entry_session_id)
|
|
284
|
+
self._agent_token = None
|
|
285
|
+
self._sid_token = None
|
|
286
|
+
|
|
287
|
+
def _exit(self, exc_type, exc, tb) -> bool:
|
|
288
|
+
try:
|
|
289
|
+
if exc_type is None:
|
|
290
|
+
outcome = self._outcome
|
|
291
|
+
elif _is_cancellation(exc_type):
|
|
292
|
+
outcome = "cancelled"
|
|
293
|
+
else:
|
|
294
|
+
outcome = "failed"
|
|
295
|
+
_runtime.event.error(
|
|
296
|
+
session_id=self.session_id,
|
|
297
|
+
agent_id=self.agent_id,
|
|
298
|
+
error_type=exc_type.__name__,
|
|
299
|
+
message=str(exc) if exc is not None else "",
|
|
300
|
+
traceback="".join(_traceback.format_exception(exc_type, exc, tb)),
|
|
301
|
+
)
|
|
302
|
+
_runtime.event.agent_end(
|
|
303
|
+
session_id=self.session_id,
|
|
304
|
+
agent_id=self.agent_id,
|
|
305
|
+
outcome=outcome,
|
|
306
|
+
summary=self._summary,
|
|
307
|
+
)
|
|
308
|
+
finally:
|
|
309
|
+
# In `finally` so the stack is intact even if emission itself blew
|
|
310
|
+
# up. A leaked frame is worse than a lost event.
|
|
311
|
+
self._unwind()
|
|
312
|
+
return False
|
|
313
|
+
|
|
314
|
+
def __enter__(self) -> _context.Identity:
|
|
315
|
+
return self._enter()
|
|
316
|
+
|
|
317
|
+
def __exit__(self, exc_type, exc, tb) -> bool:
|
|
318
|
+
return self._exit(exc_type, exc, tb)
|
|
319
|
+
|
|
320
|
+
async def __aenter__(self) -> _context.Identity:
|
|
321
|
+
return self._enter()
|
|
322
|
+
|
|
323
|
+
async def __aexit__(self, exc_type, exc, tb) -> bool:
|
|
324
|
+
return self._exit(exc_type, exc, tb)
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
class ToolCall:
|
|
328
|
+
"""The handle `tool_call()` yields. Set `.output`; read `.id`."""
|
|
329
|
+
|
|
330
|
+
__slots__ = ("_id", "output")
|
|
331
|
+
|
|
332
|
+
def __init__(self, tool_call_id: str) -> None:
|
|
333
|
+
self._id = tool_call_id
|
|
334
|
+
self.output: Any = None
|
|
335
|
+
|
|
336
|
+
@property
|
|
337
|
+
def id(self) -> str:
|
|
338
|
+
"""The correlation id on both the `tool_use` and the `tool_result`."""
|
|
339
|
+
return self._id
|
|
340
|
+
|
|
341
|
+
def __repr__(self) -> str: # pragma: no cover - debugging aid
|
|
342
|
+
return f"ToolCall(id={self._id!r})"
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
class tool_call:
|
|
346
|
+
"""Bracket a tool invocation with `tool_use` / `tool_result`.
|
|
347
|
+
|
|
348
|
+
with failproofai_sdk.tool_call("web_search", input={"q": q}) as t:
|
|
349
|
+
t.output = search(q)
|
|
350
|
+
|
|
351
|
+
`tool_call_id` defaults to `uuid4().hex`. Identity comes from the enclosing
|
|
352
|
+
scope; if nothing is bound, the underlying `event.tool_use()` raises the
|
|
353
|
+
usual `TypeError` naming the fix.
|
|
354
|
+
|
|
355
|
+
On failure this emits `tool_result(error="TypeName: msg")` and **no `error`
|
|
356
|
+
event**. A tool failure the agent loop catches is not a run-level error, and
|
|
357
|
+
one that propagates is reported exactly once, by the enclosing `agent()`.
|
|
358
|
+
Cancellation closes the leaf with no `error` string at all, for the same
|
|
359
|
+
reason `agent()` does not mark it failed.
|
|
360
|
+
"""
|
|
361
|
+
|
|
362
|
+
__slots__ = ("tool_name", "_requested_id", "_input", "_fields", "_box", "_sid", "_aid")
|
|
363
|
+
|
|
364
|
+
def __init__(
|
|
365
|
+
self,
|
|
366
|
+
tool_name: str,
|
|
367
|
+
*,
|
|
368
|
+
tool_call_id: str | None = None,
|
|
369
|
+
input: dict | None = None,
|
|
370
|
+
**fields: Any,
|
|
371
|
+
) -> None:
|
|
372
|
+
self.tool_name = tool_name
|
|
373
|
+
self._requested_id = tool_call_id
|
|
374
|
+
self._input = input
|
|
375
|
+
self._fields = fields
|
|
376
|
+
self._box: ToolCall | None = None
|
|
377
|
+
self._sid: str | None = None
|
|
378
|
+
self._aid: str | None = None
|
|
379
|
+
|
|
380
|
+
def _enter(self) -> ToolCall:
|
|
381
|
+
# Resolve once, at entry: a tool that pushes its own scope inside must
|
|
382
|
+
# not make the closing tool_result land on a different agent_id.
|
|
383
|
+
self._sid = _context.session_id()
|
|
384
|
+
self._aid = _context.agent_id()
|
|
385
|
+
box = ToolCall(self._requested_id or uuid.uuid4().hex)
|
|
386
|
+
self._box = box
|
|
387
|
+
_runtime.event.tool_use(
|
|
388
|
+
session_id=self._sid,
|
|
389
|
+
agent_id=self._aid,
|
|
390
|
+
tool_name=self.tool_name,
|
|
391
|
+
tool_call_id=box.id,
|
|
392
|
+
input=self._input,
|
|
393
|
+
**self._fields,
|
|
394
|
+
)
|
|
395
|
+
return box
|
|
396
|
+
|
|
397
|
+
def _exit(self, exc_type, exc, tb) -> bool:
|
|
398
|
+
assert self._box is not None
|
|
399
|
+
error = None
|
|
400
|
+
if exc_type is not None and not _is_cancellation(exc_type):
|
|
401
|
+
error = _describe(exc_type, exc)
|
|
402
|
+
_runtime.event.tool_result(
|
|
403
|
+
session_id=self._sid,
|
|
404
|
+
agent_id=self._aid,
|
|
405
|
+
tool_name=self.tool_name,
|
|
406
|
+
tool_call_id=self._box.id,
|
|
407
|
+
output=self._box.output,
|
|
408
|
+
error=error,
|
|
409
|
+
)
|
|
410
|
+
return False
|
|
411
|
+
|
|
412
|
+
def __enter__(self) -> ToolCall:
|
|
413
|
+
return self._enter()
|
|
414
|
+
|
|
415
|
+
def __exit__(self, exc_type, exc, tb) -> bool:
|
|
416
|
+
return self._exit(exc_type, exc, tb)
|
|
417
|
+
|
|
418
|
+
async def __aenter__(self) -> ToolCall:
|
|
419
|
+
return self._enter()
|
|
420
|
+
|
|
421
|
+
async def __aexit__(self, exc_type, exc, tb) -> bool:
|
|
422
|
+
return self._exit(exc_type, exc, tb)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.1b1"
|