@elevasis/core 0.1.0
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/dist/index.d.ts +435 -0
- package/dist/index.js +403 -0
- package/dist/organization-model/index.d.ts +435 -0
- package/dist/organization-model/index.js +403 -0
- package/package.json +62 -0
- package/src/README.md +34 -0
- package/src/__tests__/observability-exports.test.ts +36 -0
- package/src/__tests__/publish.test.ts +18 -0
- package/src/__tests__/template-foundations-compatibility.test.ts +34 -0
- package/src/auth/index.ts +8 -0
- package/src/auth/multi-tenancy/credentials/README.md +38 -0
- package/src/auth/multi-tenancy/credentials/__tests__/encryption.test.ts +216 -0
- package/src/auth/multi-tenancy/credentials/__tests__/service.test.ts +174 -0
- package/src/auth/multi-tenancy/credentials/index.ts +6 -0
- package/src/auth/multi-tenancy/credentials/server/encryption.ts +39 -0
- package/src/auth/multi-tenancy/credentials/server/service.ts +60 -0
- package/src/auth/multi-tenancy/index.ts +17 -0
- package/src/auth/multi-tenancy/invitations/__tests__/invitation.test.ts +237 -0
- package/src/auth/multi-tenancy/invitations/api-schemas.ts +107 -0
- package/src/auth/multi-tenancy/invitations/index.ts +38 -0
- package/src/auth/multi-tenancy/invitations/invitation.ts +86 -0
- package/src/auth/multi-tenancy/invitations/server/index.ts +25 -0
- package/src/auth/multi-tenancy/invitations/server/transforms.ts +24 -0
- package/src/auth/multi-tenancy/invitations/server/workos.ts +24 -0
- package/src/auth/multi-tenancy/invitations/supabase.ts +50 -0
- package/src/auth/multi-tenancy/memberships/__tests__/membership.test.ts +227 -0
- package/src/auth/multi-tenancy/memberships/__tests__/supabase-transforms.test.ts +88 -0
- package/src/auth/multi-tenancy/memberships/__tests__/workos-transforms.test.ts +139 -0
- package/src/auth/multi-tenancy/memberships/api-schemas.ts +126 -0
- package/src/auth/multi-tenancy/memberships/index.ts +22 -0
- package/src/auth/multi-tenancy/memberships/membership.ts +138 -0
- package/src/auth/multi-tenancy/memberships/server/index.ts +15 -0
- package/src/auth/multi-tenancy/memberships/server/transforms.ts +32 -0
- package/src/auth/multi-tenancy/memberships/server/workos.ts +21 -0
- package/src/auth/multi-tenancy/memberships/supabase.ts +46 -0
- package/src/auth/multi-tenancy/organizations/__tests__/organization.test.ts +249 -0
- package/src/auth/multi-tenancy/organizations/api-schemas.ts +128 -0
- package/src/auth/multi-tenancy/organizations/index.ts +23 -0
- package/src/auth/multi-tenancy/organizations/organization.ts +25 -0
- package/src/auth/multi-tenancy/organizations/server/index.ts +10 -0
- package/src/auth/multi-tenancy/organizations/server/transforms.ts +35 -0
- package/src/auth/multi-tenancy/organizations/server/workos.ts +20 -0
- package/src/auth/multi-tenancy/types.ts +89 -0
- package/src/auth/multi-tenancy/users/__tests__/user.test.ts +208 -0
- package/src/auth/multi-tenancy/users/api-schemas.ts +194 -0
- package/src/auth/multi-tenancy/users/index.ts +28 -0
- package/src/auth/multi-tenancy/users/server/index.ts +19 -0
- package/src/auth/multi-tenancy/users/server/transforms.ts +21 -0
- package/src/auth/multi-tenancy/users/server/workos.ts +16 -0
- package/src/auth/multi-tenancy/users/user.ts +65 -0
- package/src/business/acquisition/api-schemas.ts +759 -0
- package/src/business/acquisition/index.ts +109 -0
- package/src/business/acquisition/types.ts +400 -0
- package/src/business/crm/api-schemas.ts +75 -0
- package/src/business/delivery/index.ts +1 -0
- package/src/business/delivery/types.ts +89 -0
- package/src/business/index.ts +12 -0
- package/src/business/pdf/assets/ElevasisLogo.png +0 -0
- package/src/business/pdf/browser/image-utils.ts +74 -0
- package/src/business/pdf/browser/index.ts +16 -0
- package/src/business/pdf/browser/pdfmake-browser.ts +229 -0
- package/src/business/pdf/index.ts +10 -0
- package/src/business/pdf/sections/acceptance.ts +112 -0
- package/src/business/pdf/sections/automation.ts +56 -0
- package/src/business/pdf/sections/cover.ts +51 -0
- package/src/business/pdf/sections/index.ts +57 -0
- package/src/business/pdf/sections/investment.ts +69 -0
- package/src/business/pdf/sections/proposal-document.ts +200 -0
- package/src/business/pdf/sections/summary-investment.ts +124 -0
- package/src/business/pdf/sections/summary.ts +55 -0
- package/src/business/pdf/sections/table-summary.ts +59 -0
- package/src/business/pdf/sections/types.ts +124 -0
- package/src/business/pdf/server/__tests__/pdfmake-test.ts +219 -0
- package/src/business/pdf/server/index.ts +21 -0
- package/src/business/pdf/server/pdfmake-service.ts +237 -0
- package/src/business/pdf/server/themes/default.ts +8 -0
- package/src/business/pdf/server/themes/index.ts +9 -0
- package/src/business/pdf/server/themes/types.ts +8 -0
- package/src/business/pdf/shared/convert.ts +514 -0
- package/src/business/pdf/shared/index.ts +12 -0
- package/src/business/pdf/themes.ts +78 -0
- package/src/business/pdf/types.ts +272 -0
- package/src/business/seo/__tests__/linking.test.ts +549 -0
- package/src/business/seo/__tests__/types.test.ts +404 -0
- package/src/business/seo/index.ts +2 -0
- package/src/business/seo/linking.ts +281 -0
- package/src/business/seo/types.ts +199 -0
- package/src/commands/index.ts +8 -0
- package/src/commands/queue/index.ts +3 -0
- package/src/commands/queue/schemas.test.ts +593 -0
- package/src/commands/queue/schemas.ts +125 -0
- package/src/commands/queue/sse-events.ts +61 -0
- package/src/commands/queue/types/action.ts +52 -0
- package/src/commands/queue/types/checkpoint.ts +44 -0
- package/src/commands/queue/types/index.ts +7 -0
- package/src/commands/queue/types/task.ts +116 -0
- package/src/commands/queue/types.ts +14 -0
- package/src/content/distribution-metadata.ts +61 -0
- package/src/content/index.ts +10 -0
- package/src/deployments/index.ts +22 -0
- package/src/execution/calibration/__tests__/schemas.test.ts +320 -0
- package/src/execution/calibration/index.ts +3 -0
- package/src/execution/calibration/schemas.ts +121 -0
- package/src/execution/calibration/sse-events.ts +125 -0
- package/src/execution/calibration/types.ts +190 -0
- package/src/execution/core/__tests__/api-schemas.test.ts +667 -0
- package/src/execution/core/__tests__/archived-logs.test.ts +72 -0
- package/src/execution/core/api-schemas.ts +312 -0
- package/src/execution/core/index.ts +11 -0
- package/src/execution/core/resource-validator.test.ts +63 -0
- package/src/execution/core/runner-types.ts +80 -0
- package/src/execution/core/server/environment.ts +31 -0
- package/src/execution/core/sse-executions.ts +119 -0
- package/src/execution/core/types.ts +29 -0
- package/src/execution/engine/__tests__/fixtures/index.ts +2 -0
- package/src/execution/engine/__tests__/fixtures/mock-scenarios.ts +60 -0
- package/src/execution/engine/__tests__/fixtures/test-agents.ts +85 -0
- package/src/execution/engine/__tests__/integration/agent-framework.integration.test.ts +1031 -0
- package/src/execution/engine/__tests__/timeout.test.ts +565 -0
- package/src/execution/engine/agent/__tests__/errors.test.ts +508 -0
- package/src/execution/engine/agent/actions/__tests__/processor.test.ts +531 -0
- package/src/execution/engine/agent/actions/executor.ts +205 -0
- package/src/execution/engine/agent/actions/navigate-knowledge-executor.ts +230 -0
- package/src/execution/engine/agent/actions/processor.ts +116 -0
- package/src/execution/engine/agent/actions/types.ts +70 -0
- package/src/execution/engine/agent/core/__tests__/agent.test.ts +614 -0
- package/src/execution/engine/agent/core/__tests__/error-passthrough.test.ts +134 -0
- package/src/execution/engine/agent/core/agent.ts +810 -0
- package/src/execution/engine/agent/core/types.ts +155 -0
- package/src/execution/engine/agent/errors.ts +251 -0
- package/src/execution/engine/agent/index.ts +78 -0
- package/src/execution/engine/agent/knowledge-map/__tests__/navigate-knowledge-executor.test.ts +580 -0
- package/src/execution/engine/agent/knowledge-map/__tests__/utils.test.ts +622 -0
- package/src/execution/engine/agent/knowledge-map/types.ts +106 -0
- package/src/execution/engine/agent/knowledge-map/utils.ts +101 -0
- package/src/execution/engine/agent/memory/__tests__/domains.test.ts +72 -0
- package/src/execution/engine/agent/memory/__tests__/manager.test.ts +754 -0
- package/src/execution/engine/agent/memory/__tests__/utils.test.ts +285 -0
- package/src/execution/engine/agent/memory/domains.ts +99 -0
- package/src/execution/engine/agent/memory/manager.ts +365 -0
- package/src/execution/engine/agent/memory/processor.ts +66 -0
- package/src/execution/engine/agent/memory/types.ts +90 -0
- package/src/execution/engine/agent/memory/utils.ts +134 -0
- package/src/execution/engine/agent/observability/logging.ts +467 -0
- package/src/execution/engine/agent/observability/types.ts +64 -0
- package/src/execution/engine/agent/reasoning/__tests__/request-builder.test.ts +209 -0
- package/src/execution/engine/agent/reasoning/adapters/agent-adapter-helpers.ts +349 -0
- package/src/execution/engine/agent/reasoning/processor.ts +92 -0
- package/src/execution/engine/agent/reasoning/prompt-sections/base-actions.ts +134 -0
- package/src/execution/engine/agent/reasoning/prompt-sections/completion.ts +49 -0
- package/src/execution/engine/agent/reasoning/prompt-sections/knowledge-map.ts +93 -0
- package/src/execution/engine/agent/reasoning/prompt-sections/memory.ts +65 -0
- package/src/execution/engine/agent/reasoning/prompt-sections/security.ts +32 -0
- package/src/execution/engine/agent/reasoning/prompt-sections/tools.ts +44 -0
- package/src/execution/engine/agent/reasoning/request-builder.ts +169 -0
- package/src/execution/engine/agent/reasoning/types.ts +18 -0
- package/src/execution/engine/base/__tests__/errors.test.ts +246 -0
- package/src/execution/engine/base/__tests__/serialization.test.ts +670 -0
- package/src/execution/engine/base/__tests__/utils.test.ts +45 -0
- package/src/execution/engine/base/errors.ts +118 -0
- package/src/execution/engine/base/index.ts +2 -0
- package/src/execution/engine/base/logging.ts +31 -0
- package/src/execution/engine/base/serialization.ts +324 -0
- package/src/execution/engine/base/types.ts +126 -0
- package/src/execution/engine/base/utils.ts +41 -0
- package/src/execution/engine/index.ts +440 -0
- package/src/execution/engine/interface/index.ts +1 -0
- package/src/execution/engine/interface/types.ts +62 -0
- package/src/execution/engine/llm/__tests__/errors.test.ts +318 -0
- package/src/execution/engine/llm/__tests__/input-sanitizer.test.ts +286 -0
- package/src/execution/engine/llm/__tests__/model-info.test.ts +50 -0
- package/src/execution/engine/llm/__tests__/model-validation.test.ts +321 -0
- package/src/execution/engine/llm/__tests__/response-schema-validator.test.ts +115 -0
- package/src/execution/engine/llm/adapters/__tests__/adapter-factory.test.ts +375 -0
- package/src/execution/engine/llm/adapters/__tests__/anthropic-adapter.test.ts +463 -0
- package/src/execution/engine/llm/adapters/__tests__/anthropic.integration.test.ts +177 -0
- package/src/execution/engine/llm/adapters/__tests__/circuit-breaker-error.test.ts +94 -0
- package/src/execution/engine/llm/adapters/__tests__/google-adapter.test.ts +722 -0
- package/src/execution/engine/llm/adapters/__tests__/google.integration.test.ts +376 -0
- package/src/execution/engine/llm/adapters/__tests__/mock-adapter.test.ts +432 -0
- package/src/execution/engine/llm/adapters/__tests__/openai-adapter.test.ts +551 -0
- package/src/execution/engine/llm/adapters/__tests__/openrouter-adapter.test.ts +563 -0
- package/src/execution/engine/llm/adapters/__tests__/openrouter.integration.test.ts +105 -0
- package/src/execution/engine/llm/adapters/__tests__/universal-adapter.test.ts +537 -0
- package/src/execution/engine/llm/adapters/circuit-breaker.ts +147 -0
- package/src/execution/engine/llm/adapters/index.ts +17 -0
- package/src/execution/engine/llm/adapters/mock-adapter.ts +116 -0
- package/src/execution/engine/llm/adapters/server/adapter-factory.ts +130 -0
- package/src/execution/engine/llm/adapters/server/anthropic.ts +137 -0
- package/src/execution/engine/llm/adapters/server/compose-signal.ts +18 -0
- package/src/execution/engine/llm/adapters/server/google.ts +283 -0
- package/src/execution/engine/llm/adapters/server/index.ts +12 -0
- package/src/execution/engine/llm/adapters/server/openai.ts +206 -0
- package/src/execution/engine/llm/adapters/server/openrouter.ts +235 -0
- package/src/execution/engine/llm/adapters/universal-adapter.ts +230 -0
- package/src/execution/engine/llm/errors.ts +186 -0
- package/src/execution/engine/llm/input-sanitizer.ts +129 -0
- package/src/execution/engine/llm/model-info.ts +332 -0
- package/src/execution/engine/llm/response-schema-validator.ts +113 -0
- package/src/execution/engine/llm/types.ts +86 -0
- package/src/execution/engine/test-utils/index.ts +6 -0
- package/src/execution/engine/test-utils/mocks.ts +56 -0
- package/src/execution/engine/tools/__tests__/tooling-error.test.ts +265 -0
- package/src/execution/engine/tools/__tests__/types.test.ts +47 -0
- package/src/execution/engine/tools/integration/base-integration-adapter.ts +50 -0
- package/src/execution/engine/tools/integration/index.ts +53 -0
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-adapter.ts +73 -0
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-tools.ts +209 -0
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-company-email/index.ts +82 -0
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-decision-maker-email/index.ts +122 -0
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-person-email/index.ts +89 -0
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/verify-email/index.ts +84 -0
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/index.ts +16 -0
- package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +293 -0
- package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.ts +100 -0
- package/src/execution/engine/tools/integration/server/adapters/apify/apify-tools.ts +217 -0
- package/src/execution/engine/tools/integration/server/adapters/apify/fetch/get-dataset-items/index.ts +92 -0
- package/src/execution/engine/tools/integration/server/adapters/apify/fetch/run-actor/index.ts +218 -0
- package/src/execution/engine/tools/integration/server/adapters/apify/fetch/start-actor/index.ts +87 -0
- package/src/execution/engine/tools/integration/server/adapters/apify/index.ts +11 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +362 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/attio-adapter.ts +162 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/attio-tools.ts +594 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/README.md +632 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-attribute/index.ts +214 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-note/index.ts +152 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-record/index.ts +141 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-note/index.ts +86 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-record/index.ts +105 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.test.ts +186 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.ts +118 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-attributes/index.ts +165 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-notes/index.ts +96 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-objects/index.ts +104 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.test.ts +338 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.ts +156 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-attribute/index.ts +220 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-record/index.ts +140 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/utils/types.ts +147 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/index.ts +31 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/__tests__/dropbox-adapter.test.ts +409 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/dropbox-adapter.ts +281 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/dropbox-tools.ts +106 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/fetch/create-folder/__tests__/index.test.ts +451 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/fetch/create-folder/index.ts +114 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/fetch/upload-file/__tests__/index.test.ts +415 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/fetch/upload-file/index.ts +111 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/index.ts +25 -0
- package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +210 -0
- package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +104 -0
- package/src/execution/engine/tools/integration/server/adapters/google-sheets/__tests__/google-sheets.integration.test.ts +261 -0
- package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-adapter.ts +1189 -0
- package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-tools.ts +641 -0
- package/src/execution/engine/tools/integration/server/adapters/google-sheets/index.ts +18 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/activate-campaign/index.ts +86 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/__tests__/index.test.ts +289 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/index.ts +154 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/__tests__/index.test.ts +325 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/index.ts +153 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-delete-leads/index.ts +84 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-campaign/index.ts +125 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-inbox-test/index.ts +107 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/delete-campaign/index.ts +85 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-account-health/index.ts +91 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign/index.ts +92 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/__tests__/index.test.ts +195 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/index.ts +113 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-daily-campaign-analytics/index.ts +104 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-emails/index.ts +155 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/__tests__/index.test.ts +196 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/index.ts +102 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/__tests__/index.test.ts +189 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/index.ts +87 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-leads/index.ts +112 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/patch-lead/index.ts +76 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/pause-campaign/index.ts +86 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/remove-from-subsequence/index.ts +98 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/send-reply/index.ts +126 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/__tests__/index.test.ts +193 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/index.ts +99 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/__tests__/index.test.ts +621 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/index.ts +125 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/index.ts +29 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-adapter.ts +178 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1473 -0
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/check-credits/index.ts +59 -0
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/verify-email/index.ts +102 -0
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/index.ts +17 -0
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-adapter.ts +80 -0
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +102 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/get-email/index.ts +102 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +134 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +75 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/index.ts +27 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/resend-adapter.ts +108 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/resend-tools.ts +132 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/types.ts +44 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/create-envelope/index.ts +274 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/download-document/index.ts +230 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/get-envelope/index.ts +133 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/utils/types.ts +246 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/void-envelope/index.ts +90 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/index.ts +38 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-adapter.ts +87 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-tools.ts +179 -0
- package/src/execution/engine/tools/integration/server/adapters/stripe/fetch/utils/types.ts +210 -0
- package/src/execution/engine/tools/integration/server/adapters/stripe/index.ts +44 -0
- package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-adapter.ts +517 -0
- package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +309 -0
- package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/domain-search/index.ts +133 -0
- package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-finder/index.ts +122 -0
- package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-verifier/index.ts +111 -0
- package/src/execution/engine/tools/integration/server/adapters/tomba/index.ts +11 -0
- package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-adapter.ts +78 -0
- package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-tools.ts +222 -0
- package/src/execution/engine/tools/integration/server/index.ts +61 -0
- package/src/execution/engine/tools/integration/service.ts +161 -0
- package/src/execution/engine/tools/integration/tool.ts +253 -0
- package/src/execution/engine/tools/integration/types/anymailfinder.ts +74 -0
- package/src/execution/engine/tools/integration/types/apify.ts +92 -0
- package/src/execution/engine/tools/integration/types/attio.ts +354 -0
- package/src/execution/engine/tools/integration/types/dropbox.ts +64 -0
- package/src/execution/engine/tools/integration/types/gmail.ts +35 -0
- package/src/execution/engine/tools/integration/types/google-sheets.ts +303 -0
- package/src/execution/engine/tools/integration/types/index.ts +19 -0
- package/src/execution/engine/tools/integration/types/instantly.ts +557 -0
- package/src/execution/engine/tools/integration/types/millionverifier.ts +56 -0
- package/src/execution/engine/tools/integration/types/resend.ts +63 -0
- package/src/execution/engine/tools/integration/types/signature-api.ts +164 -0
- package/src/execution/engine/tools/integration/types/stripe.ts +162 -0
- package/src/execution/engine/tools/integration/types/tomba.ts +94 -0
- package/src/execution/engine/tools/lead-service-types.ts +884 -0
- package/src/execution/engine/tools/llm/index.ts +11 -0
- package/src/execution/engine/tools/llm/server/index.ts +8 -0
- package/src/execution/engine/tools/llm/server/llm-call-tool.ts +118 -0
- package/src/execution/engine/tools/platform/__tests__/approval.test.ts +242 -0
- package/src/execution/engine/tools/platform/__tests__/email.test.ts +482 -0
- package/src/execution/engine/tools/platform/__tests__/hitl-cancel.test.ts +97 -0
- package/src/execution/engine/tools/platform/__tests__/notification.test.ts +208 -0
- package/src/execution/engine/tools/platform/__tests__/pdf.test.ts +441 -0
- package/src/execution/engine/tools/platform/__tests__/scheduler.test.ts +189 -0
- package/src/execution/engine/tools/platform/__tests__/schedules.test.ts +336 -0
- package/src/execution/engine/tools/platform/acquisition/company-tools.ts +248 -0
- package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +319 -0
- package/src/execution/engine/tools/platform/acquisition/index.ts +43 -0
- package/src/execution/engine/tools/platform/acquisition/list-tools.ts +148 -0
- package/src/execution/engine/tools/platform/acquisition/types.ts +260 -0
- package/src/execution/engine/tools/platform/approval/cancel-by-metadata.ts +65 -0
- package/src/execution/engine/tools/platform/approval/index.ts +4 -0
- package/src/execution/engine/tools/platform/approval/tool.ts +99 -0
- package/src/execution/engine/tools/platform/email/index.ts +122 -0
- package/src/execution/engine/tools/platform/email/types.ts +96 -0
- package/src/execution/engine/tools/platform/index.ts +181 -0
- package/src/execution/engine/tools/platform/notification.ts +81 -0
- package/src/execution/engine/tools/platform/pdf/index.ts +110 -0
- package/src/execution/engine/tools/platform/pdf/types.ts +77 -0
- package/src/execution/engine/tools/platform/resource-invocation/__tests__/edge-cases.test.ts +507 -0
- package/src/execution/engine/tools/platform/resource-invocation/__tests__/resource-invocation-service.test.ts +500 -0
- package/src/execution/engine/tools/platform/resource-invocation/__tests__/tool.test.ts +555 -0
- package/src/execution/engine/tools/platform/resource-invocation/dynamic-tool.ts +94 -0
- package/src/execution/engine/tools/platform/resource-invocation/index.ts +14 -0
- package/src/execution/engine/tools/platform/resource-invocation/resource-invocation-service.ts +147 -0
- package/src/execution/engine/tools/platform/resource-invocation/tool.ts +115 -0
- package/src/execution/engine/tools/platform/resource-invocation/types.ts +31 -0
- package/src/execution/engine/tools/platform/scheduler.ts +87 -0
- package/src/execution/engine/tools/platform/schedules/cancel-by-key-tool.ts +48 -0
- package/src/execution/engine/tools/platform/schedules/cancel-by-metadata-tool.ts +42 -0
- package/src/execution/engine/tools/platform/schedules/delete-by-key-tool.ts +43 -0
- package/src/execution/engine/tools/platform/schedules/index.ts +13 -0
- package/src/execution/engine/tools/platform/schedules/list-tool.ts +56 -0
- package/src/execution/engine/tools/platform/schedules/types.ts +88 -0
- package/src/execution/engine/tools/platform/storage/__tests__/storage.test.ts +998 -0
- package/src/execution/engine/tools/platform/storage/index.ts +370 -0
- package/src/execution/engine/tools/platform/storage/types.ts +128 -0
- package/src/execution/engine/tools/platform/types.ts +148 -0
- package/src/execution/engine/tools/registry.ts +590 -0
- package/src/execution/engine/tools/tool-maps.ts +694 -0
- package/src/execution/engine/tools/types.ts +233 -0
- package/src/execution/engine/workflow/__tests__/errors.test.ts +139 -0
- package/src/execution/engine/workflow/__tests__/utils.test.ts +645 -0
- package/src/execution/engine/workflow/__tests__/workflow.test.ts +818 -0
- package/src/execution/engine/workflow/errors.ts +63 -0
- package/src/execution/engine/workflow/helpers/index.ts +11 -0
- package/src/execution/engine/workflow/helpers/server/index.ts +8 -0
- package/src/execution/engine/workflow/helpers/server/llm-call.ts +93 -0
- package/src/execution/engine/workflow/index.ts +19 -0
- package/src/execution/engine/workflow/log-truncate.ts +26 -0
- package/src/execution/engine/workflow/logging.ts +191 -0
- package/src/execution/engine/workflow/types.ts +183 -0
- package/src/execution/engine/workflow/utils.ts +280 -0
- package/src/execution/engine/workflow/workflow.ts +168 -0
- package/src/execution/index.ts +20 -0
- package/src/execution/scheduler/__tests__/api-schemas.test.ts +733 -0
- package/src/execution/scheduler/__tests__/retry.test.ts +37 -0
- package/src/execution/scheduler/__tests__/utils.test.ts +1009 -0
- package/src/execution/scheduler/api-schemas.ts +296 -0
- package/src/execution/scheduler/index.ts +50 -0
- package/src/execution/scheduler/schemas.ts +264 -0
- package/src/execution/scheduler/types.ts +111 -0
- package/src/execution/scheduler/utils.ts +364 -0
- package/src/forms/index.ts +7 -0
- package/src/forms/schemas.test.ts +113 -0
- package/src/forms/schemas.ts +69 -0
- package/src/forms/types.ts +70 -0
- package/src/index.ts +54 -0
- package/src/integrations/credentials/__tests__/api-schemas.test.ts +496 -0
- package/src/integrations/credentials/__tests__/schemas.test.ts +82 -0
- package/src/integrations/credentials/__tests__/utils.test.ts +144 -0
- package/src/integrations/credentials/api-schemas.ts +143 -0
- package/src/integrations/credentials/index.ts +32 -0
- package/src/integrations/credentials/schemas.ts +164 -0
- package/src/integrations/credentials/utils.ts +59 -0
- package/src/integrations/oauth/__tests__/provider-registry.test.ts +59 -0
- package/src/integrations/oauth/api-schemas.ts +92 -0
- package/src/integrations/oauth/index.ts +19 -0
- package/src/integrations/oauth/provider-registry.ts +61 -0
- package/src/integrations/oauth/server/__tests__/refresh-concurrent.test.ts +183 -0
- package/src/integrations/oauth/server/__tests__/refresh.integration.test.ts +257 -0
- package/src/integrations/oauth/server/__tests__/refresh.test.ts +577 -0
- package/src/integrations/oauth/server/credentials.ts +39 -0
- package/src/integrations/oauth/server/refresh.ts +214 -0
- package/src/integrations/oauth/types.ts +34 -0
- package/src/integrations/webhook-endpoints/__tests__/api-schemas.test.ts +318 -0
- package/src/integrations/webhook-endpoints/api-schemas.ts +102 -0
- package/src/integrations/webhook-endpoints/index.ts +28 -0
- package/src/integrations/webhook-endpoints/types.ts +51 -0
- package/src/operations/activities/api-schemas.ts +79 -0
- package/src/operations/activities/index.ts +9 -0
- package/src/operations/activities/sse-events.ts +30 -0
- package/src/operations/activities/types.ts +63 -0
- package/src/operations/debug-logs/client.ts +60 -0
- package/src/operations/debug-logs/debug-logger.ts +83 -0
- package/src/operations/debug-logs/index.ts +8 -0
- package/src/operations/debug-logs/server.ts +19 -0
- package/src/operations/debug-logs/types.ts +33 -0
- package/src/operations/index.ts +50 -0
- package/src/operations/notifications/__tests__/api-schemas.test.ts +216 -0
- package/src/operations/notifications/api-schemas.ts +91 -0
- package/src/operations/notifications/index.ts +3 -0
- package/src/operations/notifications/sse-events.ts +21 -0
- package/src/operations/notifications/types.ts +47 -0
- package/src/operations/observability/__tests__/openrouter-cost-flow.test.ts +297 -0
- package/src/operations/observability/__tests__/schemas.test.ts +151 -0
- package/src/operations/observability/__tests__/types.test.ts +109 -0
- package/src/operations/observability/__tests__/utils.test.ts +54 -0
- package/src/operations/observability/ai-usage-collector.ts +64 -0
- package/src/operations/observability/index.ts +13 -0
- package/src/operations/observability/metrics-collector.ts +49 -0
- package/src/operations/observability/schemas.ts +39 -0
- package/src/operations/observability/types.ts +463 -0
- package/src/operations/observability/utils.ts +77 -0
- package/src/operations/sessions/__tests__/api-schemas.test.ts +361 -0
- package/src/operations/sessions/__tests__/manager.test.ts +821 -0
- package/src/operations/sessions/api-schemas.ts +166 -0
- package/src/operations/sessions/index.ts +26 -0
- package/src/operations/sessions/server/manager.ts +90 -0
- package/src/operations/sessions/server/session.ts +180 -0
- package/src/operations/sessions/types.ts +98 -0
- package/src/operations/triggers/index.ts +12 -0
- package/src/operations/triggers/webhook/definitions/__tests__/instantly-reply-received.test.ts +72 -0
- package/src/operations/triggers/webhook/definitions/instantly-account-error.ts +44 -0
- package/src/operations/triggers/webhook/definitions/instantly-auto-reply-received.ts +51 -0
- package/src/operations/triggers/webhook/definitions/instantly-campaign-completed.ts +45 -0
- package/src/operations/triggers/webhook/definitions/instantly-email-bounced.ts +49 -0
- package/src/operations/triggers/webhook/definitions/instantly-lead-unsubscribed.ts +45 -0
- package/src/operations/triggers/webhook/definitions/instantly-reply-received.ts +54 -0
- package/src/operations/triggers/webhook/index.ts +35 -0
- package/src/operations/triggers/webhook/types.ts +74 -0
- package/src/organization-model/README.md +79 -0
- package/src/organization-model/__tests__/graph.test.ts +250 -0
- package/src/organization-model/__tests__/resolve.test.ts +47 -0
- package/src/organization-model/defaults.ts +60 -0
- package/src/organization-model/domains/branding.ts +22 -0
- package/src/organization-model/domains/crm.ts +46 -0
- package/src/organization-model/domains/delivery.ts +48 -0
- package/src/organization-model/domains/features.ts +57 -0
- package/src/organization-model/domains/lead-gen.ts +33 -0
- package/src/organization-model/domains/navigation.ts +103 -0
- package/src/organization-model/domains/shared.ts +42 -0
- package/src/organization-model/graph/build.ts +432 -0
- package/src/organization-model/graph/index.ts +4 -0
- package/src/organization-model/graph/schema.ts +50 -0
- package/src/organization-model/graph/types.ts +52 -0
- package/src/organization-model/index.ts +11 -0
- package/src/organization-model/published.ts +18 -0
- package/src/organization-model/resolve.ts +42 -0
- package/src/organization-model/schema.ts +21 -0
- package/src/organization-model/types.ts +27 -0
- package/src/platform/api/index.ts +1 -0
- package/src/platform/api/types.ts +35 -0
- package/src/platform/constants/http.ts +37 -0
- package/src/platform/constants/index.ts +5 -0
- package/src/platform/constants/limits.ts +32 -0
- package/src/platform/constants/resilience.ts +51 -0
- package/src/platform/constants/timeouts.ts +20 -0
- package/src/platform/constants/versions.ts +3 -0
- package/src/platform/index.ts +27 -0
- package/src/platform/registry/__tests__/command-view.test.ts +410 -0
- package/src/platform/registry/__tests__/resource-registry-static.test.ts +347 -0
- package/src/platform/registry/__tests__/resource-registry.integration.test.ts +1004 -0
- package/src/platform/registry/__tests__/resource-registry.list-executable.test.ts +393 -0
- package/src/platform/registry/__tests__/resource-registry.test.ts +1942 -0
- package/src/platform/registry/__tests__/serialization.test.ts +1127 -0
- package/src/platform/registry/__tests__/validation.test.ts +1086 -0
- package/src/platform/registry/command-view.ts +180 -0
- package/src/platform/registry/domains.ts +165 -0
- package/src/platform/registry/index.ts +93 -0
- package/src/platform/registry/reserved.ts +24 -0
- package/src/platform/registry/resource-metadata.ts +59 -0
- package/src/platform/registry/resource-registry.command-queue-groups.test.ts +129 -0
- package/src/platform/registry/resource-registry.ts +788 -0
- package/src/platform/registry/serialization.ts +273 -0
- package/src/platform/registry/serialized-types.ts +231 -0
- package/src/platform/registry/stats-types.ts +66 -0
- package/src/platform/registry/types.ts +404 -0
- package/src/platform/registry/validation.ts +513 -0
- package/src/platform/resilience/__tests__/circuit-breaker.test.ts +291 -0
- package/src/platform/resilience/__tests__/http-error-mapper.test.ts +173 -0
- package/src/platform/resilience/__tests__/rate-limiter.test.ts +471 -0
- package/src/platform/resilience/__tests__/retry.test.ts +380 -0
- package/src/platform/resilience/__tests__/timeout.test.ts +219 -0
- package/src/platform/resilience/circuit-breaker.ts +164 -0
- package/src/platform/resilience/errors.ts +68 -0
- package/src/platform/resilience/http-error-mapper.ts +129 -0
- package/src/platform/resilience/index.ts +93 -0
- package/src/platform/resilience/rate-limiter-types.ts +46 -0
- package/src/platform/resilience/rate-limiter.ts +140 -0
- package/src/platform/resilience/retry.ts +89 -0
- package/src/platform/resilience/timeout.ts +63 -0
- package/src/platform/sse/events.ts +67 -0
- package/src/platform/sse/index.ts +7 -0
- package/src/platform/utils/__tests__/currency.test.ts +77 -0
- package/src/platform/utils/__tests__/validation.test.ts +1083 -0
- package/src/platform/utils/currency.ts +96 -0
- package/src/platform/utils/debounce.ts +52 -0
- package/src/platform/utils/error.ts +42 -0
- package/src/platform/utils/hmac.test.ts +97 -0
- package/src/platform/utils/index.ts +32 -0
- package/src/platform/utils/server/betterstack-logger.ts +210 -0
- package/src/platform/utils/server/hmac.ts +44 -0
- package/src/platform/utils/server/unsubscribe.ts +111 -0
- package/src/platform/utils/token-counter.ts +96 -0
- package/src/platform/utils/validation.ts +425 -0
- package/src/projects/api-schemas.ts +265 -0
- package/src/published.ts +1 -0
- package/src/server.ts +273 -0
- package/src/supabase/__tests__/helpers.test.ts +51 -0
- package/src/supabase/database.types.ts +2674 -0
- package/src/supabase/helpers.ts +20 -0
- package/src/supabase/index.ts +52 -0
- package/src/supabase/server/client.ts +58 -0
- package/src/test-utils/README.md +150 -0
- package/src/test-utils/browser-mocks.ts +54 -0
- package/src/test-utils/fixtures/api-keys.ts +52 -0
- package/src/test-utils/fixtures/index.ts +4 -0
- package/src/test-utils/fixtures/memberships.ts +80 -0
- package/src/test-utils/fixtures/organizations.ts +69 -0
- package/src/test-utils/fixtures/users.ts +79 -0
- package/src/test-utils/index.ts +11 -0
- package/src/test-utils/mocks/index.ts +2 -0
- package/src/test-utils/mocks/supabase.ts +142 -0
- package/src/test-utils/mocks/workos.ts +108 -0
- package/src/test-utils/rls/RLSTestContext.ts +586 -0
- package/src/test-utils/rls/index.ts +1 -0
|
@@ -0,0 +1,1031 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Framework Integration Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests complete agent execution flows with tools and knowledge map
|
|
5
|
+
* using real framework components with mocked external boundaries.
|
|
6
|
+
*
|
|
7
|
+
* Mock Boundaries:
|
|
8
|
+
* - LLM API calls → MockAdapter with configurable responses
|
|
9
|
+
* - Platform services → vi.mocked(getToolServices)
|
|
10
|
+
*
|
|
11
|
+
* Test Real:
|
|
12
|
+
* - Agent execution (initialize → iterate → complete)
|
|
13
|
+
* - MemoryManager (session memory, history, auto-compaction)
|
|
14
|
+
* - Tool factories and execution
|
|
15
|
+
* - Action processors
|
|
16
|
+
* - ExecutionContext propagation
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
|
20
|
+
import { Agent } from '../../agent/core/agent'
|
|
21
|
+
import { MockAdapter } from '../../llm/adapters/mock-adapter'
|
|
22
|
+
import type { LLMAdapterFactory } from '../../agent/core/types'
|
|
23
|
+
import { createApprovalTool } from '../../tools/platform/approval'
|
|
24
|
+
import { createNotificationTool } from '../../tools/platform/notification'
|
|
25
|
+
import { getToolServices } from '../../tools/registry'
|
|
26
|
+
import { z } from 'zod'
|
|
27
|
+
import type { ExecutionContext } from '../../base/types'
|
|
28
|
+
import { createKnowledgeMapAgent } from '../fixtures/test-agents'
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Create a mock LLMAdapterFactory that returns a given MockAdapter instance.
|
|
32
|
+
* Satisfies the Agent constructor's second parameter (adapterFactory).
|
|
33
|
+
*/
|
|
34
|
+
function createMockAdapterFactory(adapter?: MockAdapter): LLMAdapterFactory {
|
|
35
|
+
const mock = adapter ?? new MockAdapter()
|
|
36
|
+
return () => mock
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Mock the tools registry
|
|
40
|
+
vi.mock('../../tools/registry', () => ({
|
|
41
|
+
getToolServices: vi.fn()
|
|
42
|
+
}))
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Phase 4: Knowledge Map Integration
|
|
46
|
+
*
|
|
47
|
+
* Validates knowledge map navigation, dynamic tool registration,
|
|
48
|
+
* and memory scoping (session vs task) for loaded knowledge.
|
|
49
|
+
*/
|
|
50
|
+
describe('Knowledge Map Integration', () => {
|
|
51
|
+
const mockContext: ExecutionContext = {
|
|
52
|
+
executionId: 'exec-789',
|
|
53
|
+
organizationId: 'org-456',
|
|
54
|
+
resourceId: 'knowledge-agent',
|
|
55
|
+
resourceType: 'agent' as const,
|
|
56
|
+
logger: {
|
|
57
|
+
info: vi.fn(),
|
|
58
|
+
error: vi.fn(),
|
|
59
|
+
warn: vi.fn(),
|
|
60
|
+
debug: vi.fn()
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
beforeEach(() => {
|
|
65
|
+
vi.clearAllMocks()
|
|
66
|
+
vi.restoreAllMocks()
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('loads knowledge node and registers tools dynamically', async () => {
|
|
70
|
+
// Setup: Create configured MockAdapter for multi-iteration flow
|
|
71
|
+
const mockLLM = new MockAdapter({
|
|
72
|
+
responses: [
|
|
73
|
+
{
|
|
74
|
+
reasoning: 'I need access to test tools',
|
|
75
|
+
nextActions: [{
|
|
76
|
+
type: 'navigate-knowledge',
|
|
77
|
+
id: 'nav-1',
|
|
78
|
+
nodeId: 'test-tools'
|
|
79
|
+
}]
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
reasoning: 'Tools loaded, now I can use them',
|
|
83
|
+
nextActions: [{
|
|
84
|
+
type: 'tool-call',
|
|
85
|
+
id: 'call-1',
|
|
86
|
+
name: 'test_tool_1',
|
|
87
|
+
input: { input: 'test data' }
|
|
88
|
+
}]
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
reasoning: 'Task complete',
|
|
92
|
+
nextActions: [{ type: 'complete' }]
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
completionOutput: { result: 'Successfully used loaded tool' }
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
const agent = new Agent(createKnowledgeMapAgent(), createMockAdapterFactory(mockLLM))
|
|
99
|
+
|
|
100
|
+
// Execute
|
|
101
|
+
const result = await agent.execute(
|
|
102
|
+
{ task: 'Load and use test tools' },
|
|
103
|
+
mockContext
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
// Assert: Execution completes with expected output
|
|
107
|
+
expect(result).toEqual({ result: 'Successfully used loaded tool' })
|
|
108
|
+
|
|
109
|
+
// Assert: Tool was registered and used
|
|
110
|
+
const snapshot = agent.getMemorySnapshot()
|
|
111
|
+
expect(snapshot.history).toContainEqual(
|
|
112
|
+
expect.objectContaining({
|
|
113
|
+
type: 'tool-result',
|
|
114
|
+
content: expect.stringContaining('Result: test data')
|
|
115
|
+
})
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
// Assert: Knowledge loaded message in history
|
|
119
|
+
expect(snapshot.history).toContainEqual(
|
|
120
|
+
expect.objectContaining({
|
|
121
|
+
type: 'tool-result',
|
|
122
|
+
content: expect.stringContaining('Knowledge node \'test-tools\' loaded successfully')
|
|
123
|
+
})
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
// Assert: Correct number of LLM calls (3 iterations + 1 completion)
|
|
127
|
+
expect(mockLLM.getCallCount()).toBe(4)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('tool availability follows N+1 iteration pattern', async () => {
|
|
131
|
+
// Setup: MockAdapter that tries to use tool BEFORE navigation
|
|
132
|
+
const mockLLM = new MockAdapter({
|
|
133
|
+
responses: [
|
|
134
|
+
{
|
|
135
|
+
reasoning: 'Attempting to use tool before loading knowledge',
|
|
136
|
+
nextActions: [{
|
|
137
|
+
type: 'tool-call',
|
|
138
|
+
id: 'call-early',
|
|
139
|
+
name: 'test_tool_1',
|
|
140
|
+
input: { input: 'premature call' }
|
|
141
|
+
}]
|
|
142
|
+
},
|
|
143
|
+
// This should fail - tool not registered yet
|
|
144
|
+
|
|
145
|
+
{
|
|
146
|
+
reasoning: 'Now loading knowledge to get the tool',
|
|
147
|
+
nextActions: [{
|
|
148
|
+
type: 'navigate-knowledge',
|
|
149
|
+
id: 'nav-1',
|
|
150
|
+
nodeId: 'test-tools'
|
|
151
|
+
}]
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
{
|
|
155
|
+
reasoning: 'Tool should be available now in N+1',
|
|
156
|
+
nextActions: [{
|
|
157
|
+
type: 'tool-call',
|
|
158
|
+
id: 'call-after',
|
|
159
|
+
name: 'test_tool_1',
|
|
160
|
+
input: { input: 'correct timing' }
|
|
161
|
+
}]
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
{
|
|
165
|
+
reasoning: 'Task complete',
|
|
166
|
+
nextActions: [{ type: 'complete' }]
|
|
167
|
+
}
|
|
168
|
+
],
|
|
169
|
+
completionOutput: { result: 'N+1 pattern validated' }
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
const agent = new Agent(createKnowledgeMapAgent(), createMockAdapterFactory(mockLLM))
|
|
173
|
+
|
|
174
|
+
// Execute
|
|
175
|
+
const result = await agent.execute(
|
|
176
|
+
{ task: 'Test N+1 tool availability' },
|
|
177
|
+
mockContext
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
// Assert: Execution completes (doesn't crash on first error)
|
|
181
|
+
expect(result).toEqual({ result: 'N+1 pattern validated' })
|
|
182
|
+
|
|
183
|
+
// Assert: Memory contains error from first tool call
|
|
184
|
+
const snapshot = agent.getMemorySnapshot()
|
|
185
|
+
const errorEntries = snapshot.history.filter(entry =>
|
|
186
|
+
entry.type === 'error' && entry.content.includes('test_tool_1')
|
|
187
|
+
)
|
|
188
|
+
expect(errorEntries.length).toBeGreaterThan(0)
|
|
189
|
+
|
|
190
|
+
// Assert: Memory contains successful result from second tool call (after navigation)
|
|
191
|
+
const successEntries = snapshot.history.filter(entry =>
|
|
192
|
+
entry.type === 'tool-result' &&
|
|
193
|
+
entry.content.includes('correct timing')
|
|
194
|
+
)
|
|
195
|
+
expect(successEntries.length).toBeGreaterThan(0)
|
|
196
|
+
|
|
197
|
+
// Assert: Knowledge navigation success message exists
|
|
198
|
+
const navEntries = snapshot.history.filter(entry =>
|
|
199
|
+
entry.content.includes('Knowledge node \'test-tools\' loaded successfully')
|
|
200
|
+
)
|
|
201
|
+
expect(navEntries.length).toBeGreaterThan(0)
|
|
202
|
+
|
|
203
|
+
// Assert: Correct number of LLM calls (4 iterations + 1 completion)
|
|
204
|
+
expect(mockLLM.getCallCount()).toBe(5)
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
it('knowledge prompts cached on node after loading', async () => {
|
|
208
|
+
// Setup: MockAdapter that loads knowledge
|
|
209
|
+
const mockLLM = new MockAdapter({
|
|
210
|
+
responses: [
|
|
211
|
+
{
|
|
212
|
+
reasoning: 'Loading session-scoped knowledge',
|
|
213
|
+
nextActions: [{
|
|
214
|
+
type: 'navigate-knowledge',
|
|
215
|
+
id: 'nav-1',
|
|
216
|
+
nodeId: 'test-tools'
|
|
217
|
+
}]
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
reasoning: 'Task complete',
|
|
221
|
+
nextActions: [{ type: 'complete' }]
|
|
222
|
+
}
|
|
223
|
+
],
|
|
224
|
+
completionOutput: { result: 'Session knowledge loaded' }
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
const agent = new Agent(createKnowledgeMapAgent(), createMockAdapterFactory(mockLLM))
|
|
228
|
+
|
|
229
|
+
// Execute
|
|
230
|
+
const result = await agent.execute(
|
|
231
|
+
{ task: 'Load session knowledge' },
|
|
232
|
+
mockContext
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
// Assert: Execution completes
|
|
236
|
+
expect(result).toEqual({ result: 'Session knowledge loaded' })
|
|
237
|
+
|
|
238
|
+
// Assert: Content cached on knowledge node
|
|
239
|
+
const tools = agent.getTools()
|
|
240
|
+
expect(tools.length).toBeGreaterThan(0)
|
|
241
|
+
|
|
242
|
+
// Assert: Correct number of LLM calls (2 iterations + 1 completion)
|
|
243
|
+
expect(mockLLM.getCallCount()).toBe(3)
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
it('knowledge tools registered and available', async () => {
|
|
247
|
+
// Setup: MockAdapter that loads and uses knowledge
|
|
248
|
+
const mockLLM = new MockAdapter({
|
|
249
|
+
responses: [
|
|
250
|
+
{
|
|
251
|
+
reasoning: 'Loading task-scoped knowledge',
|
|
252
|
+
nextActions: [{
|
|
253
|
+
type: 'navigate-knowledge',
|
|
254
|
+
id: 'nav-1',
|
|
255
|
+
nodeId: 'test-tools' // Key: store in history
|
|
256
|
+
}]
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
reasoning: 'Task complete',
|
|
260
|
+
nextActions: [{ type: 'complete' }]
|
|
261
|
+
}
|
|
262
|
+
],
|
|
263
|
+
completionOutput: { result: 'Task knowledge loaded' }
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
const agent = new Agent(createKnowledgeMapAgent(), createMockAdapterFactory(mockLLM))
|
|
267
|
+
|
|
268
|
+
// Execute
|
|
269
|
+
const result = await agent.execute(
|
|
270
|
+
{ task: 'Load task knowledge' },
|
|
271
|
+
mockContext
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
// Assert: Execution completes
|
|
275
|
+
expect(result).toEqual({ result: 'Task knowledge loaded' })
|
|
276
|
+
|
|
277
|
+
// Assert: Tools registered and available
|
|
278
|
+
const tools = agent.getTools()
|
|
279
|
+
expect(tools.length).toBeGreaterThan(0)
|
|
280
|
+
expect(tools.some(t => t.name === 'test_tool_1')).toBe(true)
|
|
281
|
+
|
|
282
|
+
// Assert: Correct number of LLM calls (2 iterations + 1 completion)
|
|
283
|
+
expect(mockLLM.getCallCount()).toBe(3)
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
it('handles duplicate tool registration idempotently', async () => {
|
|
287
|
+
// Setup: MockAdapter that loads same knowledge node twice
|
|
288
|
+
const mockLLM = new MockAdapter({
|
|
289
|
+
responses: [
|
|
290
|
+
{
|
|
291
|
+
reasoning: 'Loading knowledge first time',
|
|
292
|
+
nextActions: [{
|
|
293
|
+
type: 'navigate-knowledge',
|
|
294
|
+
id: 'nav-1',
|
|
295
|
+
nodeId: 'test-tools'
|
|
296
|
+
}]
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
reasoning: 'Loading same knowledge again',
|
|
300
|
+
nextActions: [{
|
|
301
|
+
type: 'navigate-knowledge',
|
|
302
|
+
id: 'nav-2',
|
|
303
|
+
nodeId: 'test-tools' // Same node - should skip duplicate
|
|
304
|
+
}]
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
reasoning: 'Task complete',
|
|
308
|
+
nextActions: [{ type: 'complete' }]
|
|
309
|
+
}
|
|
310
|
+
],
|
|
311
|
+
completionOutput: { result: 'Duplicate registration handled' }
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
const agent = new Agent(createKnowledgeMapAgent(), createMockAdapterFactory(mockLLM))
|
|
315
|
+
|
|
316
|
+
// Execute
|
|
317
|
+
const result = await agent.execute(
|
|
318
|
+
{ task: 'Load knowledge twice' },
|
|
319
|
+
mockContext
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
// Assert: Execution completes without errors
|
|
323
|
+
expect(result).toEqual({ result: 'Duplicate registration handled' })
|
|
324
|
+
|
|
325
|
+
// Assert: Tool registry contains only one instance
|
|
326
|
+
const tools = agent.getTools()
|
|
327
|
+
const testTools = tools.filter(t => t.name === 'test_tool_1')
|
|
328
|
+
expect(testTools).toHaveLength(1)
|
|
329
|
+
|
|
330
|
+
// Assert: Both knowledge loading operations succeeded
|
|
331
|
+
const snapshot = agent.getMemorySnapshot()
|
|
332
|
+
const successMessages = snapshot.history.filter(entry =>
|
|
333
|
+
entry.type === 'tool-result' &&
|
|
334
|
+
entry.content.includes('Knowledge node \'test-tools\' loaded successfully')
|
|
335
|
+
)
|
|
336
|
+
expect(successMessages).toHaveLength(2) // Both loads succeeded
|
|
337
|
+
|
|
338
|
+
// Assert: Correct number of LLM calls (3 iterations + 1 completion)
|
|
339
|
+
expect(mockLLM.getCallCount()).toBe(4)
|
|
340
|
+
})
|
|
341
|
+
|
|
342
|
+
it('hierarchical navigation - flattens child nodes into main map', async () => {
|
|
343
|
+
// Setup: Knowledge map with hierarchical nodes
|
|
344
|
+
const hierarchicalKnowledgeMap = {
|
|
345
|
+
organizationId: 'test-org',
|
|
346
|
+
nodes: {
|
|
347
|
+
'parent-node': {
|
|
348
|
+
id: 'parent-node',
|
|
349
|
+
description: 'Parent node with child nodes',
|
|
350
|
+
load: async () => ({
|
|
351
|
+
prompt: '# Parent Knowledge\n\nBase tools available.',
|
|
352
|
+
tools: [
|
|
353
|
+
{
|
|
354
|
+
name: 'parent_tool',
|
|
355
|
+
description: 'Parent tool',
|
|
356
|
+
inputSchema: z.object({ data: z.string() }),
|
|
357
|
+
outputSchema: z.object({ result: z.string() }),
|
|
358
|
+
execute: async ({ input }: { input: Record<string, unknown> }) => ({ result: `Parent: ${input.data}` })
|
|
359
|
+
}
|
|
360
|
+
],
|
|
361
|
+
nodes: {
|
|
362
|
+
'child-node-1': {
|
|
363
|
+
id: 'child-node-1',
|
|
364
|
+
description: 'Child node 1',
|
|
365
|
+
load: async () => ({
|
|
366
|
+
prompt: '# Child Knowledge 1\n\nSpecialized tools.',
|
|
367
|
+
tools: [
|
|
368
|
+
{
|
|
369
|
+
name: 'child_tool_1',
|
|
370
|
+
description: 'Child tool 1',
|
|
371
|
+
inputSchema: z.object({ value: z.string() }),
|
|
372
|
+
outputSchema: z.object({ output: z.string() }),
|
|
373
|
+
execute: async ({ input }: { input: Record<string, unknown> }) => ({ output: `Child1: ${input.value}` })
|
|
374
|
+
}
|
|
375
|
+
]
|
|
376
|
+
})
|
|
377
|
+
},
|
|
378
|
+
'child-node-2': {
|
|
379
|
+
id: 'child-node-2',
|
|
380
|
+
description: 'Child node 2',
|
|
381
|
+
load: async () => ({
|
|
382
|
+
prompt: '# Child Knowledge 2\n\nMore specialized tools.',
|
|
383
|
+
tools: []
|
|
384
|
+
})
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
})
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Setup: MockAdapter that navigates parent, then child
|
|
393
|
+
const mockLLM = new MockAdapter({
|
|
394
|
+
responses: [
|
|
395
|
+
{
|
|
396
|
+
reasoning: 'Loading parent node first',
|
|
397
|
+
nextActions: [{
|
|
398
|
+
type: 'navigate-knowledge',
|
|
399
|
+
id: 'nav-1',
|
|
400
|
+
nodeId: 'parent-node'
|
|
401
|
+
}]
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
reasoning: 'Now child nodes should be available - navigate to child-node-1',
|
|
405
|
+
nextActions: [{
|
|
406
|
+
type: 'navigate-knowledge',
|
|
407
|
+
id: 'nav-2',
|
|
408
|
+
nodeId: 'child-node-1'
|
|
409
|
+
}]
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
reasoning: 'Using child tool',
|
|
413
|
+
nextActions: [{
|
|
414
|
+
type: 'tool-call',
|
|
415
|
+
id: 'call-1',
|
|
416
|
+
name: 'child_tool_1',
|
|
417
|
+
input: { value: 'hierarchical test' }
|
|
418
|
+
}]
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
reasoning: 'Task complete',
|
|
422
|
+
nextActions: [{ type: 'complete' }]
|
|
423
|
+
}
|
|
424
|
+
],
|
|
425
|
+
completionOutput: { result: 'Hierarchical navigation successful' }
|
|
426
|
+
})
|
|
427
|
+
|
|
428
|
+
const agent = new Agent({
|
|
429
|
+
config: {
|
|
430
|
+
resourceId: 'hierarchical-agent',
|
|
431
|
+
name: 'Hierarchical Knowledge Agent',
|
|
432
|
+
description: 'Tests hierarchical navigation',
|
|
433
|
+
systemPrompt: 'Navigate knowledge hierarchically',
|
|
434
|
+
type: 'agent',
|
|
435
|
+
status: 'dev',
|
|
436
|
+
version: '1.0.0'
|
|
437
|
+
},
|
|
438
|
+
contract: {
|
|
439
|
+
inputSchema: z.object({ task: z.string() }),
|
|
440
|
+
outputSchema: z.object({ result: z.string() })
|
|
441
|
+
},
|
|
442
|
+
tools: [],
|
|
443
|
+
knowledgeMap: hierarchicalKnowledgeMap,
|
|
444
|
+
modelConfig: { provider: 'mock', model: 'mock', apiKey: 'test-api-key' }
|
|
445
|
+
}, createMockAdapterFactory(mockLLM))
|
|
446
|
+
|
|
447
|
+
// Execute
|
|
448
|
+
const result = await agent.execute(
|
|
449
|
+
{ task: 'Test hierarchical navigation' },
|
|
450
|
+
mockContext
|
|
451
|
+
)
|
|
452
|
+
|
|
453
|
+
// Assert: Execution completes
|
|
454
|
+
expect(result).toEqual({ result: 'Hierarchical navigation successful' })
|
|
455
|
+
|
|
456
|
+
// Assert: Child nodes were discovered
|
|
457
|
+
const snapshot = agent.getMemorySnapshot()
|
|
458
|
+
const discoveryMessages = snapshot.history.filter(entry =>
|
|
459
|
+
entry.type === 'tool-result' &&
|
|
460
|
+
entry.content.includes('child nodes discovered')
|
|
461
|
+
)
|
|
462
|
+
expect(discoveryMessages.length).toBeGreaterThan(0)
|
|
463
|
+
|
|
464
|
+
// Assert: Child node was successfully loaded
|
|
465
|
+
const childLoadMessages = snapshot.history.filter(entry =>
|
|
466
|
+
entry.type === 'tool-result' &&
|
|
467
|
+
entry.content.includes('child-node-1')
|
|
468
|
+
)
|
|
469
|
+
expect(childLoadMessages.length).toBeGreaterThan(0)
|
|
470
|
+
|
|
471
|
+
// Assert: Child tool was used
|
|
472
|
+
const childToolResults = snapshot.history.filter(entry =>
|
|
473
|
+
entry.type === 'tool-result' &&
|
|
474
|
+
entry.content.includes('Child1: hierarchical test')
|
|
475
|
+
)
|
|
476
|
+
expect(childToolResults.length).toBeGreaterThan(0)
|
|
477
|
+
|
|
478
|
+
// Assert: Correct number of LLM calls (4 iterations + 1 completion)
|
|
479
|
+
expect(mockLLM.getCallCount()).toBe(5)
|
|
480
|
+
})
|
|
481
|
+
|
|
482
|
+
it('cross-turn persistence - tools reload from sessionMemory state', async () => {
|
|
483
|
+
// Setup: First execution loads knowledge and stores state
|
|
484
|
+
const firstMockLLM = new MockAdapter({
|
|
485
|
+
responses: [
|
|
486
|
+
{
|
|
487
|
+
reasoning: 'Loading knowledge first time',
|
|
488
|
+
nextActions: [{
|
|
489
|
+
type: 'navigate-knowledge',
|
|
490
|
+
id: 'nav-1',
|
|
491
|
+
nodeId: 'test-tools'
|
|
492
|
+
}]
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
reasoning: 'Task complete',
|
|
496
|
+
nextActions: [{ type: 'complete' }]
|
|
497
|
+
}
|
|
498
|
+
],
|
|
499
|
+
completionOutput: { result: 'First turn complete' }
|
|
500
|
+
})
|
|
501
|
+
|
|
502
|
+
const agentDef = createKnowledgeMapAgent()
|
|
503
|
+
const firstAgent = new Agent(agentDef, createMockAdapterFactory(firstMockLLM))
|
|
504
|
+
|
|
505
|
+
// First execution
|
|
506
|
+
await firstAgent.execute(
|
|
507
|
+
{ task: 'First turn - load knowledge' },
|
|
508
|
+
mockContext
|
|
509
|
+
)
|
|
510
|
+
|
|
511
|
+
const firstSnapshot = firstAgent.getMemorySnapshot()
|
|
512
|
+
|
|
513
|
+
// Assert: Knowledge state was stored
|
|
514
|
+
expect(firstSnapshot.sessionMemory).toHaveProperty('knowledge-map-state')
|
|
515
|
+
const stateJson = firstSnapshot.sessionMemory['knowledge-map-state']
|
|
516
|
+
expect(stateJson).toBeDefined()
|
|
517
|
+
|
|
518
|
+
const state = JSON.parse(stateJson.content)
|
|
519
|
+
expect(state.loadedNodes).toContain('test-tools')
|
|
520
|
+
|
|
521
|
+
// Setup: Second execution reloads tools from state
|
|
522
|
+
const secondMockLLM = new MockAdapter({
|
|
523
|
+
responses: [
|
|
524
|
+
{
|
|
525
|
+
reasoning: 'Tools should be already loaded - using them directly',
|
|
526
|
+
nextActions: [{
|
|
527
|
+
type: 'tool-call',
|
|
528
|
+
id: 'call-1',
|
|
529
|
+
name: 'test_tool_1', // Should be available without navigate-knowledge
|
|
530
|
+
input: { input: 'reloaded tool' }
|
|
531
|
+
}]
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
reasoning: 'Task complete',
|
|
535
|
+
nextActions: [{ type: 'complete' }]
|
|
536
|
+
}
|
|
537
|
+
],
|
|
538
|
+
completionOutput: { result: 'Second turn - tools persisted' }
|
|
539
|
+
})
|
|
540
|
+
|
|
541
|
+
// Create agent with preloadMemory that returns first execution's memory
|
|
542
|
+
const agentDefWithPreload = {
|
|
543
|
+
...agentDef,
|
|
544
|
+
preloadMemory: async () => firstSnapshot
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
const secondAgent = new Agent(agentDefWithPreload, createMockAdapterFactory(secondMockLLM))
|
|
548
|
+
|
|
549
|
+
// Second execution
|
|
550
|
+
const result = await secondAgent.execute(
|
|
551
|
+
{ task: 'Second turn - use reloaded tools' },
|
|
552
|
+
mockContext
|
|
553
|
+
)
|
|
554
|
+
|
|
555
|
+
// Assert: Tool was available and used successfully
|
|
556
|
+
expect(result).toEqual({ result: 'Second turn - tools persisted' })
|
|
557
|
+
|
|
558
|
+
const secondSnapshot = secondAgent.getMemorySnapshot()
|
|
559
|
+
const toolResults = secondSnapshot.history.filter(entry =>
|
|
560
|
+
entry.type === 'tool-result' &&
|
|
561
|
+
entry.content.includes('Result: reloaded tool')
|
|
562
|
+
)
|
|
563
|
+
expect(toolResults.length).toBeGreaterThan(0)
|
|
564
|
+
|
|
565
|
+
// Assert: Tool was available from first iteration (no navigate-knowledge needed)
|
|
566
|
+
const tools = secondAgent.getTools()
|
|
567
|
+
const testTools = tools.filter(t => t.name === 'test_tool_1')
|
|
568
|
+
expect(testTools).toHaveLength(1)
|
|
569
|
+
|
|
570
|
+
// Assert: Correct number of LLM calls (2 iterations + 1 completion)
|
|
571
|
+
expect(secondMockLLM.getCallCount()).toBe(3)
|
|
572
|
+
})
|
|
573
|
+
})
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* Phase 5: Multi-Iteration Complex Scenarios
|
|
577
|
+
*
|
|
578
|
+
* Tests agent execution across multiple iterations with:
|
|
579
|
+
* - Tool chaining (multiple tools across iterations)
|
|
580
|
+
* - Memory evolution (state changes across iterations)
|
|
581
|
+
* - Iteration limits enforcement
|
|
582
|
+
* - Error recovery patterns
|
|
583
|
+
* - Context propagation through lifecycle
|
|
584
|
+
*/
|
|
585
|
+
describe('Multi-Iteration Scenarios', () => {
|
|
586
|
+
const mockContext: ExecutionContext = {
|
|
587
|
+
executionId: 'exec-multi',
|
|
588
|
+
organizationId: 'org-multi',
|
|
589
|
+
resourceId: 'multi-agent',
|
|
590
|
+
resourceType: 'agent' as const,
|
|
591
|
+
logger: {
|
|
592
|
+
info: vi.fn(),
|
|
593
|
+
error: vi.fn(),
|
|
594
|
+
warn: vi.fn(),
|
|
595
|
+
debug: vi.fn()
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
beforeEach(() => {
|
|
600
|
+
vi.clearAllMocks()
|
|
601
|
+
})
|
|
602
|
+
|
|
603
|
+
it('chains tools across iterations with memory evolution', async () => {
|
|
604
|
+
// Setup: Mock services for multi-tool chaining
|
|
605
|
+
const mockCommandQueue = {
|
|
606
|
+
createTask: vi.fn().mockResolvedValue({ id: 'task-chain-123' })
|
|
607
|
+
}
|
|
608
|
+
const mockNotifications = {
|
|
609
|
+
create: vi.fn().mockResolvedValue({ id: 'notif-chain-456' })
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
vi.mocked(getToolServices).mockReturnValue({
|
|
613
|
+
commandQueueService: mockCommandQueue,
|
|
614
|
+
taskSchedulerService: null,
|
|
615
|
+
notificationsService: mockNotifications,
|
|
616
|
+
credentialsService: null,
|
|
617
|
+
integrationService: null
|
|
618
|
+
})
|
|
619
|
+
|
|
620
|
+
const agent = new Agent({
|
|
621
|
+
config: {
|
|
622
|
+
resourceId: 'multi-agent',
|
|
623
|
+
name: 'Multi-Tool Agent',
|
|
624
|
+
systemPrompt: 'You coordinate approval and notification workflows',
|
|
625
|
+
environment: 'test',
|
|
626
|
+
type: 'agent',
|
|
627
|
+
status: 'development',
|
|
628
|
+
version: '1.0.0'
|
|
629
|
+
},
|
|
630
|
+
contract: {
|
|
631
|
+
inputSchema: z.object({ amount: z.number() }),
|
|
632
|
+
outputSchema: z.object({
|
|
633
|
+
response: z.string().optional(),
|
|
634
|
+
processedAt: z.string().optional()
|
|
635
|
+
})
|
|
636
|
+
},
|
|
637
|
+
tools: [
|
|
638
|
+
createApprovalTool({
|
|
639
|
+
name: 'request_approval',
|
|
640
|
+
description: 'Request approval',
|
|
641
|
+
inputSchema: z.object({ amount: z.number() }),
|
|
642
|
+
outputSchema: z.object({ taskId: z.string() }),
|
|
643
|
+
approveTargetResourceId: 'approver'
|
|
644
|
+
}),
|
|
645
|
+
createNotificationTool({
|
|
646
|
+
name: 'send_notification',
|
|
647
|
+
description: 'Send notification',
|
|
648
|
+
inputSchema: z.object({ title: z.string(), message: z.string() }),
|
|
649
|
+
outputSchema: z.object({ notificationId: z.string() }),
|
|
650
|
+
userId: 'user-123',
|
|
651
|
+
category: 'info'
|
|
652
|
+
})
|
|
653
|
+
],
|
|
654
|
+
modelConfig: { provider: 'mock', model: 'mock' }
|
|
655
|
+
}, createMockAdapterFactory())
|
|
656
|
+
|
|
657
|
+
// Execute
|
|
658
|
+
const result = await agent.execute({ amount: 5000 }, mockContext)
|
|
659
|
+
|
|
660
|
+
// Assert: Execution completed successfully
|
|
661
|
+
// Note: Default MockAdapter returns empty object for completion
|
|
662
|
+
// This test validates the framework machinery (agent + tools) works correctly
|
|
663
|
+
expect(result).toBeDefined()
|
|
664
|
+
|
|
665
|
+
// Assert: Memory snapshot available and contains execution history
|
|
666
|
+
const snapshot = agent.getMemorySnapshot()
|
|
667
|
+
expect(snapshot).toBeDefined()
|
|
668
|
+
expect(snapshot.history).toBeDefined()
|
|
669
|
+
expect(snapshot.history.length).toBeGreaterThan(0)
|
|
670
|
+
})
|
|
671
|
+
|
|
672
|
+
it('auto-compacts memory during execution when budget exceeded', async () => {
|
|
673
|
+
// Setup: Agent with low token budget that will trigger auto-compaction
|
|
674
|
+
const mockLLM = new MockAdapter({
|
|
675
|
+
responses: [
|
|
676
|
+
{
|
|
677
|
+
reasoning: 'First iteration - generating large content to fill memory',
|
|
678
|
+
nextActions: [{
|
|
679
|
+
type: 'tool-call',
|
|
680
|
+
id: 'call-1',
|
|
681
|
+
name: 'generate_large_output',
|
|
682
|
+
input: { size: 'large' }
|
|
683
|
+
}]
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
reasoning: 'Second iteration - more large content',
|
|
687
|
+
nextActions: [{
|
|
688
|
+
type: 'tool-call',
|
|
689
|
+
id: 'call-2',
|
|
690
|
+
name: 'generate_large_output',
|
|
691
|
+
input: { size: 'large' }
|
|
692
|
+
}]
|
|
693
|
+
},
|
|
694
|
+
{
|
|
695
|
+
reasoning: 'Third iteration - even more content',
|
|
696
|
+
nextActions: [{
|
|
697
|
+
type: 'tool-call',
|
|
698
|
+
id: 'call-3',
|
|
699
|
+
name: 'generate_large_output',
|
|
700
|
+
input: { size: 'large' }
|
|
701
|
+
}]
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
reasoning: 'Fourth iteration - final large content',
|
|
705
|
+
nextActions: [{
|
|
706
|
+
type: 'tool-call',
|
|
707
|
+
id: 'call-4',
|
|
708
|
+
name: 'generate_large_output',
|
|
709
|
+
input: { size: 'large' }
|
|
710
|
+
}]
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
reasoning: 'Task complete after generating lots of content',
|
|
714
|
+
nextActions: [{ type: 'complete' }]
|
|
715
|
+
}
|
|
716
|
+
],
|
|
717
|
+
completionOutput: { result: 'Completed with auto-compaction' }
|
|
718
|
+
})
|
|
719
|
+
|
|
720
|
+
// Tool that generates large output to fill memory budget
|
|
721
|
+
const largeTool = {
|
|
722
|
+
name: 'generate_large_output',
|
|
723
|
+
description: 'Generates large output to test memory compaction',
|
|
724
|
+
inputSchema: z.object({ size: z.string() }),
|
|
725
|
+
outputSchema: z.object({ data: z.string() }),
|
|
726
|
+
execute: async () => ({
|
|
727
|
+
// Generate ~500 tokens per call (roughly 2000 chars)
|
|
728
|
+
data: 'A'.repeat(2000) + ' - Large output generated'
|
|
729
|
+
})
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
const agent = new Agent({
|
|
733
|
+
config: {
|
|
734
|
+
resourceId: 'compact-agent',
|
|
735
|
+
name: 'Compaction Test Agent',
|
|
736
|
+
description: 'Tests auto-compaction',
|
|
737
|
+
systemPrompt: 'Generate large outputs to test memory',
|
|
738
|
+
type: 'agent',
|
|
739
|
+
status: 'dev',
|
|
740
|
+
version: '1.0.0',
|
|
741
|
+
constraints: {
|
|
742
|
+
maxMemoryTokens: 2000 // Low budget to trigger compaction
|
|
743
|
+
}
|
|
744
|
+
},
|
|
745
|
+
contract: {
|
|
746
|
+
inputSchema: z.object({ task: z.string() }),
|
|
747
|
+
outputSchema: z.object({ result: z.string() })
|
|
748
|
+
},
|
|
749
|
+
tools: [largeTool],
|
|
750
|
+
modelConfig: { provider: 'mock', model: 'mock', apiKey: 'test-api-key' }
|
|
751
|
+
}, createMockAdapterFactory(mockLLM))
|
|
752
|
+
|
|
753
|
+
// Execute
|
|
754
|
+
const result = await agent.execute(
|
|
755
|
+
{ task: 'Generate large outputs to trigger compaction' },
|
|
756
|
+
mockContext
|
|
757
|
+
)
|
|
758
|
+
|
|
759
|
+
// Assert: Execution completed
|
|
760
|
+
expect(result).toEqual({ result: 'Completed with auto-compaction' })
|
|
761
|
+
|
|
762
|
+
// Assert: Memory was compacted (history should be reduced)
|
|
763
|
+
const snapshot = agent.getMemorySnapshot()
|
|
764
|
+
expect(snapshot).toBeDefined()
|
|
765
|
+
|
|
766
|
+
// With 4 tool calls + reasoning entries, without compaction we'd have ~20+ entries
|
|
767
|
+
// After compaction, we should have first entry + last 10 (or fewer due to aggressive compaction)
|
|
768
|
+
expect(snapshot!.history.length).toBeLessThanOrEqual(12) // First + last 10 + some buffer
|
|
769
|
+
|
|
770
|
+
// Assert: First entry (input) is preserved
|
|
771
|
+
expect(snapshot!.history[0].type).toBe('input')
|
|
772
|
+
|
|
773
|
+
// Assert: Recent entries are preserved (last entries should be from later iterations)
|
|
774
|
+
const lastEntry = snapshot!.history[snapshot!.history.length - 1]
|
|
775
|
+
expect(lastEntry).toBeDefined()
|
|
776
|
+
})
|
|
777
|
+
|
|
778
|
+
it('enforces maxIterations constraint', async () => {
|
|
779
|
+
// Setup: MockAdapter that never signals completion (always continues)
|
|
780
|
+
const mockLLM = new MockAdapter({
|
|
781
|
+
responses: [
|
|
782
|
+
{
|
|
783
|
+
reasoning: 'Iteration 1 - still working',
|
|
784
|
+
nextActions: [{
|
|
785
|
+
type: 'tool-call',
|
|
786
|
+
id: 'call-1',
|
|
787
|
+
name: 'infinite_work',
|
|
788
|
+
input: { iteration: 1 }
|
|
789
|
+
}]
|
|
790
|
+
},
|
|
791
|
+
{
|
|
792
|
+
reasoning: 'Iteration 2 - still working',
|
|
793
|
+
nextActions: [{
|
|
794
|
+
type: 'tool-call',
|
|
795
|
+
id: 'call-2',
|
|
796
|
+
name: 'infinite_work',
|
|
797
|
+
input: { iteration: 2 }
|
|
798
|
+
}]
|
|
799
|
+
},
|
|
800
|
+
{
|
|
801
|
+
reasoning: 'Iteration 3 - still working (should be last allowed)',
|
|
802
|
+
nextActions: [{
|
|
803
|
+
type: 'tool-call',
|
|
804
|
+
id: 'call-3',
|
|
805
|
+
name: 'infinite_work',
|
|
806
|
+
input: { iteration: 3 }
|
|
807
|
+
}]
|
|
808
|
+
},
|
|
809
|
+
// These should never be reached due to maxIterations=3
|
|
810
|
+
{
|
|
811
|
+
reasoning: 'Iteration 4 - should not reach here',
|
|
812
|
+
nextActions: [{ type: 'complete' }]
|
|
813
|
+
}
|
|
814
|
+
],
|
|
815
|
+
completionOutput: { result: 'Should not reach completion' }
|
|
816
|
+
})
|
|
817
|
+
|
|
818
|
+
// Simple tool that just returns success
|
|
819
|
+
const infiniteWorkTool = {
|
|
820
|
+
name: 'infinite_work',
|
|
821
|
+
description: 'Simulates work that never ends',
|
|
822
|
+
inputSchema: z.object({ iteration: z.number() }),
|
|
823
|
+
outputSchema: z.object({ status: z.string() }),
|
|
824
|
+
execute: async ({ input }: { input: { iteration: number } }) => ({
|
|
825
|
+
status: `Work completed for iteration ${input.iteration}`
|
|
826
|
+
})
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
const agent = new Agent({
|
|
830
|
+
config: {
|
|
831
|
+
resourceId: 'max-iter-agent',
|
|
832
|
+
name: 'Max Iterations Agent',
|
|
833
|
+
description: 'Tests maxIterations enforcement',
|
|
834
|
+
systemPrompt: 'Keep working forever',
|
|
835
|
+
type: 'agent',
|
|
836
|
+
status: 'dev',
|
|
837
|
+
version: '1.0.0',
|
|
838
|
+
constraints: {
|
|
839
|
+
maxIterations: 3 // Strict limit
|
|
840
|
+
}
|
|
841
|
+
},
|
|
842
|
+
contract: {
|
|
843
|
+
inputSchema: z.object({ task: z.string() }),
|
|
844
|
+
outputSchema: z.object({ result: z.string() })
|
|
845
|
+
},
|
|
846
|
+
tools: [infiniteWorkTool],
|
|
847
|
+
modelConfig: { provider: 'mock', model: 'mock', apiKey: 'test-api-key' }
|
|
848
|
+
}, createMockAdapterFactory(mockLLM))
|
|
849
|
+
|
|
850
|
+
// Execute - should throw AgentMaxIterationsError
|
|
851
|
+
await expect(
|
|
852
|
+
agent.execute({ task: 'Work forever' }, mockContext)
|
|
853
|
+
).rejects.toThrow(/exceeded maximum iterations/)
|
|
854
|
+
|
|
855
|
+
// Assert: Exactly 3 iterations were executed (3 iteration calls + no completion)
|
|
856
|
+
// Each iteration = 1 LLM call for reasoning
|
|
857
|
+
expect(mockLLM.getCallCount()).toBe(3)
|
|
858
|
+
|
|
859
|
+
// Note: Memory snapshot is not available after error because toSnapshot()
|
|
860
|
+
// is called in complete() phase which doesn't run when maxIterations throws.
|
|
861
|
+
// This is correct behavior - the error bubbles up before completion.
|
|
862
|
+
// The test validates that:
|
|
863
|
+
// 1. The error is thrown with correct message
|
|
864
|
+
// 2. Exactly maxIterations (3) LLM calls were made
|
|
865
|
+
// 3. No additional iterations occurred
|
|
866
|
+
})
|
|
867
|
+
|
|
868
|
+
it('handles tool errors and recovers in next iteration', async () => {
|
|
869
|
+
// Setup: MockAdapter that first calls failing tool, then recovers with working tool
|
|
870
|
+
const mockLLM = new MockAdapter({
|
|
871
|
+
responses: [
|
|
872
|
+
{
|
|
873
|
+
reasoning: 'Calling the unreliable tool that might fail',
|
|
874
|
+
nextActions: [{
|
|
875
|
+
type: 'tool-call',
|
|
876
|
+
id: 'call-fail',
|
|
877
|
+
name: 'unreliable_tool',
|
|
878
|
+
input: { shouldFail: true }
|
|
879
|
+
}]
|
|
880
|
+
},
|
|
881
|
+
{
|
|
882
|
+
reasoning: 'Previous tool failed, trying reliable tool instead',
|
|
883
|
+
nextActions: [{
|
|
884
|
+
type: 'tool-call',
|
|
885
|
+
id: 'call-success',
|
|
886
|
+
name: 'reliable_tool',
|
|
887
|
+
input: { data: 'recovery data' }
|
|
888
|
+
}]
|
|
889
|
+
},
|
|
890
|
+
{
|
|
891
|
+
reasoning: 'Recovered successfully, completing task',
|
|
892
|
+
nextActions: [{ type: 'complete' }]
|
|
893
|
+
}
|
|
894
|
+
],
|
|
895
|
+
completionOutput: { result: 'Recovered from error and completed' }
|
|
896
|
+
})
|
|
897
|
+
|
|
898
|
+
// Tool that throws an error
|
|
899
|
+
const unreliableTool = {
|
|
900
|
+
name: 'unreliable_tool',
|
|
901
|
+
description: 'Tool that fails when shouldFail is true',
|
|
902
|
+
inputSchema: z.object({ shouldFail: z.boolean() }),
|
|
903
|
+
outputSchema: z.object({ result: z.string() }),
|
|
904
|
+
execute: async ({ input }: { input: { shouldFail: boolean } }) => {
|
|
905
|
+
if (input.shouldFail) {
|
|
906
|
+
throw new Error('Simulated tool failure: Service unavailable')
|
|
907
|
+
}
|
|
908
|
+
return { result: 'Success' }
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
// Tool that always succeeds
|
|
913
|
+
const reliableTool = {
|
|
914
|
+
name: 'reliable_tool',
|
|
915
|
+
description: 'Tool that always succeeds',
|
|
916
|
+
inputSchema: z.object({ data: z.string() }),
|
|
917
|
+
outputSchema: z.object({ processed: z.string() }),
|
|
918
|
+
execute: async ({ input }: { input: { data: string } }) => ({
|
|
919
|
+
processed: `Processed: ${input.data}`
|
|
920
|
+
})
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
const agent = new Agent({
|
|
924
|
+
config: {
|
|
925
|
+
resourceId: 'recovery-agent',
|
|
926
|
+
name: 'Error Recovery Agent',
|
|
927
|
+
description: 'Tests error recovery patterns',
|
|
928
|
+
systemPrompt: 'Try tools and recover from failures',
|
|
929
|
+
type: 'agent',
|
|
930
|
+
status: 'dev',
|
|
931
|
+
version: '1.0.0'
|
|
932
|
+
},
|
|
933
|
+
contract: {
|
|
934
|
+
inputSchema: z.object({ task: z.string() }),
|
|
935
|
+
outputSchema: z.object({ result: z.string() })
|
|
936
|
+
},
|
|
937
|
+
tools: [unreliableTool, reliableTool],
|
|
938
|
+
modelConfig: { provider: 'mock', model: 'mock', apiKey: 'test-api-key' }
|
|
939
|
+
}, createMockAdapterFactory(mockLLM))
|
|
940
|
+
|
|
941
|
+
// Execute - should complete successfully despite first tool failure
|
|
942
|
+
const result = await agent.execute(
|
|
943
|
+
{ task: 'Try unreliable tool, then recover with reliable tool' },
|
|
944
|
+
mockContext
|
|
945
|
+
)
|
|
946
|
+
|
|
947
|
+
// Assert: Execution completed successfully
|
|
948
|
+
expect(result).toEqual({ result: 'Recovered from error and completed' })
|
|
949
|
+
|
|
950
|
+
// Assert: Memory contains the error from failed tool
|
|
951
|
+
const snapshot = agent.getMemorySnapshot()
|
|
952
|
+
expect(snapshot).toBeDefined()
|
|
953
|
+
|
|
954
|
+
const errorEntries = snapshot!.history.filter(e => e.type === 'error')
|
|
955
|
+
expect(errorEntries.length).toBeGreaterThan(0)
|
|
956
|
+
expect(errorEntries[0].content).toContain('Simulated tool failure')
|
|
957
|
+
|
|
958
|
+
// Assert: Memory contains successful recovery
|
|
959
|
+
const toolResults = snapshot!.history.filter(e =>
|
|
960
|
+
e.type === 'tool-result' && e.content.includes('Processed: recovery data')
|
|
961
|
+
)
|
|
962
|
+
expect(toolResults.length).toBe(1)
|
|
963
|
+
|
|
964
|
+
// Assert: All 3 iterations + 1 completion call were made
|
|
965
|
+
expect(mockLLM.getCallCount()).toBe(4)
|
|
966
|
+
})
|
|
967
|
+
|
|
968
|
+
it('emits lifecycle events for SSE broadcasting', async () => {
|
|
969
|
+
// Setup: Simple agent that completes successfully
|
|
970
|
+
const mockLLM = new MockAdapter({
|
|
971
|
+
responses: [
|
|
972
|
+
{
|
|
973
|
+
reasoning: 'Task complete',
|
|
974
|
+
nextActions: [{ type: 'complete' }]
|
|
975
|
+
}
|
|
976
|
+
],
|
|
977
|
+
completionOutput: { result: 'Done' }
|
|
978
|
+
})
|
|
979
|
+
|
|
980
|
+
// Track SSE events (observable behavior for real-time UI updates)
|
|
981
|
+
const emittedEvents: Array<{ type: string }> = []
|
|
982
|
+
const testContext: ExecutionContext = {
|
|
983
|
+
executionId: 'exec-sse-test',
|
|
984
|
+
organizationId: 'org-sse-test',
|
|
985
|
+
resourceId: 'sse-agent',
|
|
986
|
+
resourceType: 'agent' as const,
|
|
987
|
+
logger: {
|
|
988
|
+
info: vi.fn(),
|
|
989
|
+
error: vi.fn(),
|
|
990
|
+
warn: vi.fn(),
|
|
991
|
+
debug: vi.fn()
|
|
992
|
+
},
|
|
993
|
+
onMessageEvent: vi.fn(async (event) => {
|
|
994
|
+
emittedEvents.push(event)
|
|
995
|
+
})
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
const agent = new Agent({
|
|
999
|
+
config: {
|
|
1000
|
+
resourceId: 'sse-agent',
|
|
1001
|
+
name: 'SSE Lifecycle Agent',
|
|
1002
|
+
description: 'Tests SSE event emission',
|
|
1003
|
+
systemPrompt: 'Complete task',
|
|
1004
|
+
type: 'agent',
|
|
1005
|
+
status: 'dev',
|
|
1006
|
+
version: '1.0.0'
|
|
1007
|
+
},
|
|
1008
|
+
contract: {
|
|
1009
|
+
inputSchema: z.object({ task: z.string() }),
|
|
1010
|
+
outputSchema: z.object({ result: z.string() })
|
|
1011
|
+
},
|
|
1012
|
+
tools: [],
|
|
1013
|
+
modelConfig: { provider: 'mock', model: 'mock', apiKey: 'test-api-key' }
|
|
1014
|
+
}, createMockAdapterFactory(mockLLM))
|
|
1015
|
+
|
|
1016
|
+
// Execute
|
|
1017
|
+
const result = await agent.execute({ task: 'Complete' }, testContext)
|
|
1018
|
+
|
|
1019
|
+
// Assert: Execution completed
|
|
1020
|
+
expect(result).toEqual({ result: 'Done' })
|
|
1021
|
+
|
|
1022
|
+
// Assert: SSE lifecycle events emitted (user-facing behavior for real-time UI)
|
|
1023
|
+
expect(emittedEvents).toContainEqual({ type: 'agent:started' })
|
|
1024
|
+
expect(emittedEvents).toContainEqual({ type: 'agent:completed' })
|
|
1025
|
+
|
|
1026
|
+
// Assert: Events emitted in correct order
|
|
1027
|
+
const startIndex = emittedEvents.findIndex(e => e.type === 'agent:started')
|
|
1028
|
+
const completeIndex = emittedEvents.findIndex(e => e.type === 'agent:completed')
|
|
1029
|
+
expect(startIndex).toBeLessThan(completeIndex)
|
|
1030
|
+
})
|
|
1031
|
+
})
|