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,130 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { existsSync, mkdtempSync, readFileSync, readdirSync, rmSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
|
+
|
|
7
|
+
import { setBaseDir } from "../src/resolver.js";
|
|
8
|
+
import { runtime } from "../src/runtime.js";
|
|
9
|
+
|
|
10
|
+
export interface Spool {
|
|
11
|
+
dir: string;
|
|
12
|
+
/** Every event written so far, oldest batch first. */
|
|
13
|
+
events(): Array<Record<string, unknown>>;
|
|
14
|
+
/** The raw lines, for tests that care about bytes rather than values. */
|
|
15
|
+
lines(): string[];
|
|
16
|
+
files(): string[];
|
|
17
|
+
/**
|
|
18
|
+
* Drain the writer into THIS spool, then remove it.
|
|
19
|
+
*
|
|
20
|
+
* Draining first is not tidiness. The writer is process-wide and its queue
|
|
21
|
+
* outlives a test, so a test that left events buffered would have them
|
|
22
|
+
* flushed by the NEXT test — into that test's assertions, and, in the window
|
|
23
|
+
* where no base directory is set, into the developer's real
|
|
24
|
+
* `~/.failproofai/custom-agents`, where a running daemon would collect them.
|
|
25
|
+
*/
|
|
26
|
+
cleanup(): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A throwaway spool root with the writer pointed at it.
|
|
31
|
+
*
|
|
32
|
+
* Every test that emits anything needs this: without it they would write into
|
|
33
|
+
* the developer's real `~/.failproofai/custom-agents`, where a daemon would
|
|
34
|
+
* happily collect the fixtures and ship them.
|
|
35
|
+
*/
|
|
36
|
+
export function useSpool(): Spool {
|
|
37
|
+
const dir = mkdtempSync(join(tmpdir(), "failproofai-sdk-test-"));
|
|
38
|
+
setBaseDir(dir);
|
|
39
|
+
const eventsDir = join(dir, "events");
|
|
40
|
+
return {
|
|
41
|
+
dir,
|
|
42
|
+
files(): string[] {
|
|
43
|
+
try {
|
|
44
|
+
return readdirSync(eventsDir)
|
|
45
|
+
.filter((name) => name.endsWith(".jsonl"))
|
|
46
|
+
.sort();
|
|
47
|
+
} catch {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
lines(): string[] {
|
|
52
|
+
return this.files().flatMap((name) =>
|
|
53
|
+
readFileSync(join(eventsDir, name), "utf8").split("\n").filter(Boolean),
|
|
54
|
+
);
|
|
55
|
+
},
|
|
56
|
+
events(): Array<Record<string, unknown>> {
|
|
57
|
+
return this.lines().map((line) => JSON.parse(line) as Record<string, unknown>);
|
|
58
|
+
},
|
|
59
|
+
async cleanup(): Promise<void> {
|
|
60
|
+
await runtime.writer.flushNow();
|
|
61
|
+
setBaseDir(null);
|
|
62
|
+
rmSync(dir, { recursive: true, force: true });
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Flush the process-wide writer and read back what landed. */
|
|
68
|
+
export async function flushed(spool: Spool): Promise<Array<Record<string, unknown>>> {
|
|
69
|
+
await runtime.writer.flushNow();
|
|
70
|
+
return spool.events();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** The built ESM entry, as a URL a child process can import. */
|
|
74
|
+
export function indexUrl(): string {
|
|
75
|
+
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
76
|
+
const entry = join(root, "dist/esm/index.js");
|
|
77
|
+
if (!existsSync(entry)) {
|
|
78
|
+
throw new Error(`dist/esm/index.js is not built. Run \`npm run build\` (\`npm test\` does it).`);
|
|
79
|
+
}
|
|
80
|
+
return pathToFileURL(entry).href;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Run `source` in a FRESH Node process and collect its output.
|
|
85
|
+
*
|
|
86
|
+
* Some of this SDK's guarantees are about process lifetime — the flush interval
|
|
87
|
+
* must not keep the loop alive, and the exit hook must write what is buffered.
|
|
88
|
+
* Neither can be observed from inside a test runner, which holds the loop open
|
|
89
|
+
* by itself and never exits.
|
|
90
|
+
*/
|
|
91
|
+
export async function runNode(
|
|
92
|
+
source: string,
|
|
93
|
+
): Promise<{ code: number | null; stdout: string; stderr: string }> {
|
|
94
|
+
return await new Promise((resolve, reject) => {
|
|
95
|
+
const child = spawn(process.execPath, ["--input-type=module", "--eval", source], {
|
|
96
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
97
|
+
});
|
|
98
|
+
let stdout = "";
|
|
99
|
+
let stderr = "";
|
|
100
|
+
child.stdout.on("data", (chunk: Buffer) => (stdout += chunk.toString()));
|
|
101
|
+
child.stderr.on("data", (chunk: Buffer) => (stderr += chunk.toString()));
|
|
102
|
+
child.on("error", reject);
|
|
103
|
+
child.on("close", (code) => {
|
|
104
|
+
resolve({ code, stdout, stderr });
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** A minimal transcript for the evaluator tests. */
|
|
110
|
+
export function transcriptWire(
|
|
111
|
+
events: Array<{ type: string; payload?: Record<string, unknown> }> = [],
|
|
112
|
+
): Record<string, unknown> {
|
|
113
|
+
return {
|
|
114
|
+
schema_version: "2",
|
|
115
|
+
assignment_id: "assignment-1",
|
|
116
|
+
session_id: "session-1",
|
|
117
|
+
session_revision_id: "revision-1",
|
|
118
|
+
agent_id: "main",
|
|
119
|
+
environment: "dev",
|
|
120
|
+
started_at: "2026-01-01T00:00:00.000000Z",
|
|
121
|
+
ended_at: "2026-01-01T00:05:00.000000Z",
|
|
122
|
+
event_count: events.length,
|
|
123
|
+
events: events.map((event, index) => ({
|
|
124
|
+
id: `e${index}`,
|
|
125
|
+
ts: "2026-01-01T00:00:01.000000Z",
|
|
126
|
+
event_type: event.type,
|
|
127
|
+
payload: event.payload ?? {},
|
|
128
|
+
})),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { agent, session } from "../src/scopes.js";
|
|
4
|
+
import { setLogger } from "../src/logger.js";
|
|
5
|
+
import * as core from "../src/integrations/core.js";
|
|
6
|
+
import { parseVersion } from "../src/integrations/compat.js";
|
|
7
|
+
import { activeFrameworks, available, instrument, uninstrument } from "../src/integrations/index.js";
|
|
8
|
+
import { flushed, useSpool } from "./helpers.js";
|
|
9
|
+
import type { Spool } from "./helpers.js";
|
|
10
|
+
|
|
11
|
+
let spool: Spool;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
spool = useSpool();
|
|
15
|
+
core.setStrict(false);
|
|
16
|
+
core.resetFailures();
|
|
17
|
+
});
|
|
18
|
+
afterEach(async () => {
|
|
19
|
+
uninstrument();
|
|
20
|
+
await spool.cleanup();
|
|
21
|
+
core.setStrict(null);
|
|
22
|
+
setLogger(null);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe("failure policy", () => {
|
|
26
|
+
it("swallows a throwing hook and degrades the call site after repeated failures", () => {
|
|
27
|
+
setLogger({ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() });
|
|
28
|
+
const boom = (): never => {
|
|
29
|
+
throw new Error("hook is broken");
|
|
30
|
+
};
|
|
31
|
+
const wrapped = core.safe("test", boom);
|
|
32
|
+
for (let i = 0; i < 3; i += 1) expect(() => wrapped()).not.toThrow();
|
|
33
|
+
// A broken adapter costs one log line, not 40% of the process.
|
|
34
|
+
expect(core.isDegraded("test.boom")).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("catches a REJECTED PROMISE, not just a synchronous throw", async () => {
|
|
38
|
+
setLogger({ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() });
|
|
39
|
+
// Half of every framework's callback surface is async. A bare try/catch
|
|
40
|
+
// sees nothing when the body rejects; the rejection lands as an unhandled
|
|
41
|
+
// rejection, which Node terminates the process for.
|
|
42
|
+
const wrapped = core.safe("test", async () => {
|
|
43
|
+
throw new Error("async hook is broken");
|
|
44
|
+
});
|
|
45
|
+
await expect(wrapped()).resolves.toBeUndefined();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("re-throws under FAILPROOFAI_SDK_STRICT", () => {
|
|
49
|
+
core.setStrict(true);
|
|
50
|
+
const wrapped = core.safe("test", () => {
|
|
51
|
+
throw new Error("visible");
|
|
52
|
+
});
|
|
53
|
+
expect(() => wrapped()).toThrow("visible");
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe("wrapCallable", () => {
|
|
58
|
+
it("returns the original value and re-throws the original error, identity intact", async () => {
|
|
59
|
+
setLogger({ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() });
|
|
60
|
+
const failure = new Error("from the framework");
|
|
61
|
+
const throwing = core.wrapCallable(
|
|
62
|
+
() => {
|
|
63
|
+
throw failure;
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
before: () => {
|
|
67
|
+
throw new Error("before is broken");
|
|
68
|
+
},
|
|
69
|
+
after: () => {
|
|
70
|
+
throw new Error("after is broken");
|
|
71
|
+
},
|
|
72
|
+
onError: () => {
|
|
73
|
+
throw new Error("onError is broken");
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
);
|
|
77
|
+
// Every one of our hooks throws, and the caller still sees exactly theirs.
|
|
78
|
+
expect(() => throwing()).toThrow(failure);
|
|
79
|
+
|
|
80
|
+
const resolving = core.wrapCallable(async () => "value", {
|
|
81
|
+
after: () => {
|
|
82
|
+
throw new Error("after is broken");
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
await expect(resolving()).resolves.toBe("value");
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("settles our hooks on the PROMISE, not on the call", async () => {
|
|
89
|
+
const seen: string[] = [];
|
|
90
|
+
const wrapped = core.wrapCallable(async () => "v", {
|
|
91
|
+
after: () => seen.push("after"),
|
|
92
|
+
});
|
|
93
|
+
const pending = wrapped();
|
|
94
|
+
expect(seen).toEqual([]);
|
|
95
|
+
await pending;
|
|
96
|
+
expect(seen).toEqual(["after"]);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe("Patcher", () => {
|
|
101
|
+
it("restores exactly what it replaced", () => {
|
|
102
|
+
const target = { method: (): string => "original" };
|
|
103
|
+
const original = target.method;
|
|
104
|
+
const patcher = new core.Patcher();
|
|
105
|
+
patcher.patch(target, "method", () => "patched");
|
|
106
|
+
expect(target.method()).toBe("patched");
|
|
107
|
+
patcher.restoreAll();
|
|
108
|
+
expect(target.method).toBe(original);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("leaves a third party's patch alone rather than deleting it", () => {
|
|
112
|
+
setLogger({ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() });
|
|
113
|
+
const target = { method: (): string => "original" };
|
|
114
|
+
const patcher = new core.Patcher();
|
|
115
|
+
patcher.patch(target, "method", () => "ours");
|
|
116
|
+
const theirs = (): string => "theirs";
|
|
117
|
+
target.method = theirs;
|
|
118
|
+
patcher.restoreAll();
|
|
119
|
+
// Restoring here would delete their patch. Two instrumentation libraries
|
|
120
|
+
// un-patching each other is how both silently stop recording.
|
|
121
|
+
expect(target.method).toBe(theirs);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("reports rather than pretends when a target refuses assignment", () => {
|
|
125
|
+
const frozen = Object.freeze({ method: (): string => "original" });
|
|
126
|
+
const patcher = new core.Patcher();
|
|
127
|
+
expect(patcher.patch(frozen, "method", () => "ours")).toBe(false);
|
|
128
|
+
expect(patcher.size).toBe(0);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe("payload discipline", () => {
|
|
133
|
+
it("truncates a long string and says so", () => {
|
|
134
|
+
const out = core.payload({ fw_prompt: "x".repeat(20_000) });
|
|
135
|
+
expect((out.fw_prompt as string).length).toBeLessThanOrEqual(core.FIELD_LIMIT);
|
|
136
|
+
expect(out.fw_truncated).toBe(true);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("keeps the SMALL fields when the budget runs out, not the first ones", () => {
|
|
140
|
+
// The adapters put the big payload before the metadata, so insertion order
|
|
141
|
+
// would drop `fw_run_id` — the field that says which run the payload
|
|
142
|
+
// belongs to — and keep the oversized blob.
|
|
143
|
+
const out = core.payload({
|
|
144
|
+
fw_inputs: "x".repeat(core.EVENT_BUDGET * 2),
|
|
145
|
+
fw_run_id: "run-1",
|
|
146
|
+
fw_node: "retrieve",
|
|
147
|
+
});
|
|
148
|
+
expect(out.fw_run_id).toBe("run-1");
|
|
149
|
+
expect(out.fw_node).toBe("retrieve");
|
|
150
|
+
expect(out.fw_truncated).toBe(true);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it("caps list and depth growth", () => {
|
|
154
|
+
const deep = core.truncate({ a: { b: { c: { d: { e: { f: { g: 1 } } } } } } });
|
|
155
|
+
expect(JSON.stringify(deep)).not.toContain('"g"');
|
|
156
|
+
const wide = core.truncate(Array.from({ length: 300 }, (_, i) => i)) as unknown[];
|
|
157
|
+
expect(wide.length).toBeLessThanOrEqual(101);
|
|
158
|
+
expect(String(wide.at(-1))).toContain("more items truncated");
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("renders a class instance as data rather than as a repr string", () => {
|
|
162
|
+
class Weather {
|
|
163
|
+
constructor(
|
|
164
|
+
readonly city: string,
|
|
165
|
+
readonly celsius: number,
|
|
166
|
+
) {}
|
|
167
|
+
}
|
|
168
|
+
expect(core.truncate(new Weather("Faro", 21))).toEqual({ city: "Faro", celsius: 21 });
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("does not run a throwing getter into the caller's face", () => {
|
|
172
|
+
const hostile = {
|
|
173
|
+
get boom(): never {
|
|
174
|
+
throw new Error("lazy attribute");
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
expect(() => core.truncate(hostile)).not.toThrow();
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
describe("extras namespacing", () => {
|
|
182
|
+
it("prefixes fw_ and drops nullish values", () => {
|
|
183
|
+
expect(core.fwFields({ run_id: "r", node: "n", tags: null, missing: undefined })).toEqual({
|
|
184
|
+
fw_run_id: "r",
|
|
185
|
+
fw_node: "n",
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it("leaves the deliberate top-level names alone", () => {
|
|
190
|
+
expect(core.fwFields({ duration_ms: 12, usage: { a: 1 }, request_id: "r" })).toEqual({
|
|
191
|
+
duration_ms: 12,
|
|
192
|
+
usage: { a: 1 },
|
|
193
|
+
request_id: "r",
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("refuses an extra that would overwrite a declared field", () => {
|
|
198
|
+
setLogger({ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() });
|
|
199
|
+
// The schema merges extras LAST, so this would silently change a promoted
|
|
200
|
+
// column and every test would still pass.
|
|
201
|
+
expect(core.guardExtras({ tool_name: "hijacked", fw_ok: 1 })).toEqual({ fw_ok: 1 });
|
|
202
|
+
core.setStrict(true);
|
|
203
|
+
expect(() => core.guardExtras({ outcome: "hijacked" })).toThrow(/would overwrite/);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
describe("agent id normalization", () => {
|
|
208
|
+
it("replaces a bare id, which would poison a LowCardinality facet", () => {
|
|
209
|
+
expect(core.normalizeAgentId("3f9a1c2b-0000-4000-8000-000000000000")).toBe("main");
|
|
210
|
+
expect(core.normalizeAgentId("a".repeat(32))).toBe("main");
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it("strips a per-run id from a readable prefix rather than discarding the name", () => {
|
|
214
|
+
expect(core.normalizeAgentId("agent-3f9a1c2b-0000-4000-8000-000000000000")).toBe("agent");
|
|
215
|
+
expect(core.normalizeAgentId("crew_" + "a".repeat(32))).toBe("crew");
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it("leaves an ordinary name untouched, separators and all", () => {
|
|
219
|
+
expect(core.normalizeAgentId("node_a_b")).toBe("node_a_b");
|
|
220
|
+
expect(core.normalizeAgentId("agent-v2")).toBe("agent-v2");
|
|
221
|
+
expect(core.normalizeAgentId("step-3")).toBe("step-3");
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it("bounds the length and falls back on nothing", () => {
|
|
225
|
+
expect(core.normalizeAgentId("x".repeat(200)).length).toBe(64);
|
|
226
|
+
expect(core.normalizeAgentId(null)).toBe("main");
|
|
227
|
+
expect(core.normalizeAgentId(" ")).toBe("main");
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
describe("RunTracker", () => {
|
|
232
|
+
it("emits against a framework's own run ids", async () => {
|
|
233
|
+
const tracker = new core.RunTracker("test");
|
|
234
|
+
tracker.startAgent("run-1", { agentId: "planner", sessionId: "s1", goal: "g" });
|
|
235
|
+
tracker.emit("toolUse", "tool-1", {
|
|
236
|
+
parentKey: "run-1",
|
|
237
|
+
toolName: "search",
|
|
238
|
+
toolCallId: "tool-1",
|
|
239
|
+
});
|
|
240
|
+
tracker.endAgent("run-1", { outcome: "success" });
|
|
241
|
+
|
|
242
|
+
const events = await flushed(spool);
|
|
243
|
+
expect(events.map((event) => event.type)).toEqual(["agent_start", "tool_use", "agent_end"]);
|
|
244
|
+
expect(events.every((event) => event.session_id === "s1")).toBe(true);
|
|
245
|
+
expect(events[1]!.agent_id).toBe("planner");
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it("walks the parent chain more than one hop", async () => {
|
|
249
|
+
const tracker = new core.RunTracker("test");
|
|
250
|
+
tracker.startAgent("root", { agentId: "planner", sessionId: "s1" });
|
|
251
|
+
// An intermediate framework run is a link, not a span.
|
|
252
|
+
tracker.link("middle", "root");
|
|
253
|
+
tracker.emit("toolUse", "leaf", { parentKey: "middle", toolName: "t", toolCallId: "leaf" });
|
|
254
|
+
const toolUse = (await flushed(spool)).find((event) => event.type === "tool_use")!;
|
|
255
|
+
expect(toolUse.agent_id).toBe("planner");
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it("joins a hand-written scope, producing ONE tree rather than two", async () => {
|
|
259
|
+
const tracker = new core.RunTracker("test");
|
|
260
|
+
await agent("planner", { sessionId: "s1" }, () => {
|
|
261
|
+
tracker.startAgent("run-1", { agentId: "retriever" });
|
|
262
|
+
});
|
|
263
|
+
const starts = (await flushed(spool)).filter((event) => event.type === "agent_start");
|
|
264
|
+
const nested = starts.find((event) => event.agent_id === "retriever")!;
|
|
265
|
+
expect(nested.session_id).toBe("s1");
|
|
266
|
+
expect(nested.parent_id).toBe("planner");
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it("does NOT claim a parent inside a bare session, which would render as a forever-ongoing span", async () => {
|
|
270
|
+
const tracker = new core.RunTracker("test");
|
|
271
|
+
await session({ sessionId: "s1" }, () => {
|
|
272
|
+
tracker.startAgent("run-1", { agentId: "retriever" });
|
|
273
|
+
});
|
|
274
|
+
const start = (await flushed(spool)).find((event) => event.type === "agent_start")!;
|
|
275
|
+
expect(start.parent_id).toBeUndefined();
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it("drops an unresolvable event with ONE warning rather than inventing a session", async () => {
|
|
279
|
+
const warn = vi.fn();
|
|
280
|
+
setLogger({ debug: vi.fn(), info: vi.fn(), warn, error: vi.fn() });
|
|
281
|
+
const tracker = new core.RunTracker("test");
|
|
282
|
+
tracker.emit("toolUse", "orphan", { toolName: "t", toolCallId: "orphan" });
|
|
283
|
+
tracker.emit("toolUse", "orphan2", { toolName: "t", toolCallId: "orphan2" });
|
|
284
|
+
// A synthesized session id splits one run into many.
|
|
285
|
+
expect(await flushed(spool)).toEqual([]);
|
|
286
|
+
expect(warn).toHaveBeenCalledTimes(1);
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
it("closes what it opened, so a dead session does not render as ongoing forever", async () => {
|
|
290
|
+
const tracker = new core.RunTracker("test");
|
|
291
|
+
tracker.startAgent("a", { agentId: "one", sessionId: "s1" });
|
|
292
|
+
tracker.startAgent("b", { agentId: "two", sessionId: "s1" });
|
|
293
|
+
tracker.closeOpenAgents();
|
|
294
|
+
const ends = (await flushed(spool)).filter((event) => event.type === "agent_end");
|
|
295
|
+
expect(ends.map((event) => event.agent_id)).toEqual(["two", "one"]);
|
|
296
|
+
expect(ends.every((event) => event.outcome === "cancelled")).toBe(true);
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it("evicts oldest-first rather than growing unboundedly", () => {
|
|
300
|
+
const tracker = new core.RunTracker("test", { maxOpen: 4 });
|
|
301
|
+
for (let i = 0; i < 20; i += 1) {
|
|
302
|
+
tracker.startAgent(`run-${i}`, { agentId: "a", sessionId: "s1" });
|
|
303
|
+
}
|
|
304
|
+
expect(tracker.openAgents().length).toBeLessThanOrEqual(4);
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it("truncates the declared fields as well as the extras, under ONE truncation flag", async () => {
|
|
308
|
+
const tracker = new core.RunTracker("test", { fieldLimit: 64 });
|
|
309
|
+
tracker.startAgent("run-1", { agentId: "a", sessionId: "s1" });
|
|
310
|
+
tracker.emit("toolResult", "t1", {
|
|
311
|
+
parentKey: "run-1",
|
|
312
|
+
toolName: "search",
|
|
313
|
+
toolCallId: "t1",
|
|
314
|
+
output: "y".repeat(500),
|
|
315
|
+
});
|
|
316
|
+
const result = (await flushed(spool)).find((event) => event.type === "tool_result")!;
|
|
317
|
+
expect((result.output as string).length).toBeLessThanOrEqual(64 + "…[truncated]".length);
|
|
318
|
+
// `fw_truncated` has to mean "this event lost data" — `output` is cut on
|
|
319
|
+
// essentially every real tool loop, and it is the field an operator filters
|
|
320
|
+
// on to find where.
|
|
321
|
+
expect(result.fw_truncated).toBe(true);
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
describe("the registry", () => {
|
|
326
|
+
it("lists the frameworks it can instrument", () => {
|
|
327
|
+
expect(available()).toEqual(["ai", "langchain", "llamaindex", "mastra"]);
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it("throws on an unknown name, listing the valid ones", async () => {
|
|
331
|
+
// A typo that silently records nothing is the worst outcome available.
|
|
332
|
+
await expect(instrument("langchian")).rejects.toThrow(/unknown framework/);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
it("accepts the spellings people actually type", async () => {
|
|
336
|
+
setLogger({ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() });
|
|
337
|
+
// LangGraph is served by the LangChain adapter; neither is installed here,
|
|
338
|
+
// so the install fails and is skipped — which is itself the contract.
|
|
339
|
+
await expect(instrument("langgraph")).resolves.toEqual([]);
|
|
340
|
+
expect(activeFrameworks()).toEqual([]);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it("does not throw when a framework is absent — it logs and moves on", async () => {
|
|
344
|
+
setLogger({ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() });
|
|
345
|
+
await expect(instrument("mastra")).resolves.toEqual([]);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it("uninstrumenting an unknown name is a no-op, not a throw", () => {
|
|
349
|
+
setLogger({ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() });
|
|
350
|
+
expect(uninstrument("nonsense")).toEqual([]);
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
describe("version parsing", () => {
|
|
355
|
+
it("reads the leading numeric components only", () => {
|
|
356
|
+
expect(parseVersion("1.5.2")).toEqual([1, 5, 2]);
|
|
357
|
+
expect(parseVersion("2.0.0-beta.1")).toEqual([2, 0, 0]);
|
|
358
|
+
expect(parseVersion("0.14.23+build")).toEqual([0, 14, 23]);
|
|
359
|
+
expect(parseVersion("next")).toEqual([]);
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
describe("duration rounding", () => {
|
|
364
|
+
it("returns a whole non-negative integer, because the server drops anything else", () => {
|
|
365
|
+
expect(core.ms(12.7)).toBe(13);
|
|
366
|
+
expect(core.ms(-5)).toBe(0);
|
|
367
|
+
expect(Number.isInteger(core.ms(0.4))).toBe(true);
|
|
368
|
+
});
|
|
369
|
+
});
|