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,709 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
FORMATS,
|
|
5
|
+
count,
|
|
6
|
+
describeTrace,
|
|
7
|
+
ofType,
|
|
8
|
+
runAgent,
|
|
9
|
+
traceViolations,
|
|
10
|
+
typecheck,
|
|
11
|
+
type Event,
|
|
12
|
+
} from "./harness.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* LlamaIndex.TS, against real releases.
|
|
16
|
+
*
|
|
17
|
+
* The expected traces follow the Python SDK's LlamaIndex adapter, captured from
|
|
18
|
+
* llama-index-core 0.14.24 running the equivalent `FunctionAgent` program with a
|
|
19
|
+
* scripted model (same tool, same tool call id, same two turns). The two SDKs
|
|
20
|
+
* write into one pipe, so for the same program they must draw the same tree
|
|
21
|
+
* (`sdk/python/skill/references/frameworks.md`):
|
|
22
|
+
*
|
|
23
|
+
* * a workflow run is the agent — session + `agent_start`/`agent_end` — named
|
|
24
|
+
* after the agent (`FunctionAgent.name`, `"Agent"` by default), never an id;
|
|
25
|
+
* * each workflow step is a HOOK (`trigger_event="workflow_step"`);
|
|
26
|
+
* * a multi-agent workflow is `AgentWorkflow` with one nested agent per agent
|
|
27
|
+
* holding the turn;
|
|
28
|
+
* * a bare model call outside any run is its own run, named after the class;
|
|
29
|
+
* * a tool failure lives on its `tool_result`, not in an `error` event.
|
|
30
|
+
*
|
|
31
|
+
* Where TS genuinely differs, it is the framework and not the adapter: the step
|
|
32
|
+
* NAMES are LlamaIndex.TS's own handler names (`runAgentStep`, where Python has
|
|
33
|
+
* `run_agent_step`), TS executes every tool call of a turn in ONE
|
|
34
|
+
* `executeToolCalls` step (Python runs a `call_tool` step per call), and
|
|
35
|
+
* `parseAgentOutput` starts INSIDE `runAgentStep` because the TS runtime
|
|
36
|
+
* dispatches the next step synchronously from `sendEvent`.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The supported floor and the latest release. 0.11.4 is the first `llamaindex`
|
|
41
|
+
* on `@llamaindex/workflow` 1.1 (then still `@llama-flow/core` underneath, with
|
|
42
|
+
* step handlers called as `handler(event)` and no bus event for a tool call);
|
|
43
|
+
* 0.9–0.11.3 ship workflow 1.0, a different runtime whose `AgentWorkflow` has no
|
|
44
|
+
* `runStream` at all.
|
|
45
|
+
*/
|
|
46
|
+
const FIXTURES = ["llamaindex-0.11", "llamaindex-0.12"] as const;
|
|
47
|
+
|
|
48
|
+
/** One line per event: `agent_id type [hook|tool]`. */
|
|
49
|
+
const shape = (events: Event[]): string[] =>
|
|
50
|
+
events.map((e) => [e.agent_id, e.type, (e.hook_name ?? e.tool_name ?? "") as string].join(" ").trim());
|
|
51
|
+
|
|
52
|
+
const hook = (agentId: string, name: string, body: string[] = []): string[] => [
|
|
53
|
+
`${agentId} hook_triggered ${name}`,
|
|
54
|
+
...body,
|
|
55
|
+
`${agentId} hook_completed ${name}`,
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
const MODEL = (agentId: string) => [`${agentId} model_request`, `${agentId} model_response`];
|
|
59
|
+
|
|
60
|
+
/** One `FunctionAgent` turn that asks for `tool`, then the turn that answers. */
|
|
61
|
+
const agentLoop = (agentId: string, tool: string): string[] => [
|
|
62
|
+
...hook(agentId, "setupAgent"),
|
|
63
|
+
`${agentId} hook_triggered runAgentStep`,
|
|
64
|
+
...MODEL(agentId),
|
|
65
|
+
...hook(agentId, "parseAgentOutput"),
|
|
66
|
+
`${agentId} hook_completed runAgentStep`,
|
|
67
|
+
...hook(agentId, "executeToolCalls", [`${agentId} tool_use ${tool}`, `${agentId} tool_result ${tool}`]),
|
|
68
|
+
...hook(agentId, "processToolResults"),
|
|
69
|
+
...hook(agentId, "setupAgent"),
|
|
70
|
+
`${agentId} hook_triggered runAgentStep`,
|
|
71
|
+
...MODEL(agentId),
|
|
72
|
+
`${agentId} hook_triggered parseAgentOutput`,
|
|
73
|
+
`${agentId} hook_completed runAgentStep`,
|
|
74
|
+
`${agentId} hook_completed parseAgentOutput`,
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
const WORKFLOW = (agentId = "Agent", tool = "get_weather"): string[] => [
|
|
78
|
+
`${agentId} agent_start`,
|
|
79
|
+
...hook(agentId, "handleInputStep"),
|
|
80
|
+
...agentLoop(agentId, tool),
|
|
81
|
+
`${agentId} agent_end`,
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
describe.each(FIXTURES)("%s", (fixture) => {
|
|
85
|
+
it("typechecks as a customer's nodenext ES-module project", () => {
|
|
86
|
+
expect(typecheck(fixture)).toBe("");
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
describe.each(FORMATS)("as %s", (format) => {
|
|
90
|
+
const run = (scenario: string, env: Record<string, string> = {}) => {
|
|
91
|
+
const result = runAgent(fixture, format, scenario, env);
|
|
92
|
+
expect(result.status, describeTrace(result)).toBe(0);
|
|
93
|
+
// Instrumenting must never load a second copy of the framework: LlamaIndex
|
|
94
|
+
// detects it and prints this to the customer's terminal.
|
|
95
|
+
expect(result.stderr).not.toContain("already imported");
|
|
96
|
+
expect(result.stdout).toContain('"instrumented":["llamaindex"]');
|
|
97
|
+
return result;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
it("records a workflow agent run as one agent with its steps as hooks", () => {
|
|
101
|
+
const result = run("workflow");
|
|
102
|
+
expect(shape(result.events), describeTrace(result)).toEqual(WORKFLOW());
|
|
103
|
+
expect(traceViolations(result.events), describeTrace(result)).toEqual([]);
|
|
104
|
+
expect(new Set(result.events.map((e) => e.session_id)).size).toBe(1);
|
|
105
|
+
for (const event of ofType(result.events, "hook_triggered")) {
|
|
106
|
+
expect(event.trigger_event).toBe("workflow_step");
|
|
107
|
+
}
|
|
108
|
+
const responses = ofType(result.events, "model_response");
|
|
109
|
+
expect(responses.map((e) => [e.input_tokens, e.output_tokens])).toEqual([
|
|
110
|
+
[12, 5],
|
|
111
|
+
[30, 7],
|
|
112
|
+
]);
|
|
113
|
+
for (const event of [...ofType(result.events, "model_request"), ...responses]) {
|
|
114
|
+
expect(event.model).toBe("scripted-1");
|
|
115
|
+
}
|
|
116
|
+
// The model's own tool call id, so a tool_use joins to the tool call that
|
|
117
|
+
// asked for it.
|
|
118
|
+
expect(ofType(result.events, "tool_use")[0]!.tool_call_id).toBe("call_1");
|
|
119
|
+
expect(ofType(result.events, "tool_result")[0]!.output).toBe("sunny in Paris");
|
|
120
|
+
const end = ofType(result.events, "agent_end")[0]!;
|
|
121
|
+
expect(end.outcome).toBe("success");
|
|
122
|
+
expect(end.summary).toBe("It is sunny in Paris.");
|
|
123
|
+
expect(ofType(result.events, "agent_start")[0]!.goal).toBe("weather in Paris?");
|
|
124
|
+
for (const event of result.events) {
|
|
125
|
+
expect(event.framework).toBe("llamaindex");
|
|
126
|
+
expect(typeof event.framework_version).toBe("string");
|
|
127
|
+
}
|
|
128
|
+
expect(result.stdout).toContain("It is sunny in Paris.");
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it("names the run after the agent", () => {
|
|
132
|
+
const result = run("named");
|
|
133
|
+
expect(shape(result.events), describeTrace(result)).toEqual(WORKFLOW("weather_bot"));
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it("records an agent built before instrument()", () => {
|
|
137
|
+
const result = run("early");
|
|
138
|
+
expect(shape(result.events), describeTrace(result)).toEqual(WORKFLOW());
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("records runStream() exactly like run()", () => {
|
|
142
|
+
const result = run("stream");
|
|
143
|
+
expect(shape(result.events), describeTrace(result)).toEqual(WORKFLOW());
|
|
144
|
+
expect(traceViolations(result.events), describeTrace(result)).toEqual([]);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("records a multi-agent handoff as nested agents under the workflow", () => {
|
|
148
|
+
const result = run("handoff");
|
|
149
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
150
|
+
"AgentWorkflow agent_start",
|
|
151
|
+
...hook("AgentWorkflow", "handleInputStep"),
|
|
152
|
+
"triage agent_start",
|
|
153
|
+
...hook("triage", "setupAgent"),
|
|
154
|
+
"triage hook_triggered runAgentStep",
|
|
155
|
+
...MODEL("triage"),
|
|
156
|
+
...hook("triage", "parseAgentOutput"),
|
|
157
|
+
"triage hook_completed runAgentStep",
|
|
158
|
+
...hook("triage", "executeToolCalls", ["triage tool_use handOff", "triage tool_result handOff"]),
|
|
159
|
+
...hook("triage", "processToolResults"),
|
|
160
|
+
"triage agent_end",
|
|
161
|
+
"forecaster agent_start",
|
|
162
|
+
...agentLoop("forecaster", "get_weather"),
|
|
163
|
+
"forecaster agent_end",
|
|
164
|
+
"AgentWorkflow agent_end",
|
|
165
|
+
]);
|
|
166
|
+
expect(traceViolations(result.events), describeTrace(result)).toEqual([]);
|
|
167
|
+
for (const start of ofType(result.events, "agent_start").slice(1)) {
|
|
168
|
+
expect(start.parent_id).toBe("AgentWorkflow");
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("records a legacy LLMAgent as one agent across all its steps", () => {
|
|
173
|
+
const result = run("legacy");
|
|
174
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
175
|
+
"LLMAgent agent_start",
|
|
176
|
+
...MODEL("LLMAgent"),
|
|
177
|
+
"LLMAgent tool_use get_weather",
|
|
178
|
+
"LLMAgent tool_result get_weather",
|
|
179
|
+
...MODEL("LLMAgent"),
|
|
180
|
+
"LLMAgent agent_end",
|
|
181
|
+
]);
|
|
182
|
+
expect(traceViolations(result.events), describeTrace(result)).toEqual([]);
|
|
183
|
+
expect(new Set(result.events.map((e) => e.session_id)).size).toBe(1);
|
|
184
|
+
expect(ofType(result.events, "model_response").map((e) => [e.input_tokens, e.output_tokens])).toEqual([
|
|
185
|
+
[12, 5],
|
|
186
|
+
[30, 7],
|
|
187
|
+
]);
|
|
188
|
+
expect(ofType(result.events, "model_request")[0]!.model).toBe("scripted-1");
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it("records a bare model call as its own run", () => {
|
|
192
|
+
const result = run("model");
|
|
193
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
194
|
+
"ScriptedLLM agent_start",
|
|
195
|
+
...MODEL("ScriptedLLM"),
|
|
196
|
+
"ScriptedLLM agent_end",
|
|
197
|
+
]);
|
|
198
|
+
expect(traceViolations(result.events), describeTrace(result)).toEqual([]);
|
|
199
|
+
const response = ofType(result.events, "model_response")[0]!;
|
|
200
|
+
expect([response.input_tokens, response.output_tokens]).toEqual([3, 1]);
|
|
201
|
+
expect(response.model).toBe("scripted-1");
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it("nests the run under an enclosing agent() scope", () => {
|
|
205
|
+
const result = run("scope");
|
|
206
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
207
|
+
"planner agent_start",
|
|
208
|
+
...WORKFLOW(),
|
|
209
|
+
"planner agent_end",
|
|
210
|
+
]);
|
|
211
|
+
expect(new Set(result.events.map((e) => e.session_id))).toEqual(new Set(["req-1"]));
|
|
212
|
+
expect(ofType(result.events, "agent_start")[1]!.parent_id).toBe("planner");
|
|
213
|
+
expect(traceViolations(result.events), describeTrace(result)).toEqual([]);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it("records a failing tool on its tool_result, once", () => {
|
|
217
|
+
const result = run("tool-error");
|
|
218
|
+
expect(shape(result.events), describeTrace(result)).toEqual(WORKFLOW("Agent", "broken"));
|
|
219
|
+
expect(traceViolations(result.events), describeTrace(result)).toEqual([]);
|
|
220
|
+
expect(ofType(result.events, "tool_result")[0]!.error).toMatch(/tool exploded/);
|
|
221
|
+
expect(ofType(result.events, "hook_completed").every((e) => e.outcome === "success")).toBe(true);
|
|
222
|
+
expect(ofType(result.events, "agent_end")[0]!.outcome).toBe("success");
|
|
223
|
+
expect(count(result.events, "error")).toBe(0);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Two requests in flight on ONE object built at startup (before
|
|
228
|
+
* instrument()), Paris slow and Rome fast, so Rome starts and ends inside
|
|
229
|
+
* Paris. Each must be its own session with its own run, and every event in
|
|
230
|
+
* a session must belong to that session's request.
|
|
231
|
+
*/
|
|
232
|
+
const concurrent = (scenario: string, expected: string[], agentId: string) => {
|
|
233
|
+
const result = run(scenario);
|
|
234
|
+
expect(traceViolations(result.events), describeTrace(result)).toEqual([]);
|
|
235
|
+
const sessions = new Map<string, Event[]>();
|
|
236
|
+
for (const e of result.events) sessions.set(e.session_id, [...(sessions.get(e.session_id) ?? []), e]);
|
|
237
|
+
expect(sessions.size, describeTrace(result)).toBe(2);
|
|
238
|
+
const byCity = new Map<string, Event[]>();
|
|
239
|
+
for (const list of sessions.values()) {
|
|
240
|
+
expect(shape(list), describeTrace(result)).toEqual(expected);
|
|
241
|
+
const start = list[0]!;
|
|
242
|
+
expect(start.agent_id).toBe(agentId);
|
|
243
|
+
expect(start.parent_id ?? null).toBeNull();
|
|
244
|
+
const city = String(start.goal).includes("Rome") ? "Rome" : "Paris";
|
|
245
|
+
byCity.set(city, list);
|
|
246
|
+
}
|
|
247
|
+
expect([...byCity.keys()].sort()).toEqual(["Paris", "Rome"]);
|
|
248
|
+
for (const [city, list] of byCity) {
|
|
249
|
+
const other = city === "Paris" ? "Rome" : "Paris";
|
|
250
|
+
// Nothing of the other request in this session.
|
|
251
|
+
expect(JSON.stringify(list), describeTrace(result)).not.toContain(other);
|
|
252
|
+
for (const response of ofType(list, "model_response")) {
|
|
253
|
+
expect([response.input_tokens, response.output_tokens]).toEqual(city === "Paris" ? [11, 2] : [21, 3]);
|
|
254
|
+
expect(response.model).toBe("echo-1");
|
|
255
|
+
}
|
|
256
|
+
const end = ofType(list, "agent_end")[0]!;
|
|
257
|
+
expect(end.outcome).toBe("success");
|
|
258
|
+
expect(end.summary).toBe(`It is sunny in ${city}.`);
|
|
259
|
+
}
|
|
260
|
+
// They really did overlap: Rome started after Paris and ended before it.
|
|
261
|
+
const index = (city: string, type: string) => result.events.indexOf(ofType(byCity.get(city)!, type)[0]!);
|
|
262
|
+
expect(index("Rome", "agent_start")).toBeGreaterThan(index("Paris", "agent_start"));
|
|
263
|
+
expect(index("Rome", "agent_end")).toBeLessThan(index("Paris", "agent_end"));
|
|
264
|
+
return byCity;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
it("keeps concurrent queries on one shared query engine in separate sessions", () => {
|
|
268
|
+
const byCity = concurrent(
|
|
269
|
+
"shared-query",
|
|
270
|
+
[
|
|
271
|
+
"RetrieverQueryEngine agent_start",
|
|
272
|
+
"RetrieverQueryEngine tool_use NotesRetriever",
|
|
273
|
+
"RetrieverQueryEngine tool_result NotesRetriever",
|
|
274
|
+
...MODEL("RetrieverQueryEngine"),
|
|
275
|
+
"RetrieverQueryEngine agent_end",
|
|
276
|
+
],
|
|
277
|
+
"RetrieverQueryEngine",
|
|
278
|
+
);
|
|
279
|
+
for (const [city, list] of byCity) {
|
|
280
|
+
expect(ofType(list, "tool_use")[0]!.input).toEqual({ query: `weather in ${city}?` });
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it("keeps concurrent chats on one shared legacy LLMAgent in separate sessions", () => {
|
|
285
|
+
const byCity = concurrent(
|
|
286
|
+
"shared-legacy",
|
|
287
|
+
[
|
|
288
|
+
"LLMAgent agent_start",
|
|
289
|
+
...MODEL("LLMAgent"),
|
|
290
|
+
"LLMAgent tool_use get_weather",
|
|
291
|
+
"LLMAgent tool_result get_weather",
|
|
292
|
+
...MODEL("LLMAgent"),
|
|
293
|
+
"LLMAgent agent_end",
|
|
294
|
+
],
|
|
295
|
+
"LLMAgent",
|
|
296
|
+
);
|
|
297
|
+
for (const [city, list] of byCity) {
|
|
298
|
+
expect(ofType(list, "tool_use")[0]!.tool_call_id).toBe(`call_${city}`);
|
|
299
|
+
expect(ofType(list, "tool_result")[0]!.output).toBe(`sunny in ${city}`);
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it("keeps concurrent runs of one shared workflow agent in separate sessions", () => {
|
|
304
|
+
const byCity = concurrent("shared-workflow", WORKFLOW(), "Agent");
|
|
305
|
+
for (const [city, list] of byCity) {
|
|
306
|
+
expect(ofType(list, "tool_use")[0]!.tool_call_id).toBe(`call_${city}`);
|
|
307
|
+
expect(ofType(list, "tool_result")[0]!.output).toBe(`sunny in ${city}`);
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it("records nothing after uninstrument()", () => {
|
|
312
|
+
const result = run("uninstrument");
|
|
313
|
+
expect(shape(result.events), describeTrace(result)).toEqual(WORKFLOW());
|
|
314
|
+
expect(result.stdout).toContain('"removed":["llamaindex"]');
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// -- the coverage sweep ------------------------------------------------------
|
|
318
|
+
//
|
|
319
|
+
// Every commonly used surface, each against the Python adapter's golden
|
|
320
|
+
// trace for the same program (llama-index-core 0.14.24, mock LLM and
|
|
321
|
+
// embeddings): a top-level chat engine, query engine or retriever call is
|
|
322
|
+
// the session's root agent named after its class, and a retrieval is a
|
|
323
|
+
// `tool_use`/`tool_result` named after the retriever's class, its output
|
|
324
|
+
// summarised. (Python's MockLLM records each call twice, chat inside
|
|
325
|
+
// complete; that is the mock, not the mapping.)
|
|
326
|
+
|
|
327
|
+
/** The fewest checks every trace must pass: sound, one session, the framework's name. */
|
|
328
|
+
const sound = (result: ReturnType<typeof run>, sessions = 1, scopes: string[] = []) => {
|
|
329
|
+
expect(traceViolations(result.events), describeTrace(result)).toEqual([]);
|
|
330
|
+
expect(new Set(result.events.map((e) => e.session_id)).size, describeTrace(result)).toBe(sessions);
|
|
331
|
+
// The application's own agent() scope is not the framework's.
|
|
332
|
+
for (const event of result.events) {
|
|
333
|
+
if (!scopes.includes(event.agent_id)) expect(event.framework).toBe("llamaindex");
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
const RETRIEVAL = (agentId: string, retriever = "VectorIndexRetriever") => [
|
|
337
|
+
`${agentId} tool_use ${retriever}`,
|
|
338
|
+
`${agentId} tool_result ${retriever}`,
|
|
339
|
+
];
|
|
340
|
+
/** The retrieval found the Paris note, summarised: count, score, text prefix. */
|
|
341
|
+
const retrievedParis = (event: Event) => {
|
|
342
|
+
const output = event.output as { num_nodes: number; top: Array<{ text: string; score: number }> };
|
|
343
|
+
expect(output.num_nodes).toBe(1);
|
|
344
|
+
expect(output.top[0]!.text).toBe("Paris is sunny.");
|
|
345
|
+
expect(typeof output.top[0]!.score).toBe("number");
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
describe.each(["chat-simple", "chat-simple-stream"])("SimpleChatEngine (%s)", (scenario) => {
|
|
349
|
+
it("is one run named after the engine, with the chat history in the model call", () => {
|
|
350
|
+
const result = run(scenario);
|
|
351
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
352
|
+
"SimpleChatEngine agent_start",
|
|
353
|
+
...MODEL("SimpleChatEngine"),
|
|
354
|
+
"SimpleChatEngine agent_end",
|
|
355
|
+
]);
|
|
356
|
+
sound(result);
|
|
357
|
+
const request = ofType(result.events, "model_request")[0]!;
|
|
358
|
+
expect(request.model).toBe("scripted-1");
|
|
359
|
+
expect(request.messages).toEqual([
|
|
360
|
+
{ role: "user", content: "hi" },
|
|
361
|
+
{ role: "assistant", content: "hello" },
|
|
362
|
+
{ role: "user", content: "weather in Paris?" },
|
|
363
|
+
]);
|
|
364
|
+
const response = ofType(result.events, "model_response")[0]!;
|
|
365
|
+
expect([response.input_tokens, response.output_tokens]).toEqual([9, 4]);
|
|
366
|
+
expect(ofType(result.events, "agent_end")[0]).toMatchObject({ outcome: "success", summary: "It is sunny in Paris." });
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
describe.each(["chat-context", "chat-context-stream"])("ContextChatEngine (%s)", (scenario) => {
|
|
371
|
+
it("is one run: the retrieval, then the model call with the history and the context", () => {
|
|
372
|
+
const result = run(scenario);
|
|
373
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
374
|
+
"ContextChatEngine agent_start",
|
|
375
|
+
...RETRIEVAL("ContextChatEngine"),
|
|
376
|
+
...MODEL("ContextChatEngine"),
|
|
377
|
+
"ContextChatEngine agent_end",
|
|
378
|
+
]);
|
|
379
|
+
sound(result);
|
|
380
|
+
expect(ofType(result.events, "tool_use")[0]!.input).toEqual({ query: "weather in Paris?" });
|
|
381
|
+
retrievedParis(ofType(result.events, "tool_result")[0]!);
|
|
382
|
+
const messages = JSON.stringify(ofType(result.events, "model_request")[0]!.messages);
|
|
383
|
+
expect(messages).toContain("Paris is sunny.");
|
|
384
|
+
expect(messages).toContain("hello");
|
|
385
|
+
const response = ofType(result.events, "model_response")[0]!;
|
|
386
|
+
expect([response.input_tokens, response.output_tokens]).toEqual([9, 4]);
|
|
387
|
+
expect(ofType(result.events, "agent_end")[0]).toMatchObject({ outcome: "success", summary: "It is sunny in Paris." });
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
describe.each(["chat-condense", "chat-condense-stream"])("CondenseQuestionChatEngine (%s)", (scenario) => {
|
|
392
|
+
it("is one run: the condensing model call, the query's retrieval and its answer", () => {
|
|
393
|
+
const result = run(scenario);
|
|
394
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
395
|
+
"CondenseQuestionChatEngine agent_start",
|
|
396
|
+
...MODEL("CondenseQuestionChatEngine"),
|
|
397
|
+
...RETRIEVAL("CondenseQuestionChatEngine"),
|
|
398
|
+
...MODEL("CondenseQuestionChatEngine"),
|
|
399
|
+
"CondenseQuestionChatEngine agent_end",
|
|
400
|
+
]);
|
|
401
|
+
sound(result);
|
|
402
|
+
// The history reaches the model through the condense prompt.
|
|
403
|
+
expect(JSON.stringify(ofType(result.events, "model_request")[0]!.messages)).toContain("hello");
|
|
404
|
+
expect(ofType(result.events, "tool_use")[0]!.input).toEqual({ query: "What is the weather in Paris?" });
|
|
405
|
+
retrievedParis(ofType(result.events, "tool_result")[0]!);
|
|
406
|
+
expect(ofType(result.events, "model_response").map((e) => [e.input_tokens, e.output_tokens])).toEqual([
|
|
407
|
+
[6, 3],
|
|
408
|
+
[9, 4],
|
|
409
|
+
]);
|
|
410
|
+
expect(ofType(result.events, "agent_end")[0]).toMatchObject({ outcome: "success", summary: "It is sunny in Paris." });
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
it("records a retriever used directly as its own run", () => {
|
|
415
|
+
const result = run("retriever");
|
|
416
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
417
|
+
"VectorIndexRetriever agent_start",
|
|
418
|
+
...RETRIEVAL("VectorIndexRetriever"),
|
|
419
|
+
"VectorIndexRetriever agent_end",
|
|
420
|
+
]);
|
|
421
|
+
sound(result);
|
|
422
|
+
expect(ofType(result.events, "tool_use")[0]!.input).toEqual({ query: "weather in Paris?" });
|
|
423
|
+
retrievedParis(ofType(result.events, "tool_result")[0]!);
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
describe.each(["index-query", "index-query-stream"])("VectorStoreIndex.asQueryEngine() (%s)", (scenario) => {
|
|
427
|
+
it("is one run named after the engine, with its retrieval and its answer", () => {
|
|
428
|
+
const result = run(scenario);
|
|
429
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
430
|
+
"RetrieverQueryEngine agent_start",
|
|
431
|
+
...RETRIEVAL("RetrieverQueryEngine"),
|
|
432
|
+
...MODEL("RetrieverQueryEngine"),
|
|
433
|
+
"RetrieverQueryEngine agent_end",
|
|
434
|
+
]);
|
|
435
|
+
sound(result);
|
|
436
|
+
expect(ofType(result.events, "agent_start")[0]!.goal).toBe("weather in Paris?");
|
|
437
|
+
retrievedParis(ofType(result.events, "tool_result")[0]!);
|
|
438
|
+
const response = ofType(result.events, "model_response")[0]!;
|
|
439
|
+
expect([response.input_tokens, response.output_tokens]).toEqual([9, 4]);
|
|
440
|
+
expect(ofType(result.events, "agent_end")[0]).toMatchObject({ outcome: "success", summary: "It is sunny in Paris." });
|
|
441
|
+
});
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
it("records nothing for building an index, with or without embeddings: true", () => {
|
|
445
|
+
// LlamaIndex.TS dispatches no embedding event on its bus, so there is
|
|
446
|
+
// nothing for `embeddings: true` to record; the option is accepted and
|
|
447
|
+
// changes nothing. (Python records embedding calls under it.)
|
|
448
|
+
expect(run("index-build").events).toEqual([]);
|
|
449
|
+
expect(run("index-build", { FAILPROOFAI_IT_OPTIONS: JSON.stringify({ embeddings: true }) }).events).toEqual([]);
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
/** workflow-core ≥1.1 exposes the hook plain workflows are recorded through; the floor's runtime does not. */
|
|
453
|
+
const plainWorkflows = fixture !== "llamaindex-0.11";
|
|
454
|
+
|
|
455
|
+
it(
|
|
456
|
+
plainWorkflows
|
|
457
|
+
? "records a createWorkflow() workflow as a run with its steps as hooks"
|
|
458
|
+
: "leaves a createWorkflow() workflow's model call a run of its own on the floor's runtime",
|
|
459
|
+
() => {
|
|
460
|
+
const result = run("custom-workflow");
|
|
461
|
+
sound(result);
|
|
462
|
+
if (plainWorkflows) {
|
|
463
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
464
|
+
"Workflow agent_start",
|
|
465
|
+
...hook("Workflow", "research"),
|
|
466
|
+
...hook("Workflow", "answer", MODEL("Workflow")),
|
|
467
|
+
"Workflow agent_end",
|
|
468
|
+
]);
|
|
469
|
+
expect(ofType(result.events, "agent_start")[0]!.goal).toBe("weather in Paris?");
|
|
470
|
+
for (const event of ofType(result.events, "hook_triggered")) expect(event.trigger_event).toBe("workflow_step");
|
|
471
|
+
expect(ofType(result.events, "agent_end")[0]).toMatchObject({ outcome: "success", summary: "It is sunny in Paris." });
|
|
472
|
+
} else {
|
|
473
|
+
// @llama-flow/core binds its handler context in a closure: there is
|
|
474
|
+
// no run boundary and no step to observe, only the model call.
|
|
475
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
476
|
+
"ScriptedLLM agent_start",
|
|
477
|
+
...MODEL("ScriptedLLM"),
|
|
478
|
+
"ScriptedLLM agent_end",
|
|
479
|
+
]);
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
);
|
|
483
|
+
|
|
484
|
+
it("nests a createWorkflow() workflow under an enclosing agent() scope", () => {
|
|
485
|
+
const result = run("custom-workflow-scoped");
|
|
486
|
+
sound(result, 1, ["forecast_flow"]);
|
|
487
|
+
const inner = plainWorkflows
|
|
488
|
+
? ["Workflow agent_start", ...hook("Workflow", "research"), ...hook("Workflow", "answer", MODEL("Workflow")), "Workflow agent_end"]
|
|
489
|
+
: ["ScriptedLLM agent_start", ...MODEL("ScriptedLLM"), "ScriptedLLM agent_end"];
|
|
490
|
+
expect(shape(result.events), describeTrace(result)).toEqual(["forecast_flow agent_start", ...inner, "forecast_flow agent_end"]);
|
|
491
|
+
expect(ofType(result.events, "agent_start")[1]!.parent_id).toBe("forecast_flow");
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
it("records a three-agent handoff chain as nested agents under the workflow", () => {
|
|
495
|
+
const result = run("handoff3");
|
|
496
|
+
const handingOff = (agentId: string) => [
|
|
497
|
+
`${agentId} agent_start`,
|
|
498
|
+
...hook(agentId, "setupAgent"),
|
|
499
|
+
`${agentId} hook_triggered runAgentStep`,
|
|
500
|
+
...MODEL(agentId),
|
|
501
|
+
...hook(agentId, "parseAgentOutput"),
|
|
502
|
+
`${agentId} hook_completed runAgentStep`,
|
|
503
|
+
...hook(agentId, "executeToolCalls", [`${agentId} tool_use handOff`, `${agentId} tool_result handOff`]),
|
|
504
|
+
...hook(agentId, "processToolResults"),
|
|
505
|
+
`${agentId} agent_end`,
|
|
506
|
+
];
|
|
507
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
508
|
+
"AgentWorkflow agent_start",
|
|
509
|
+
...hook("AgentWorkflow", "handleInputStep"),
|
|
510
|
+
...handingOff("triage"),
|
|
511
|
+
...handingOff("researcher"),
|
|
512
|
+
"forecaster agent_start",
|
|
513
|
+
...agentLoop("forecaster", "get_weather"),
|
|
514
|
+
"forecaster agent_end",
|
|
515
|
+
"AgentWorkflow agent_end",
|
|
516
|
+
]);
|
|
517
|
+
sound(result);
|
|
518
|
+
for (const start of ofType(result.events, "agent_start").slice(1)) expect(start.parent_id).toBe("AgentWorkflow");
|
|
519
|
+
expect(ofType(result.events, "tool_use").map((e) => e.tool_call_id)).toEqual(["call_h1", "call_h2", "call_1"]);
|
|
520
|
+
expect(ofType(result.events, "agent_end").at(-1)!.summary).toBe("It is sunny in Paris.");
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
// `responseFormat` arrived after the floor (@llamaindex/workflow 1.1.5 ignores it).
|
|
524
|
+
it.skipIf(fixture === "llamaindex-0.11")("records agent() with responseFormat: the structured-output call and tool", () => {
|
|
525
|
+
const result = run("structured");
|
|
526
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
527
|
+
"Agent agent_start",
|
|
528
|
+
...hook("Agent", "handleInputStep"),
|
|
529
|
+
...hook("Agent", "setupAgent"),
|
|
530
|
+
"Agent hook_triggered runAgentStep",
|
|
531
|
+
...MODEL("Agent"),
|
|
532
|
+
"Agent hook_triggered parseAgentOutput",
|
|
533
|
+
"Agent hook_completed runAgentStep",
|
|
534
|
+
...MODEL("Agent"),
|
|
535
|
+
"Agent tool_use format_output",
|
|
536
|
+
"Agent tool_result format_output",
|
|
537
|
+
"Agent hook_completed parseAgentOutput",
|
|
538
|
+
"Agent agent_end",
|
|
539
|
+
]);
|
|
540
|
+
sound(result);
|
|
541
|
+
expect(ofType(result.events, "tool_result")[0]!.output).toEqual({ city: "Paris", sky: "sunny" });
|
|
542
|
+
expect(result.stdout).toContain('"object":{"city":"Paris","sky":"sunny"}');
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
it("records a FunctionTool.from() tool like a tool() one", () => {
|
|
546
|
+
const result = run("function-tool");
|
|
547
|
+
expect(shape(result.events), describeTrace(result)).toEqual(WORKFLOW("Agent", "lookup_weather"));
|
|
548
|
+
sound(result);
|
|
549
|
+
expect(ofType(result.events, "tool_use")[0]).toMatchObject({ tool_call_id: "call_1", input: { city: "Paris" } });
|
|
550
|
+
expect(ofType(result.events, "tool_result")[0]!.output).toBe("sunny in Paris");
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
it("records a QueryEngineTool with the query's retrieval and model call inside it", () => {
|
|
554
|
+
const result = run("query-engine-tool");
|
|
555
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
556
|
+
"Agent agent_start",
|
|
557
|
+
...hook("Agent", "handleInputStep"),
|
|
558
|
+
...hook("Agent", "setupAgent"),
|
|
559
|
+
"Agent hook_triggered runAgentStep",
|
|
560
|
+
...MODEL("Agent"),
|
|
561
|
+
...hook("Agent", "parseAgentOutput"),
|
|
562
|
+
"Agent hook_completed runAgentStep",
|
|
563
|
+
...hook("Agent", "executeToolCalls", [
|
|
564
|
+
"Agent tool_use city_notes",
|
|
565
|
+
...RETRIEVAL("Agent"),
|
|
566
|
+
...MODEL("Agent"),
|
|
567
|
+
"Agent tool_result city_notes",
|
|
568
|
+
]),
|
|
569
|
+
...hook("Agent", "processToolResults"),
|
|
570
|
+
...hook("Agent", "setupAgent"),
|
|
571
|
+
"Agent hook_triggered runAgentStep",
|
|
572
|
+
...MODEL("Agent"),
|
|
573
|
+
"Agent hook_triggered parseAgentOutput",
|
|
574
|
+
"Agent hook_completed runAgentStep",
|
|
575
|
+
"Agent hook_completed parseAgentOutput",
|
|
576
|
+
"Agent agent_end",
|
|
577
|
+
]);
|
|
578
|
+
sound(result);
|
|
579
|
+
expect(ofType(result.events, "tool_result").at(-1)!.output).toEqual({ content: "Paris is sunny." });
|
|
580
|
+
expect(ofType(result.events, "model_response").map((e) => [e.input_tokens, e.output_tokens])).toEqual([
|
|
581
|
+
[12, 5],
|
|
582
|
+
[7, 3],
|
|
583
|
+
[30, 7],
|
|
584
|
+
]);
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
it("records parallel tool calls from one model turn, each on its own id", () => {
|
|
588
|
+
const result = run("parallel-tools");
|
|
589
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
590
|
+
"Agent agent_start",
|
|
591
|
+
...hook("Agent", "handleInputStep"),
|
|
592
|
+
...hook("Agent", "setupAgent"),
|
|
593
|
+
"Agent hook_triggered runAgentStep",
|
|
594
|
+
...MODEL("Agent"),
|
|
595
|
+
...hook("Agent", "parseAgentOutput"),
|
|
596
|
+
"Agent hook_completed runAgentStep",
|
|
597
|
+
...hook("Agent", "executeToolCalls", [
|
|
598
|
+
"Agent tool_use get_weather",
|
|
599
|
+
"Agent tool_result get_weather",
|
|
600
|
+
"Agent tool_use get_time",
|
|
601
|
+
"Agent tool_result get_time",
|
|
602
|
+
]),
|
|
603
|
+
...hook("Agent", "processToolResults"),
|
|
604
|
+
...hook("Agent", "setupAgent"),
|
|
605
|
+
"Agent hook_triggered runAgentStep",
|
|
606
|
+
...MODEL("Agent"),
|
|
607
|
+
"Agent hook_triggered parseAgentOutput",
|
|
608
|
+
"Agent hook_completed runAgentStep",
|
|
609
|
+
"Agent hook_completed parseAgentOutput",
|
|
610
|
+
"Agent agent_end",
|
|
611
|
+
]);
|
|
612
|
+
sound(result);
|
|
613
|
+
expect(ofType(result.events, "tool_result").map((e) => [e.tool_call_id, e.output])).toEqual([
|
|
614
|
+
["call_1", "sunny in Paris"],
|
|
615
|
+
["call_2", "noon in Paris"],
|
|
616
|
+
]);
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
it("closes the run as failed when the provider fails mid-stream (an unhandled rejection in LlamaIndex)", () => {
|
|
620
|
+
// The workflow runtime lets this error escape as an unhandled rejection
|
|
621
|
+
// and `run()` never settles — LlamaIndex's behaviour, with or without
|
|
622
|
+
// the SDK. The failed step is the signal: the run still closes, failed.
|
|
623
|
+
const result = run("stream-error");
|
|
624
|
+
expect(shape(result.events), describeTrace(result)).toEqual([
|
|
625
|
+
"Agent agent_start",
|
|
626
|
+
...hook("Agent", "handleInputStep"),
|
|
627
|
+
...hook("Agent", "setupAgent"),
|
|
628
|
+
"Agent hook_triggered runAgentStep",
|
|
629
|
+
...MODEL("Agent"),
|
|
630
|
+
"Agent hook_completed runAgentStep",
|
|
631
|
+
"Agent agent_end",
|
|
632
|
+
]);
|
|
633
|
+
sound(result);
|
|
634
|
+
expect(result.stdout).toContain('"settled":"pending"');
|
|
635
|
+
expect(result.stdout).toContain('"unhandled":["Error: provider dropped the stream"]');
|
|
636
|
+
expect(ofType(result.events, "model_response")[0]!.error).toMatch(/provider dropped the stream/);
|
|
637
|
+
expect(ofType(result.events, "hook_completed").at(-1)).toMatchObject({ outcome: "failed" });
|
|
638
|
+
expect(ofType(result.events, "agent_end")[0]).toMatchObject({ outcome: "failed" });
|
|
639
|
+
expect(count(result.events, "error")).toBe(0);
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Ten requests in flight at once on ONE object: each its own session, and
|
|
644
|
+
* nothing of any other request in it. CityLLM's usage is per city
|
|
645
|
+
* (`[100 + n, n]`), so every model response says which request it answered.
|
|
646
|
+
*/
|
|
647
|
+
const CITIES = ["Paris", "Rome", "Oslo", "Lima", "Cairo", "Delhi", "Tokyo", "Quito", "Accra", "Hanoi"];
|
|
648
|
+
const tenWay = (scenario: string, expected: (agentId: string) => string[], agentId: string) => {
|
|
649
|
+
const result = run(scenario);
|
|
650
|
+
sound(result, CITIES.length);
|
|
651
|
+
const byCity = new Map<string, Event[]>();
|
|
652
|
+
for (const e of result.events) {
|
|
653
|
+
const list = [...result.events.filter((x) => x.session_id === e.session_id)];
|
|
654
|
+
const text = JSON.stringify(list);
|
|
655
|
+
const city = CITIES.find((c) => text.includes(`weather in ${c}?`));
|
|
656
|
+
expect(city, describeTrace(result)).toBeDefined();
|
|
657
|
+
byCity.set(city!, list);
|
|
658
|
+
}
|
|
659
|
+
expect([...byCity.keys()].sort()).toEqual([...CITIES].sort());
|
|
660
|
+
for (const [city, list] of byCity) {
|
|
661
|
+
expect(shape(list), describeTrace(result)).toEqual(expected(agentId));
|
|
662
|
+
expect(list[0]!.agent_id).toBe(agentId);
|
|
663
|
+
expect(list[0]!.parent_id ?? null).toBeNull();
|
|
664
|
+
const text = JSON.stringify(list);
|
|
665
|
+
for (const other of CITIES) if (other !== city) expect(text, `${city}'s session mentions ${other}`).not.toContain(other);
|
|
666
|
+
const n = CITIES.indexOf(city);
|
|
667
|
+
for (const response of ofType(list, "model_response")) {
|
|
668
|
+
expect([response.input_tokens, response.output_tokens]).toEqual([100 + n, n]);
|
|
669
|
+
expect(response.model).toBe("city-1");
|
|
670
|
+
}
|
|
671
|
+
expect(ofType(list, "agent_end")[0]).toMatchObject({ outcome: "success", summary: `It is sunny in ${city}.` });
|
|
672
|
+
}
|
|
673
|
+
return byCity;
|
|
674
|
+
};
|
|
675
|
+
|
|
676
|
+
it("keeps 10 concurrent run()s of one agent object apart", () => {
|
|
677
|
+
const byCity = tenWay("concurrent-agents", (id) => WORKFLOW(id), "Agent");
|
|
678
|
+
for (const [city, list] of byCity) {
|
|
679
|
+
expect(ofType(list, "tool_use")[0]!.tool_call_id).toBe(`call_${city}`);
|
|
680
|
+
expect(ofType(list, "tool_result")[0]!.output).toBe(`sunny in ${city}`);
|
|
681
|
+
}
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
it("keeps 10 concurrent queries on one shared query engine apart", () => {
|
|
685
|
+
const byCity = tenWay(
|
|
686
|
+
"concurrent-queries",
|
|
687
|
+
(id) => [`${id} agent_start`, ...RETRIEVAL(id), ...MODEL(id), `${id} agent_end`],
|
|
688
|
+
"RetrieverQueryEngine",
|
|
689
|
+
);
|
|
690
|
+
for (const [city, list] of byCity) {
|
|
691
|
+
expect(ofType(list, "tool_use")[0]!.input).toEqual({ query: `weather in ${city}?` });
|
|
692
|
+
expect((ofType(list, "tool_result")[0]!.output as { top: Array<{ text: string }> }).top[0]!.text).toBe(
|
|
693
|
+
`${city} is sunny.`,
|
|
694
|
+
);
|
|
695
|
+
}
|
|
696
|
+
});
|
|
697
|
+
|
|
698
|
+
it("keeps 10 concurrent chats on one shared chat engine apart", () => {
|
|
699
|
+
const byCity = tenWay(
|
|
700
|
+
"concurrent-chats",
|
|
701
|
+
(id) => [`${id} agent_start`, ...RETRIEVAL(id), ...MODEL(id), `${id} agent_end`],
|
|
702
|
+
"ContextChatEngine",
|
|
703
|
+
);
|
|
704
|
+
for (const [city, list] of byCity) {
|
|
705
|
+
expect(ofType(list, "tool_use")[0]!.input).toEqual({ query: `weather in ${city}?` });
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
});
|
|
709
|
+
});
|