failproofai 1.0.7-beta.1 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +4 -4
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js +4 -4
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js +4 -4
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route.js +7 -8
- package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page.js +5 -7
- package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js +6 -6
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
- package/.next/standalone/.next/server/app/policies/page.js +11 -13
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js +7 -8
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +7 -7
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js +6 -7
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +8 -41
- package/.next/standalone/.next/server/app/settings/page.js +9 -12
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__1j-zsg5._.js → [externals]__1_bftcl._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__19_pzeq._.js → [externals]__1msfs-h._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1bf34x4._.js → [root-of-the-server]__1_r2rbg._.js} +7 -5
- package/.next/standalone/.next/server/chunks/_09dz7xv._.js +21 -21
- package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
- package/.next/standalone/.next/server/chunks/{_1q5i8mb._.js → _1c3k-8x._.js} +2 -2
- package/.next/standalone/.next/server/chunks/_1ek68ln._.js +16 -16
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +1 -1
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_hooks_0iu54mz._.js +3 -0
- package/.next/standalone/.next/server/chunks/src_hooks_custom-hooks-loader_ts_0lnb3n3._.js +2 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-_ki57._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0yxwl6j._.js → [root-of-the-server]__0bd3mje._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cg-bgc._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cpu_mj._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1mf3zp6._.js → [root-of-the-server]__0cxe_2_._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u3w0ll._.js +22 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17d_ffl._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__19d9tgz._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ctpynv._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1jiwfsj._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1phc187._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_06imw3p._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_1w_5l7t._.js → _0h_douw._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_214wgrp._.js → _1-i_gzc._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{_0bn2oo8._.js → _166t73i._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_1q46vxx._.js → _1_qswah._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{_1gb0ifp._.js → _1es2j7i._.js} +5 -5
- package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_18_d8l1._.js → node_modules_next_dist_0drixxt._.js} +4 -4
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1cv9_c4._.js +10 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-home_ts_0je3xkv._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_pack-cli_ts_0t7me65._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +23 -56
- package/.next/standalone/.next/static/chunks/094xgi4owxaqf.js +1 -0
- package/.next/standalone/.next/static/chunks/0__8a7m868fvf.js +1 -0
- package/.next/standalone/.next/static/chunks/{12tvm75t5ffui.js → 0o6qlkgubtoex.js} +1 -1
- package/.next/standalone/.next/static/chunks/13i7-9is-vhys.js +1 -0
- package/.next/standalone/.next/static/chunks/1rz20_pz828f3.js +6 -0
- package/.next/standalone/.next/static/chunks/2k9f4tyv04809.css +1 -0
- package/.next/standalone/.next/static/chunks/{0vmd180qfntfb.js → 2klitrtzpaoe0.js} +1 -1
- package/.next/standalone/.next/static/chunks/{258668t68du6b.js → 2mdh397ghgnvv.js} +1 -1
- package/.next/standalone/.next/static/chunks/2rshywgeqsyzk.css +2 -0
- package/.next/standalone/.next/static/chunks/3pzx4chkhko9k.js +1 -0
- package/.next/standalone/.next/static/chunks/{0qrbdkv9qmvli.js → 3rh5o7e16irrm.js} +1 -1
- package/.next/standalone/.next/static/chunks/{29fql3nbnfc9q.js → 43ufqrz8qo3h-.js} +1 -1
- package/.next/standalone/SECURITY.md +53 -0
- package/.next/standalone/app/actions/pack-actions.ts +0 -12
- package/.next/standalone/app/policies/hooks-client.tsx +0 -9
- package/.next/standalone/app/settings/page.tsx +1 -20
- package/.next/standalone/app/settings/settings-client.tsx +1 -27
- package/.next/standalone/app/settings/settings.css +0 -79
- package/.next/standalone/package.json +9 -9
- package/.next/standalone/sdk/python/skill/SKILL.md +60 -14
- package/.next/standalone/sdk/python/skill/agents/openai.yaml +2 -1
- package/.next/standalone/sdk/python/skill/references/evaluator.md +255 -0
- package/.next/standalone/sdk/python/skill/references/events.md +17 -8
- package/.next/standalone/sdk/python/skill/references/frameworks.md +3 -0
- package/.next/standalone/sdk/python/skill/references/install.md +3 -0
- package/.next/standalone/sdk/python/skill/references/integration.md +6 -2
- package/.next/standalone/sdk/python/skill/references/typescript.md +568 -0
- package/.next/standalone/sdk/typescript/CHANGELOG.md +133 -0
- package/.next/standalone/sdk/typescript/LICENSE +42 -0
- package/.next/standalone/sdk/typescript/README.md +552 -0
- package/.next/standalone/sdk/typescript/eslint.config.mjs +59 -0
- package/.next/standalone/sdk/typescript/examples/research-agent.ts +197 -0
- package/.next/standalone/sdk/typescript/integration/ai.test.ts +920 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/agent.ts +337 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package-lock.json +261 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package.json +16 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/surfaces.ts +605 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/agent.ts +342 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package-lock.json +156 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package.json +16 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/surfaces.ts +628 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/agent.ts +346 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package-lock.json +156 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package.json +13 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/surfaces.ts +651 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/agent.ts +350 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package-lock.json +153 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package.json +13 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/surfaces.ts +651 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/agent.ts +623 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package-lock.json +344 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package.json +19 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/agent-v1.ts +99 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/agent.ts +623 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package-lock.json +336 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/agent.ts +96 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package-lock.json +441 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package.json +19 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/index.cjs +53 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/index.mjs +55 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/package.json +18 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/agent.ts +659 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package-lock.json +635 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/agent.ts +659 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package-lock.json +553 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/agent.ts +877 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/mcp-server.mjs +66 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package-lock.json +6797 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package.json +24 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/agent.ts +872 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/mcp-server.mjs +66 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package-lock.json +2540 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/actions.ts +18 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/ai/route.ts +42 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/edge/route.ts +29 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/langgraph/route.ts +21 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/llamaindex/route.ts +11 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/mastra/route.ts +19 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/status/route.ts +7 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/layout.tsx +9 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/page.tsx +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/instrumentation.ts +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/ai.ts +61 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/langgraph.ts +68 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/llamaindex.ts +98 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/mastra.ts +90 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/next.config.ts +52 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package-lock.json +4343 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package.json +28 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/agent.ts +51 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/deno-npm.ts +76 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package-lock.json +484 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/types/agent.ts +79 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/types/package-lock.json +740 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/types/package.json +11 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/agent.ts +197 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/package-lock.json +70 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/package.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/global-setup.ts +29 -0
- package/.next/standalone/sdk/typescript/integration/harness.ts +451 -0
- package/.next/standalone/sdk/typescript/integration/langchain.test.ts +682 -0
- package/.next/standalone/sdk/typescript/integration/llamaindex.test.ts +709 -0
- package/.next/standalone/sdk/typescript/integration/mastra-coverage.test.ts +386 -0
- package/.next/standalone/sdk/typescript/integration/mastra.test.ts +311 -0
- package/.next/standalone/sdk/typescript/integration/nextjs.test.ts +341 -0
- package/.next/standalone/sdk/typescript/integration/runtime-parity.ts +180 -0
- package/.next/standalone/sdk/typescript/integration/runtimes.bun.test.ts +15 -0
- package/.next/standalone/sdk/typescript/integration/runtimes.core.test.ts +113 -0
- package/.next/standalone/sdk/typescript/integration/runtimes.deno.test.ts +19 -0
- package/.next/standalone/sdk/typescript/integration/types.test.ts +141 -0
- package/.next/standalone/sdk/typescript/integration/vanilla.test.ts +255 -0
- package/.next/standalone/sdk/typescript/package-lock.json +2640 -0
- package/.next/standalone/sdk/typescript/package.json +401 -0
- package/.next/standalone/sdk/typescript/scripts/finalize-build.mjs +123 -0
- package/.next/standalone/sdk/typescript/scripts/release.mjs +177 -0
- package/.next/standalone/sdk/typescript/src/clock.ts +58 -0
- package/.next/standalone/sdk/typescript/src/context.ts +214 -0
- package/.next/standalone/sdk/typescript/src/edge/adapter.ts +18 -0
- package/.next/standalone/sdk/typescript/src/edge/ai.ts +116 -0
- package/.next/standalone/sdk/typescript/src/edge/index.ts +238 -0
- package/.next/standalone/sdk/typescript/src/edge/langchain.ts +18 -0
- package/.next/standalone/sdk/typescript/src/edge/llamaindex.ts +12 -0
- package/.next/standalone/sdk/typescript/src/edge/mastra.ts +17 -0
- package/.next/standalone/sdk/typescript/src/edge/notice.ts +33 -0
- package/.next/standalone/sdk/typescript/src/environment.ts +75 -0
- package/.next/standalone/sdk/typescript/src/evaluator/authoring.ts +480 -0
- package/.next/standalone/sdk/typescript/src/evaluator/cli.ts +96 -0
- package/.next/standalone/sdk/typescript/src/evaluator/client.ts +421 -0
- package/.next/standalone/sdk/typescript/src/evaluator/expression.ts +1292 -0
- package/.next/standalone/sdk/typescript/src/evaluator/index.ts +144 -0
- package/.next/standalone/sdk/typescript/src/evaluator/protocol.ts +747 -0
- package/.next/standalone/sdk/typescript/src/evaluator/runtime.ts +930 -0
- package/.next/standalone/sdk/typescript/src/evaluator/sandbox-worker.ts +171 -0
- package/.next/standalone/sdk/typescript/src/evaluator/source-limits.ts +27 -0
- package/.next/standalone/sdk/typescript/src/evaluator/source.ts +509 -0
- package/.next/standalone/sdk/typescript/src/events.ts +879 -0
- package/.next/standalone/sdk/typescript/src/exit.ts +117 -0
- package/.next/standalone/sdk/typescript/src/index.ts +186 -0
- package/.next/standalone/sdk/typescript/src/integrations/ai.ts +1566 -0
- package/.next/standalone/sdk/typescript/src/integrations/compat.ts +322 -0
- package/.next/standalone/sdk/typescript/src/integrations/core.ts +1321 -0
- package/.next/standalone/sdk/typescript/src/integrations/index.ts +355 -0
- package/.next/standalone/sdk/typescript/src/integrations/langchain.ts +2340 -0
- package/.next/standalone/sdk/typescript/src/integrations/llamaindex.ts +2111 -0
- package/.next/standalone/sdk/typescript/src/integrations/mastra.ts +1802 -0
- package/.next/standalone/sdk/typescript/src/logger.ts +98 -0
- package/.next/standalone/sdk/typescript/src/next.ts +115 -0
- package/.next/standalone/sdk/typescript/src/node-require.ts +446 -0
- package/.next/standalone/sdk/typescript/src/redact.ts +305 -0
- package/.next/standalone/sdk/typescript/src/resolver.ts +120 -0
- package/.next/standalone/sdk/typescript/src/runtime.ts +29 -0
- package/.next/standalone/sdk/typescript/src/schema.ts +410 -0
- package/.next/standalone/sdk/typescript/src/scopes.ts +701 -0
- package/.next/standalone/sdk/typescript/src/shared.ts +33 -0
- package/.next/standalone/sdk/typescript/src/version.ts +5 -0
- package/.next/standalone/sdk/typescript/src/writer.ts +934 -0
- package/.next/standalone/sdk/typescript/test/adapters.test.ts +397 -0
- package/.next/standalone/sdk/typescript/test/ai.test.ts +1076 -0
- package/.next/standalone/sdk/typescript/test/copies.test.ts +204 -0
- package/.next/standalone/sdk/typescript/test/edge.test.ts +183 -0
- package/.next/standalone/sdk/typescript/test/evaluator-client.test.ts +234 -0
- package/.next/standalone/sdk/typescript/test/evaluator-protocol.test.ts +225 -0
- package/.next/standalone/sdk/typescript/test/events.test.ts +193 -0
- package/.next/standalone/sdk/typescript/test/expression.test.ts +181 -0
- package/.next/standalone/sdk/typescript/test/global-setup.ts +26 -0
- package/.next/standalone/sdk/typescript/test/helpers.ts +130 -0
- package/.next/standalone/sdk/typescript/test/integrations.test.ts +369 -0
- package/.next/standalone/sdk/typescript/test/langchain-copies.test.ts +204 -0
- package/.next/standalone/sdk/typescript/test/langchain.test.ts +999 -0
- package/.next/standalone/sdk/typescript/test/llamaindex.test.ts +1760 -0
- package/.next/standalone/sdk/typescript/test/mastra-coverage.test.ts +501 -0
- package/.next/standalone/sdk/typescript/test/mastra-lifecycle.test.ts +479 -0
- package/.next/standalone/sdk/typescript/test/mastra.test.ts +285 -0
- package/.next/standalone/sdk/typescript/test/next.test.ts +109 -0
- package/.next/standalone/sdk/typescript/test/packaging.test.ts +312 -0
- package/.next/standalone/sdk/typescript/test/redaction.test.ts +171 -0
- package/.next/standalone/sdk/typescript/test/runtimes.test.ts +101 -0
- package/.next/standalone/sdk/typescript/test/sandbox.test.ts +189 -0
- package/.next/standalone/sdk/typescript/test/scopes.test.ts +271 -0
- package/.next/standalone/sdk/typescript/test/setup.ts +19 -0
- package/.next/standalone/sdk/typescript/test/skill-snippets.test.ts +73 -0
- package/.next/standalone/sdk/typescript/test/spool-contract.test.ts +124 -0
- package/.next/standalone/sdk/typescript/test/tracker-bounds.test.ts +191 -0
- package/.next/standalone/sdk/typescript/test/wire-format.test.ts +214 -0
- package/.next/standalone/sdk/typescript/test/writer.test.ts +407 -0
- package/.next/standalone/sdk/typescript/tsconfig.build.json +15 -0
- package/.next/standalone/sdk/typescript/tsconfig.cjs.json +19 -0
- package/.next/standalone/sdk/typescript/tsconfig.json +28 -0
- package/.next/standalone/sdk/typescript/vitest.config.ts +33 -0
- package/.next/standalone/sdk/typescript/vitest.integration.config.ts +23 -0
- package/.next/standalone/server.js +1 -1
- package/bin/failproofai.mjs +2 -115
- package/dist/cli.mjs +6538 -13686
- package/dist/index.js +1 -19
- package/dist/worker.mjs +2085 -8012
- package/package.json +9 -9
- package/pi-extension/index.ts +0 -11
- package/scripts/build-policy-pack.mjs +2 -39
- package/src/hooks/builtin-policies.ts +3 -21
- package/src/hooks/cloud-enrollment-cli.ts +1 -1
- package/src/hooks/cloud-managed-policies.ts +0 -22
- package/src/hooks/custom-hooks-loader.ts +7 -45
- package/src/hooks/custom-hooks-registry.ts +1 -45
- package/src/hooks/first-run-gate.ts +0 -5
- package/src/hooks/fp-home.ts +0 -23
- package/src/hooks/handler.ts +6 -265
- package/src/hooks/hook-activity-store.ts +1 -105
- package/src/hooks/hook-telemetry.ts +0 -41
- package/src/hooks/loader-utils.ts +0 -6
- package/src/hooks/pack-cli.ts +17 -278
- package/src/hooks/pack-manifest.ts +7 -479
- package/src/hooks/pack-store.ts +10 -156
- package/src/hooks/policy-catalog.ts +0 -65
- package/src/hooks/policy-evaluator.ts +796 -940
- package/src/hooks/policy-registry.ts +0 -25
- package/src/hooks/policy-types.ts +0 -126
- package/src/hooks/worker-server.ts +26 -119
- package/src/index.ts +0 -6
- package/.next/standalone/.next/server/chunks/src_hooks_01frwmb._.js +0 -5
- package/.next/standalone/.next/server/chunks/src_hooks_18qtd42._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01bmjsj._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__056wjo4._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__059yza8._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0eip4_k._.js +0 -22
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n0xg95._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qcb0mg._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qxnccm._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rwtwpm._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s_yomn._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0soxz2z._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0yrsbd_._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11mayhe._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13d-wb6._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1dinjii._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pprgri._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1q4p5b8._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qiz0e4._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_042cgl1._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0uyu3jf._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1feuvhb._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9sni._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_0w6mzq5._.js +0 -151
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_095a_79._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_15t8kqj._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_18k8rl0._.js +0 -12
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1fm2w5z._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1j0zy3v._.js +0 -3
- package/.next/standalone/.next/static/chunks/0cd-_8-c-m1ea.js +0 -6
- package/.next/standalone/.next/static/chunks/0uldbut9y2-e8.js +0 -1
- package/.next/standalone/.next/static/chunks/1u5zsejmgrir_.js +0 -1
- package/.next/standalone/.next/static/chunks/285spx855h_3r.css +0 -2
- package/.next/standalone/.next/static/chunks/2qv4hshejedtx.css +0 -1
- package/.next/standalone/.next/static/chunks/2vkvu9-opa_1z.js +0 -1
- package/.next/standalone/.next/static/chunks/37lhv7wa3ywt6.js +0 -1
- package/.next/standalone/app/actions/get-jev-config.ts +0 -409
- package/.next/standalone/app/actions/update-jev-config.ts +0 -420
- package/.next/standalone/app/components/jev-notices.tsx +0 -96
- package/.next/standalone/app/settings/jev-panel.tsx +0 -469
- package/src/hooks/effective-reviewers.ts +0 -79
- package/src/hooks/jev-activity.ts +0 -385
- package/src/hooks/jev-cli.ts +0 -1193
- package/src/hooks/policy-authority.ts +0 -333
- package/src/hooks/policy-reviewability.ts +0 -229
- package/src/hooks/semantic/combine.ts +0 -541
- package/src/hooks/semantic/compile.ts +0 -176
- package/src/hooks/semantic/decide.ts +0 -392
- package/src/hooks/semantic/envelope.ts +0 -1296
- package/src/hooks/semantic/evaluator.ts +0 -547
- package/src/hooks/semantic/facts.ts +0 -292
- package/src/hooks/semantic/intent.ts +0 -1190
- package/src/hooks/semantic/jev-client.ts +0 -643
- package/src/hooks/semantic/jev-config.ts +0 -594
- package/src/hooks/semantic/jev-review.ts +0 -374
- package/src/hooks/semantic/jev-stats.ts +0 -289
- package/src/hooks/semantic/jev-throttle.ts +0 -421
- package/src/hooks/semantic/pack-policies.ts +0 -251
- package/src/hooks/semantic/policies.ts +0 -596
- package/src/hooks/semantic/precondition-names.ts +0 -60
- package/src/hooks/semantic/preconditions.ts +0 -58
- package/src/hooks/semantic/redact.ts +0 -2910
- package/src/hooks/semantic/types.ts +0 -145
- package/src/hooks/semver-precedence.ts +0 -128
- /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → PgeWCHmyVbjRznv2VO7KF}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → PgeWCHmyVbjRznv2VO7KF}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → PgeWCHmyVbjRznv2VO7KF}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
// LlamaIndex.TS 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, and it is built
|
|
5
|
+
// the way LlamaIndex's own provider packages build theirs (`@llamaindex/openai`
|
|
6
|
+
// decorates `chat` with exactly `@wrapEventCaller @wrapLLMEvent`), so the
|
|
7
|
+
// callback events it produces are the ones a real provider produces. The
|
|
8
|
+
// assertions compare against the Python SDK's golden trace for the equivalent
|
|
9
|
+
// `FunctionAgent` program.
|
|
10
|
+
import * as failproofai from "@failproofai/sdk";
|
|
11
|
+
import { wrapEventCaller, wrapLLMEvent } from "@llamaindex/core/decorator";
|
|
12
|
+
import {
|
|
13
|
+
ToolCallLLM,
|
|
14
|
+
type ChatMessage,
|
|
15
|
+
type ChatResponse,
|
|
16
|
+
type ChatResponseChunk,
|
|
17
|
+
type LLMChatParamsNonStreaming,
|
|
18
|
+
type LLMChatParamsStreaming,
|
|
19
|
+
type LLMMetadata,
|
|
20
|
+
type ToolCallLLMMessageOptions,
|
|
21
|
+
} from "@llamaindex/core/llms";
|
|
22
|
+
import { RetrieverQueryEngine, type QueryBundle } from "@llamaindex/core/query-engine";
|
|
23
|
+
import { getResponseSynthesizer } from "@llamaindex/core/response-synthesizers";
|
|
24
|
+
import { BaseRetriever } from "@llamaindex/core/retriever";
|
|
25
|
+
import { TextNode, type NodeWithScore } from "@llamaindex/core/schema";
|
|
26
|
+
import { extractText } from "@llamaindex/core/utils";
|
|
27
|
+
import { agent, createWorkflow, multiAgent, workflowEvent } from "@llamaindex/workflow";
|
|
28
|
+
import {
|
|
29
|
+
BaseEmbedding,
|
|
30
|
+
CondenseQuestionChatEngine,
|
|
31
|
+
ContextChatEngine,
|
|
32
|
+
Document,
|
|
33
|
+
FunctionTool,
|
|
34
|
+
LLMAgent,
|
|
35
|
+
QueryEngineTool,
|
|
36
|
+
Settings,
|
|
37
|
+
SimpleChatEngine,
|
|
38
|
+
VectorStoreIndex,
|
|
39
|
+
tool,
|
|
40
|
+
} from "llamaindex";
|
|
41
|
+
import { z } from "zod";
|
|
42
|
+
|
|
43
|
+
type Options = ToolCallLLMMessageOptions;
|
|
44
|
+
|
|
45
|
+
/** One scripted turn: either a tool call or a final answer, with its usage. */
|
|
46
|
+
interface Turn {
|
|
47
|
+
tool?: { name: string; input: Record<string, unknown>; id: string };
|
|
48
|
+
/** Several tool calls in ONE assistant message (parallel tool calling). */
|
|
49
|
+
tools?: Array<{ name: string; input: Record<string, unknown>; id: string }>;
|
|
50
|
+
text?: string;
|
|
51
|
+
/** The provider fails: before answering, or (streaming) after the first chunk. */
|
|
52
|
+
fail?: string;
|
|
53
|
+
usage: { prompt_tokens: number; completion_tokens: number };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const weatherTurns = (): Turn[] => [
|
|
57
|
+
{ tool: { name: "get_weather", input: { city: "Paris" }, id: "call_1" }, usage: { prompt_tokens: 12, completion_tokens: 5 } },
|
|
58
|
+
{ text: "It is sunny in Paris.", usage: { prompt_tokens: 30, completion_tokens: 7 } },
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
class ScriptedLLM extends ToolCallLLM {
|
|
62
|
+
supportToolCall = true;
|
|
63
|
+
metadata: LLMMetadata = {
|
|
64
|
+
model: "scripted-1",
|
|
65
|
+
temperature: 0,
|
|
66
|
+
topP: 1,
|
|
67
|
+
contextWindow: 4096,
|
|
68
|
+
tokenizer: undefined,
|
|
69
|
+
structuredOutput: false,
|
|
70
|
+
};
|
|
71
|
+
private readonly turns: Turn[];
|
|
72
|
+
|
|
73
|
+
constructor(turns: Turn[] = weatherTurns()) {
|
|
74
|
+
super();
|
|
75
|
+
this.turns = turns;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
chat(params: LLMChatParamsStreaming<object, Options>): Promise<AsyncIterable<ChatResponseChunk<Options>>>;
|
|
79
|
+
chat(params: LLMChatParamsNonStreaming<object, Options>): Promise<ChatResponse<Options>>;
|
|
80
|
+
@wrapEventCaller
|
|
81
|
+
@wrapLLMEvent
|
|
82
|
+
async chat(
|
|
83
|
+
params: LLMChatParamsStreaming<object, Options> | LLMChatParamsNonStreaming<object, Options>,
|
|
84
|
+
): Promise<AsyncIterable<ChatResponseChunk<Options>> | ChatResponse<Options>> {
|
|
85
|
+
const turn = this.turns.shift() ?? { text: "done", usage: { prompt_tokens: 1, completion_tokens: 1 } };
|
|
86
|
+
const calls = turn.tools ?? (turn.tool ? [turn.tool] : []);
|
|
87
|
+
const options: Options = calls.length > 0 ? { toolCall: calls } : {};
|
|
88
|
+
const message: ChatMessage<Options> = { role: "assistant", content: turn.text ?? "", options };
|
|
89
|
+
if (params.stream) {
|
|
90
|
+
// OpenAI's stream shape: content chunks, then a content-less chunk whose
|
|
91
|
+
// `raw` carries the usage (what `stream_options.include_usage` sends).
|
|
92
|
+
return (async function* (): AsyncGenerator<ChatResponseChunk<Options>> {
|
|
93
|
+
yield { delta: turn.text ?? "", raw: { choices: [{ delta: {} }] }, options };
|
|
94
|
+
if (turn.fail) throw new Error(turn.fail);
|
|
95
|
+
yield { delta: "", raw: { choices: [], usage: turn.usage }, options: {} };
|
|
96
|
+
})();
|
|
97
|
+
}
|
|
98
|
+
if (turn.fail) throw new Error(turn.fail);
|
|
99
|
+
return { message, raw: { choices: [{ finish_reason: calls.length > 0 ? "tool_calls" : "stop" }], usage: turn.usage } };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// One object built once and shared by concurrent requests — the way a server
|
|
105
|
+
// holds its query engine or agent. Everything below is stateless per call, so
|
|
106
|
+
// two calls in flight at once cannot disturb each other: whatever the trace
|
|
107
|
+
// mixes up is the adapter's doing.
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
|
|
110
|
+
const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));
|
|
111
|
+
const textOf = (content: unknown): string => (typeof content === "string" ? content : JSON.stringify(content));
|
|
112
|
+
/** The city a request is about. Paris is the SLOW request, so Rome starts and ends inside it. */
|
|
113
|
+
const cityIn = (text: string): "Paris" | "Rome" => (text.includes("Rome") ? "Rome" : "Paris");
|
|
114
|
+
const delay = (city: string) => sleep(city === "Paris" ? 40 : 5);
|
|
115
|
+
/** Per-city usage, so a model_response carries which request it answered. */
|
|
116
|
+
const USAGE = { Paris: { prompt_tokens: 11, completion_tokens: 2 }, Rome: { prompt_tokens: 21, completion_tokens: 3 } };
|
|
117
|
+
|
|
118
|
+
/** A model that answers from its input alone: a tool call first, then the answer. */
|
|
119
|
+
class EchoLLM extends ToolCallLLM {
|
|
120
|
+
supportToolCall = true;
|
|
121
|
+
metadata: LLMMetadata = {
|
|
122
|
+
model: "echo-1",
|
|
123
|
+
temperature: 0,
|
|
124
|
+
topP: 1,
|
|
125
|
+
contextWindow: 4096,
|
|
126
|
+
tokenizer: undefined,
|
|
127
|
+
structuredOutput: false,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
chat(params: LLMChatParamsStreaming<object, Options>): Promise<AsyncIterable<ChatResponseChunk<Options>>>;
|
|
131
|
+
chat(params: LLMChatParamsNonStreaming<object, Options>): Promise<ChatResponse<Options>>;
|
|
132
|
+
@wrapEventCaller
|
|
133
|
+
@wrapLLMEvent
|
|
134
|
+
async chat(
|
|
135
|
+
params: LLMChatParamsStreaming<object, Options> | LLMChatParamsNonStreaming<object, Options>,
|
|
136
|
+
): Promise<AsyncIterable<ChatResponseChunk<Options>> | ChatResponse<Options>> {
|
|
137
|
+
const city = cityIn(params.messages.map((m) => textOf(m.content)).join("\n"));
|
|
138
|
+
await delay(city);
|
|
139
|
+
const answered = params.messages.some((m) => m.options !== undefined && "toolResult" in m.options);
|
|
140
|
+
const call = params.tools?.length && !answered ? { name: "get_weather", input: { city }, id: `call_${city}` } : null;
|
|
141
|
+
const options: Options = call ? { toolCall: [call] } : {};
|
|
142
|
+
const text = call ? "" : `It is sunny in ${city}.`;
|
|
143
|
+
const usage = USAGE[city];
|
|
144
|
+
if (params.stream) {
|
|
145
|
+
return (async function* (): AsyncGenerator<ChatResponseChunk<Options>> {
|
|
146
|
+
yield { delta: text, raw: { choices: [{ delta: {} }] }, options };
|
|
147
|
+
await delay(city);
|
|
148
|
+
yield { delta: "", raw: { choices: [], usage }, options: {} };
|
|
149
|
+
})();
|
|
150
|
+
}
|
|
151
|
+
const message: ChatMessage<Options> = { role: "assistant", content: text, options };
|
|
152
|
+
return { message, raw: { choices: [{ finish_reason: call ? "tool_calls" : "stop" }], usage } };
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** A retriever with no index and no embeddings: one note about the question. */
|
|
157
|
+
class NotesRetriever extends BaseRetriever {
|
|
158
|
+
// BaseRetriever's constructor is protected; a subclass's is public.
|
|
159
|
+
constructor() {
|
|
160
|
+
super();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async _retrieve(params: QueryBundle): Promise<NodeWithScore[]> {
|
|
164
|
+
const question = extractText(params.query);
|
|
165
|
+
await delay(cityIn(question));
|
|
166
|
+
return [{ node: new TextNode({ text: `notes on ${question}` }), score: 1 }];
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const getWeather = tool({
|
|
171
|
+
name: "get_weather",
|
|
172
|
+
description: "Current weather for a city",
|
|
173
|
+
parameters: z.object({ city: z.string() }),
|
|
174
|
+
execute: ({ city }) => `sunny in ${city}`,
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const broken = tool({
|
|
178
|
+
name: "broken",
|
|
179
|
+
description: "Always fails",
|
|
180
|
+
parameters: z.object({ city: z.string() }),
|
|
181
|
+
execute: (): string => {
|
|
182
|
+
throw new Error("tool exploded");
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
// The coverage sweep: every commonly used LlamaIndex.TS surface, offline.
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* An embedding model with no network: one dimension per city, so a question
|
|
192
|
+
* about Paris retrieves the Paris note and nothing else.
|
|
193
|
+
*/
|
|
194
|
+
const CITIES = ["Paris", "Rome", "Oslo", "Lima", "Cairo", "Delhi", "Tokyo", "Quito", "Accra", "Hanoi"] as const;
|
|
195
|
+
class FakeEmbedding extends BaseEmbedding {
|
|
196
|
+
// BaseEmbedding's constructor is protected; a subclass's is public.
|
|
197
|
+
constructor() {
|
|
198
|
+
super();
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async getTextEmbedding(text: string): Promise<number[]> {
|
|
202
|
+
return [...CITIES.map((city) => (text.includes(city) ? 1 : 0)), 0.01];
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const HISTORY: ChatMessage[] = [
|
|
207
|
+
{ role: "user", content: "hi" },
|
|
208
|
+
{ role: "assistant", content: "hello" },
|
|
209
|
+
];
|
|
210
|
+
|
|
211
|
+
/** Every city's note, indexed with the fake embedding model. */
|
|
212
|
+
const cityIndex = () =>
|
|
213
|
+
VectorStoreIndex.fromDocuments(CITIES.map((city) => new Document({ text: `${city} is sunny.`, id_: `doc-${city}` })));
|
|
214
|
+
|
|
215
|
+
/** The city a question is about. */
|
|
216
|
+
const cityOf = (text: string): string => {
|
|
217
|
+
const hits = CITIES.filter((city) => text.includes(city));
|
|
218
|
+
return hits[hits.length - 1] ?? "Paris";
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* `EchoLLM` for ten requests: answers from its input alone (a tool call, then
|
|
223
|
+
* the answer), with a per-city delay and per-city usage so every event says
|
|
224
|
+
* which request it belongs to.
|
|
225
|
+
*/
|
|
226
|
+
class CityLLM extends ToolCallLLM {
|
|
227
|
+
supportToolCall = true;
|
|
228
|
+
metadata: LLMMetadata = {
|
|
229
|
+
model: "city-1",
|
|
230
|
+
temperature: 0,
|
|
231
|
+
topP: 1,
|
|
232
|
+
contextWindow: 4096,
|
|
233
|
+
tokenizer: undefined,
|
|
234
|
+
structuredOutput: false,
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
chat(params: LLMChatParamsStreaming<object, Options>): Promise<AsyncIterable<ChatResponseChunk<Options>>>;
|
|
238
|
+
chat(params: LLMChatParamsNonStreaming<object, Options>): Promise<ChatResponse<Options>>;
|
|
239
|
+
@wrapEventCaller
|
|
240
|
+
@wrapLLMEvent
|
|
241
|
+
async chat(
|
|
242
|
+
params: LLMChatParamsStreaming<object, Options> | LLMChatParamsNonStreaming<object, Options>,
|
|
243
|
+
): Promise<AsyncIterable<ChatResponseChunk<Options>> | ChatResponse<Options>> {
|
|
244
|
+
const city = cityOf(params.messages.map((m) => textOf(m.content)).join("\n"));
|
|
245
|
+
const n = CITIES.indexOf(city as (typeof CITIES)[number]);
|
|
246
|
+
await sleep(((n * 7) % 5) * 6);
|
|
247
|
+
const answered = params.messages.some((m) => m.options !== undefined && "toolResult" in m.options);
|
|
248
|
+
const call = params.tools?.length && !answered ? { name: "get_weather", input: { city }, id: `call_${city}` } : null;
|
|
249
|
+
const options: Options = call ? { toolCall: [call] } : {};
|
|
250
|
+
const text = call ? "" : `It is sunny in ${city}.`;
|
|
251
|
+
const usage = { prompt_tokens: 100 + n, completion_tokens: n };
|
|
252
|
+
if (params.stream) {
|
|
253
|
+
return (async function* (): AsyncGenerator<ChatResponseChunk<Options>> {
|
|
254
|
+
yield { delta: text, raw: { choices: [{ delta: {} }] }, options };
|
|
255
|
+
await sleep(((n * 3) % 4) * 5);
|
|
256
|
+
yield { delta: "", raw: { choices: [], usage }, options: {} };
|
|
257
|
+
})();
|
|
258
|
+
}
|
|
259
|
+
const message: ChatMessage<Options> = { role: "assistant", content: text, options };
|
|
260
|
+
return { message, raw: { choices: [{ finish_reason: call ? "tool_calls" : "stop" }], usage } };
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const say = (text: string, prompt = 5, completion = 2): Turn => ({
|
|
265
|
+
text,
|
|
266
|
+
usage: { prompt_tokens: prompt, completion_tokens: completion },
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
/** Drain whatever a streaming chat or query returned. */
|
|
270
|
+
async function drain(stream: AsyncIterable<unknown>): Promise<number> {
|
|
271
|
+
let chunks = 0;
|
|
272
|
+
for await (const _ of stream) chunks += 1;
|
|
273
|
+
return chunks;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const lookup = FunctionTool.from(({ city }: { city: string }) => `sunny in ${city}`, {
|
|
277
|
+
name: "lookup_weather",
|
|
278
|
+
description: "Current weather for a city",
|
|
279
|
+
parameters: z.object({ city: z.string() }),
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
const getTime = tool({
|
|
283
|
+
name: "get_time",
|
|
284
|
+
description: "Current time in a city",
|
|
285
|
+
parameters: z.object({ city: z.string() }),
|
|
286
|
+
execute: ({ city }) => `noon in ${city}`,
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
/** A plain `createWorkflow()` workflow with two steps; the second asks the model. */
|
|
290
|
+
function plainWorkflow(llm: ScriptedLLM) {
|
|
291
|
+
const start = workflowEvent<string>({ debugLabel: "start" });
|
|
292
|
+
const researched = workflowEvent<string>({ debugLabel: "researched" });
|
|
293
|
+
const stop = workflowEvent<string>({ debugLabel: "stop" });
|
|
294
|
+
const workflow = createWorkflow();
|
|
295
|
+
// Named functions: a step's name is its handler's name. `...args` because the
|
|
296
|
+
// floor's runtime calls `handler(event)` and later ones `handler(context, event)`.
|
|
297
|
+
workflow.handle([start], async function research(...args: unknown[]) {
|
|
298
|
+
const event = args[args.length - 1] as { data: string };
|
|
299
|
+
await sleep(1);
|
|
300
|
+
return researched.with(`notes on ${event.data}`);
|
|
301
|
+
});
|
|
302
|
+
workflow.handle([researched], async function answer(...args: unknown[]) {
|
|
303
|
+
const event = args[args.length - 1] as { data: string };
|
|
304
|
+
const response = await llm.chat({ messages: [{ role: "user", content: event.data }] });
|
|
305
|
+
return stop.with(String(response.message.content));
|
|
306
|
+
});
|
|
307
|
+
return { workflow, start, stop };
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
async function runPlainWorkflow(llm: ScriptedLLM, input: string): Promise<string> {
|
|
311
|
+
const { workflow, start, stop } = plainWorkflow(llm);
|
|
312
|
+
const { stream, sendEvent } = workflow.createContext();
|
|
313
|
+
sendEvent(start.with(input));
|
|
314
|
+
const events = await stream.until(stop).toArray();
|
|
315
|
+
return String((events.at(-1) as { data: unknown }).data);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const report = (value: unknown) => console.log(JSON.stringify(value));
|
|
319
|
+
const QUESTION = "weather in Paris?";
|
|
320
|
+
|
|
321
|
+
async function main(scenario: string): Promise<void> {
|
|
322
|
+
// Built BEFORE instrument(): the adapter must not depend on construction order.
|
|
323
|
+
const early = agent({ llm: new ScriptedLLM(), tools: [getWeather] });
|
|
324
|
+
// Shared objects, also built at startup, before instrument().
|
|
325
|
+
const sharedEngine = new RetrieverQueryEngine(
|
|
326
|
+
new NotesRetriever(),
|
|
327
|
+
getResponseSynthesizer("compact", { llm: new EchoLLM() }),
|
|
328
|
+
);
|
|
329
|
+
const sharedLegacy = new LLMAgent({ llm: new EchoLLM(), tools: [getWeather] });
|
|
330
|
+
const sharedAgent = agent({ llm: new EchoLLM(), tools: [getWeather] });
|
|
331
|
+
// Adapter options, for the cases that exercise one (`embeddings: true`).
|
|
332
|
+
const options = JSON.parse(process.env.FAILPROOFAI_IT_OPTIONS ?? "{}") as Record<string, unknown>;
|
|
333
|
+
report({ instrumented: await failproofai.instrument("llamaindex", options) });
|
|
334
|
+
const QUESTIONS = ["weather in Paris?", "weather in Rome?"];
|
|
335
|
+
|
|
336
|
+
switch (scenario) {
|
|
337
|
+
case "workflow": {
|
|
338
|
+
const out = await agent({ llm: new ScriptedLLM(), tools: [getWeather] }).run(QUESTION);
|
|
339
|
+
report({ answer: out.data.result });
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
case "named": {
|
|
343
|
+
const out = await agent({ name: "weather_bot", llm: new ScriptedLLM(), tools: [getWeather] }).run(QUESTION);
|
|
344
|
+
report({ answer: out.data.result });
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
case "early": {
|
|
348
|
+
const out = await early.run(QUESTION);
|
|
349
|
+
report({ answer: out.data.result });
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
case "stream": {
|
|
353
|
+
let events = 0;
|
|
354
|
+
for await (const _ of agent({ llm: new ScriptedLLM(), tools: [getWeather] }).runStream(QUESTION)) events += 1;
|
|
355
|
+
report({ events });
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
case "legacy": {
|
|
359
|
+
const out = await new LLMAgent({ llm: new ScriptedLLM(), tools: [getWeather] }).chat({ message: QUESTION });
|
|
360
|
+
report({ answer: String(out.message.content) });
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
case "model": {
|
|
364
|
+
const out = await new ScriptedLLM([{ text: "hello", usage: { prompt_tokens: 3, completion_tokens: 1 } }]).chat({
|
|
365
|
+
messages: [{ role: "user", content: "hi" }],
|
|
366
|
+
});
|
|
367
|
+
report({ answer: out.message.content });
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
case "scope": {
|
|
371
|
+
await failproofai.session({ sessionId: "req-1" }, () =>
|
|
372
|
+
failproofai.agent("planner", { goal: "plan" }, () =>
|
|
373
|
+
agent({ llm: new ScriptedLLM(), tools: [getWeather] }).run(QUESTION),
|
|
374
|
+
),
|
|
375
|
+
);
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
case "tool-error": {
|
|
379
|
+
const turns = weatherTurns();
|
|
380
|
+
turns[0]!.tool = { name: "broken", input: { city: "Paris" }, id: "call_1" };
|
|
381
|
+
const out = await agent({ llm: new ScriptedLLM(turns), tools: [broken] }).run(QUESTION);
|
|
382
|
+
report({ answer: out.data.result });
|
|
383
|
+
break;
|
|
384
|
+
}
|
|
385
|
+
case "handoff": {
|
|
386
|
+
const triage = agent({
|
|
387
|
+
name: "triage",
|
|
388
|
+
description: "Routes questions",
|
|
389
|
+
llm: new ScriptedLLM([
|
|
390
|
+
{
|
|
391
|
+
tool: { name: "handOff", input: { toAgent: "forecaster", reason: "weather question" }, id: "call_h" },
|
|
392
|
+
usage: { prompt_tokens: 8, completion_tokens: 4 },
|
|
393
|
+
},
|
|
394
|
+
]),
|
|
395
|
+
tools: [getWeather],
|
|
396
|
+
canHandoffTo: ["forecaster"],
|
|
397
|
+
});
|
|
398
|
+
const forecaster = agent({
|
|
399
|
+
name: "forecaster",
|
|
400
|
+
description: "Knows the weather",
|
|
401
|
+
llm: new ScriptedLLM(),
|
|
402
|
+
tools: [getWeather],
|
|
403
|
+
});
|
|
404
|
+
const out = await multiAgent({ agents: [triage, forecaster], rootAgent: triage }).run(QUESTION);
|
|
405
|
+
report({ answer: out.data.result });
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
case "shared-query": {
|
|
409
|
+
const answers = await Promise.all(QUESTIONS.map((query) => sharedEngine.query({ query })));
|
|
410
|
+
report({ answers: answers.map((a) => a.message.content) });
|
|
411
|
+
break;
|
|
412
|
+
}
|
|
413
|
+
case "shared-legacy": {
|
|
414
|
+
const answers = await Promise.all(QUESTIONS.map((message) => sharedLegacy.chat({ message })));
|
|
415
|
+
report({ answers: answers.map((a) => String(a.message.content)) });
|
|
416
|
+
break;
|
|
417
|
+
}
|
|
418
|
+
case "shared-workflow": {
|
|
419
|
+
const answers = await Promise.all(QUESTIONS.map((question) => sharedAgent.run(question)));
|
|
420
|
+
report({ answers: answers.map((a) => a.data.result) });
|
|
421
|
+
break;
|
|
422
|
+
}
|
|
423
|
+
case "uninstrument": {
|
|
424
|
+
// One recorded run, then nothing: the second workflow and the legacy agent
|
|
425
|
+
// run after uninstrument() and must leave no trace.
|
|
426
|
+
await agent({ llm: new ScriptedLLM(), tools: [getWeather] }).run(QUESTION);
|
|
427
|
+
report({ removed: failproofai.uninstrument() });
|
|
428
|
+
await agent({ llm: new ScriptedLLM(), tools: [getWeather] }).run(QUESTION);
|
|
429
|
+
await new LLMAgent({ llm: new ScriptedLLM(), tools: [getWeather] }).chat({ message: QUESTION });
|
|
430
|
+
break;
|
|
431
|
+
}
|
|
432
|
+
// -- chat engines --------------------------------------------------------
|
|
433
|
+
case "chat-simple": {
|
|
434
|
+
const engine = new SimpleChatEngine({ llm: new ScriptedLLM([say("It is sunny in Paris.", 9, 4)]) });
|
|
435
|
+
const out = await engine.chat({ message: QUESTION, chatHistory: HISTORY });
|
|
436
|
+
report({ answer: out.message.content });
|
|
437
|
+
break;
|
|
438
|
+
}
|
|
439
|
+
case "chat-simple-stream": {
|
|
440
|
+
const engine = new SimpleChatEngine({ llm: new ScriptedLLM([say("It is sunny in Paris.", 9, 4)]) });
|
|
441
|
+
report({ chunks: await drain(await engine.chat({ message: QUESTION, chatHistory: HISTORY, stream: true })) });
|
|
442
|
+
break;
|
|
443
|
+
}
|
|
444
|
+
case "chat-context":
|
|
445
|
+
case "chat-context-stream": {
|
|
446
|
+
Settings.embedModel = new FakeEmbedding();
|
|
447
|
+
const index = await cityIndex();
|
|
448
|
+
// The floor's chat memory reads Settings.llm even when a chatModel is given.
|
|
449
|
+
const llm = new ScriptedLLM([say("It is sunny in Paris.", 9, 4)]);
|
|
450
|
+
Settings.llm = llm;
|
|
451
|
+
const engine = new ContextChatEngine({
|
|
452
|
+
retriever: index.asRetriever({ similarityTopK: 1 }),
|
|
453
|
+
chatModel: llm,
|
|
454
|
+
chatHistory: HISTORY,
|
|
455
|
+
});
|
|
456
|
+
if (scenario === "chat-context") {
|
|
457
|
+
report({ answer: (await engine.chat({ message: QUESTION })).message.content });
|
|
458
|
+
} else {
|
|
459
|
+
report({ chunks: await drain(await engine.chat({ message: QUESTION, stream: true })) });
|
|
460
|
+
}
|
|
461
|
+
break;
|
|
462
|
+
}
|
|
463
|
+
case "chat-condense":
|
|
464
|
+
case "chat-condense-stream": {
|
|
465
|
+
Settings.embedModel = new FakeEmbedding();
|
|
466
|
+
// CondenseQuestionChatEngine takes its model from Settings, and so does
|
|
467
|
+
// the query engine's synthesizer: first the condensed question, then the answer.
|
|
468
|
+
Settings.llm = new ScriptedLLM([say("What is the weather in Paris?", 6, 3), say("It is sunny in Paris.", 9, 4)]);
|
|
469
|
+
const index = await cityIndex();
|
|
470
|
+
const engine = new CondenseQuestionChatEngine({
|
|
471
|
+
queryEngine: index.asQueryEngine({ similarityTopK: 1 }),
|
|
472
|
+
chatHistory: HISTORY,
|
|
473
|
+
});
|
|
474
|
+
if (scenario === "chat-condense") {
|
|
475
|
+
report({ answer: (await engine.chat({ message: QUESTION })).message.content });
|
|
476
|
+
} else {
|
|
477
|
+
report({ chunks: await drain(await engine.chat({ message: QUESTION, stream: true })) });
|
|
478
|
+
}
|
|
479
|
+
break;
|
|
480
|
+
}
|
|
481
|
+
// -- retrieval and indexes -----------------------------------------------
|
|
482
|
+
case "index-build": {
|
|
483
|
+
Settings.embedModel = new FakeEmbedding();
|
|
484
|
+
const index = await cityIndex();
|
|
485
|
+
report({ built: typeof index.asRetriever });
|
|
486
|
+
break;
|
|
487
|
+
}
|
|
488
|
+
case "retriever": {
|
|
489
|
+
Settings.embedModel = new FakeEmbedding();
|
|
490
|
+
const index = await cityIndex();
|
|
491
|
+
const nodes = await index.asRetriever({ similarityTopK: 1 }).retrieve({ query: QUESTION });
|
|
492
|
+
report({ nodes: nodes.map((n) => n.node.id_) });
|
|
493
|
+
break;
|
|
494
|
+
}
|
|
495
|
+
case "index-query":
|
|
496
|
+
case "index-query-stream": {
|
|
497
|
+
Settings.embedModel = new FakeEmbedding();
|
|
498
|
+
Settings.llm = new ScriptedLLM([say("It is sunny in Paris.", 9, 4)]);
|
|
499
|
+
const engine = (await cityIndex()).asQueryEngine({ similarityTopK: 1 });
|
|
500
|
+
if (scenario === "index-query") {
|
|
501
|
+
report({ answer: (await engine.query({ query: QUESTION })).message.content });
|
|
502
|
+
} else {
|
|
503
|
+
report({ chunks: await drain(await engine.query({ query: QUESTION, stream: true })) });
|
|
504
|
+
}
|
|
505
|
+
break;
|
|
506
|
+
}
|
|
507
|
+
// -- plain workflows -----------------------------------------------------
|
|
508
|
+
case "custom-workflow": {
|
|
509
|
+
report({ answer: await runPlainWorkflow(new ScriptedLLM([say("It is sunny in Paris.", 9, 4)]), QUESTION) });
|
|
510
|
+
break;
|
|
511
|
+
}
|
|
512
|
+
case "custom-workflow-scoped": {
|
|
513
|
+
const answer = await failproofai.agent("forecast_flow", { goal: QUESTION }, () =>
|
|
514
|
+
runPlainWorkflow(new ScriptedLLM([say("It is sunny in Paris.", 9, 4)]), QUESTION),
|
|
515
|
+
);
|
|
516
|
+
report({ answer });
|
|
517
|
+
break;
|
|
518
|
+
}
|
|
519
|
+
// -- agents --------------------------------------------------------------
|
|
520
|
+
case "handoff3": {
|
|
521
|
+
const handOff = (to: string, id: string): Turn => ({
|
|
522
|
+
tool: { name: "handOff", input: { toAgent: to, reason: "next" }, id },
|
|
523
|
+
usage: { prompt_tokens: 8, completion_tokens: 4 },
|
|
524
|
+
});
|
|
525
|
+
const triage = agent({
|
|
526
|
+
name: "triage",
|
|
527
|
+
description: "Routes questions",
|
|
528
|
+
llm: new ScriptedLLM([handOff("researcher", "call_h1")]),
|
|
529
|
+
tools: [getWeather],
|
|
530
|
+
canHandoffTo: ["researcher"],
|
|
531
|
+
});
|
|
532
|
+
const researcher = agent({
|
|
533
|
+
name: "researcher",
|
|
534
|
+
description: "Finds facts",
|
|
535
|
+
llm: new ScriptedLLM([handOff("forecaster", "call_h2")]),
|
|
536
|
+
tools: [getWeather],
|
|
537
|
+
canHandoffTo: ["forecaster"],
|
|
538
|
+
});
|
|
539
|
+
const forecaster = agent({
|
|
540
|
+
name: "forecaster",
|
|
541
|
+
description: "Knows the weather",
|
|
542
|
+
llm: new ScriptedLLM(),
|
|
543
|
+
tools: [getWeather],
|
|
544
|
+
});
|
|
545
|
+
const out = await multiAgent({ agents: [triage, researcher, forecaster], rootAgent: triage }).run(QUESTION);
|
|
546
|
+
report({ answer: out.data.result });
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
case "structured": {
|
|
550
|
+
const llm = new ScriptedLLM([
|
|
551
|
+
say("It is sunny in Paris.", 9, 4),
|
|
552
|
+
{
|
|
553
|
+
tool: { name: "format_output", input: { city: "Paris", sky: "sunny" }, id: "call_s" },
|
|
554
|
+
usage: { prompt_tokens: 4, completion_tokens: 3 },
|
|
555
|
+
},
|
|
556
|
+
]);
|
|
557
|
+
// `responseFormat` arrived in @llamaindex/workflow after the floor, so it
|
|
558
|
+
// is passed untyped: the floor's types (and runtime) ignore it.
|
|
559
|
+
const params = { responseFormat: z.object({ city: z.string(), sky: z.string() }) } as Record<string, unknown>;
|
|
560
|
+
const out = await agent({ llm, tools: [getWeather] }).run(QUESTION, params as never);
|
|
561
|
+
report({ answer: out.data.result, object: (out.data as { object?: unknown }).object });
|
|
562
|
+
break;
|
|
563
|
+
}
|
|
564
|
+
// -- tool variants -------------------------------------------------------
|
|
565
|
+
case "function-tool": {
|
|
566
|
+
const turns = weatherTurns();
|
|
567
|
+
turns[0]!.tool = { name: "lookup_weather", input: { city: "Paris" }, id: "call_1" };
|
|
568
|
+
const out = await agent({ llm: new ScriptedLLM(turns), tools: [lookup] }).run(QUESTION);
|
|
569
|
+
report({ answer: out.data.result });
|
|
570
|
+
break;
|
|
571
|
+
}
|
|
572
|
+
case "query-engine-tool": {
|
|
573
|
+
Settings.embedModel = new FakeEmbedding();
|
|
574
|
+
// The query engine's synthesizer answers from Settings.llm, the agent from its own.
|
|
575
|
+
Settings.llm = new ScriptedLLM([say("Paris is sunny.", 7, 3)]);
|
|
576
|
+
const notes = new QueryEngineTool({
|
|
577
|
+
queryEngine: (await cityIndex()).asQueryEngine({ similarityTopK: 1 }),
|
|
578
|
+
metadata: { name: "city_notes", description: "Notes about cities" },
|
|
579
|
+
});
|
|
580
|
+
const turns = weatherTurns();
|
|
581
|
+
turns[0]!.tool = { name: "city_notes", input: { query: "Paris" }, id: "call_1" };
|
|
582
|
+
const out = await agent({ llm: new ScriptedLLM(turns), tools: [notes] }).run(QUESTION);
|
|
583
|
+
report({ answer: out.data.result });
|
|
584
|
+
break;
|
|
585
|
+
}
|
|
586
|
+
case "parallel-tools": {
|
|
587
|
+
const turns = weatherTurns();
|
|
588
|
+
turns[0]!.tool = undefined;
|
|
589
|
+
turns[0]!.tools = [
|
|
590
|
+
{ name: "get_weather", input: { city: "Paris" }, id: "call_1" },
|
|
591
|
+
{ name: "get_time", input: { city: "Paris" }, id: "call_2" },
|
|
592
|
+
];
|
|
593
|
+
const out = await agent({ llm: new ScriptedLLM(turns), tools: [getWeather, getTime] }).run(QUESTION);
|
|
594
|
+
report({ answer: out.data.result });
|
|
595
|
+
break;
|
|
596
|
+
}
|
|
597
|
+
case "stream-error": {
|
|
598
|
+
// LlamaIndex's workflow runtime lets a provider error that happens
|
|
599
|
+
// mid-stream escape as an UNHANDLED rejection (reproducible without the
|
|
600
|
+
// SDK), and `run()` never settles. A server survives that with a handler;
|
|
601
|
+
// so does this case, and the run must still close as failed.
|
|
602
|
+
const unhandled: string[] = [];
|
|
603
|
+
process.on("unhandledRejection", (error) => unhandled.push(String(error)));
|
|
604
|
+
const turns: Turn[] = [
|
|
605
|
+
{ text: "It is", fail: "provider dropped the stream", usage: { prompt_tokens: 1, completion_tokens: 1 } },
|
|
606
|
+
];
|
|
607
|
+
const running = agent({ llm: new ScriptedLLM(turns), tools: [getWeather] }).run(QUESTION);
|
|
608
|
+
const settled = await Promise.race([
|
|
609
|
+
running.then(
|
|
610
|
+
() => "resolved",
|
|
611
|
+
(error: unknown) => `rejected: ${String(error)}`,
|
|
612
|
+
),
|
|
613
|
+
sleep(300).then(() => "pending"),
|
|
614
|
+
]);
|
|
615
|
+
report({ settled, unhandled });
|
|
616
|
+
break;
|
|
617
|
+
}
|
|
618
|
+
// -- concurrency ---------------------------------------------------------
|
|
619
|
+
case "concurrent-agents": {
|
|
620
|
+
const shared = agent({ llm: new CityLLM(), tools: [getWeather] });
|
|
621
|
+
const answers = await Promise.all(CITIES.map((city) => shared.run(`weather in ${city}?`)));
|
|
622
|
+
report({ answers: answers.map((a) => a.data.result) });
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
case "concurrent-queries": {
|
|
626
|
+
Settings.embedModel = new FakeEmbedding();
|
|
627
|
+
// The synthesizer answers from Settings.llm: one model object shared by all ten.
|
|
628
|
+
Settings.llm = new CityLLM();
|
|
629
|
+
const engine = (await cityIndex()).asQueryEngine({ similarityTopK: 1 });
|
|
630
|
+
const answers = await Promise.all(CITIES.map((city) => engine.query({ query: `weather in ${city}?` })));
|
|
631
|
+
report({ answers: answers.map((a) => a.message.content) });
|
|
632
|
+
break;
|
|
633
|
+
}
|
|
634
|
+
case "concurrent-chats": {
|
|
635
|
+
Settings.embedModel = new FakeEmbedding();
|
|
636
|
+
const llm = new CityLLM();
|
|
637
|
+
Settings.llm = llm;
|
|
638
|
+
const engine = new ContextChatEngine({
|
|
639
|
+
retriever: (await cityIndex()).asRetriever({ similarityTopK: 1 }),
|
|
640
|
+
chatModel: llm,
|
|
641
|
+
});
|
|
642
|
+
// Per-call history: a shared engine's own memory would mix the requests'
|
|
643
|
+
// messages in the FRAMEWORK, which is not what this case is about.
|
|
644
|
+
const answers = await Promise.all(
|
|
645
|
+
CITIES.map((city) => engine.chat({ message: `weather in ${city}?`, chatHistory: [] })),
|
|
646
|
+
);
|
|
647
|
+
report({ answers: answers.map((a) => a.message.content) });
|
|
648
|
+
break;
|
|
649
|
+
}
|
|
650
|
+
default:
|
|
651
|
+
throw new Error(`unknown scenario ${scenario}`);
|
|
652
|
+
}
|
|
653
|
+
await failproofai.flush();
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
main(process.argv[2] ?? "workflow").catch((error: unknown) => {
|
|
657
|
+
console.error("FATAL", error);
|
|
658
|
+
process.exit(1);
|
|
659
|
+
});
|