failproofai 1.0.7-beta.1 → 1.0.7-beta.2
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 +3 -3
- 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.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.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.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.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.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.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.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.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.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 +7 -7
- package/.next/standalone/.next/server/app/settings/page.js +2 -2
- 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/[root-of-the-server]__0l3yhx4._.js +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
- 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/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_18qtd42._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__056wjo4._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0yxwl6j._.js → [root-of-the-server]__0l44ual._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n0xg95._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rwtwpm._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s_yomn._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11mayhe._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pprgri._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1q4p5b8._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_042cgl1._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_214wgrp._.js → _1mel6y1._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{_0bn2oo8._.js → _1v-jvrv._.js} +1 -1
- 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_actions_get-scheduled-audit_ts_0ei9sni._.js +1 -1
- 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 +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_15t8kqj._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1fm2w5z._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1j0zy3v._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.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 +22 -22
- package/.next/standalone/.next/static/chunks/043j99m8ykg__.css +2 -0
- package/.next/standalone/.next/static/chunks/0fqd7m_u81mi5.js +1 -0
- package/.next/standalone/.next/static/chunks/129ag2bw93bdh.js +1 -0
- package/.next/standalone/.next/static/chunks/{29fql3nbnfc9q.js → 1qd741hzlmjbo.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0vmd180qfntfb.js → 2_pltstd8-xgs.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1u5zsejmgrir_.js → 2c8j9l6j_b1ci.js} +1 -1
- package/.next/standalone/.next/static/chunks/3-k569wzcli8q.js +1 -0
- package/.next/standalone/.next/static/chunks/{258668t68du6b.js → 3brze37td_wnc.js} +1 -1
- package/.next/standalone/.next/static/chunks/3otmypm6j_xfo.js +6 -0
- package/.next/standalone/.next/static/chunks/{12tvm75t5ffui.js → 3ugmd_7dyn0id.js} +1 -1
- package/.next/standalone/.next/static/chunks/3yxro_r2_o9ad.js +69 -0
- package/.next/standalone/PROBE-FOLLOWUP.md +186 -0
- package/.next/standalone/app/actions/get-jev-config.ts +38 -23
- package/.next/standalone/app/actions/update-jev-config.ts +1 -1
- package/.next/standalone/app/settings/jev-panel.tsx +33 -29
- package/.next/standalone/package.json +10 -10
- 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 +119 -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 +281 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package.json +13 -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 +168 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package.json +13 -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 +463 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package.json +15 -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 +579 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package.json +15 -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 +6417 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package.json +15 -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/README.md +2 -2
- package/dist/cli.mjs +208 -27
- package/dist/worker.mjs +120 -14
- package/package.json +10 -10
- package/scripts/build-policy-pack.mjs +14 -0
- package/src/audit/features.ts +3 -2
- package/src/hooks/builtin-policies.ts +156 -5
- package/src/hooks/jev-cli.ts +57 -1
- package/src/hooks/manager.ts +1 -1
- package/src/hooks/pack-cli.ts +150 -18
- package/src/hooks/pack-store.ts +1 -1
- package/src/hooks/policy-catalog.ts +148 -9
- package/src/hooks/types.ts +1 -1
- package/.next/standalone/.next/static/chunks/0cd-_8-c-m1ea.js +0 -6
- package/.next/standalone/.next/static/chunks/0qrbdkv9qmvli.js +0 -69
- package/.next/standalone/.next/static/chunks/0uldbut9y2-e8.js +0 -1
- package/.next/standalone/.next/static/chunks/285spx855h_3r.css +0 -2
- 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/.next/static/{T8YAYM9h_64fKv705vug7 → gbEOjBgZAxF2UIUwZVHNu}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → gbEOjBgZAxF2UIUwZVHNu}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → gbEOjBgZAxF2UIUwZVHNu}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { existsSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { dirname, join, resolve } from "node:path";
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
|
+
|
|
8
|
+
import { describe, expect, it } from "vitest";
|
|
9
|
+
|
|
10
|
+
import { VERSION } from "../src/version.js";
|
|
11
|
+
import { runNode, indexUrl } from "./helpers.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* What a consumer actually gets.
|
|
15
|
+
*
|
|
16
|
+
* Everything else in this suite runs against `src/`. These cases run against
|
|
17
|
+
* `dist/` and `package.json`, because the failures they guard — a missing
|
|
18
|
+
* export condition, a CommonJS build Node reads as ESM, a dependency somebody
|
|
19
|
+
* added with `--save` — are invisible from inside the source tree and total
|
|
20
|
+
* from outside it.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/** An `exports` value: a target, or conditions that nest (`require.types`). */
|
|
24
|
+
type Conditions = string | { [condition: string]: Conditions };
|
|
25
|
+
|
|
26
|
+
/** Every `[condition path, target]` under one `exports` entry. */
|
|
27
|
+
const targetsOf = (value: Conditions, path: string[] = []): Array<[string[], string]> =>
|
|
28
|
+
typeof value === "string"
|
|
29
|
+
? [[path, value]]
|
|
30
|
+
: Object.entries(value).flatMap(([condition, next]) => targetsOf(next, [...path, condition]));
|
|
31
|
+
|
|
32
|
+
/** The single target the given condition path selects, e.g. `["require", "default"]`. */
|
|
33
|
+
const targetAt = (value: Conditions, ...path: string[]): string => {
|
|
34
|
+
const found = targetsOf(value).filter(([p]) => p.join(".") === path.join("."));
|
|
35
|
+
if (found.length !== 1) throw new Error(`no single target at ${path.join(".")}`);
|
|
36
|
+
return found[0]![1];
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
40
|
+
const manifest = JSON.parse(readFileSync(join(root, "package.json"), "utf8")) as {
|
|
41
|
+
name: string;
|
|
42
|
+
version: string;
|
|
43
|
+
type: string;
|
|
44
|
+
bin: Record<string, string>;
|
|
45
|
+
exports: Record<string, Conditions>;
|
|
46
|
+
main: string;
|
|
47
|
+
types: string;
|
|
48
|
+
typesVersions?: Record<string, Record<string, string[]>>;
|
|
49
|
+
dependencies?: Record<string, string>;
|
|
50
|
+
optionalDependencies?: Record<string, string>;
|
|
51
|
+
peerDependencies?: Record<string, string>;
|
|
52
|
+
peerDependenciesMeta?: Record<string, { optional?: boolean }>;
|
|
53
|
+
files: string[];
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
describe("zero runtime dependencies", () => {
|
|
57
|
+
it("declares none, because every one would be a constraint the host inherits", () => {
|
|
58
|
+
// This package installs into other people's agent processes. A dependency
|
|
59
|
+
// we declare is a version they have to resolve against, in the process
|
|
60
|
+
// whose reliability we are supposed to be improving.
|
|
61
|
+
expect(manifest.dependencies ?? {}).toEqual({});
|
|
62
|
+
expect(manifest.optionalDependencies ?? {}).toEqual({});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("marks every peer dependency optional, so npm installs none of them", () => {
|
|
66
|
+
for (const name of Object.keys(manifest.peerDependencies ?? {})) {
|
|
67
|
+
expect(manifest.peerDependenciesMeta?.[name]?.optional).toBe(true);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("imports nothing outside node: builtins", () => {
|
|
72
|
+
const offenders: string[] = [];
|
|
73
|
+
const walk = (dir: string): void => {
|
|
74
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
75
|
+
const path = join(dir, entry.name);
|
|
76
|
+
if (entry.isDirectory()) {
|
|
77
|
+
walk(path);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (!entry.name.endsWith(".ts")) continue;
|
|
81
|
+
const source = readFileSync(path, "utf8");
|
|
82
|
+
for (const match of source.matchAll(/^\s*import\s[^;]*?from\s+"([^"]+)"/gm)) {
|
|
83
|
+
const specifier = match[1]!;
|
|
84
|
+
const bare = !specifier.startsWith(".") && !specifier.startsWith("node:");
|
|
85
|
+
if (bare) offenders.push(`${path}: ${specifier}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
walk(join(root, "src"));
|
|
90
|
+
// Framework imports are DYNAMIC and guarded — a static one would make
|
|
91
|
+
// `import "@failproofai/sdk"` pull LangChain into every process.
|
|
92
|
+
expect(offenders).toEqual([]);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe("the published surface", () => {
|
|
97
|
+
it("builds every path its exports map promises", () => {
|
|
98
|
+
for (const [entry, conditions] of Object.entries(manifest.exports)) {
|
|
99
|
+
for (const [path, target] of targetsOf(conditions)) {
|
|
100
|
+
expect(existsSync(join(root, target)), `${entry}.${path.join(".")} -> ${target}`).toBe(true);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("hands each module system the declarations of its own half", () => {
|
|
106
|
+
// A `.d.ts` takes its module format from the nearest package.json, exactly
|
|
107
|
+
// like a `.js`. ESM declarations under `require` told every CommonJS
|
|
108
|
+
// project on `module: node16` that a CommonJS file was an ES module
|
|
109
|
+
// (TS1479 on every import).
|
|
110
|
+
for (const [entry, conditions] of Object.entries(manifest.exports)) {
|
|
111
|
+
if (entry === "./package.json") continue;
|
|
112
|
+
if (entry === "./sandbox-worker") {
|
|
113
|
+
// CommonJS only, for both module systems: types and code agree.
|
|
114
|
+
for (const [path, target] of targetsOf(conditions)) {
|
|
115
|
+
expect(target.startsWith("./dist/cjs/"), `${entry}.${path.join(".")}`).toBe(true);
|
|
116
|
+
}
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
for (const [half, dir] of [
|
|
120
|
+
["import", "./dist/esm/"],
|
|
121
|
+
["require", "./dist/cjs/"],
|
|
122
|
+
] as const) {
|
|
123
|
+
const types = targetAt(conditions, half, "types");
|
|
124
|
+
const code = targetAt(conditions, half, "default");
|
|
125
|
+
expect(types.startsWith(dir), `${entry}.${half}.types -> ${types}`).toBe(true);
|
|
126
|
+
expect(code.startsWith(dir), `${entry}.${half}.default -> ${code}`).toBe(true);
|
|
127
|
+
expect(types, entry).toBe(code.replace(/\.js$/, ".d.ts"));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("gives moduleResolution: node (node10) every subpath, as CommonJS declarations", () => {
|
|
133
|
+
// node10 ignores `exports`; `typesVersions` is its only route to a subpath,
|
|
134
|
+
// and `types` to the root. A node10 project compiles to CommonJS.
|
|
135
|
+
expect(manifest.types).toBe("./dist/cjs/index.d.ts");
|
|
136
|
+
expect(manifest.main).toBe("./dist/cjs/index.js");
|
|
137
|
+
const mapping = manifest.typesVersions?.["*"] ?? {};
|
|
138
|
+
const subpaths = Object.keys(manifest.exports)
|
|
139
|
+
.filter((entry) => entry !== "." && entry !== "./package.json")
|
|
140
|
+
.map((entry) => entry.slice(2));
|
|
141
|
+
expect(Object.keys(mapping).sort()).toEqual(subpaths.sort());
|
|
142
|
+
for (const subpath of subpaths) {
|
|
143
|
+
const conditions = manifest.exports[`./${subpath}`]!;
|
|
144
|
+
const expected =
|
|
145
|
+
subpath === "sandbox-worker"
|
|
146
|
+
? targetAt(conditions, "types")
|
|
147
|
+
: targetAt(conditions, "require", "types");
|
|
148
|
+
expect(mapping[subpath], subpath).toEqual([expected]);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it("builds the CommonJS declarations the require conditions point at", () => {
|
|
153
|
+
const cjs = readFileSync(join(root, "dist/cjs/index.d.ts"), "utf8");
|
|
154
|
+
expect(cjs).toContain("export declare function configure");
|
|
155
|
+
expect(existsSync(join(root, "dist/cjs/evaluator/sandbox-worker.d.ts"))).toBe(true);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("tells Node which half of the dual build is CommonJS", () => {
|
|
159
|
+
// The package is `"type": "module"`, so without this every `.js` under
|
|
160
|
+
// `dist/cjs` is read as ESM and its `require` calls are a syntax error.
|
|
161
|
+
expect(manifest.type).toBe("module");
|
|
162
|
+
expect(JSON.parse(readFileSync(join(root, "dist/cjs/package.json"), "utf8"))).toEqual({
|
|
163
|
+
type: "commonjs",
|
|
164
|
+
});
|
|
165
|
+
expect(JSON.parse(readFileSync(join(root, "dist/esm/package.json"), "utf8"))).toEqual({
|
|
166
|
+
type: "module",
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it("ships an executable CLI", () => {
|
|
171
|
+
const cli = join(root, manifest.bin["failproofai-evaluator"]!);
|
|
172
|
+
expect(existsSync(cli)).toBe(true);
|
|
173
|
+
expect(statSync(cli).mode & 0o111).toBeGreaterThan(0);
|
|
174
|
+
expect(readFileSync(cli, "utf8").startsWith("#!/usr/bin/env node")).toBe(true);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it("prints usage rather than a stack trace when run with no arguments", () => {
|
|
178
|
+
const cli = join(root, manifest.bin["failproofai-evaluator"]!);
|
|
179
|
+
const output = execFileSync(process.execPath, [cli, "--help"], { encoding: "utf8" });
|
|
180
|
+
expect(output).toContain("Usage: failproofai-evaluator");
|
|
181
|
+
expect(output).toContain("FAILPROOFAI_EVALUATOR_URL");
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it("keeps the version in one place", () => {
|
|
185
|
+
expect(manifest.version).toBe(VERSION);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it("includes only what a consumer needs", () => {
|
|
189
|
+
expect(manifest.files).toContain("dist/");
|
|
190
|
+
expect(manifest.files).not.toContain("src/");
|
|
191
|
+
expect(manifest.files).not.toContain("test/");
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
describe("both module systems load it", () => {
|
|
196
|
+
it("works as ESM", async () => {
|
|
197
|
+
const child = await runNode(`
|
|
198
|
+
const fp = await import(${JSON.stringify(indexUrl())});
|
|
199
|
+
if (typeof fp.configure !== "function") throw new Error("configure is missing");
|
|
200
|
+
if (typeof fp.agent !== "function") throw new Error("agent is missing");
|
|
201
|
+
if (typeof fp.event.toolUse !== "function") throw new Error("event.toolUse is missing");
|
|
202
|
+
console.log(fp.version);
|
|
203
|
+
`);
|
|
204
|
+
expect(child.stderr).toBe("");
|
|
205
|
+
expect(child.stdout.trim()).toBe(VERSION);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it("works as CommonJS", async () => {
|
|
209
|
+
const cjs = JSON.stringify(join(root, "dist/cjs/index.js"));
|
|
210
|
+
const child = await runNode(`
|
|
211
|
+
const { createRequire } = await import("node:module");
|
|
212
|
+
const require_ = createRequire(${JSON.stringify(join(root, "anchor.js"))});
|
|
213
|
+
const fp = require_(${cjs});
|
|
214
|
+
if (typeof fp.configure !== "function") throw new Error("configure is missing");
|
|
215
|
+
if (typeof fp.session !== "function") throw new Error("session is missing");
|
|
216
|
+
console.log(fp.version);
|
|
217
|
+
`);
|
|
218
|
+
expect(child.stderr).toBe("");
|
|
219
|
+
expect(child.stdout.trim()).toBe(VERSION);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it("loads the evaluator and the adapters from their subpaths", async () => {
|
|
223
|
+
const require_ = createRequire(join(root, "anchor.js"));
|
|
224
|
+
for (const subpath of ["./evaluator", "./ai", "./mastra", "./langchain", "./llamaindex"]) {
|
|
225
|
+
const target = targetAt(manifest.exports[subpath]!, "require", "default");
|
|
226
|
+
expect(existsSync(join(root, target))).toBe(true);
|
|
227
|
+
expect(() => require_(join(root, target))).not.toThrow();
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it("applies configure() from one copy to every copy in the process", async () => {
|
|
232
|
+
// Next.js without withFailproofai bundles a copy per route beside the one
|
|
233
|
+
// instrumentation.ts configures; the dual build loads ESM and CommonJS
|
|
234
|
+
// side by side. Per-copy settings sent the route's events out as `dev`,
|
|
235
|
+
// into whatever spool that copy defaulted to.
|
|
236
|
+
const dir = mkdtempSync(join(tmpdir(), "fpai-copies-"));
|
|
237
|
+
try {
|
|
238
|
+
const child = await runNode(`
|
|
239
|
+
const esm = await import(${JSON.stringify(indexUrl())});
|
|
240
|
+
const { createRequire } = await import("node:module");
|
|
241
|
+
const cjs = createRequire(${JSON.stringify(join(root, "anchor.js"))})(${JSON.stringify(join(root, "dist/cjs/index.js"))});
|
|
242
|
+
if (esm.configure === cjs.configure) throw new Error("expected two copies");
|
|
243
|
+
esm.configure({ environment: "prod-eu", baseDir: ${JSON.stringify(dir)} });
|
|
244
|
+
cjs.event.agentStart({ sessionId: "copies" });
|
|
245
|
+
await cjs.flush();
|
|
246
|
+
`);
|
|
247
|
+
expect(child.stderr).toBe("");
|
|
248
|
+
const events = readdirSync(join(dir, "events"))
|
|
249
|
+
.flatMap((f) => readFileSync(join(dir, "events", f), "utf8").split("\n").filter(Boolean))
|
|
250
|
+
.map((line) => JSON.parse(line) as Record<string, unknown>);
|
|
251
|
+
expect(events.map((e) => [e.session_id, e.environment])).toEqual([["copies", "prod-eu"]]);
|
|
252
|
+
} finally {
|
|
253
|
+
rmSync(dir, { recursive: true, force: true });
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it("runs an evaluator module written as CommonJS or as ESM through the bin", () => {
|
|
258
|
+
// The bin is the ESM build. A CommonJS evals file gets `Evaluator` from
|
|
259
|
+
// `dist/cjs` — a second copy of the class — so an `instanceof` check in the
|
|
260
|
+
// loader refused it with "resolved to Evaluator, not an Evaluator", and the
|
|
261
|
+
// commonest setup (plain `tsc` output, no "type": "module") could not start.
|
|
262
|
+
const dir = mkdtempSync(join(tmpdir(), "fpai-evals-"));
|
|
263
|
+
const cjsEntry = JSON.stringify(join(root, targetAt(manifest.exports["./evaluator"]!, "require", "default")));
|
|
264
|
+
const esmEntry = JSON.stringify(
|
|
265
|
+
pathToFileURL(join(root, targetAt(manifest.exports["./evaluator"]!, "import", "default"))).href,
|
|
266
|
+
);
|
|
267
|
+
writeFileSync(
|
|
268
|
+
join(dir, "evals.cjs"),
|
|
269
|
+
`const { Evaluator } = require(${cjsEntry});\nexports.app = new Evaluator({ name: "cjs", version: "1" });\n`,
|
|
270
|
+
);
|
|
271
|
+
writeFileSync(
|
|
272
|
+
join(dir, "evals.mjs"),
|
|
273
|
+
`import { Evaluator } from ${esmEntry};\nexport const app = new Evaluator({ name: "esm", version: "1" });\n`,
|
|
274
|
+
);
|
|
275
|
+
writeFileSync(join(dir, "not-evals.cjs"), "exports.app = { runFromEnv() {} };\n");
|
|
276
|
+
|
|
277
|
+
const run = (file: string) => {
|
|
278
|
+
const env = { ...process.env };
|
|
279
|
+
delete env.FAILPROOFAI_EVALUATOR_URL;
|
|
280
|
+
delete env.FAILPROOFAI_EVALUATOR_TOKEN;
|
|
281
|
+
try {
|
|
282
|
+
execFileSync(process.execPath, [join(root, manifest.bin["failproofai-evaluator"]!), join(dir, file)], {
|
|
283
|
+
env,
|
|
284
|
+
encoding: "utf8",
|
|
285
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
286
|
+
});
|
|
287
|
+
return "";
|
|
288
|
+
} catch (error) {
|
|
289
|
+
return String((error as { stderr?: string }).stderr ?? error);
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
try {
|
|
293
|
+
// Loading succeeded when the worker gets as far as reading its config.
|
|
294
|
+
expect(run("evals.cjs")).toContain("FAILPROOFAI_EVALUATOR_URL is required");
|
|
295
|
+
expect(run("evals.mjs")).toContain("FAILPROOFAI_EVALUATOR_URL is required");
|
|
296
|
+
expect(run("not-evals.cjs")).toContain("not an Evaluator");
|
|
297
|
+
} finally {
|
|
298
|
+
rmSync(dir, { recursive: true, force: true });
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
it("does not pull a framework into the process just by being imported", async () => {
|
|
303
|
+
const child = await runNode(`
|
|
304
|
+
const fp = await import(${JSON.stringify(indexUrl())});
|
|
305
|
+
const loaded = Object.keys(await import("node:module").then((m) => m.createRequire(process.cwd() + "/x.js").cache));
|
|
306
|
+
const frameworks = loaded.filter((p) => /node_modules[\\\\/](@langchain|ai|@mastra|llamaindex)[\\\\/]/.test(p));
|
|
307
|
+
console.log(JSON.stringify(frameworks));
|
|
308
|
+
`);
|
|
309
|
+
expect(child.stderr).toBe("");
|
|
310
|
+
expect(JSON.parse(child.stdout.trim())).toEqual([]);
|
|
311
|
+
});
|
|
312
|
+
});
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { mkdtempSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
6
|
+
|
|
7
|
+
import { redactJsonLine, redactionEnabled, scrubString } from "../src/redact.js";
|
|
8
|
+
import { runtime } from "../src/runtime.js";
|
|
9
|
+
import { useSpool } from "./helpers.js";
|
|
10
|
+
import type { Spool } from "./helpers.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The SDK redacts before bytes reach disk; the daemon redacts again before
|
|
14
|
+
* upload. Both sides implement the same rules, so these cases are the contract
|
|
15
|
+
* between them — a rule that matches here and not there means a credential
|
|
16
|
+
* sitting in a spool file waiting for a collector that will not clean it.
|
|
17
|
+
*
|
|
18
|
+
* ## Why the fixtures are assembled rather than written out
|
|
19
|
+
*
|
|
20
|
+
* A credential-shaped literal in a source file is a credential-shaped literal,
|
|
21
|
+
* whatever the comment beside it says. This repository scans itself for exactly
|
|
22
|
+
* these prefixes (and so does every CI secret scanner worth having), so a test
|
|
23
|
+
* that spelled one out would trip its own tooling and train everybody to wave
|
|
24
|
+
* the alert through. `fake()` builds the same bytes at runtime from parts that
|
|
25
|
+
* are individually meaningless.
|
|
26
|
+
*/
|
|
27
|
+
const fake = (...parts: string[]): string => parts.join("");
|
|
28
|
+
|
|
29
|
+
const ANTHROPIC = fake("sk-", "ant-", "api03-", "A".repeat(20));
|
|
30
|
+
const GITHUB = fake("ghp", "_", "A".repeat(24));
|
|
31
|
+
const GITHUB_OTHER = fake("ghp", "_", "B".repeat(24));
|
|
32
|
+
const AWS = fake("AKIA", "IOSFODNN7EXAMPLE1234");
|
|
33
|
+
const SLACK = fake("xoxb", "-1234567890-ABCDEFGHIJKLMNOP");
|
|
34
|
+
|
|
35
|
+
describe("scrubString", () => {
|
|
36
|
+
const redacted = (value: string): string => scrubString(value)[0];
|
|
37
|
+
|
|
38
|
+
it("redacts provider key prefixes at a token boundary", () => {
|
|
39
|
+
expect(redacted(`use ${ANTHROPIC} now`)).toBe("use [redacted:anthropic-key] now");
|
|
40
|
+
expect(redacted(GITHUB)).toBe("[redacted:github-token]");
|
|
41
|
+
expect(redacted(AWS)).toBe("[redacted:aws-access-key-id]");
|
|
42
|
+
expect(redacted(SLACK)).toBe("[redacted:slack-token]");
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("leaves a prefix that is too short to be a key", () => {
|
|
46
|
+
expect(redacted(fake("sk-", "short"))).toBe("sk-short");
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("does not fire mid-token, where a match would be a coincidence", () => {
|
|
50
|
+
expect(redacted(`x${ANTHROPIC}`)).toBe(`x${ANTHROPIC}`);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("redacts a three-segment JWT", () => {
|
|
54
|
+
const jwt = fake("eyJ", "hbGciOiJIUzI1NiJ9", ".", "a".repeat(30), ".", "b".repeat(20));
|
|
55
|
+
expect(redacted(jwt)).toBe("[redacted:jwt]");
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("redacts a bearer token, case-insensitively on the scheme", () => {
|
|
59
|
+
expect(redacted('Authorization: Bearer abcdefghijkl"')).toBe(
|
|
60
|
+
'Authorization: [redacted:bearer-token]"',
|
|
61
|
+
);
|
|
62
|
+
expect(redacted("authorization: bearer abcdefghijkl")).toBe(
|
|
63
|
+
"authorization: [redacted:bearer-token]",
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("redacts a secret-shaped assignment but not an ordinary one", () => {
|
|
68
|
+
expect(redacted("API_KEY=abcdefghijklmnop")).toBe("API_KEY=[redacted:secret-assignment]");
|
|
69
|
+
expect(redacted('DB_PASSWORD="hunter2hunter2"')).toBe(
|
|
70
|
+
'DB_PASSWORD="[redacted:secret-assignment]"',
|
|
71
|
+
);
|
|
72
|
+
// `key` on its own is too weak a name to be a secret; only a compound one
|
|
73
|
+
// counts, or the redactor eats every ordinary `key=` in a tool output.
|
|
74
|
+
expect(redacted("key=abcdefghijklmnop")).toBe("key=abcdefghijklmnop");
|
|
75
|
+
expect(redacted("NAME=abcdefghijklmnop")).toBe("NAME=abcdefghijklmnop");
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("leaves an interpolated or placeholder value alone", () => {
|
|
79
|
+
expect(redacted("API_KEY=${SECRET_FROM_VAULT}")).toBe("API_KEY=${SECRET_FROM_VAULT}");
|
|
80
|
+
expect(redacted("API_KEY=<your-key-here>")).toBe("API_KEY=<your-key-here>");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("returns the original string when nothing matched", () => {
|
|
84
|
+
const value = "a perfectly ordinary tool output";
|
|
85
|
+
const [scrubbed, hits] = scrubString(value);
|
|
86
|
+
expect(hits).toBe(0);
|
|
87
|
+
expect(scrubbed).toBe(value);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("counts UTF-8 bytes, not code units, for the length thresholds", () => {
|
|
91
|
+
// Two 3-byte characters is 6 bytes — under the bearer minimum of 8 — but a
|
|
92
|
+
// naive code-unit count would see 2 and a naive character count would see
|
|
93
|
+
// 2 as well, so only a byte count refuses this one and accepts the next.
|
|
94
|
+
expect(redacted("Bearer 日本")).toBe("Bearer 日本");
|
|
95
|
+
expect(redacted("Bearer 日本語日本語日本")).toBe("[redacted:bearer-token]");
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe("redactJsonLine", () => {
|
|
100
|
+
it("redacts values, and leaves an untouched line byte-identical", () => {
|
|
101
|
+
const clean = JSON.stringify({ type: "tool_use", input: { q: "kites" } });
|
|
102
|
+
expect(redactJsonLine(clean)).toBe(clean);
|
|
103
|
+
|
|
104
|
+
const dirty = JSON.stringify({ type: "tool_use", input: { token: GITHUB } });
|
|
105
|
+
expect(JSON.parse(redactJsonLine(dirty)).input.token).toBe("[redacted:github-token]");
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("redacts a secret-NAMED field even when the value has no recognisable shape", () => {
|
|
109
|
+
const line = JSON.stringify({ type: "t", api_secret: "totally-ordinary-looking" });
|
|
110
|
+
expect(JSON.parse(redactJsonLine(line)).api_secret).toBe("[redacted:secret-assignment]");
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("applies the field name to every element of an array value", () => {
|
|
114
|
+
const line = JSON.stringify({ type: "t", api_secret: ["aaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbb"] });
|
|
115
|
+
expect(JSON.parse(redactJsonLine(line)).api_secret).toEqual([
|
|
116
|
+
"[redacted:secret-assignment]",
|
|
117
|
+
"[redacted:secret-assignment]",
|
|
118
|
+
]);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("keeps two keys distinct when redacting collapses them to the same name", () => {
|
|
122
|
+
const line = JSON.stringify({ [GITHUB]: 1, [GITHUB_OTHER]: 2 });
|
|
123
|
+
expect(Object.keys(JSON.parse(redactJsonLine(line)))).toEqual([
|
|
124
|
+
"[redacted:github-token]",
|
|
125
|
+
"[redacted:github-token]#2",
|
|
126
|
+
]);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
describe("the daemon's redaction switch", () => {
|
|
131
|
+
it("defaults to ON when there is no config at all", () => {
|
|
132
|
+
const home = mkdtempSync(join(tmpdir(), "fp-config-"));
|
|
133
|
+
expect(redactionEnabled(join(home, "custom-agents"))).toBe(true);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it("defaults to ON when the config is unreadable or malformed", () => {
|
|
137
|
+
const home = mkdtempSync(join(tmpdir(), "fp-config-"));
|
|
138
|
+
writeFileSync(join(home, "config.json"), "{ not json");
|
|
139
|
+
// Failing open here would mean one typo silently ships credentials.
|
|
140
|
+
expect(redactionEnabled(join(home, "custom-agents"))).toBe(true);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it("honours an explicit off", () => {
|
|
144
|
+
const home = mkdtempSync(join(tmpdir(), "fp-config-"));
|
|
145
|
+
writeFileSync(join(home, "config.json"), JSON.stringify({ collector: { redact: "off" } }));
|
|
146
|
+
expect(redactionEnabled(join(home, "custom-agents"))).toBe(false);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe("end to end", () => {
|
|
151
|
+
let spool: Spool;
|
|
152
|
+
beforeEach(() => {
|
|
153
|
+
spool = useSpool();
|
|
154
|
+
});
|
|
155
|
+
afterEach(async () => {
|
|
156
|
+
await spool.cleanup();
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("redacts before the bytes reach disk", async () => {
|
|
160
|
+
runtime.event.toolUse({
|
|
161
|
+
sessionId: "s",
|
|
162
|
+
toolName: "shell",
|
|
163
|
+
toolCallId: "c1",
|
|
164
|
+
input: { command: "curl -H 'Authorization: Bearer abcdefghijklmnop'" },
|
|
165
|
+
});
|
|
166
|
+
await runtime.writer.flushNow();
|
|
167
|
+
const raw = spool.lines().join("");
|
|
168
|
+
expect(raw).not.toContain("abcdefghijklmnop");
|
|
169
|
+
expect(raw).toContain("[redacted:bearer-token]");
|
|
170
|
+
});
|
|
171
|
+
});
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { dirname, join, resolve } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest";
|
|
8
|
+
|
|
9
|
+
import { appImportsReachCommonJs, entryIsCommonJs, isCommonJsMain, isNextServer } from "../src/node-require.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Runtime differences the SDK core has to read correctly. The end-to-end proof
|
|
13
|
+
* for each is in `integration/runtimes.*.test.ts` and `integration/nextjs.test.ts`;
|
|
14
|
+
* these pin the decisions.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
18
|
+
|
|
19
|
+
describe("isCommonJsMain", () => {
|
|
20
|
+
it("reads Node's undefined and Deno's null alike: an ES-module entry", () => {
|
|
21
|
+
// Deno sets `require.main` to null for an ES-module entry. Treating that as
|
|
22
|
+
// CommonJS patched the frameworks' CommonJS copies in every ES-module Deno
|
|
23
|
+
// app, while the app ran the ES-module copies — nothing was recorded.
|
|
24
|
+
expect(isCommonJsMain(undefined)).toBe(false);
|
|
25
|
+
expect(isCommonJsMain(null)).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("reads a module object as a CommonJS entry", () => {
|
|
29
|
+
expect(isCommonJsMain({ filename: "/app/index.cjs", id: "." })).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe("appImportsReachCommonJs", () => {
|
|
34
|
+
const saved = process.env.NEXT_RUNTIME;
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
if (saved === undefined) delete process.env.NEXT_RUNTIME;
|
|
37
|
+
else process.env.NEXT_RUNTIME = saved;
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("follows the entry point outside Next.js", () => {
|
|
41
|
+
delete process.env.NEXT_RUNTIME;
|
|
42
|
+
expect(isNextServer()).toBe(false);
|
|
43
|
+
expect(appImportsReachCommonJs()).toBe(entryIsCommonJs());
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("is false in a Next.js server, whatever the (CommonJS) launcher is", () => {
|
|
47
|
+
process.env.NEXT_RUNTIME = "nodejs";
|
|
48
|
+
expect(isNextServer()).toBe(true);
|
|
49
|
+
expect(appImportsReachCommonJs()).toBe(false);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The same decision from a real CommonJS entry, the shape `next start` has:
|
|
55
|
+
* Next's launcher is CommonJS, and it `import()`s every server-external
|
|
56
|
+
* package — so inside a Next server the ES-module copy is the one to patch.
|
|
57
|
+
*/
|
|
58
|
+
describe("requireModuleCopies under a CommonJS launcher", () => {
|
|
59
|
+
let app: string;
|
|
60
|
+
|
|
61
|
+
beforeAll(() => {
|
|
62
|
+
app = mkdtempSync(join(tmpdir(), "failproofai-launcher-"));
|
|
63
|
+
const pkg = join(app, "node_modules", "dualfw");
|
|
64
|
+
mkdirSync(join(pkg, "esm"), { recursive: true });
|
|
65
|
+
mkdirSync(join(pkg, "cjs"), { recursive: true });
|
|
66
|
+
writeFileSync(
|
|
67
|
+
join(pkg, "package.json"),
|
|
68
|
+
JSON.stringify({ name: "dualfw", exports: { ".": { import: "./esm/index.js", require: "./cjs/index.cjs" } } }),
|
|
69
|
+
);
|
|
70
|
+
writeFileSync(join(pkg, "esm", "index.js"), 'export const marker = "esm";\n');
|
|
71
|
+
writeFileSync(join(pkg, "esm", "package.json"), JSON.stringify({ type: "module" }));
|
|
72
|
+
writeFileSync(join(pkg, "cjs", "index.cjs"), 'exports.marker = "cjs";\n');
|
|
73
|
+
const compat = join(root, "dist", "cjs", "integrations", "compat.js");
|
|
74
|
+
writeFileSync(
|
|
75
|
+
join(app, "launcher.cjs"),
|
|
76
|
+
`const compat = require(${JSON.stringify(compat)});\n` +
|
|
77
|
+
`compat.requireModuleCopies("dualfw", "npm i dualfw").then((copies) => ` +
|
|
78
|
+
`console.log(JSON.stringify(copies.map((m) => m.marker))));\n`,
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
afterAll(() => rmSync(app, { recursive: true, force: true }));
|
|
83
|
+
|
|
84
|
+
const run = (env: Record<string, string>) => {
|
|
85
|
+
const child = spawnSync(process.execPath, [join(app, "launcher.cjs")], {
|
|
86
|
+
cwd: app,
|
|
87
|
+
encoding: "utf8",
|
|
88
|
+
env: { ...process.env, NEXT_RUNTIME: "", ...env },
|
|
89
|
+
});
|
|
90
|
+
expect(child.stderr).toBe("");
|
|
91
|
+
return JSON.parse(child.stdout.trim()) as string[];
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
it("patches the CommonJS copy for a plain CommonJS app", () => {
|
|
95
|
+
expect(run({})).toEqual(["cjs"]);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("patches the ES-module copy inside a Next.js server", () => {
|
|
99
|
+
expect(run({ NEXT_RUNTIME: "nodejs" })).toEqual(["esm"]);
|
|
100
|
+
});
|
|
101
|
+
});
|