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,407 @@
|
|
|
1
|
+
import { statSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
5
|
+
|
|
6
|
+
import { setLogger } from "../src/logger.js";
|
|
7
|
+
import { runtime } from "../src/runtime.js";
|
|
8
|
+
import {
|
|
9
|
+
EventWriter,
|
|
10
|
+
approxSize,
|
|
11
|
+
capFields,
|
|
12
|
+
encodeEntry,
|
|
13
|
+
roll,
|
|
14
|
+
sanitize,
|
|
15
|
+
scrubSurrogates,
|
|
16
|
+
validatedInterval,
|
|
17
|
+
} from "../src/writer.js";
|
|
18
|
+
import { indexUrl, runNode, useSpool } from "./helpers.js";
|
|
19
|
+
import type { Spool } from "./helpers.js";
|
|
20
|
+
|
|
21
|
+
let spool: Spool;
|
|
22
|
+
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
spool = useSpool();
|
|
25
|
+
});
|
|
26
|
+
afterEach(async () => {
|
|
27
|
+
await spool.cleanup();
|
|
28
|
+
setLogger(null);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe("flush interval validation", () => {
|
|
32
|
+
it("refuses a value the timer cannot run on, at the boundary", () => {
|
|
33
|
+
for (const bad of [0, -1, Number.NaN, Number.POSITIVE_INFINITY]) {
|
|
34
|
+
expect(() => validatedInterval(bad)).toThrow(/finite number greater than zero/);
|
|
35
|
+
}
|
|
36
|
+
expect(validatedInterval(0.25)).toBe(0.25);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("leaves the writer on its old interval when a new one is rejected", () => {
|
|
40
|
+
const writer = new EventWriter(0.5);
|
|
41
|
+
try {
|
|
42
|
+
expect(() => writer.setFlushInterval(-1)).toThrow();
|
|
43
|
+
expect(writer.getFlushInterval()).toBe(0.5);
|
|
44
|
+
} finally {
|
|
45
|
+
writer.close();
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe("durability", () => {
|
|
51
|
+
it("publishes .jsonl files, never leaving a .tmp behind", async () => {
|
|
52
|
+
runtime.event.agentStart({ sessionId: "s" });
|
|
53
|
+
await runtime.writer.flushNow();
|
|
54
|
+
expect(spool.files()).toHaveLength(1);
|
|
55
|
+
expect(spool.files()[0]).toMatch(/^event-.*-\d+-\d+\.jsonl$/);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("names each batch uniquely, so two in the same millisecond cannot overwrite", async () => {
|
|
59
|
+
runtime.event.agentStart({ sessionId: "s" });
|
|
60
|
+
await runtime.writer.flushNow();
|
|
61
|
+
runtime.event.agentStart({ sessionId: "s" });
|
|
62
|
+
await runtime.writer.flushNow();
|
|
63
|
+
const files = spool.files();
|
|
64
|
+
expect(new Set(files).size).toBe(2);
|
|
65
|
+
// The pid is in the stem so unrelated processes sharing one spool root
|
|
66
|
+
// cannot collide either.
|
|
67
|
+
for (const name of files) expect(name).toContain(`-${process.pid}-`);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("writes 0600 batches inside a 0700 directory", async () => {
|
|
71
|
+
runtime.event.agentStart({ sessionId: "s" });
|
|
72
|
+
await runtime.writer.flushNow();
|
|
73
|
+
const eventsDir = join(spool.dir, "events");
|
|
74
|
+
expect(statSync(eventsDir).mode & 0o777).toBe(0o700);
|
|
75
|
+
expect(statSync(join(eventsDir, spool.files()[0]!)).mode & 0o777).toBe(0o600);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("flushNow() writes an event emitted while another flush was already writing", async () => {
|
|
79
|
+
// The interval timer (or a second caller) can be mid-write when you call
|
|
80
|
+
// `flush()`. That flush drained the queue BEFORE this event arrived, so
|
|
81
|
+
// returning it — what flushNow() used to do — resolved with the newest
|
|
82
|
+
// event still in memory, breaking "resolves once your events are on disk"
|
|
83
|
+
// for exactly the emit-flush-exit script it exists for.
|
|
84
|
+
runtime.event.agentStart({ sessionId: "s" });
|
|
85
|
+
const alreadyWriting = runtime.writer.flushNow();
|
|
86
|
+
runtime.event.agentEnd({ sessionId: "s" });
|
|
87
|
+
await runtime.writer.flushNow();
|
|
88
|
+
expect(spool.events().map((e) => e.type)).toEqual(["agent_start", "agent_end"]);
|
|
89
|
+
await alreadyWriting;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("ends every batch file with a newline, as the collector's line reader expects", async () => {
|
|
93
|
+
runtime.event.agentStart({ sessionId: "s" });
|
|
94
|
+
await runtime.writer.flushNow();
|
|
95
|
+
const raw = spool.lines();
|
|
96
|
+
expect(raw).toHaveLength(1);
|
|
97
|
+
expect(JSON.parse(raw[0]!)).toMatchObject({ type: "agent_start" });
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe("encoding isolation", () => {
|
|
102
|
+
it("drops ONE unencodable event rather than the batch around it", async () => {
|
|
103
|
+
const circular: Record<string, unknown> = { name: "loop" };
|
|
104
|
+
circular.self = circular;
|
|
105
|
+
setLogger({ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() });
|
|
106
|
+
|
|
107
|
+
runtime.event.agentStart({ sessionId: "s", fw_before: 1 });
|
|
108
|
+
runtime.event.agentStart({ sessionId: "s", fw_cycle: circular });
|
|
109
|
+
runtime.event.agentStart({ sessionId: "s", fw_after: 1 });
|
|
110
|
+
await runtime.writer.flushNow();
|
|
111
|
+
|
|
112
|
+
const events = spool.events();
|
|
113
|
+
expect(events).toHaveLength(3);
|
|
114
|
+
// The cyclic one is still published — sanitized, not dropped.
|
|
115
|
+
expect(events[1]!.fw_cycle).toEqual({ name: "loop", self: "<circular reference>" });
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("sanitizes a cycle rather than failing the event", () => {
|
|
119
|
+
const node: Record<string, unknown> = { a: 1 };
|
|
120
|
+
node.self = node;
|
|
121
|
+
expect(sanitize(node, new Set())).toEqual({ a: 1, self: "<circular reference>" });
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("does not mistake a DAG for a cycle", () => {
|
|
125
|
+
const shared = { value: 1 };
|
|
126
|
+
expect(sanitize({ left: shared, right: shared }, new Set())).toEqual({
|
|
127
|
+
left: { value: 1 },
|
|
128
|
+
right: { value: 1 },
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("makes a lone surrogate inert, which ingest would otherwise skip at 200 OK", () => {
|
|
133
|
+
expect(scrubSurrogates("ok\ud800bad")).toBe("ok\\ud800bad");
|
|
134
|
+
// A well-formed pair is left alone.
|
|
135
|
+
expect(scrubSurrogates("emoji \u{1F600}")).toBe("emoji \u{1F600}");
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("scrubs a lone surrogate in a KEY as well as a value", () => {
|
|
139
|
+
// An unscrubbed key reaches the wire as a JSON lone-surrogate escape, ingest
|
|
140
|
+
// answers 200 with `{"accepted":0,"skipped":1}`, and the uploader parks that
|
|
141
|
+
// batch and poisons it after three retries — so one bad key loses every
|
|
142
|
+
// event batched with it. A filesystem path, the realistic source, is most
|
|
143
|
+
// naturally a key.
|
|
144
|
+
const encoded = encodeEntry({ type: "t", ["path\udcff"]: "x", value: "v\udcff" })!;
|
|
145
|
+
// No RAW surrogate survives anywhere in the line...
|
|
146
|
+
expect(/[\uD800-\uDFFF]/.test(encoded)).toBe(false);
|
|
147
|
+
// ...and both the key and the value carry the byte visibly instead.
|
|
148
|
+
const parsed = JSON.parse(encoded) as Record<string, unknown>;
|
|
149
|
+
expect(Object.keys(parsed)).toContain(String.raw`path\udcff`);
|
|
150
|
+
expect(parsed.value).toBe(String.raw`v\udcff`);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it("writes a non-finite number as null rather than invalid JSON", () => {
|
|
154
|
+
const encoded = encodeEntry({ type: "t", value: Number.NaN, other: Number.POSITIVE_INFINITY })!;
|
|
155
|
+
expect(JSON.parse(encoded)).toEqual({ type: "t", value: null, other: null });
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("encodes the values JSON.stringify refuses", () => {
|
|
159
|
+
const encoded = encodeEntry({
|
|
160
|
+
type: "t",
|
|
161
|
+
big: 1n,
|
|
162
|
+
set: new Set([1, 2]),
|
|
163
|
+
map: new Map([["a", 1]]),
|
|
164
|
+
when: new Date("2026-01-01T00:00:00Z"),
|
|
165
|
+
})!;
|
|
166
|
+
expect(JSON.parse(encoded)).toEqual({
|
|
167
|
+
type: "t",
|
|
168
|
+
big: "1",
|
|
169
|
+
set: [1, 2],
|
|
170
|
+
map: { a: 1 },
|
|
171
|
+
when: "2026-01-01T00:00:00.000Z",
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it("never lets a throwing getter escape the encoder", () => {
|
|
176
|
+
const hostile = {
|
|
177
|
+
type: "t",
|
|
178
|
+
get boom(): never {
|
|
179
|
+
throw new Error("from the caller's own code");
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
setLogger({ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() });
|
|
183
|
+
expect(() => encodeEntry(hostile)).not.toThrow();
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
describe("size bounds", () => {
|
|
188
|
+
it("caps an oversized event's fields so the collector can still deliver the batch", () => {
|
|
189
|
+
const huge = "x".repeat(5 * 1024 * 1024);
|
|
190
|
+
const encoded = encodeEntry({ type: "tool_result", output: huge })!;
|
|
191
|
+
expect(Buffer.byteLength(encoded, "utf8")).toBeLessThan(4 * 1024 * 1024);
|
|
192
|
+
expect(JSON.parse(encoded).output).toContain("…[truncated]");
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it("never splits a surrogate pair when it truncates", () => {
|
|
196
|
+
const capped = capFields("\u{1F600}".repeat(10), 5) as string;
|
|
197
|
+
expect(capped.endsWith("…[truncated]")).toBe(true);
|
|
198
|
+
expect(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])/.test(capped)).toBe(false);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it("rolls lines into batches that each stay under the limit", () => {
|
|
202
|
+
const lines = Array.from({ length: 5 }, () => ({ text: "x".repeat(40), bytes: 40 }));
|
|
203
|
+
const chunks = roll(lines, 100);
|
|
204
|
+
expect(chunks.map((chunk) => chunk.length)).toEqual([2, 2, 1]);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it("emits an over-limit line alone rather than dropping it", () => {
|
|
208
|
+
const chunks = roll(
|
|
209
|
+
[
|
|
210
|
+
{ text: "a", bytes: 1 },
|
|
211
|
+
{ text: "b", bytes: 500 },
|
|
212
|
+
],
|
|
213
|
+
100,
|
|
214
|
+
);
|
|
215
|
+
expect(chunks).toHaveLength(2);
|
|
216
|
+
expect(chunks[1]![0]!.bytes).toBe(500);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it("sizes a value by walking nodes, not characters", () => {
|
|
220
|
+
expect(approxSize("abcd")).toBe(4);
|
|
221
|
+
expect(approxSize({ a: "bb" })).toBe(3);
|
|
222
|
+
expect(approxSize([1, 2, 3])).toBe(24);
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
describe("queue bounds", () => {
|
|
227
|
+
it("discards the OLDEST events when the queue stops draining, and says so once", () => {
|
|
228
|
+
const warn = vi.fn();
|
|
229
|
+
setLogger({ debug: vi.fn(), info: vi.fn(), warn, error: vi.fn() });
|
|
230
|
+
const writer = new EventWriter(3600);
|
|
231
|
+
try {
|
|
232
|
+
for (let i = 0; i < 10_050; i += 1) writer.submit({ type: "t", index: i });
|
|
233
|
+
const stats = writer.stats();
|
|
234
|
+
expect(stats.queued).toBeLessThanOrEqual(10_000);
|
|
235
|
+
expect(stats.dropped).toBeGreaterThan(0);
|
|
236
|
+
expect(warn).toHaveBeenCalledWith(expect.stringContaining("queue is full"));
|
|
237
|
+
} finally {
|
|
238
|
+
writer.close();
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it("bounds by BYTES as well as by count, because a count is not a memory bound", () => {
|
|
243
|
+
const writer = new EventWriter(3600);
|
|
244
|
+
try {
|
|
245
|
+
const chunk = "x".repeat(2 * 1024 * 1024);
|
|
246
|
+
for (let i = 0; i < 64; i += 1) writer.submit({ type: "t", blob: chunk });
|
|
247
|
+
// 64 x 2 MiB is 128 MiB, well past the 64 MiB ceiling, and far under the
|
|
248
|
+
// 10,000-event count cap — so only the byte bound can have stopped it.
|
|
249
|
+
expect(writer.stats().queuedBytes).toBeLessThanOrEqual(64 * 1024 * 1024);
|
|
250
|
+
expect(writer.stats().dropped).toBeGreaterThan(0);
|
|
251
|
+
} finally {
|
|
252
|
+
writer.close();
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
describe("process lifetime", () => {
|
|
258
|
+
it("lets a script that merely imports it exit, and flushes on the way out", async () => {
|
|
259
|
+
// The flush interval MUST be unref'd. Without that, importing this SDK
|
|
260
|
+
// stops every script that uses it from ever exiting — the most visible bug
|
|
261
|
+
// a telemetry library can ship, and one no in-process assertion can catch,
|
|
262
|
+
// because the test runner keeps the loop alive by itself.
|
|
263
|
+
const child = await runNode(`
|
|
264
|
+
const fp = await import(${JSON.stringify(indexUrl())});
|
|
265
|
+
fp.configure({ baseDir: ${JSON.stringify(spool.dir)}, flushInterval: 3600 });
|
|
266
|
+
fp.event.agentStart({ sessionId: "exit-test" });
|
|
267
|
+
console.log("emitted");
|
|
268
|
+
`);
|
|
269
|
+
expect(child.code).toBe(0);
|
|
270
|
+
expect(child.stdout.trim()).toBe("emitted");
|
|
271
|
+
// The exit hook is the only thing that can have written this: the interval
|
|
272
|
+
// was set to an hour.
|
|
273
|
+
expect(spool.events().map((event) => event.session_id)).toEqual(["exit-test"]);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it("closes the runs a SIGTERM abandons, so none renders as running forever", async () => {
|
|
277
|
+
// The documented shutdown recipe, killed mid-tool. It used to leave an
|
|
278
|
+
// agent_start with no agent_end and a tool_use with no tool_result, and
|
|
279
|
+
// exit 0 — every deploy stranded the runs it interrupted.
|
|
280
|
+
const child = await runNode(`
|
|
281
|
+
const fp = await import(${JSON.stringify(indexUrl())});
|
|
282
|
+
fp.configure({ baseDir: ${JSON.stringify(spool.dir)}, flushInterval: 3600 });
|
|
283
|
+
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
284
|
+
process.once(signal, () => { fp.flushSync(); process.exit(0); });
|
|
285
|
+
}
|
|
286
|
+
setInterval(() => {}, 1000); // a service's server keeps the loop alive
|
|
287
|
+
setTimeout(() => process.kill(process.pid, "SIGTERM"), 50);
|
|
288
|
+
await fp.agent("svc", { sessionId: "term-test" }, async () => {
|
|
289
|
+
await fp.agent("writer", async () => {
|
|
290
|
+
await fp.toolCall("slow", { toolCallId: "t1" }, () => new Promise(() => {}));
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
`);
|
|
294
|
+
expect(child.code).toBe(0);
|
|
295
|
+
const events = spool.events();
|
|
296
|
+
expect(events.map((e) => [e.agent_id, e.type])).toEqual([
|
|
297
|
+
["svc", "agent_start"],
|
|
298
|
+
["writer", "agent_start"],
|
|
299
|
+
["writer", "tool_use"],
|
|
300
|
+
["writer", "tool_result"],
|
|
301
|
+
["writer", "error"],
|
|
302
|
+
["writer", "agent_end"],
|
|
303
|
+
["svc", "error"],
|
|
304
|
+
["svc", "agent_end"],
|
|
305
|
+
]);
|
|
306
|
+
const result = events.find((e) => e.type === "tool_result")!;
|
|
307
|
+
expect(result.tool_call_id).toBe("t1");
|
|
308
|
+
expect(result.error).toMatch(/^ProcessExit: the process exited \(code 0\) while tool "slow"/);
|
|
309
|
+
for (const end of events.filter((e) => e.type === "agent_end")) expect(end.outcome).toBe("failed");
|
|
310
|
+
expect(events.find((e) => e.type === "error")!.error_type).toBe("ProcessExit");
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it("closes a hand-written model call left open by a SIGTERM", async () => {
|
|
314
|
+
// The no-framework recipe: modelRequest before the provider call,
|
|
315
|
+
// modelResponse after. Killed in between, the request had no response and
|
|
316
|
+
// rendered as running forever.
|
|
317
|
+
const child = await runNode(`
|
|
318
|
+
const fp = await import(${JSON.stringify(indexUrl())});
|
|
319
|
+
fp.configure({ baseDir: ${JSON.stringify(spool.dir)}, flushInterval: 3600 });
|
|
320
|
+
process.once("SIGTERM", () => { fp.flushSync(); process.exit(143); });
|
|
321
|
+
setInterval(() => {}, 1000);
|
|
322
|
+
setTimeout(() => process.kill(process.pid, "SIGTERM"), 50);
|
|
323
|
+
await fp.agent("planner", { sessionId: "model-term" }, async () => {
|
|
324
|
+
fp.event.modelRequest({ model: "m", requestId: "r1" });
|
|
325
|
+
await new Promise(() => {});
|
|
326
|
+
});
|
|
327
|
+
`);
|
|
328
|
+
expect(child.code).toBe(143);
|
|
329
|
+
const events = spool.events();
|
|
330
|
+
expect(events.map((e) => e.type)).toEqual(["agent_start", "model_request", "model_response", "error", "agent_end"]);
|
|
331
|
+
const response = events[2]!;
|
|
332
|
+
expect(response.request_id).toBe("r1");
|
|
333
|
+
expect(response.stop_reason).toBe("error");
|
|
334
|
+
expect(response.error).toMatch(/^ProcessExit: the process exited \(code 143\) while the model call/);
|
|
335
|
+
// Timed like the tools and hooks closed beside it.
|
|
336
|
+
expect(typeof response.duration_ms).toBe("number");
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it("names the uncaught exception a crash exited on, in what it closes", async () => {
|
|
340
|
+
// A timer throwing mid-run used to leave only "the process exited (code 1)"
|
|
341
|
+
// in the trace — the exception itself was nowhere.
|
|
342
|
+
const child = await runNode(`
|
|
343
|
+
const fp = await import(${JSON.stringify(indexUrl())});
|
|
344
|
+
fp.configure({ baseDir: ${JSON.stringify(spool.dir)}, flushInterval: 3600 });
|
|
345
|
+
setInterval(() => {}, 1000);
|
|
346
|
+
class QuotaError extends Error {}
|
|
347
|
+
setTimeout(() => { throw new QuotaError("boom from a timer"); }, 50);
|
|
348
|
+
await fp.agent("svc", { sessionId: "crash" }, async () => {
|
|
349
|
+
await fp.toolCall("slow", { toolCallId: "t1" }, () => new Promise(() => {}));
|
|
350
|
+
});
|
|
351
|
+
`);
|
|
352
|
+
expect(child.code).toBe(1);
|
|
353
|
+
expect(child.stderr).toContain("boom from a timer"); // still crashes as it would have
|
|
354
|
+
const events = spool.events();
|
|
355
|
+
expect(events.map((e) => e.type)).toEqual(["agent_start", "tool_use", "tool_result", "error", "agent_end"]);
|
|
356
|
+
expect(events[2]!.error).toMatch(/\(code 1\) on an uncaught QuotaError: boom from a timer while tool "slow"/);
|
|
357
|
+
expect(events[3]!.message).toMatch(/on an uncaught QuotaError: boom from a timer/);
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
it("closes a nested run most-recent-first: a sub-agent ends before the tool that started it", async () => {
|
|
361
|
+
// Live: a planner's delegate tool ran a writer sub-agent, killed during the
|
|
362
|
+
// writer's model call. Closing all tools before all agents showed the
|
|
363
|
+
// delegate tool finishing while the writer it started was still running.
|
|
364
|
+
const child = await runNode(`
|
|
365
|
+
const fp = await import(${JSON.stringify(indexUrl())});
|
|
366
|
+
fp.configure({ baseDir: ${JSON.stringify(spool.dir)}, flushInterval: 3600 });
|
|
367
|
+
process.once("SIGTERM", () => { fp.flushSync(); process.exit(143); });
|
|
368
|
+
setInterval(() => {}, 1000);
|
|
369
|
+
setTimeout(() => process.kill(process.pid, "SIGTERM"), 50);
|
|
370
|
+
await fp.agent("planner", { sessionId: "nested-term" }, async () => {
|
|
371
|
+
await fp.toolCall("delegate_writer", { toolCallId: "d1" }, async () => {
|
|
372
|
+
await fp.agent("writer", async () => {
|
|
373
|
+
fp.event.modelRequest({ model: "m", requestId: "w1" });
|
|
374
|
+
await new Promise(() => {});
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
`);
|
|
379
|
+
expect(child.code).toBe(143);
|
|
380
|
+
const closing = spool.events().slice(4); // planner start, tool_use, writer start, model_request
|
|
381
|
+
expect(closing.map((e) => [e.agent_id, e.type])).toEqual([
|
|
382
|
+
["writer", "model_response"],
|
|
383
|
+
["writer", "error"],
|
|
384
|
+
["writer", "agent_end"],
|
|
385
|
+
["planner", "tool_result"],
|
|
386
|
+
["planner", "error"],
|
|
387
|
+
["planner", "agent_end"],
|
|
388
|
+
]);
|
|
389
|
+
expect(closing.find((e) => e.type === "error")!.traceback).toBeUndefined();
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
it("closes nothing on a flushSync() while the process carries on", async () => {
|
|
393
|
+
const child = await runNode(`
|
|
394
|
+
const fp = await import(${JSON.stringify(indexUrl())});
|
|
395
|
+
fp.configure({ baseDir: ${JSON.stringify(spool.dir)}, flushInterval: 3600 });
|
|
396
|
+
await fp.agent("svc", { sessionId: "flush-test" }, async () => {
|
|
397
|
+
fp.flushSync();
|
|
398
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
399
|
+
});
|
|
400
|
+
`);
|
|
401
|
+
expect(child.code).toBe(0);
|
|
402
|
+
expect(spool.events().map((e) => [e.type, e.outcome ?? null])).toEqual([
|
|
403
|
+
["agent_start", null],
|
|
404
|
+
["agent_end", "success"],
|
|
405
|
+
]);
|
|
406
|
+
});
|
|
407
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"rootDir": "src",
|
|
5
|
+
"outDir": "dist/esm",
|
|
6
|
+
"module": "NodeNext",
|
|
7
|
+
"moduleResolution": "NodeNext",
|
|
8
|
+
"noEmit": false,
|
|
9
|
+
// `@internal` exports (test hooks such as `_stats`, `_internals`,
|
|
10
|
+
// `attach`) stay out of the published declarations: a name in a `.d.ts`
|
|
11
|
+
// is a name a customer can come to depend on.
|
|
12
|
+
"stripInternal": true
|
|
13
|
+
},
|
|
14
|
+
"include": ["src/**/*.ts"]
|
|
15
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
// Declarations are emitted here too, and `exports[*].require.types` points
|
|
4
|
+
// at them. Under dist/cjs's `"type": "commonjs"` they ARE CommonJS
|
|
5
|
+
// declarations; handing `require` the ESM ones instead is what made every
|
|
6
|
+
// CommonJS project on `module: node16` fail with TS1479.
|
|
7
|
+
"compilerOptions": {
|
|
8
|
+
"rootDir": "src",
|
|
9
|
+
"outDir": "dist/cjs",
|
|
10
|
+
"module": "CommonJS",
|
|
11
|
+
"moduleResolution": "Node10",
|
|
12
|
+
"noEmit": false,
|
|
13
|
+
// `@internal` exports (test hooks such as `_stats`, `_internals`,
|
|
14
|
+
// `attach`) stay out of the published declarations: a name in a `.d.ts`
|
|
15
|
+
// is a name a customer can come to depend on.
|
|
16
|
+
"stripInternal": true
|
|
17
|
+
},
|
|
18
|
+
"include": ["src/**/*.ts"]
|
|
19
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2023", "ESNext.Disposable"],
|
|
5
|
+
"module": "NodeNext",
|
|
6
|
+
"moduleResolution": "NodeNext",
|
|
7
|
+
"types": ["node"],
|
|
8
|
+
|
|
9
|
+
"strict": true,
|
|
10
|
+
"noUncheckedIndexedAccess": true,
|
|
11
|
+
"exactOptionalPropertyTypes": false,
|
|
12
|
+
"noImplicitOverride": true,
|
|
13
|
+
"noFallthroughCasesInSwitch": true,
|
|
14
|
+
"noUnusedLocals": true,
|
|
15
|
+
"noUnusedParameters": true,
|
|
16
|
+
"useUnknownInCatchVariables": true,
|
|
17
|
+
"verbatimModuleSyntax": false,
|
|
18
|
+
|
|
19
|
+
"declaration": true,
|
|
20
|
+
"declarationMap": true,
|
|
21
|
+
"sourceMap": true,
|
|
22
|
+
"esModuleInterop": true,
|
|
23
|
+
"forceConsistentCasingInFileNames": true,
|
|
24
|
+
"skipLibCheck": true,
|
|
25
|
+
"isolatedModules": true
|
|
26
|
+
},
|
|
27
|
+
"include": ["src/**/*.ts", "test/**/*.ts", "integration/*.ts", "scripts/**/*.mjs", "*.ts", "*.mts"]
|
|
28
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { defineConfig } from "vitest/config";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
// Vite searches UPWARD from the project root for a PostCSS config, and this
|
|
5
|
+
// package sits inside a monorepo whose root has one — which requires
|
|
6
|
+
// `@tailwindcss/postcss`, a root devDependency that is deliberately not in
|
|
7
|
+
// this package's isolated `node_modules`. Vite then dies before a single test
|
|
8
|
+
// runs.
|
|
9
|
+
//
|
|
10
|
+
// It only fails where the isolation is real: locally the root's
|
|
11
|
+
// `node_modules` is present and Node's resolution walks up into it, so the
|
|
12
|
+
// search succeeds and nothing looks wrong. In CI, where this package is
|
|
13
|
+
// installed on its own, it is fatal.
|
|
14
|
+
//
|
|
15
|
+
// An inline (empty) config turns the search off. This package has no CSS at
|
|
16
|
+
// all, so there is nothing to configure — the only thing that search can do
|
|
17
|
+
// here is find somebody else's tooling.
|
|
18
|
+
css: { postcss: {} },
|
|
19
|
+
test: {
|
|
20
|
+
include: ["test/**/*.test.ts"],
|
|
21
|
+
environment: "node",
|
|
22
|
+
globalSetup: ["./test/global-setup.ts"],
|
|
23
|
+
setupFiles: ["./test/setup.ts"],
|
|
24
|
+
// The writer, the sandbox and the adapters all reach for process-wide state
|
|
25
|
+
// (an exit hook, a patched prototype, a spool directory). Running files one
|
|
26
|
+
// at a time keeps a test from observing another file's patch, and keeps the
|
|
27
|
+
// sandbox suite from competing with itself for the concurrency semaphore.
|
|
28
|
+
pool: "forks",
|
|
29
|
+
fileParallelism: false,
|
|
30
|
+
testTimeout: 30_000,
|
|
31
|
+
hookTimeout: 30_000,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { defineConfig } from "vitest/config";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The real-framework suite (`integration/`). Separate from `vitest.config.ts`
|
|
5
|
+
* because it installs real frameworks from the registry and spawns real Node
|
|
6
|
+
* processes against the PACKED artifact — minutes, not seconds, and it needs
|
|
7
|
+
* the network the unit suite deliberately does not.
|
|
8
|
+
*/
|
|
9
|
+
export default defineConfig({
|
|
10
|
+
// Same reason as vitest.config.ts: stop Vite finding the monorepo root's
|
|
11
|
+
// PostCSS config, which needs a package this isolated install does not have.
|
|
12
|
+
css: { postcss: {} },
|
|
13
|
+
test: {
|
|
14
|
+
include: ["integration/**/*.test.ts"],
|
|
15
|
+
environment: "node",
|
|
16
|
+
globalSetup: ["./integration/global-setup.ts"],
|
|
17
|
+
// Every case is its own child process with its own spool, so files are
|
|
18
|
+
// independent and can run side by side.
|
|
19
|
+
fileParallelism: true,
|
|
20
|
+
testTimeout: 120_000,
|
|
21
|
+
hookTimeout: 900_000,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
@@ -9,7 +9,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
|
|
|
9
9
|
const hostname = process.env.HOSTNAME || '0.0.0.0'
|
|
10
10
|
|
|
11
11
|
let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
|
|
12
|
-
const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"1.0.7-beta.
|
|
12
|
+
const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"1.0.7-beta.2"},"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"instrumentationClientInject":[],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/failproofai/failproofai","enablePrerenderSourceMaps":true,"cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":true,"coldCacheBadge":false,"devValidationWorker":true,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"dynamicOnHover":false,"useOffline":false,"varyParams":true,"optimisticRouting":true,"instrumentationClientRouterTransitionEvents":false,"prefetchInlining":{"maxSize":2048,"maxBundleSize":10240},"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptOperationCache":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"devMemoryThresholdRestart":true,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"requestInsights":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"useTypeScriptCli":true,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":true,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"serverComponentsHmrCancellation":false,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":true,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","turbopackMemoryEvictionMode":"auto","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"useCacheTimeout":54,"instantInsights":{"validationLevel":"warning"},"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","outputFileTracingExcludes":{"*":["node_modules/@img/**","node_modules/sharp/**"]},"turbopack":{"root":"/home/runner/work/failproofai/failproofai"},"repoRoot":"/home/runner/work/failproofai/failproofai","distDirRoot":".next"}
|
|
13
13
|
|
|
14
14
|
process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
|
|
15
15
|
|
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
Wherever your agents run, we see it — and we can say no. Failproof hooks 12 agent
|
|
19
19
|
harnesses — coding CLIs like Claude Code and Codex, chat gateways like Hermes,
|
|
20
20
|
self-hosted assistants like OpenClaw — capturing every run and blocking dangerous
|
|
21
|
-
tool calls before they execute.
|
|
21
|
+
tool calls before they execute. 40 built-in policies. Zero latency. Runs locally.
|
|
22
22
|
|
|
23
23
|
</div>
|
|
24
24
|
|
|
@@ -176,7 +176,7 @@ three are the developer favourites — coding CLIs are the harness class we cove
|
|
|
176
176
|
deepest. The `sanitize-*` family is separate: it runs after a tool returns, so
|
|
177
177
|
it reports a secret in tool output rather than keeping it out of the context.
|
|
178
178
|
|
|
179
|
-
→ [All
|
|
179
|
+
→ [All 40 built-in policies](https://docs.befailproof.ai/policies/packs)
|
|
180
180
|
|
|
181
181
|
---
|
|
182
182
|
|