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