failproofai 1.0.7-beta.1 → 1.0.7
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 +4 -4
- 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 +4 -4
- 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 +4 -4
- 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.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route.js +7 -8
- 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.nft.json +1 -1
- 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.nft.json +1 -1
- 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 +5 -7
- 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 +6 -6
- 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 +14 -14
- package/.next/standalone/.next/server/app/policies/page.js +11 -13
- 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 +7 -8
- 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 +7 -7
- 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 +6 -7
- 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 +8 -41
- package/.next/standalone/.next/server/app/settings/page.js +9 -12
- 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]__1j-zsg5._.js → [externals]__1_bftcl._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__19_pzeq._.js → [externals]__1msfs-h._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1bf34x4._.js → [root-of-the-server]__1_r2rbg._.js} +7 -5
- package/.next/standalone/.next/server/chunks/_09dz7xv._.js +21 -21
- package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
- package/.next/standalone/.next/server/chunks/{_1q5i8mb._.js → _1c3k-8x._.js} +2 -2
- package/.next/standalone/.next/server/chunks/_1ek68ln._.js +16 -16
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.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_0iu54mz._.js +3 -0
- package/.next/standalone/.next/server/chunks/src_hooks_custom-hooks-loader_ts_0lnb3n3._.js +2 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-_ki57._.js +4 -0
- 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]__0yxwl6j._.js → [root-of-the-server]__0bd3mje._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cg-bgc._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cpu_mj._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1mf3zp6._.js → [root-of-the-server]__0cxe_2_._.js} +3 -3
- 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]__0p-5p8u._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u3w0ll._.js +22 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17d_ffl._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__19d9tgz._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ctpynv._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1jiwfsj._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1phc187._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_06imw3p._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_1w_5l7t._.js → _0h_douw._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_214wgrp._.js → _1-i_gzc._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{_0bn2oo8._.js → _166t73i._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_1q46vxx._.js → _1_qswah._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{_1gb0ifp._.js → _1es2j7i._.js} +5 -5
- package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
- 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 +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_18_d8l1._.js → node_modules_next_dist_0drixxt._.js} +4 -4
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1cv9_c4._.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/chunks/ssr/src_hooks_pack-cli_ts_0t7me65._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- 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 +23 -56
- package/.next/standalone/.next/static/chunks/094xgi4owxaqf.js +1 -0
- package/.next/standalone/.next/static/chunks/0__8a7m868fvf.js +1 -0
- package/.next/standalone/.next/static/chunks/{12tvm75t5ffui.js → 0o6qlkgubtoex.js} +1 -1
- package/.next/standalone/.next/static/chunks/13i7-9is-vhys.js +1 -0
- package/.next/standalone/.next/static/chunks/1rz20_pz828f3.js +6 -0
- package/.next/standalone/.next/static/chunks/2k9f4tyv04809.css +1 -0
- package/.next/standalone/.next/static/chunks/{0vmd180qfntfb.js → 2klitrtzpaoe0.js} +1 -1
- package/.next/standalone/.next/static/chunks/{258668t68du6b.js → 2mdh397ghgnvv.js} +1 -1
- package/.next/standalone/.next/static/chunks/2rshywgeqsyzk.css +2 -0
- package/.next/standalone/.next/static/chunks/3pzx4chkhko9k.js +1 -0
- package/.next/standalone/.next/static/chunks/{0qrbdkv9qmvli.js → 3rh5o7e16irrm.js} +1 -1
- package/.next/standalone/.next/static/chunks/{29fql3nbnfc9q.js → 43ufqrz8qo3h-.js} +1 -1
- package/.next/standalone/SECURITY.md +53 -0
- package/.next/standalone/app/actions/pack-actions.ts +0 -12
- package/.next/standalone/app/policies/hooks-client.tsx +0 -9
- package/.next/standalone/app/settings/page.tsx +1 -20
- package/.next/standalone/app/settings/settings-client.tsx +1 -27
- package/.next/standalone/app/settings/settings.css +0 -79
- package/.next/standalone/package.json +9 -9
- package/.next/standalone/sdk/python/skill/SKILL.md +60 -14
- package/.next/standalone/sdk/python/skill/agents/openai.yaml +2 -1
- package/.next/standalone/sdk/python/skill/references/evaluator.md +255 -0
- package/.next/standalone/sdk/python/skill/references/events.md +17 -8
- package/.next/standalone/sdk/python/skill/references/frameworks.md +3 -0
- package/.next/standalone/sdk/python/skill/references/install.md +3 -0
- package/.next/standalone/sdk/python/skill/references/integration.md +6 -2
- package/.next/standalone/sdk/python/skill/references/typescript.md +568 -0
- package/.next/standalone/sdk/typescript/CHANGELOG.md +133 -0
- package/.next/standalone/sdk/typescript/LICENSE +42 -0
- package/.next/standalone/sdk/typescript/README.md +552 -0
- package/.next/standalone/sdk/typescript/eslint.config.mjs +59 -0
- package/.next/standalone/sdk/typescript/examples/research-agent.ts +197 -0
- package/.next/standalone/sdk/typescript/integration/ai.test.ts +920 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/agent.ts +337 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package-lock.json +261 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package.json +16 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/surfaces.ts +605 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/agent.ts +342 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package-lock.json +156 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package.json +16 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/surfaces.ts +628 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/agent.ts +346 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package-lock.json +156 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package.json +13 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/surfaces.ts +651 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/agent.ts +350 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package-lock.json +153 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package.json +13 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/surfaces.ts +651 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/agent.ts +623 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package-lock.json +344 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package.json +19 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/agent-v1.ts +99 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/agent.ts +623 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package-lock.json +336 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/agent.ts +96 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package-lock.json +441 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package.json +19 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/index.cjs +53 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/index.mjs +55 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/package.json +18 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/agent.ts +659 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package-lock.json +635 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/agent.ts +659 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package-lock.json +553 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/agent.ts +877 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/mcp-server.mjs +66 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package-lock.json +6797 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package.json +24 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/agent.ts +872 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/mcp-server.mjs +66 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package-lock.json +2540 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/actions.ts +18 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/ai/route.ts +42 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/edge/route.ts +29 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/langgraph/route.ts +21 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/llamaindex/route.ts +11 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/mastra/route.ts +19 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/status/route.ts +7 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/layout.tsx +9 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/page.tsx +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/instrumentation.ts +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/ai.ts +61 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/langgraph.ts +68 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/llamaindex.ts +98 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/mastra.ts +90 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/next.config.ts +52 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package-lock.json +4343 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package.json +28 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/agent.ts +51 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/deno-npm.ts +76 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package-lock.json +484 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/types/agent.ts +79 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/types/package-lock.json +740 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/types/package.json +11 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/agent.ts +197 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/package-lock.json +70 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/package.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/global-setup.ts +29 -0
- package/.next/standalone/sdk/typescript/integration/harness.ts +451 -0
- package/.next/standalone/sdk/typescript/integration/langchain.test.ts +682 -0
- package/.next/standalone/sdk/typescript/integration/llamaindex.test.ts +709 -0
- package/.next/standalone/sdk/typescript/integration/mastra-coverage.test.ts +386 -0
- package/.next/standalone/sdk/typescript/integration/mastra.test.ts +311 -0
- package/.next/standalone/sdk/typescript/integration/nextjs.test.ts +341 -0
- package/.next/standalone/sdk/typescript/integration/runtime-parity.ts +180 -0
- package/.next/standalone/sdk/typescript/integration/runtimes.bun.test.ts +15 -0
- package/.next/standalone/sdk/typescript/integration/runtimes.core.test.ts +113 -0
- package/.next/standalone/sdk/typescript/integration/runtimes.deno.test.ts +19 -0
- package/.next/standalone/sdk/typescript/integration/types.test.ts +141 -0
- package/.next/standalone/sdk/typescript/integration/vanilla.test.ts +255 -0
- package/.next/standalone/sdk/typescript/package-lock.json +2640 -0
- package/.next/standalone/sdk/typescript/package.json +401 -0
- package/.next/standalone/sdk/typescript/scripts/finalize-build.mjs +123 -0
- package/.next/standalone/sdk/typescript/scripts/release.mjs +177 -0
- package/.next/standalone/sdk/typescript/src/clock.ts +58 -0
- package/.next/standalone/sdk/typescript/src/context.ts +214 -0
- package/.next/standalone/sdk/typescript/src/edge/adapter.ts +18 -0
- package/.next/standalone/sdk/typescript/src/edge/ai.ts +116 -0
- package/.next/standalone/sdk/typescript/src/edge/index.ts +238 -0
- package/.next/standalone/sdk/typescript/src/edge/langchain.ts +18 -0
- package/.next/standalone/sdk/typescript/src/edge/llamaindex.ts +12 -0
- package/.next/standalone/sdk/typescript/src/edge/mastra.ts +17 -0
- package/.next/standalone/sdk/typescript/src/edge/notice.ts +33 -0
- package/.next/standalone/sdk/typescript/src/environment.ts +75 -0
- package/.next/standalone/sdk/typescript/src/evaluator/authoring.ts +480 -0
- package/.next/standalone/sdk/typescript/src/evaluator/cli.ts +96 -0
- package/.next/standalone/sdk/typescript/src/evaluator/client.ts +421 -0
- package/.next/standalone/sdk/typescript/src/evaluator/expression.ts +1292 -0
- package/.next/standalone/sdk/typescript/src/evaluator/index.ts +144 -0
- package/.next/standalone/sdk/typescript/src/evaluator/protocol.ts +747 -0
- package/.next/standalone/sdk/typescript/src/evaluator/runtime.ts +930 -0
- package/.next/standalone/sdk/typescript/src/evaluator/sandbox-worker.ts +171 -0
- package/.next/standalone/sdk/typescript/src/evaluator/source-limits.ts +27 -0
- package/.next/standalone/sdk/typescript/src/evaluator/source.ts +509 -0
- package/.next/standalone/sdk/typescript/src/events.ts +879 -0
- package/.next/standalone/sdk/typescript/src/exit.ts +117 -0
- package/.next/standalone/sdk/typescript/src/index.ts +186 -0
- package/.next/standalone/sdk/typescript/src/integrations/ai.ts +1566 -0
- package/.next/standalone/sdk/typescript/src/integrations/compat.ts +322 -0
- package/.next/standalone/sdk/typescript/src/integrations/core.ts +1321 -0
- package/.next/standalone/sdk/typescript/src/integrations/index.ts +355 -0
- package/.next/standalone/sdk/typescript/src/integrations/langchain.ts +2340 -0
- package/.next/standalone/sdk/typescript/src/integrations/llamaindex.ts +2111 -0
- package/.next/standalone/sdk/typescript/src/integrations/mastra.ts +1802 -0
- package/.next/standalone/sdk/typescript/src/logger.ts +98 -0
- package/.next/standalone/sdk/typescript/src/next.ts +115 -0
- package/.next/standalone/sdk/typescript/src/node-require.ts +446 -0
- package/.next/standalone/sdk/typescript/src/redact.ts +305 -0
- package/.next/standalone/sdk/typescript/src/resolver.ts +120 -0
- package/.next/standalone/sdk/typescript/src/runtime.ts +29 -0
- package/.next/standalone/sdk/typescript/src/schema.ts +410 -0
- package/.next/standalone/sdk/typescript/src/scopes.ts +701 -0
- package/.next/standalone/sdk/typescript/src/shared.ts +33 -0
- package/.next/standalone/sdk/typescript/src/version.ts +5 -0
- package/.next/standalone/sdk/typescript/src/writer.ts +934 -0
- package/.next/standalone/sdk/typescript/test/adapters.test.ts +397 -0
- package/.next/standalone/sdk/typescript/test/ai.test.ts +1076 -0
- package/.next/standalone/sdk/typescript/test/copies.test.ts +204 -0
- package/.next/standalone/sdk/typescript/test/edge.test.ts +183 -0
- package/.next/standalone/sdk/typescript/test/evaluator-client.test.ts +234 -0
- package/.next/standalone/sdk/typescript/test/evaluator-protocol.test.ts +225 -0
- package/.next/standalone/sdk/typescript/test/events.test.ts +193 -0
- package/.next/standalone/sdk/typescript/test/expression.test.ts +181 -0
- package/.next/standalone/sdk/typescript/test/global-setup.ts +26 -0
- package/.next/standalone/sdk/typescript/test/helpers.ts +130 -0
- package/.next/standalone/sdk/typescript/test/integrations.test.ts +369 -0
- package/.next/standalone/sdk/typescript/test/langchain-copies.test.ts +204 -0
- package/.next/standalone/sdk/typescript/test/langchain.test.ts +999 -0
- package/.next/standalone/sdk/typescript/test/llamaindex.test.ts +1760 -0
- package/.next/standalone/sdk/typescript/test/mastra-coverage.test.ts +501 -0
- package/.next/standalone/sdk/typescript/test/mastra-lifecycle.test.ts +479 -0
- package/.next/standalone/sdk/typescript/test/mastra.test.ts +285 -0
- package/.next/standalone/sdk/typescript/test/next.test.ts +109 -0
- package/.next/standalone/sdk/typescript/test/packaging.test.ts +312 -0
- package/.next/standalone/sdk/typescript/test/redaction.test.ts +171 -0
- package/.next/standalone/sdk/typescript/test/runtimes.test.ts +101 -0
- package/.next/standalone/sdk/typescript/test/sandbox.test.ts +189 -0
- package/.next/standalone/sdk/typescript/test/scopes.test.ts +271 -0
- package/.next/standalone/sdk/typescript/test/setup.ts +19 -0
- package/.next/standalone/sdk/typescript/test/skill-snippets.test.ts +73 -0
- package/.next/standalone/sdk/typescript/test/spool-contract.test.ts +124 -0
- package/.next/standalone/sdk/typescript/test/tracker-bounds.test.ts +191 -0
- package/.next/standalone/sdk/typescript/test/wire-format.test.ts +214 -0
- package/.next/standalone/sdk/typescript/test/writer.test.ts +407 -0
- package/.next/standalone/sdk/typescript/tsconfig.build.json +15 -0
- package/.next/standalone/sdk/typescript/tsconfig.cjs.json +19 -0
- package/.next/standalone/sdk/typescript/tsconfig.json +28 -0
- package/.next/standalone/sdk/typescript/vitest.config.ts +33 -0
- package/.next/standalone/sdk/typescript/vitest.integration.config.ts +23 -0
- package/.next/standalone/server.js +1 -1
- package/bin/failproofai.mjs +2 -115
- package/dist/cli.mjs +6538 -13686
- package/dist/index.js +1 -19
- package/dist/worker.mjs +2085 -8012
- package/package.json +9 -9
- package/pi-extension/index.ts +0 -11
- package/scripts/build-policy-pack.mjs +2 -39
- package/src/hooks/builtin-policies.ts +3 -21
- package/src/hooks/cloud-enrollment-cli.ts +1 -1
- package/src/hooks/cloud-managed-policies.ts +0 -22
- package/src/hooks/custom-hooks-loader.ts +7 -45
- package/src/hooks/custom-hooks-registry.ts +1 -45
- package/src/hooks/first-run-gate.ts +0 -5
- package/src/hooks/fp-home.ts +0 -23
- package/src/hooks/handler.ts +6 -265
- package/src/hooks/hook-activity-store.ts +1 -105
- package/src/hooks/hook-telemetry.ts +0 -41
- package/src/hooks/loader-utils.ts +0 -6
- package/src/hooks/pack-cli.ts +17 -278
- package/src/hooks/pack-manifest.ts +7 -479
- package/src/hooks/pack-store.ts +10 -156
- package/src/hooks/policy-catalog.ts +0 -65
- package/src/hooks/policy-evaluator.ts +796 -940
- package/src/hooks/policy-registry.ts +0 -25
- package/src/hooks/policy-types.ts +0 -126
- package/src/hooks/worker-server.ts +26 -119
- package/src/index.ts +0 -6
- package/.next/standalone/.next/server/chunks/src_hooks_01frwmb._.js +0 -5
- package/.next/standalone/.next/server/chunks/src_hooks_18qtd42._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01bmjsj._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__056wjo4._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__059yza8._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0eip4_k._.js +0 -22
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n0xg95._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qcb0mg._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qxnccm._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rwtwpm._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s_yomn._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0soxz2z._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0yrsbd_._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11mayhe._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13d-wb6._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1dinjii._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pprgri._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1q4p5b8._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qiz0e4._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_042cgl1._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0uyu3jf._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1feuvhb._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9sni._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_0w6mzq5._.js +0 -151
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_095a_79._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_15t8kqj._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_18k8rl0._.js +0 -12
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1fm2w5z._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1j0zy3v._.js +0 -3
- package/.next/standalone/.next/static/chunks/0cd-_8-c-m1ea.js +0 -6
- package/.next/standalone/.next/static/chunks/0uldbut9y2-e8.js +0 -1
- package/.next/standalone/.next/static/chunks/1u5zsejmgrir_.js +0 -1
- package/.next/standalone/.next/static/chunks/285spx855h_3r.css +0 -2
- package/.next/standalone/.next/static/chunks/2qv4hshejedtx.css +0 -1
- package/.next/standalone/.next/static/chunks/2vkvu9-opa_1z.js +0 -1
- package/.next/standalone/.next/static/chunks/37lhv7wa3ywt6.js +0 -1
- package/.next/standalone/app/actions/get-jev-config.ts +0 -409
- package/.next/standalone/app/actions/update-jev-config.ts +0 -420
- package/.next/standalone/app/components/jev-notices.tsx +0 -96
- package/.next/standalone/app/settings/jev-panel.tsx +0 -469
- package/src/hooks/effective-reviewers.ts +0 -79
- package/src/hooks/jev-activity.ts +0 -385
- package/src/hooks/jev-cli.ts +0 -1193
- package/src/hooks/policy-authority.ts +0 -333
- package/src/hooks/policy-reviewability.ts +0 -229
- package/src/hooks/semantic/combine.ts +0 -541
- package/src/hooks/semantic/compile.ts +0 -176
- package/src/hooks/semantic/decide.ts +0 -392
- package/src/hooks/semantic/envelope.ts +0 -1296
- package/src/hooks/semantic/evaluator.ts +0 -547
- package/src/hooks/semantic/facts.ts +0 -292
- package/src/hooks/semantic/intent.ts +0 -1190
- package/src/hooks/semantic/jev-client.ts +0 -643
- package/src/hooks/semantic/jev-config.ts +0 -594
- package/src/hooks/semantic/jev-review.ts +0 -374
- package/src/hooks/semantic/jev-stats.ts +0 -289
- package/src/hooks/semantic/jev-throttle.ts +0 -421
- package/src/hooks/semantic/pack-policies.ts +0 -251
- package/src/hooks/semantic/policies.ts +0 -596
- package/src/hooks/semantic/precondition-names.ts +0 -60
- package/src/hooks/semantic/preconditions.ts +0 -58
- package/src/hooks/semantic/redact.ts +0 -2910
- package/src/hooks/semantic/types.ts +0 -145
- package/src/hooks/semver-precedence.ts +0 -128
- /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → PgeWCHmyVbjRznv2VO7KF}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → PgeWCHmyVbjRznv2VO7KF}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → PgeWCHmyVbjRznv2VO7KF}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
# @failproofai/sdk
|
|
2
|
+
|
|
3
|
+
Telemetry for TypeScript and JavaScript AI agents. Emit events, spool them to
|
|
4
|
+
disk, let the daemon ship them.
|
|
5
|
+
|
|
6
|
+
Zero runtime dependencies. Node ≥ 20.9, ESM and CommonJS.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install @failproofai/sdk
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import * as failproofai from "@failproofai/sdk";
|
|
14
|
+
|
|
15
|
+
await failproofai.agent("planner", { goal: question }, async () => {
|
|
16
|
+
const hits = await failproofai.toolCall("web_search", { input: { q } }, () => search(q));
|
|
17
|
+
failproofai.event.modelResponse({ model, inputTokens: 1_200, outputTokens: 340 });
|
|
18
|
+
});
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
That is the whole setup. Events land in `~/.failproofai/custom-agents/events/`,
|
|
22
|
+
and `failproofaid` — the daemon the `failproofai` CLI installs — picks them up.
|
|
23
|
+
Nothing here opens a socket, and nothing blocks your agent loop on the network.
|
|
24
|
+
|
|
25
|
+
This is the TypeScript counterpart to the Python
|
|
26
|
+
[`failproofai-sdk`](https://pypi.org/project/failproofai-sdk/). Same 15 events,
|
|
27
|
+
same wire format, same spool directory: a fleet running both writes into one
|
|
28
|
+
pipe, and the dashboard cannot tell which language wrote what.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Three surfaces
|
|
33
|
+
|
|
34
|
+
### 1. Scopes
|
|
35
|
+
|
|
36
|
+
`session()`, `agent()` and `toolCall()` bind run identity and — for the latter
|
|
37
|
+
two — bracket the work with its own events.
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
await failproofai.session({ sessionId: requestId }, async () => {
|
|
41
|
+
await failproofai.agent("supervisor", { goal: "answer the question" }, async () => {
|
|
42
|
+
await failproofai.agent("researcher", async () => {
|
|
43
|
+
// parentId is "supervisor", sessionId is requestId — nothing was passed.
|
|
44
|
+
const docs = await failproofai.toolCall("search", { input: { q } }, () => search(q));
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Identity rides on `AsyncLocalStorage`, so it follows `await`, `.then()`, timers
|
|
51
|
+
and callbacks created inside the scope — and two concurrent runs in one process
|
|
52
|
+
never mix.
|
|
53
|
+
|
|
54
|
+
| what happened | events | `outcome` |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| the block returned | `agent_end` | `"success"` (or your `outcome`) |
|
|
57
|
+
| the block threw | `error`, then `agent_end` | `"failed"` |
|
|
58
|
+
| an `AbortError` | `agent_end` only | `"cancelled"` |
|
|
59
|
+
|
|
60
|
+
The error is always re-thrown. A tool failure is recorded on the leaf
|
|
61
|
+
(`tool_result` with an `error`) and emits **no** run-level `error`: one the
|
|
62
|
+
agent loop catches is not a run failure, and one that propagates is reported
|
|
63
|
+
exactly once, by the enclosing `agent()`.
|
|
64
|
+
|
|
65
|
+
A synchronous body stays synchronous — `agent("x", () => 1)` returns `1`, not a
|
|
66
|
+
promise — because a constructor or an `EventEmitter` listener cannot await one.
|
|
67
|
+
|
|
68
|
+
**`using`, when a callback will not fit.** A scope opened in a constructor and
|
|
69
|
+
closed in a teardown, or one that straddles existing control flow:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
{
|
|
73
|
+
using span = failproofai.agent.open("planner", { goal });
|
|
74
|
+
using call = failproofai.toolCall.open("search", { input: { q } });
|
|
75
|
+
call.call.output = await search(q);
|
|
76
|
+
} // tool_result, then agent_end
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Prefer the callback form. It runs inside `AsyncLocalStorage.run()`, so there is
|
|
80
|
+
nothing to unwind and the whole class of "opened here, closed over there" bugs
|
|
81
|
+
is unreachable.
|
|
82
|
+
|
|
83
|
+
### 2. Adapters
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
await failproofai.instrument(); // whatever it can find
|
|
87
|
+
await failproofai.instrument("langchain"); // exactly one
|
|
88
|
+
failproofai.uninstrument(); // put everything back
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
| framework | supported | how it attaches |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| **LangChain.js / LangGraph.js** | `@langchain/core` 0.3 – 1.x, LangGraph.js 0.4 – 1.x | `CallbackManager.configure`, so every `invoke`/`stream`/`batch` is covered without passing `callbacks:` anywhere — or pass `langchainHandler()` yourself and patch nothing. |
|
|
94
|
+
| **Vercel AI SDK** | `ai` 4 – 7 | `telemetry()` at the call site, or `instrument("ai")` for the whole process on `ai` 7 (on 4–6 that is opt-in) — see below. |
|
|
95
|
+
| **Mastra** | `@mastra/core` 0.20 – 1.x | `Agent.generate`/`.stream`, the agent's model and tool resolution, and the workflow run/step engine. Tools built before `instrument()` are covered. |
|
|
96
|
+
| **LlamaIndex.TS** | `llamaindex` 0.11.4 – 0.x | `Settings.callbackManager` (subscribed) plus `AgentWorkflow.runStream`, for workflow runs and their steps. |
|
|
97
|
+
|
|
98
|
+
**Every range in that table is tested, not declared.** `integration/` installs
|
|
99
|
+
real framework releases at both ends of each range, extracts the packed tarball
|
|
100
|
+
into each project, and runs one agent as an ES module and again as CommonJS on
|
|
101
|
+
every CI run — the same bar the Python SDK's framework job holds.
|
|
102
|
+
|
|
103
|
+
**The mapping is the Python SDK's**, so a TypeScript agent and a Python one on
|
|
104
|
+
the same framework draw the same tree. A construct is an **agent** if and only
|
|
105
|
+
if it owns an LLM decision loop: a graph or chain run, an AI SDK
|
|
106
|
+
`generateText`/`streamText` call, a Mastra agent, a LlamaIndex agent run.
|
|
107
|
+
Machinery around it — a LangGraph node, a Mastra or LlamaIndex workflow step —
|
|
108
|
+
is a **hook** (`hook_triggered`/`hook_completed` with a `trigger_event`), never
|
|
109
|
+
a nested agent, so `agent_id` stays a small set of real names. Model calls are
|
|
110
|
+
`model_request`/`model_response` pairs with token counts; tool calls are
|
|
111
|
+
`tool_use`/`tool_result` carrying the model's own tool call id. A failure is
|
|
112
|
+
recorded once, on the event it happened in — not once per layer it unwound
|
|
113
|
+
through.
|
|
114
|
+
|
|
115
|
+
**ES modules and CommonJS both work.** Most of these frameworks ship two builds,
|
|
116
|
+
and Node loads them as two unrelated copies: patching one does nothing to the
|
|
117
|
+
other. The adapters patch the copy your application loads, plus the CommonJS
|
|
118
|
+
copy if something has already `require`d it, and never load a second copy
|
|
119
|
+
nobody uses. What no adapter can reach is a framework **bundled into your own
|
|
120
|
+
output** (esbuild, webpack): the copy in `node_modules` is not the one running.
|
|
121
|
+
On Next.js, `withFailproofai()` fixes that (see below); elsewhere use the
|
|
122
|
+
call-site helpers — `langchainHandler()`, `telemetry()`, `wrapTool()`.
|
|
123
|
+
|
|
124
|
+
**Naming the agent and owning the session id.** `agent_id` comes from the
|
|
125
|
+
graph's name (`createReactAgent({ name })`, `.withConfig({ runName })`), the AI
|
|
126
|
+
SDK's `functionId`, the Mastra agent's `name`, or LlamaIndex's `agent({ name })`.
|
|
127
|
+
An adapter mints a session id when none is bound; to use your own request or job
|
|
128
|
+
id, bind it around the call —
|
|
129
|
+
`await failproofai.session({ sessionId: requestId }, () => graph.invoke(input))`.
|
|
130
|
+
An `agent()` wrapper of the same name as the framework agent becomes that agent
|
|
131
|
+
rather than nesting a copy of it; a differently named one is its parent.
|
|
132
|
+
|
|
133
|
+
Everything an adapter records is namespaced `fw_*`, bounded per field and per
|
|
134
|
+
event, and tagged with `framework` / `framework_version`. An adapter that fails
|
|
135
|
+
is logged and skipped; the others still install, because a broken LlamaIndex
|
|
136
|
+
should not cost you LangGraph. `FAILPROOFAI_SDK_STRICT=1` turns every swallowed
|
|
137
|
+
failure into a throw.
|
|
138
|
+
|
|
139
|
+
**The Vercel AI SDK** exports plain functions from an ES module, and an ES
|
|
140
|
+
module namespace is immutable by specification — there is nowhere to stand. So
|
|
141
|
+
it uses the extension points the SDK itself documents:
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
import { telemetry } from "@failproofai/sdk/ai";
|
|
145
|
+
|
|
146
|
+
const { text } = await generateText({
|
|
147
|
+
model,
|
|
148
|
+
prompt,
|
|
149
|
+
experimental_telemetry: telemetry({ functionId: "answer-question" }),
|
|
150
|
+
// on ai 7, `telemetry: telemetry({ … })` — the same object, the new name
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
That is the complete integration: an agent span named by `functionId`, a
|
|
155
|
+
model request/response pair per step with token counts, and every tool call.
|
|
156
|
+
One call site works on every major: `ai` 4–6 read the tracer it carries, `ai` 7
|
|
157
|
+
reads the telemetry integration it carries.
|
|
158
|
+
|
|
159
|
+
`instrument("ai")` does the same for the whole process **on `ai` 7**: every
|
|
160
|
+
call, through the AI SDK's global telemetry-integration list, which is additive
|
|
161
|
+
and takes nothing from anybody else's.
|
|
162
|
+
|
|
163
|
+
**On `ai` 4–6, `instrument("ai")` records nothing by itself, and logs one
|
|
164
|
+
warning saying so.** The only process-wide hook those majors have is the global
|
|
165
|
+
OpenTelemetry tracer provider — a single slot that OpenTelemetry refuses to hand
|
|
166
|
+
over once taken. Registering ours would silently refuse your own
|
|
167
|
+
`NodeSDK.start()` later in startup and send your http/database spans to a tracer
|
|
168
|
+
that exports nothing. Use `telemetry()` at the call site (above) or `wrapModel`
|
|
169
|
+
(below) there. If the process runs no OpenTelemetry of its own, you can opt in:
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
await instrument("ai", { registerGlobalTracer: true });
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
— it then records every call that passes `experimental_telemetry: { isEnabled:
|
|
176
|
+
true }` (the AI SDK only consults the global tracer for those), and only takes
|
|
177
|
+
the slot if it is still empty. `registerGlobalTracer: false` keeps the default
|
|
178
|
+
and silences the warning.
|
|
179
|
+
|
|
180
|
+
If you would rather wrap the model once, `wrapModel` sees model calls only,
|
|
181
|
+
because tool calls happen above the model layer. A wrapped model called with
|
|
182
|
+
nothing around it is recorded as its own run, named after the model. A streamed
|
|
183
|
+
call closes however the stream stops: `stop_reason: "cancelled"` when the
|
|
184
|
+
consumer cancels it, `"error"` with the error when it fails part-way:
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
import { wrapModel } from "@failproofai/sdk/ai";
|
|
188
|
+
const model = await wrapModel(openai("gpt-4o"));
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Using both is fine: the middleware notices the call is already being recorded
|
|
192
|
+
and defers, so each call is recorded once.
|
|
193
|
+
|
|
194
|
+
**LangChain without patching**, for hosts where patching is not wanted — the
|
|
195
|
+
handler works with or without `instrument()`, and never double-records:
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
import { langchainHandler } from "@failproofai/sdk/langchain";
|
|
199
|
+
await graph.invoke(input, { callbacks: [langchainHandler()] });
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
`instrument("langchain")` also takes `sessionId`, `captureContent`,
|
|
203
|
+
`includeChains`, `graphCallbacks` and `captureLimit`, as the Python adapter
|
|
204
|
+
does; a per-call `metadata: { failproofai_sdk_session_id }` picks the session
|
|
205
|
+
for one invocation.
|
|
206
|
+
|
|
207
|
+
**Mastra** tool calls made outside any agent can be wrapped by hand:
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
import { wrapTool } from "@failproofai/sdk/mastra";
|
|
211
|
+
const lookup = wrapTool(createTool({ id: "lookup", /* … */ }));
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
#### What each adapter records, framework by framework
|
|
215
|
+
|
|
216
|
+
- **LangChain / LangGraph** — also `createAgent` from the v1 `langchain`
|
|
217
|
+
package (its middleware hooks are steps), plain LCEL chains, retrievers
|
|
218
|
+
(`tool_use`/`tool_result` summarised as `{ n, sources }`), `.batch()` (one
|
|
219
|
+
session per input), `.stream()`/`.streamEvents()`, structured output, and
|
|
220
|
+
`interrupt()`/`Command` resumes (`human_wait` + `agent_pause`, then
|
|
221
|
+
`agent_resume` + `human_input`, across processes too). A provider package
|
|
222
|
+
that pins its own nested `@langchain/core` is instrumented as well.
|
|
223
|
+
- **Vercel AI SDK** — `generateText`/`streamText`/`generateObject`/
|
|
224
|
+
`streamObject`, the agent classes (`ToolLoopAgent`/`Agent`; named by
|
|
225
|
+
`functionId`, since the SDK does not pass the agent's `id` through), parallel,
|
|
226
|
+
client-side and approval-gated tools. An `embed` inside an agent is that
|
|
227
|
+
agent's model call; a bare one is its own run. A stream that stops early ends
|
|
228
|
+
`cancelled`. On `ai` 7, pass `abortSignal: request.signal` in a route handler
|
|
229
|
+
so a client that disconnects closes the run. A tool approval produces two
|
|
230
|
+
runs — wrap them in one `failproofai.session()` to keep one session.
|
|
231
|
+
- **Mastra** — agents on a `Mastra` instance, agent networks (`.network()` is
|
|
232
|
+
one agent, with delegates nested under it), agent-as-tool, workflows
|
|
233
|
+
(branch, parallel, loops, nested, agent steps; steps are hooks), MCP tools,
|
|
234
|
+
structured output (a separate structuring model appears as a nested agent),
|
|
235
|
+
processors. A memory **thread** is the session, and a suspended workflow's run
|
|
236
|
+
id keeps its session through `resume()`, with the human-in-the-loop events. A
|
|
237
|
+
run blocked by a processor tripwire ends `rejected`.
|
|
238
|
+
- **LlamaIndex.TS** — `agent()`/`multiAgent()` workflows, `createWorkflow()`
|
|
239
|
+
workflows (llamaindex 0.12+), chat engines, query engines and retrievers
|
|
240
|
+
(named after the retriever class), the legacy `LLMAgent`, bare LLM calls.
|
|
241
|
+
Concurrent requests on one shared engine or agent stay in separate sessions.
|
|
242
|
+
LlamaIndex.TS has no embedding events, so `embeddings: true` records nothing.
|
|
243
|
+
|
|
244
|
+
#### Token counts on streamed calls
|
|
245
|
+
|
|
246
|
+
OpenAI-compatible APIs only report usage on a **stream** when the client asks
|
|
247
|
+
for it, and two frameworks don't ask by default — so their streamed model calls
|
|
248
|
+
arrive with no token counts, and there is nothing to record:
|
|
249
|
+
|
|
250
|
+
```ts
|
|
251
|
+
// LlamaIndex
|
|
252
|
+
new OpenAI({ model, additionalChatOptions: { stream_options: { include_usage: true } } });
|
|
253
|
+
// Mastra: build the model with usage on, e.g. createOpenAICompatible({ …, includeUsage: true })
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
LangChain and the Vercel AI SDK already request it.
|
|
257
|
+
|
|
258
|
+
#### Next.js
|
|
259
|
+
|
|
260
|
+
`next build` bundles your server's dependencies by default, and a framework
|
|
261
|
+
bundled into the build is a copy `instrument()` cannot reach. Wrap the config
|
|
262
|
+
once, and call `instrument()` from Next's startup hook:
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
// next.config.ts
|
|
266
|
+
import { withFailproofai } from "@failproofai/sdk/next";
|
|
267
|
+
export default withFailproofai({ /* your config */ });
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
```ts
|
|
271
|
+
// instrumentation.ts
|
|
272
|
+
export async function register() {
|
|
273
|
+
if (process.env.NEXT_RUNTIME !== "nodejs") return;
|
|
274
|
+
const failproofai = await import("@failproofai/sdk");
|
|
275
|
+
await failproofai.instrument();
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
`withFailproofai` adds LangChain, Mastra, LlamaIndex and the SDK itself to
|
|
280
|
+
`serverExternalPackages`, keeping your own list. Without it, `instrument()`
|
|
281
|
+
warns once per framework it cannot reach — it never fails silently. If you list
|
|
282
|
+
the packages by hand, set `FAILPROOFAI_NEXT_EXTERNALS=1` to silence the warning.
|
|
283
|
+
The Vercel AI SDK and every call-site helper work either way. An **Edge**
|
|
284
|
+
route gets a no-op build: importing the SDK is safe, and nothing is recorded
|
|
285
|
+
there.
|
|
286
|
+
|
|
287
|
+
#### Runtimes
|
|
288
|
+
|
|
289
|
+
Node ≥ 20.9, Bun and Deno (including `npm:` imports) — every framework, as an ES
|
|
290
|
+
module and as CommonJS, is tested on each and must record the same trace Node
|
|
291
|
+
does. The SDK runs beside the `failproofaid` daemon, which ships what it writes.
|
|
292
|
+
|
|
293
|
+
### 3. `event.*`
|
|
294
|
+
|
|
295
|
+
The 15 event methods, for anything the adapters do not cover:
|
|
296
|
+
|
|
297
|
+
`toolUse` · `toolResult` · `modelRequest` · `modelResponse` · `agentStart` ·
|
|
298
|
+
`agentEnd` · `agentPause` · `agentResume` · `hookTriggered` · `hookCompleted` ·
|
|
299
|
+
`error` · `humanWait` · `humanInput` · `humanPause` · `humanInterrupt`
|
|
300
|
+
|
|
301
|
+
```ts
|
|
302
|
+
failproofai.event.humanWait({ inputId: "approval-1", prompt: "Ship it?" });
|
|
303
|
+
// …later, from anywhere in the same session:
|
|
304
|
+
failproofai.event.humanInput({ inputId: "approval-1", response: "yes" });
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
`sessionId` and `agentId` are optional on every one — omitted, they resolve from
|
|
308
|
+
the enclosing scope. Nothing bound and nothing passed is an **error**, never a
|
|
309
|
+
silent drop: ingest skips an event with no session and answers `200 OK`, so the
|
|
310
|
+
run would simply never appear.
|
|
311
|
+
|
|
312
|
+
The paired events (`toolResult`, `agentResume`, `hookCompleted`, `humanInput`)
|
|
313
|
+
compute `duration_ms` from the matching start. You cannot pass it yourself — a
|
|
314
|
+
reported duration is unfalsifiable.
|
|
315
|
+
|
|
316
|
+
Any key you add that the method does not name becomes a custom payload field.
|
|
317
|
+
Namespace anything framework-specific `fw_*`; a name that collides with a
|
|
318
|
+
declared field is refused rather than silently overwriting a promoted column.
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## Your own agent — no framework
|
|
323
|
+
|
|
324
|
+
For an agent loop you wrote yourself, or a framework without an adapter. There is
|
|
325
|
+
nothing to instrument: you emit the events, with the same API the adapters use
|
|
326
|
+
underneath — so the trace is the same shape and the same quality.
|
|
327
|
+
|
|
328
|
+
You do not need to know anything about how the agent is organised beyond this:
|
|
329
|
+
**every hand-built agent already has three places** — whatever its functions are
|
|
330
|
+
called — and those three are the whole integration.
|
|
331
|
+
|
|
332
|
+
| where | what to add | emits |
|
|
333
|
+
|---|---|---|
|
|
334
|
+
| where **one run** starts and ends | `failproofai.agent("name", { goal }, async () => …)` | `agent_start` / `agent_end` |
|
|
335
|
+
| the **one function that calls the model** | `event.modelRequest` before, `event.modelResponse` after — both halves, even on failure | one pair per model turn |
|
|
336
|
+
| the **one function that runs tools** | `failproofai.toolCall(name, { toolCallId, input }, () => run())` | `tool_use` / `tool_result` |
|
|
337
|
+
|
|
338
|
+
```ts
|
|
339
|
+
// 1. the run
|
|
340
|
+
await failproofai.agent("inventory", { goal: question }, async () => {
|
|
341
|
+
for (;;) {
|
|
342
|
+
const message = await callModel(messages); // 2.
|
|
343
|
+
if (!message.tool_calls?.length) return message.content;
|
|
344
|
+
for (const call of message.tool_calls) await dispatch(call); // 3.
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
// 2. the model call — pair on requestId, time it yourself, close it on failure
|
|
349
|
+
async function callModel(messages) {
|
|
350
|
+
const requestId = randomUUID();
|
|
351
|
+
const started = Date.now();
|
|
352
|
+
failproofai.event.modelRequest({ model: MODEL, requestId,
|
|
353
|
+
messages: messages.map((m) => ({ role: m.role, content: m.content })) });
|
|
354
|
+
let reply;
|
|
355
|
+
try {
|
|
356
|
+
reply = await client.chat.completions.create({ model: MODEL, messages, tools });
|
|
357
|
+
} catch (error) {
|
|
358
|
+
failproofai.event.modelResponse({ model: MODEL, requestId, stopReason: "error",
|
|
359
|
+
error: String(error), duration_ms: Date.now() - started });
|
|
360
|
+
throw error;
|
|
361
|
+
}
|
|
362
|
+
const { message, finish_reason } = reply.choices[0];
|
|
363
|
+
failproofai.event.modelResponse({
|
|
364
|
+
model: reply.model, requestId, role: message.role, content: message.content ?? "",
|
|
365
|
+
stopReason: finish_reason, duration_ms: Date.now() - started,
|
|
366
|
+
inputTokens: reply.usage?.prompt_tokens, outputTokens: reply.usage?.completion_tokens,
|
|
367
|
+
fw_tool_calls: (message.tool_calls ?? []).map((c) =>
|
|
368
|
+
({ toolCallId: c.id, toolName: c.function.name, input: c.function.arguments })),
|
|
369
|
+
});
|
|
370
|
+
return message;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// 3. the tool dispatcher — reuse the model's own tool-call id
|
|
374
|
+
async function dispatch(call) {
|
|
375
|
+
const input = JSON.parse(call.function.arguments);
|
|
376
|
+
return failproofai.toolCall(call.function.name, { toolCallId: call.id, input },
|
|
377
|
+
() => runTool(call.function.name, input));
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
Identity is ambient: everything inside `agent()` — the model wrapper, the
|
|
382
|
+
dispatcher, any function they call — lands on that run's session without taking an
|
|
383
|
+
id. Nothing else in the program changes, including whatever the agent already
|
|
384
|
+
writes to its own database.
|
|
385
|
+
|
|
386
|
+
- **A service or a worker:** pass your own request or job id as `sessionId`
|
|
387
|
+
(`agent("assistant", { sessionId: requestId }, …)`), so a session on the
|
|
388
|
+
dashboard and the record in your own logs or database are the same string.
|
|
389
|
+
- **Sub-agents:** nest `agent()` calls. The inner one joins the session and takes
|
|
390
|
+
the outer as its `parent_id`.
|
|
391
|
+
- **Emit the pairs.** A `modelRequest` with no `modelResponse` is a span the
|
|
392
|
+
dashboard shows as running forever — hence the `catch` above.
|
|
393
|
+
|
|
394
|
+
[`examples/research-agent.ts`](./examples/research-agent.ts) is the complete,
|
|
395
|
+
runnable version: a real OpenAI tool loop instrumented exactly like this. The
|
|
396
|
+
integration suite runs that file on every CI run, as an ES module and as
|
|
397
|
+
CommonJS, against the real `openai` client — the example is proven, not just
|
|
398
|
+
documented.
|
|
399
|
+
|
|
400
|
+
## Configuration
|
|
401
|
+
|
|
402
|
+
```ts
|
|
403
|
+
failproofai.configure({
|
|
404
|
+
environment: "production", // or AGENTEYE_ENVIRONMENT; defaults to "dev"
|
|
405
|
+
flushInterval: 0.5, // seconds
|
|
406
|
+
baseDir: undefined, // the ONLY way to move the spool
|
|
407
|
+
});
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
Call it once at startup, before any `event.*` call. Nothing is applied unless
|
|
411
|
+
all of it validates, so a rejected call leaves the SDK exactly as it was.
|
|
412
|
+
|
|
413
|
+
| variable | effect |
|
|
414
|
+
|---|---|
|
|
415
|
+
| `AGENTEYE_ENVIRONMENT` | the `environment` label on every event |
|
|
416
|
+
| `FAILPROOFAI_HOME` | moves the umbrella; the spool is always `<home>/custom-agents` |
|
|
417
|
+
| `FAILPROOFAI_SDK_LOG_LEVEL` | `debug` \| `info` \| `warn` (default) \| `error` \| `silent` |
|
|
418
|
+
| `FAILPROOFAI_SDK_STRICT` | `1` makes a swallowed adapter failure throw |
|
|
419
|
+
| `FAILPROOFAI_SDK_STRICT_INTEGRATIONS` | `1` makes a framework-version warning throw |
|
|
420
|
+
|
|
421
|
+
No environment variable can move the spool off the umbrella. A redirect with no
|
|
422
|
+
confirmation and no error means batches land where nothing reads them, and an
|
|
423
|
+
unread spool is indistinguishable from an idle one.
|
|
424
|
+
|
|
425
|
+
Route the SDK's own log lines into your logger with
|
|
426
|
+
`failproofai.setLogger({ debug, info, warn, error })`.
|
|
427
|
+
|
|
428
|
+
## Shutdown
|
|
429
|
+
|
|
430
|
+
Buffered events are flushed on `process.on("exit")` automatically.
|
|
431
|
+
|
|
432
|
+
A process killed by a signal never reaches that — Node's default for `SIGTERM`
|
|
433
|
+
is to terminate without running exit handlers — so a containerised agent loses
|
|
434
|
+
whatever the last interval had not yet written. **This package will not install
|
|
435
|
+
a signal handler for you**: registering one changes the process's behaviour (a
|
|
436
|
+
listener suppresses Node's default termination), and a library that silently
|
|
437
|
+
stopped Ctrl-C from working would be worse than the lost events. Two lines, at
|
|
438
|
+
your own startup:
|
|
439
|
+
|
|
440
|
+
```ts
|
|
441
|
+
for (const [signal, code] of [["SIGINT", 130], ["SIGTERM", 143]] as const) {
|
|
442
|
+
process.once(signal, () => {
|
|
443
|
+
failproofai.flushSync();
|
|
444
|
+
process.exit(code);
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
On the way out, whatever is still open is closed rather than stranded: an
|
|
450
|
+
interrupted tool gets its `tool_result` with a `ProcessExit` error, and each open
|
|
451
|
+
agent — hand-written or opened by an adapter — gets an `error` and `agent_end`
|
|
452
|
+
with `outcome: "failed"`, innermost first. A deploy never leaves a run showing
|
|
453
|
+
as running forever. A `flushSync()` while the process carries on closes nothing.
|
|
454
|
+
|
|
455
|
+
A short-lived script or a serverless handler should `await failproofai.flush()`
|
|
456
|
+
before returning: the interval alone does not guarantee delivery, and a function
|
|
457
|
+
that returns right after its last event routinely exits before the next cycle.
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
## Evaluations
|
|
462
|
+
|
|
463
|
+
```ts
|
|
464
|
+
import { Evaluator, EvalResult, Score } from "@failproofai/sdk/evaluator";
|
|
465
|
+
|
|
466
|
+
export const app = new Evaluator({ name: "my-evals", version: "1" });
|
|
467
|
+
|
|
468
|
+
app.eval("tool_success_rate", { version: "1" }, (session) => {
|
|
469
|
+
const results = session.eventsOfType("tool_result");
|
|
470
|
+
const failures = results.filter((event) => event.payload.error != null).length;
|
|
471
|
+
return new EvalResult({
|
|
472
|
+
score: new Score(results.length === 0 ? 1 : 1 - failures / results.length),
|
|
473
|
+
reasoning: `${failures} of ${results.length} tool calls failed`,
|
|
474
|
+
});
|
|
475
|
+
});
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
```bash
|
|
479
|
+
FAILPROOFAI_EVALUATOR_URL=https://… \
|
|
480
|
+
FAILPROOFAI_EVALUATOR_TOKEN=… \
|
|
481
|
+
npx failproofai-evaluator ./my-evals.js
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
The worker claims assignments, runs each definition's condition, submits a plan,
|
|
485
|
+
runs the planned evaluations under a heartbeat, and submits each result.
|
|
486
|
+
|
|
487
|
+
**An evaluation must yield.** A synchronous function that never returns blocks
|
|
488
|
+
the one thread there is, and no timeout can fire while it does. Write `async`
|
|
489
|
+
evaluations, or let the sandbox run them.
|
|
490
|
+
|
|
491
|
+
### The sandbox
|
|
492
|
+
|
|
493
|
+
Server-authored ("managed") evaluations arrive as source. This package runs them
|
|
494
|
+
through a restricted expression language that is **parsed and interpreted** —
|
|
495
|
+
never `eval`'d, never handed to `node:vm`.
|
|
496
|
+
|
|
497
|
+
That is not belt-and-braces. JavaScript has a reachable path from any value to
|
|
498
|
+
arbitrary code:
|
|
499
|
+
|
|
500
|
+
```js
|
|
501
|
+
(() => {}).constructor("return process")()
|
|
502
|
+
x["constructor"]["constructor"]("…")()
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
A static allowlist cannot close the second one, because the key is computed at
|
|
506
|
+
runtime and no source check can see it. `node:vm` does not close it either — a
|
|
507
|
+
vm context has its own `Function`. Interpreting removes the question: every
|
|
508
|
+
property read goes through one function that checks the actual key at the moment
|
|
509
|
+
of the read, and the interpreter never constructs a function.
|
|
510
|
+
|
|
511
|
+
A `worker_threads` sandbox sits around that with V8 heap limits, a wall-clock
|
|
512
|
+
`terminate()`, a bounded result and a cap on concurrent sandboxes. That is the
|
|
513
|
+
RESOURCE bound — it stops a permitted expression from eating the worker even
|
|
514
|
+
though every operation in it is individually legal. If the sandbox cannot be
|
|
515
|
+
established, managed source is **refused**, never run unbounded.
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
## What it will not do to your process
|
|
520
|
+
|
|
521
|
+
* **It will not block your agent loop.** Events go into an in-memory queue; a
|
|
522
|
+
timer writes them. The timer is `unref`'d, so importing this package never
|
|
523
|
+
stops a script exiting.
|
|
524
|
+
* **It will not grow without bound.** The queue is capped by count *and* by
|
|
525
|
+
measured bytes. Past either, the oldest events are discarded and a warning
|
|
526
|
+
says so — a telemetry outage must not become an OOM kill.
|
|
527
|
+
* **It will not take the process down.** One unencodable event is dropped
|
|
528
|
+
alone, not the batch around it. A throwing getter, a circular reference, a
|
|
529
|
+
`BigInt`, a lone surrogate: each is handled rather than propagated.
|
|
530
|
+
* **It will not leave a half-written batch.** Content is `fsync`ed before an
|
|
531
|
+
atomic rename, the directory is `fsync`ed after, and a failed write cleans up
|
|
532
|
+
its temporary file.
|
|
533
|
+
* **It will not leave transcripts world-readable.** Batches are `0600` inside a
|
|
534
|
+
`0700` directory. They carry goals, prompts, tool arguments and tool output.
|
|
535
|
+
* **It will not ship credentials.** API keys, tokens, JWTs, bearer headers and
|
|
536
|
+
secret-shaped assignments are redacted before the bytes reach disk. The daemon
|
|
537
|
+
redacts again before upload.
|
|
538
|
+
|
|
539
|
+
## Zero dependencies, on purpose
|
|
540
|
+
|
|
541
|
+
This package installs into other people's agent processes. Every dependency it
|
|
542
|
+
declared would be a version constraint they inherit, in the process whose
|
|
543
|
+
reliability it exists to improve. It imports nothing outside Node's standard
|
|
544
|
+
library; the framework packages are peer dependencies, all optional, imported
|
|
545
|
+
dynamically and only when you ask for them.
|
|
546
|
+
|
|
547
|
+
A test fails if a runtime dependency is ever added, and the build refuses to
|
|
548
|
+
produce a tarball that declares one.
|
|
549
|
+
|
|
550
|
+
## License
|
|
551
|
+
|
|
552
|
+
MIT. See [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import js from "@eslint/js";
|
|
2
|
+
import tseslint from "typescript-eslint";
|
|
3
|
+
|
|
4
|
+
export default tseslint.config(
|
|
5
|
+
// examples/ imports packages this project does not install (openai); each is
|
|
6
|
+
// typechecked as a real consumer by its integration fixture (vanilla.test.ts).
|
|
7
|
+
{ ignores: ["dist/**", "node_modules/**", "eslint.config.mjs", "integration/fixtures/**", "examples/**"] },
|
|
8
|
+
js.configs.recommended,
|
|
9
|
+
...tseslint.configs.recommendedTypeChecked,
|
|
10
|
+
{
|
|
11
|
+
languageOptions: {
|
|
12
|
+
parserOptions: {
|
|
13
|
+
projectService: { allowDefaultProject: ["scripts/*.mjs"] },
|
|
14
|
+
tsconfigRootDir: import.meta.dirname,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
rules: {
|
|
18
|
+
// This package talks to four frameworks and one wire protocol, all of
|
|
19
|
+
// which hand it `unknown`. Narrowing every one of those at the boundary
|
|
20
|
+
// is exactly what the adapters and the `fromWire` readers already do by
|
|
21
|
+
// hand; the rules below would flag that work rather than the mistakes.
|
|
22
|
+
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
23
|
+
"@typescript-eslint/no-unsafe-member-access": "off",
|
|
24
|
+
"@typescript-eslint/no-unsafe-call": "off",
|
|
25
|
+
"@typescript-eslint/no-unsafe-argument": "off",
|
|
26
|
+
"@typescript-eslint/no-unsafe-return": "off",
|
|
27
|
+
"@typescript-eslint/restrict-template-expressions": [
|
|
28
|
+
"error",
|
|
29
|
+
{ allowNumber: true, allowBoolean: true },
|
|
30
|
+
],
|
|
31
|
+
"@typescript-eslint/no-explicit-any": "error",
|
|
32
|
+
"@typescript-eslint/no-non-null-assertion": "off",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
files: ["test/**/*.ts", "integration/*.ts", "scripts/**/*.mjs"],
|
|
37
|
+
rules: {
|
|
38
|
+
// A test's whole job is to feed the wrong shape in and watch what
|
|
39
|
+
// happens, so the casts it needs are the point rather than a smell.
|
|
40
|
+
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
41
|
+
"@typescript-eslint/no-unsafe-member-access": "off",
|
|
42
|
+
"@typescript-eslint/no-confusing-void-expression": "off",
|
|
43
|
+
"@typescript-eslint/require-await": "off",
|
|
44
|
+
// `await agent("x", () => 1)` is exactly what a caller writes, and the
|
|
45
|
+
// scopes deliberately stay synchronous for a synchronous body — so the
|
|
46
|
+
// value awaited here is sometimes a promise and sometimes not, which is
|
|
47
|
+
// the behaviour under test rather than a mistake.
|
|
48
|
+
"@typescript-eslint/await-thenable": "off",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
files: ["scripts/**/*.mjs"],
|
|
53
|
+
...tseslint.configs.disableTypeChecked,
|
|
54
|
+
languageOptions: {
|
|
55
|
+
// Build scripts run under plain Node, outside the typed project.
|
|
56
|
+
globals: { process: "readonly", console: "readonly", URL: "readonly" },
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
);
|