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,623 @@
|
|
|
1
|
+
// LangChain.js / LangGraph.js consumer. Run as `node agent.{mjs,cjs} <case>`.
|
|
2
|
+
//
|
|
3
|
+
// Deliberately the shape a customer writes: import the framework, instrument,
|
|
4
|
+
// run. The scripted model makes it deterministic and offline — first call asks
|
|
5
|
+
// for the `get_weather` tool, the next one answers — and mirrors the Python
|
|
6
|
+
// SDK's golden trace for the same graph, which is what the assertions compare
|
|
7
|
+
// against.
|
|
8
|
+
//
|
|
9
|
+
// The SAME file is the agent of every `langchain-*` fixture (it is copied, not
|
|
10
|
+
// shared, because the harness transpiles each fixture's own `agent.ts` beside
|
|
11
|
+
// its own `node_modules`). Keep it to APIs present across the whole declared
|
|
12
|
+
// peer range, so a failure is always the adapter's and never the fixture's.
|
|
13
|
+
import { spawnSync } from "node:child_process";
|
|
14
|
+
import { readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
15
|
+
|
|
16
|
+
import * as failproofai from "@failproofai/sdk";
|
|
17
|
+
import { langchainHandler } from "@failproofai/sdk/langchain";
|
|
18
|
+
import type { CallbackManagerForLLMRun } from "@langchain/core/callbacks/manager";
|
|
19
|
+
import { Document } from "@langchain/core/documents";
|
|
20
|
+
import { Embeddings } from "@langchain/core/embeddings";
|
|
21
|
+
import {
|
|
22
|
+
BaseChatModel,
|
|
23
|
+
type BaseChatModelCallOptions,
|
|
24
|
+
type BaseChatModelParams,
|
|
25
|
+
} from "@langchain/core/language_models/chat_models";
|
|
26
|
+
import { AIMessage, AIMessageChunk, HumanMessage, type BaseMessage } from "@langchain/core/messages";
|
|
27
|
+
import { StringOutputParser } from "@langchain/core/output_parsers";
|
|
28
|
+
import { ChatGenerationChunk, type ChatResult } from "@langchain/core/outputs";
|
|
29
|
+
import { ChatPromptTemplate } from "@langchain/core/prompts";
|
|
30
|
+
import { BaseRetriever } from "@langchain/core/retrievers";
|
|
31
|
+
import {
|
|
32
|
+
RunnableLambda,
|
|
33
|
+
RunnableParallel,
|
|
34
|
+
RunnablePassthrough,
|
|
35
|
+
RunnableSequence,
|
|
36
|
+
type RunnableConfig,
|
|
37
|
+
} from "@langchain/core/runnables";
|
|
38
|
+
import { tool } from "@langchain/core/tools";
|
|
39
|
+
import { convertToOpenAITool } from "@langchain/core/utils/function_calling";
|
|
40
|
+
import { VectorStore } from "@langchain/core/vectorstores";
|
|
41
|
+
import { Annotation, Command, END, MemorySaver, MessagesAnnotation, START, StateGraph, interrupt } from "@langchain/langgraph";
|
|
42
|
+
import { ToolNode, createReactAgent } from "@langchain/langgraph/prebuilt";
|
|
43
|
+
import { z } from "zod";
|
|
44
|
+
|
|
45
|
+
class ScriptedModel extends BaseChatModel {
|
|
46
|
+
calls = 0;
|
|
47
|
+
private readonly fail: boolean;
|
|
48
|
+
|
|
49
|
+
constructor(fields: BaseChatModelParams & { fail?: boolean } = {}) {
|
|
50
|
+
super(fields);
|
|
51
|
+
this.fail = fields.fail ?? false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
_llmType(): string {
|
|
55
|
+
return "scripted";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// The script decides the tool calls; binding only has to hand back a model.
|
|
59
|
+
override bindTools(): this {
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async _generate(messages: BaseMessage[]): Promise<ChatResult> {
|
|
64
|
+
this.calls += 1;
|
|
65
|
+
if (this.fail) throw new Error("model exploded");
|
|
66
|
+
const answered = messages.some((m) => m.getType() === "tool");
|
|
67
|
+
const message = answered
|
|
68
|
+
? new AIMessage({
|
|
69
|
+
content: "It is sunny in Paris.",
|
|
70
|
+
usage_metadata: { input_tokens: 30, output_tokens: 7, total_tokens: 37 },
|
|
71
|
+
response_metadata: { finish_reason: "stop" },
|
|
72
|
+
})
|
|
73
|
+
: new AIMessage({
|
|
74
|
+
content: "",
|
|
75
|
+
tool_calls: [{ id: "call_1", name: "get_weather", args: { city: "Paris" }, type: "tool_call" }],
|
|
76
|
+
usage_metadata: { input_tokens: 12, output_tokens: 5, total_tokens: 17 },
|
|
77
|
+
response_metadata: { finish_reason: "tool_calls" },
|
|
78
|
+
});
|
|
79
|
+
return { generations: [{ text: typeof message.content === "string" ? message.content : "", message }] };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* A model that streams, the way a real provider integration does: one chunk
|
|
85
|
+
* per piece, each reported through `handleLLMNewToken`. Five chunks, the same
|
|
86
|
+
* split the Python golden's `GenericFakeChatModel` makes of this sentence.
|
|
87
|
+
*/
|
|
88
|
+
class StreamingModel extends ScriptedModel {
|
|
89
|
+
override async *_streamResponseChunks(
|
|
90
|
+
_messages: BaseMessage[],
|
|
91
|
+
_options: this["ParsedCallOptions"],
|
|
92
|
+
runManager?: CallbackManagerForLLMRun,
|
|
93
|
+
): AsyncGenerator<ChatGenerationChunk> {
|
|
94
|
+
for (const text of ["hello", " ", "there", " ", "friend"]) {
|
|
95
|
+
const chunk = new ChatGenerationChunk({ text, message: new AIMessageChunk({ content: text }) });
|
|
96
|
+
yield chunk;
|
|
97
|
+
await runManager?.handleLLMNewToken(text, undefined, undefined, undefined, undefined, { chunk });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const getWeather = tool(async ({ city }: { city: string }) => `sunny in ${city}`, {
|
|
103
|
+
name: "get_weather",
|
|
104
|
+
description: "Current weather for a city",
|
|
105
|
+
schema: z.object({ city: z.string() }),
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Same name, and it fails. `ToolNode` turns the throw into an error
|
|
109
|
+
// ToolMessage for the model, so the RUN carries on — the failure belongs to the
|
|
110
|
+
// tool call alone.
|
|
111
|
+
const brokenWeather = tool(
|
|
112
|
+
async ({ city }: { city: string }): Promise<string> => {
|
|
113
|
+
throw new Error(`no weather for ${city}`);
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: "get_weather",
|
|
117
|
+
description: "Current weather for a city",
|
|
118
|
+
schema: z.object({ city: z.string() }),
|
|
119
|
+
},
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
// Plain LangChain: LCEL, retrievers, structured output, bound tools
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
|
|
126
|
+
const ANSWER = "It is sunny in Paris.";
|
|
127
|
+
/** How `AnswerModel` streams `ANSWER`: five chunks, usage on the last one. */
|
|
128
|
+
const ANSWER_CHUNKS = ["It", " is", " sunny", " in", " Paris."];
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Always answers, and streams like a provider does. The usage rides on the
|
|
132
|
+
* LAST chunk, where OpenAI and Anthropic put it, so a streamed call's tokens
|
|
133
|
+
* survive only if the adapter reads the aggregated generation.
|
|
134
|
+
*/
|
|
135
|
+
class AnswerModel extends BaseChatModel {
|
|
136
|
+
_llmType(): string {
|
|
137
|
+
return "answer";
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async _generate(): Promise<ChatResult> {
|
|
141
|
+
const message = new AIMessage({
|
|
142
|
+
content: ANSWER,
|
|
143
|
+
usage_metadata: { input_tokens: 30, output_tokens: 7, total_tokens: 37 },
|
|
144
|
+
response_metadata: { finish_reason: "stop" },
|
|
145
|
+
});
|
|
146
|
+
return { generations: [{ text: ANSWER, message }] };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
override async *_streamResponseChunks(
|
|
150
|
+
_messages: BaseMessage[],
|
|
151
|
+
_options: this["ParsedCallOptions"],
|
|
152
|
+
runManager?: CallbackManagerForLLMRun,
|
|
153
|
+
): AsyncGenerator<ChatGenerationChunk> {
|
|
154
|
+
for (const [index, text] of ANSWER_CHUNKS.entries()) {
|
|
155
|
+
const last = index === ANSWER_CHUNKS.length - 1;
|
|
156
|
+
const message = new AIMessageChunk({
|
|
157
|
+
content: text,
|
|
158
|
+
...(last ? { usage_metadata: { input_tokens: 30, output_tokens: 7, total_tokens: 37 } } : {}),
|
|
159
|
+
});
|
|
160
|
+
const chunk = new ChatGenerationChunk({ text, message });
|
|
161
|
+
yield chunk;
|
|
162
|
+
await runManager?.handleLLMNewToken(text, undefined, undefined, undefined, undefined, { chunk });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
interface ToolCallingOptions extends BaseChatModelCallOptions {
|
|
168
|
+
tools?: Array<{ function?: { name?: string } }>;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* A model that binds tools the way a real provider integration does: the
|
|
173
|
+
* formatted tools and `tool_choice` ride on the call options, and come back
|
|
174
|
+
* out through `invocationParams` — which is where the adapter reads them.
|
|
175
|
+
* Asks for whichever tool it was bound to first, then answers — as a chunk,
|
|
176
|
+
* which is what a 1.x provider returns and what `withStructuredOutput` checks.
|
|
177
|
+
*/
|
|
178
|
+
class ToolCallingModel extends BaseChatModel<ToolCallingOptions> {
|
|
179
|
+
_llmType(): string {
|
|
180
|
+
return "tool-calling";
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
override invocationParams(options?: this["ParsedCallOptions"]): Record<string, unknown> {
|
|
184
|
+
return { model: "tool-calling-1", tools: options?.tools, tool_choice: options?.tool_choice };
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
override bindTools(tools: unknown[], kwargs?: Partial<ToolCallingOptions>) {
|
|
188
|
+
return this.withConfig({
|
|
189
|
+
tools: tools.map((t) => convertToOpenAITool(t as never)),
|
|
190
|
+
...kwargs,
|
|
191
|
+
} as Partial<ToolCallingOptions>) as never;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async _generate(messages: BaseMessage[], options: this["ParsedCallOptions"]): Promise<ChatResult> {
|
|
195
|
+
const wanted = options.tools?.[0]?.function?.name ?? "get_weather";
|
|
196
|
+
const answered = messages.some((m) => m.getType() === "tool");
|
|
197
|
+
const message = answered
|
|
198
|
+
? new AIMessageChunk({
|
|
199
|
+
content: ANSWER,
|
|
200
|
+
usage_metadata: { input_tokens: 30, output_tokens: 7, total_tokens: 37 },
|
|
201
|
+
})
|
|
202
|
+
: new AIMessageChunk({
|
|
203
|
+
content: "",
|
|
204
|
+
tool_calls: [
|
|
205
|
+
wanted === "Weather"
|
|
206
|
+
? { id: "call_s", name: "Weather", args: { city: "Paris", sky: "sunny" }, type: "tool_call" }
|
|
207
|
+
: { id: "call_1", name: "get_weather", args: { city: "Paris" }, type: "tool_call" },
|
|
208
|
+
],
|
|
209
|
+
usage_metadata: { input_tokens: 12, output_tokens: 5, total_tokens: 17 },
|
|
210
|
+
});
|
|
211
|
+
return { generations: [{ text: typeof message.content === "string" ? message.content : "", message }] };
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const WEATHER_DOCS = [
|
|
216
|
+
new Document({ pageContent: "Paris is sunny", metadata: { source: "wx.txt" } }),
|
|
217
|
+
new Document({ pageContent: "Rome is rainy", metadata: { source: "wx2.txt" } }),
|
|
218
|
+
];
|
|
219
|
+
|
|
220
|
+
/** The smallest custom retriever: what a hand-rolled RAG lookup is. */
|
|
221
|
+
class Docs extends BaseRetriever {
|
|
222
|
+
lc_namespace = ["failproofai", "fixtures"];
|
|
223
|
+
|
|
224
|
+
async _getRelevantDocuments(_query: string): Promise<Document[]> {
|
|
225
|
+
return WEATHER_DOCS;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** Deterministic, offline embeddings: letter frequencies. */
|
|
230
|
+
class LetterEmbeddings extends Embeddings {
|
|
231
|
+
constructor() {
|
|
232
|
+
super({});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
private vector(text: string): number[] {
|
|
236
|
+
const out = new Array<number>(26).fill(0);
|
|
237
|
+
for (const ch of text.toLowerCase()) {
|
|
238
|
+
const code = ch.charCodeAt(0) - 97;
|
|
239
|
+
if (code >= 0 && code < 26) out[code] += 1;
|
|
240
|
+
}
|
|
241
|
+
return out;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async embedDocuments(texts: string[]): Promise<number[][]> {
|
|
245
|
+
return texts.map((text) => this.vector(text));
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
async embedQuery(text: string): Promise<number[]> {
|
|
249
|
+
return this.vector(text);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* An in-memory vector store, so `.asRetriever()` — the retriever almost every
|
|
255
|
+
* RAG app actually runs — is exercised without a network or a native module.
|
|
256
|
+
*/
|
|
257
|
+
class TinyVectorStore extends VectorStore {
|
|
258
|
+
declare FilterType: never;
|
|
259
|
+
private rows: Array<{ vector: number[]; doc: Document }> = [];
|
|
260
|
+
|
|
261
|
+
_vectorstoreType(): string {
|
|
262
|
+
return "tiny";
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
async addVectors(vectors: number[][], documents: Document[]): Promise<void> {
|
|
266
|
+
vectors.forEach((vector, i) => this.rows.push({ vector, doc: documents[i]! }));
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
async addDocuments(documents: Document[]): Promise<void> {
|
|
270
|
+
await this.addVectors(await this.embeddings.embedDocuments(documents.map((d) => d.pageContent)), documents);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
async similaritySearchVectorWithScore(query: number[], k: number): Promise<Array<[Document, number]>> {
|
|
274
|
+
const dot = (a: number[], b: number[]) => a.reduce((sum, x, i) => sum + x * (b[i] ?? 0), 0);
|
|
275
|
+
return this.rows
|
|
276
|
+
.map(({ vector, doc }): [Document, number] => [doc, dot(vector, query)])
|
|
277
|
+
.sort((a, b) => b[1] - a[1])
|
|
278
|
+
.slice(0, k);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const prompt = () => ChatPromptTemplate.fromMessages([["human", "{q}"]]);
|
|
283
|
+
const lcel = () => prompt().pipe(new AnswerModel({})).pipe(new StringOutputParser());
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Every plain-LangChain surface, each runnable with or without an explicit
|
|
287
|
+
* handler: `<name>` runs it under `instrument()`, `handler:<name>` passes
|
|
288
|
+
* `callbacks: [langchainHandler()]` instead and never instruments.
|
|
289
|
+
*/
|
|
290
|
+
const SURFACES: Record<string, (config: RunnableConfig) => Promise<unknown>> = {
|
|
291
|
+
lcel: (config) => lcel().invoke({ q: "weather?" }, config),
|
|
292
|
+
sequence: (config) =>
|
|
293
|
+
RunnableSequence.from([
|
|
294
|
+
RunnableLambda.from((x: number) => x + 1),
|
|
295
|
+
RunnableLambda.from((x: number) => x * 2),
|
|
296
|
+
]).invoke(1, config),
|
|
297
|
+
parallel: (config) =>
|
|
298
|
+
RunnableParallel.from({
|
|
299
|
+
a: RunnableLambda.from((x: number) => x + 1),
|
|
300
|
+
b: RunnableLambda.from((x: number) => x * 2),
|
|
301
|
+
}).invoke(1, config),
|
|
302
|
+
lambda: (config) => RunnableLambda.from((x: string) => x.toUpperCase()).withConfig({ runName: "shout" }).invoke("abc", config),
|
|
303
|
+
retriever: (config) => new Docs().invoke("weather in Paris", config),
|
|
304
|
+
vectorstore: async (config) => {
|
|
305
|
+
const store = new TinyVectorStore(new LetterEmbeddings(), {});
|
|
306
|
+
await store.addDocuments([WEATHER_DOCS[0]!]);
|
|
307
|
+
return store.asRetriever({ k: 1 }).invoke("Paris", config);
|
|
308
|
+
},
|
|
309
|
+
rag: (config) =>
|
|
310
|
+
RunnableSequence.from([
|
|
311
|
+
{
|
|
312
|
+
context: new Docs().pipe((docs: Document[]) => docs.map((d) => d.pageContent).join("\n")),
|
|
313
|
+
q: new RunnablePassthrough(),
|
|
314
|
+
},
|
|
315
|
+
ChatPromptTemplate.fromMessages([["human", "{context}\n{q}"]]),
|
|
316
|
+
new AnswerModel({}),
|
|
317
|
+
new StringOutputParser(),
|
|
318
|
+
]).invoke("weather?", config),
|
|
319
|
+
batch3: (config) => lcel().batch([{ q: "a" }, { q: "b" }, { q: "c" }], config),
|
|
320
|
+
"stream-events": async (config) => {
|
|
321
|
+
const kinds: string[] = [];
|
|
322
|
+
for await (const event of lcel().streamEvents({ q: "weather?" }, { ...config, version: "v2" })) {
|
|
323
|
+
kinds.push(event.event);
|
|
324
|
+
}
|
|
325
|
+
return kinds.includes("on_chat_model_stream");
|
|
326
|
+
},
|
|
327
|
+
"lcel-stream": async (config) => {
|
|
328
|
+
let text = "";
|
|
329
|
+
for await (const chunk of await lcel().stream({ q: "weather?" }, config)) text += chunk;
|
|
330
|
+
return text;
|
|
331
|
+
},
|
|
332
|
+
structured: (config) =>
|
|
333
|
+
new ToolCallingModel({})
|
|
334
|
+
.withStructuredOutput(z.object({ city: z.string(), sky: z.string() }), { name: "Weather" })
|
|
335
|
+
.invoke("weather?", config),
|
|
336
|
+
"bind-tools": (config) =>
|
|
337
|
+
(new ToolCallingModel({}).bindTools([getWeather], { tool_choice: "get_weather" }) as unknown as ToolCallingModel)
|
|
338
|
+
.invoke("weather?", config)
|
|
339
|
+
.then((message) => (message as AIMessage).tool_calls?.length),
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
function buildGraph(model: ScriptedModel, tools = [getWeather]) {
|
|
343
|
+
const callModel = async (state: typeof MessagesAnnotation.State) => ({
|
|
344
|
+
messages: [await model.invoke(state.messages)],
|
|
345
|
+
});
|
|
346
|
+
const route = (state: typeof MessagesAnnotation.State) => {
|
|
347
|
+
const last = state.messages[state.messages.length - 1] as AIMessage;
|
|
348
|
+
return last.tool_calls?.length ? "tools" : END;
|
|
349
|
+
};
|
|
350
|
+
return new StateGraph(MessagesAnnotation)
|
|
351
|
+
.addNode("agent", callModel)
|
|
352
|
+
.addNode("tools", new ToolNode(tools))
|
|
353
|
+
.addEdge(START, "agent")
|
|
354
|
+
.addConditionalEdges("agent", route, ["tools", END])
|
|
355
|
+
.addEdge("tools", "agent")
|
|
356
|
+
.compile({ name: "weather_graph" });
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const Trail = Annotation.Root({
|
|
360
|
+
trail: Annotation<string[]>({ reducer: (a, b) => a.concat(b), default: () => [] }),
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
/** plan -> approve (asks a human) -> act, checkpointed so it can be resumed. */
|
|
364
|
+
function buildHitlGraph(checkpointer = new MemorySaver()) {
|
|
365
|
+
return new StateGraph(Trail)
|
|
366
|
+
.addNode("plan", async () => ({ trail: ["plan"] }))
|
|
367
|
+
.addNode("approve", async () => {
|
|
368
|
+
const answer = interrupt({ prompt: "ship it?", options: ["yes", "no"] }) as string;
|
|
369
|
+
return { trail: [`approve:${answer}`] };
|
|
370
|
+
})
|
|
371
|
+
.addNode("act", async () => ({ trail: ["act"] }))
|
|
372
|
+
.addEdge(START, "plan")
|
|
373
|
+
.addEdge("plan", "approve")
|
|
374
|
+
.addEdge("approve", "act")
|
|
375
|
+
.addEdge("act", END)
|
|
376
|
+
.compile({ name: "hitl_graph", checkpointer });
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/** A compiled graph used as a node of another one. */
|
|
380
|
+
function buildParentGraph() {
|
|
381
|
+
const child = new StateGraph(Trail)
|
|
382
|
+
.addNode("inner", async () => ({ trail: ["inner"] }))
|
|
383
|
+
.addEdge(START, "inner")
|
|
384
|
+
.addEdge("inner", END)
|
|
385
|
+
.compile({ name: "child_graph" });
|
|
386
|
+
return new StateGraph(Trail)
|
|
387
|
+
.addNode("pre", async () => ({ trail: ["pre"] }))
|
|
388
|
+
.addNode("child", child)
|
|
389
|
+
.addEdge(START, "pre")
|
|
390
|
+
.addEdge("pre", "child")
|
|
391
|
+
.addEdge("child", END)
|
|
392
|
+
.compile({ name: "parent_graph" });
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* A `MemorySaver`'s contents as JSON, and back. The one piece of state two
|
|
397
|
+
* processes share in a real deployment is the checkpointer; this stands in for
|
|
398
|
+
* a database-backed one so the pause and the approval can happen in two
|
|
399
|
+
* genuinely separate processes with nothing else in common.
|
|
400
|
+
*/
|
|
401
|
+
interface SaverState {
|
|
402
|
+
storage: Record<string, unknown>;
|
|
403
|
+
writes: Record<string, unknown>;
|
|
404
|
+
}
|
|
405
|
+
const encodeBytes = (_key: string, value: unknown): unknown =>
|
|
406
|
+
value instanceof Uint8Array ? { __u8: Buffer.from(value).toString("base64") } : value;
|
|
407
|
+
const decodeBytes = (_key: string, value: unknown): unknown =>
|
|
408
|
+
value !== null && typeof value === "object" && typeof (value as { __u8?: unknown }).__u8 === "string"
|
|
409
|
+
? new Uint8Array(Buffer.from((value as { __u8: string }).__u8, "base64"))
|
|
410
|
+
: value;
|
|
411
|
+
|
|
412
|
+
function saverState(saver: MemorySaver): SaverState {
|
|
413
|
+
return saver as unknown as SaverState;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const question = { messages: [new HumanMessage("weather?")] };
|
|
417
|
+
const report = (value: unknown) => console.log(JSON.stringify(value));
|
|
418
|
+
|
|
419
|
+
/** `instrument()` options per case; every case not listed uses the defaults. */
|
|
420
|
+
const OPTIONS: Record<string, Record<string, unknown>> = {
|
|
421
|
+
"include-chains": { includeChains: ["summarise"] },
|
|
422
|
+
"session-option": { sessionId: "fixed-session" },
|
|
423
|
+
"capture-off": { captureContent: false },
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
async function main(scenario: string): Promise<void> {
|
|
427
|
+
const explicit = scenario.startsWith("handler:");
|
|
428
|
+
const surface = SURFACES[explicit ? scenario.slice("handler:".length) : scenario];
|
|
429
|
+
if (surface !== undefined) {
|
|
430
|
+
if (!explicit) report({ instrumented: await failproofai.instrument("langchain") });
|
|
431
|
+
const out = await surface(explicit ? { callbacks: [langchainHandler() as never] } : {});
|
|
432
|
+
report({ out });
|
|
433
|
+
await failproofai.flush();
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (scenario !== "handler") {
|
|
438
|
+
report({ instrumented: await failproofai.instrument("langchain", OPTIONS[scenario] ?? {}) });
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
switch (scenario) {
|
|
442
|
+
case "graph":
|
|
443
|
+
case "session-option":
|
|
444
|
+
case "capture-off": {
|
|
445
|
+
const out = await buildGraph(new ScriptedModel()).invoke(question);
|
|
446
|
+
report({ answer: out.messages.at(-1)?.content });
|
|
447
|
+
break;
|
|
448
|
+
}
|
|
449
|
+
case "stream": {
|
|
450
|
+
let chunks = 0;
|
|
451
|
+
for await (const _ of await buildGraph(new ScriptedModel()).stream(question, { streamMode: "updates" })) {
|
|
452
|
+
chunks += 1;
|
|
453
|
+
}
|
|
454
|
+
report({ chunks });
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
case "react": {
|
|
458
|
+
const agent = createReactAgent({ llm: new ScriptedModel(), tools: [getWeather], name: "react_bot" });
|
|
459
|
+
const out = await agent.invoke(question);
|
|
460
|
+
report({ answer: out.messages.at(-1)?.content });
|
|
461
|
+
break;
|
|
462
|
+
}
|
|
463
|
+
case "error": {
|
|
464
|
+
try {
|
|
465
|
+
await buildGraph(new ScriptedModel({ fail: true })).invoke({ messages: [new HumanMessage("x")] });
|
|
466
|
+
report({ threw: false });
|
|
467
|
+
} catch (error) {
|
|
468
|
+
report({ threw: (error as Error).message });
|
|
469
|
+
}
|
|
470
|
+
break;
|
|
471
|
+
}
|
|
472
|
+
case "tool-error": {
|
|
473
|
+
const out = await buildGraph(new ScriptedModel(), [brokenWeather]).invoke(question);
|
|
474
|
+
report({ answer: out.messages.at(-1)?.content });
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
case "model": {
|
|
478
|
+
const out = await new ScriptedModel().invoke([new HumanMessage("hi")]);
|
|
479
|
+
report({ toolCalls: (out as AIMessage).tool_calls?.length });
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
case "tool": {
|
|
483
|
+
report({ out: await getWeather.invoke({ city: "Rome" }) });
|
|
484
|
+
break;
|
|
485
|
+
}
|
|
486
|
+
case "batch": {
|
|
487
|
+
const out = await new ScriptedModel().batch([[new HumanMessage("a")], [new HumanMessage("b")]]);
|
|
488
|
+
report({ batch: out.length });
|
|
489
|
+
break;
|
|
490
|
+
}
|
|
491
|
+
case "stream-model": {
|
|
492
|
+
let text = "";
|
|
493
|
+
for await (const chunk of await new StreamingModel().stream([new HumanMessage("hi")])) {
|
|
494
|
+
text += String(chunk.content);
|
|
495
|
+
}
|
|
496
|
+
report({ text });
|
|
497
|
+
break;
|
|
498
|
+
}
|
|
499
|
+
case "include-chains": {
|
|
500
|
+
const chain = RunnableLambda.from((x: string) => x)
|
|
501
|
+
.pipe(RunnableLambda.from((x: string) => x.toUpperCase()).withConfig({ runName: "summarise" }))
|
|
502
|
+
.withConfig({ runName: "pipeline" });
|
|
503
|
+
report({ out: await chain.invoke("abc") });
|
|
504
|
+
break;
|
|
505
|
+
}
|
|
506
|
+
case "metadata-session": {
|
|
507
|
+
await buildGraph(new ScriptedModel()).invoke(question, {
|
|
508
|
+
metadata: { failproofai_sdk_session_id: "meta-sid" },
|
|
509
|
+
});
|
|
510
|
+
break;
|
|
511
|
+
}
|
|
512
|
+
case "thread-session": {
|
|
513
|
+
await buildGraph(new ScriptedModel()).invoke(question, { configurable: { thread_id: "thread-9" } });
|
|
514
|
+
break;
|
|
515
|
+
}
|
|
516
|
+
case "hitl":
|
|
517
|
+
case "hitl-uninstrument": {
|
|
518
|
+
const graph = buildHitlGraph();
|
|
519
|
+
const config = { configurable: { thread_id: "t-1" } };
|
|
520
|
+
const first = await graph.invoke({ trail: [] }, config);
|
|
521
|
+
report({ interrupted: "__interrupt__" in first });
|
|
522
|
+
if (scenario === "hitl") {
|
|
523
|
+
const done = await graph.invoke(new Command({ resume: "yes" }), config);
|
|
524
|
+
report({ trail: done.trail });
|
|
525
|
+
} else {
|
|
526
|
+
report({ removed: failproofai.uninstrument() });
|
|
527
|
+
}
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
530
|
+
case "remote-resume-pause": {
|
|
531
|
+
// Process A: serve the request that interrupts, persist the checkpoint,
|
|
532
|
+
// exit with the pause still open.
|
|
533
|
+
const saver = new MemorySaver();
|
|
534
|
+
// `durability: "sync"`: the default persists the checkpoint in the
|
|
535
|
+
// background, and this process is about to exit.
|
|
536
|
+
await buildHitlGraph(saver).invoke({ trail: [] }, { configurable: { thread_id: "t-1" }, durability: "sync" });
|
|
537
|
+
// The two tables, not the saver: 1.x gives MemorySaver a `toJSON`.
|
|
538
|
+
const { storage, writes } = saverState(saver);
|
|
539
|
+
writeFileSync(process.argv[3]!, JSON.stringify({ storage, writes }, encodeBytes));
|
|
540
|
+
break;
|
|
541
|
+
}
|
|
542
|
+
case "remote-resume": {
|
|
543
|
+
// Process B: a different process, sharing only the checkpointer, takes
|
|
544
|
+
// the human's answer.
|
|
545
|
+
const file = `${process.argv[1]}.${process.pid}.checkpoint.json`;
|
|
546
|
+
const child = spawnSync(process.execPath, [process.argv[1]!, "remote-resume-pause", file], {
|
|
547
|
+
env: process.env,
|
|
548
|
+
encoding: "utf8",
|
|
549
|
+
});
|
|
550
|
+
if (child.status !== 0) throw new Error(`the pausing process failed: ${child.stderr}`);
|
|
551
|
+
const saver = new MemorySaver();
|
|
552
|
+
const saved = JSON.parse(readFileSync(file, "utf8"), decodeBytes) as SaverState;
|
|
553
|
+
rmSync(file, { force: true });
|
|
554
|
+
Object.assign(saverState(saver).storage, saved.storage);
|
|
555
|
+
Object.assign(saverState(saver).writes, saved.writes);
|
|
556
|
+
const done = await buildHitlGraph(saver).invoke(new Command({ resume: "yes" }), {
|
|
557
|
+
configurable: { thread_id: "t-1" },
|
|
558
|
+
});
|
|
559
|
+
report({ trail: done.trail });
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
case "abort": {
|
|
563
|
+
// The caller gives up: the signal fires while a node is running.
|
|
564
|
+
const controller = new AbortController();
|
|
565
|
+
const graph = new StateGraph(Trail)
|
|
566
|
+
.addNode("slow", async () => {
|
|
567
|
+
controller.abort();
|
|
568
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
569
|
+
return { trail: ["slow"] };
|
|
570
|
+
})
|
|
571
|
+
.addEdge(START, "slow")
|
|
572
|
+
.addEdge("slow", END)
|
|
573
|
+
.compile({ name: "abort_graph" });
|
|
574
|
+
try {
|
|
575
|
+
await graph.invoke({ trail: [] }, { signal: controller.signal });
|
|
576
|
+
report({ threw: false });
|
|
577
|
+
} catch (error) {
|
|
578
|
+
report({ threw: (error as Error).name });
|
|
579
|
+
}
|
|
580
|
+
// LangGraph.js 1.x never closes an aborted graph's own run; the adapter
|
|
581
|
+
// does, once the run has been silent for its grace period. Outlive it.
|
|
582
|
+
await new Promise((resolve) => setTimeout(resolve, 3_300));
|
|
583
|
+
break;
|
|
584
|
+
}
|
|
585
|
+
case "subgraph": {
|
|
586
|
+
const out = await buildParentGraph().invoke({ trail: [] });
|
|
587
|
+
report({ trail: out.trail });
|
|
588
|
+
break;
|
|
589
|
+
}
|
|
590
|
+
case "scope": {
|
|
591
|
+
await failproofai.session({ sessionId: "req-1" }, () =>
|
|
592
|
+
failproofai.agent("planner", { goal: "plan" }, () => buildGraph(new ScriptedModel()).invoke(question)),
|
|
593
|
+
);
|
|
594
|
+
break;
|
|
595
|
+
}
|
|
596
|
+
case "handler": {
|
|
597
|
+
// No instrument(): the explicit handler is the patch-free path.
|
|
598
|
+
const out = await buildGraph(new ScriptedModel()).invoke(question, {
|
|
599
|
+
callbacks: [langchainHandler() as never],
|
|
600
|
+
});
|
|
601
|
+
report({ answer: out.messages.at(-1)?.content });
|
|
602
|
+
break;
|
|
603
|
+
}
|
|
604
|
+
case "handler-and-instrument": {
|
|
605
|
+
report({ instrumented: await failproofai.instrument("langchain") });
|
|
606
|
+
await buildGraph(new ScriptedModel()).invoke(question, { callbacks: [langchainHandler() as never] });
|
|
607
|
+
break;
|
|
608
|
+
}
|
|
609
|
+
case "uninstrument": {
|
|
610
|
+
report({ removed: failproofai.uninstrument() });
|
|
611
|
+
await buildGraph(new ScriptedModel()).invoke(question);
|
|
612
|
+
break;
|
|
613
|
+
}
|
|
614
|
+
default:
|
|
615
|
+
throw new Error(`unknown scenario ${scenario}`);
|
|
616
|
+
}
|
|
617
|
+
await failproofai.flush();
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
main(process.argv[2] ?? "graph").catch((error: unknown) => {
|
|
621
|
+
console.error("FATAL", error);
|
|
622
|
+
process.exit(1);
|
|
623
|
+
});
|