@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,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic circuit breaker state machine.
|
|
3
|
+
* Provides the core state management logic that can be reused across different services.
|
|
4
|
+
*
|
|
5
|
+
* State Transitions:
|
|
6
|
+
* - CLOSED -> OPEN: After failureThreshold consecutive failures
|
|
7
|
+
* - OPEN -> HALF_OPEN: After resetTimeoutMs has elapsed
|
|
8
|
+
* - HALF_OPEN -> CLOSED: After successThreshold consecutive successes
|
|
9
|
+
* - HALF_OPEN -> OPEN: On any failure
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { ServiceUnavailableError } from './errors'
|
|
13
|
+
import {
|
|
14
|
+
CIRCUIT_BREAKER_FAILURE_THRESHOLD,
|
|
15
|
+
CIRCUIT_BREAKER_COOLDOWN_MS,
|
|
16
|
+
CIRCUIT_BREAKER_SUCCESS_THRESHOLD,
|
|
17
|
+
CIRCUIT_BREAKER_HALF_OPEN_MAX_REQUESTS
|
|
18
|
+
} from '../constants/resilience'
|
|
19
|
+
|
|
20
|
+
export enum CircuitState {
|
|
21
|
+
CLOSED = 'closed',
|
|
22
|
+
OPEN = 'open',
|
|
23
|
+
HALF_OPEN = 'half_open'
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface CircuitBreakerConfig {
|
|
27
|
+
/** Number of failures before opening circuit (default: 5) */
|
|
28
|
+
failureThreshold?: number
|
|
29
|
+
/** Time in ms before attempting recovery (default: 60000) */
|
|
30
|
+
resetTimeoutMs?: number
|
|
31
|
+
/** Successes needed to close circuit from half-open (default: 2) */
|
|
32
|
+
successThreshold?: number
|
|
33
|
+
/** Max concurrent requests in half-open state (default: 3) */
|
|
34
|
+
halfOpenMaxRequests?: number
|
|
35
|
+
/** Called when circuit state changes. Use for alerting on OPEN transitions. */
|
|
36
|
+
onStateChange?: (service: string, from: CircuitState, to: CircuitState, context: { failureCount: number }) => void
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface CircuitBreaker {
|
|
40
|
+
/** Execute a function through the circuit breaker */
|
|
41
|
+
execute<T>(fn: () => Promise<T>): Promise<T>
|
|
42
|
+
/** Get current circuit state */
|
|
43
|
+
getState(): CircuitState
|
|
44
|
+
/** Get current failure count */
|
|
45
|
+
getFailureCount(): number
|
|
46
|
+
/** Reset circuit to closed state */
|
|
47
|
+
reset(): void
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const DEFAULT_CONFIG: Required<Pick<CircuitBreakerConfig, 'failureThreshold' | 'resetTimeoutMs' | 'successThreshold' | 'halfOpenMaxRequests'>> = {
|
|
51
|
+
failureThreshold: CIRCUIT_BREAKER_FAILURE_THRESHOLD,
|
|
52
|
+
resetTimeoutMs: CIRCUIT_BREAKER_COOLDOWN_MS,
|
|
53
|
+
successThreshold: CIRCUIT_BREAKER_SUCCESS_THRESHOLD,
|
|
54
|
+
halfOpenMaxRequests: CIRCUIT_BREAKER_HALF_OPEN_MAX_REQUESTS
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Creates a circuit breaker instance for a specific service.
|
|
59
|
+
*
|
|
60
|
+
* @param service - Service name for error context (e.g., 'llm:gpt-4', 'workos')
|
|
61
|
+
* @param config - Optional configuration overrides
|
|
62
|
+
* @returns CircuitBreaker instance
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const breaker = createCircuitBreaker('workos')
|
|
67
|
+
*
|
|
68
|
+
* try {
|
|
69
|
+
* const result = await breaker.execute(() => workos.userManagement.getUser(id))
|
|
70
|
+
* } catch (error) {
|
|
71
|
+
* if (error instanceof ServiceUnavailableError) {
|
|
72
|
+
* // Circuit is open, service unavailable
|
|
73
|
+
* }
|
|
74
|
+
* }
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export function createCircuitBreaker(
|
|
78
|
+
service: string,
|
|
79
|
+
config?: CircuitBreakerConfig
|
|
80
|
+
): CircuitBreaker {
|
|
81
|
+
const cfg = { ...DEFAULT_CONFIG, ...config }
|
|
82
|
+
|
|
83
|
+
let state = CircuitState.CLOSED
|
|
84
|
+
let failureCount = 0
|
|
85
|
+
let successCount = 0
|
|
86
|
+
let lastFailureTime = 0
|
|
87
|
+
let halfOpenRequests = 0
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
async execute<T>(fn: () => Promise<T>): Promise<T> {
|
|
91
|
+
// Check if circuit should transition from OPEN to HALF_OPEN
|
|
92
|
+
if (state === CircuitState.OPEN) {
|
|
93
|
+
if (Date.now() - lastFailureTime >= cfg.resetTimeoutMs) {
|
|
94
|
+
const prev = state
|
|
95
|
+
state = CircuitState.HALF_OPEN
|
|
96
|
+
halfOpenRequests = 0
|
|
97
|
+
successCount = 0
|
|
98
|
+
cfg.onStateChange?.(service, prev, state, { failureCount })
|
|
99
|
+
} else {
|
|
100
|
+
throw new ServiceUnavailableError(service, 'circuit_open', {
|
|
101
|
+
failureCount,
|
|
102
|
+
resetIn: cfg.resetTimeoutMs - (Date.now() - lastFailureTime)
|
|
103
|
+
})
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// In HALF_OPEN, limit concurrent requests to prevent thundering herd
|
|
108
|
+
if (state === CircuitState.HALF_OPEN) {
|
|
109
|
+
if (halfOpenRequests >= cfg.halfOpenMaxRequests) {
|
|
110
|
+
throw new ServiceUnavailableError(service, 'circuit_open', {
|
|
111
|
+
reason: 'half_open_limit_reached'
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
halfOpenRequests++
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
const result = await fn()
|
|
119
|
+
|
|
120
|
+
// Success handling
|
|
121
|
+
if (state === CircuitState.HALF_OPEN) {
|
|
122
|
+
successCount++
|
|
123
|
+
if (successCount >= cfg.successThreshold) {
|
|
124
|
+
const prev = state
|
|
125
|
+
state = CircuitState.CLOSED
|
|
126
|
+
failureCount = 0
|
|
127
|
+
cfg.onStateChange?.(service, prev, state, { failureCount: 0 })
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
// Reset failure count on success in CLOSED state
|
|
131
|
+
failureCount = 0
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return result
|
|
135
|
+
} catch (error) {
|
|
136
|
+
failureCount++
|
|
137
|
+
lastFailureTime = Date.now()
|
|
138
|
+
|
|
139
|
+
if (state === CircuitState.HALF_OPEN) {
|
|
140
|
+
// Any failure in HALF_OPEN immediately opens the circuit
|
|
141
|
+
const prev = state
|
|
142
|
+
state = CircuitState.OPEN
|
|
143
|
+
cfg.onStateChange?.(service, prev, state, { failureCount })
|
|
144
|
+
} else if (failureCount >= cfg.failureThreshold) {
|
|
145
|
+
// Threshold reached in CLOSED state
|
|
146
|
+
const prev = state
|
|
147
|
+
state = CircuitState.OPEN
|
|
148
|
+
cfg.onStateChange?.(service, prev, state, { failureCount })
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
throw error
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
|
|
155
|
+
getState: () => state,
|
|
156
|
+
getFailureCount: () => failureCount,
|
|
157
|
+
reset: () => {
|
|
158
|
+
state = CircuitState.CLOSED
|
|
159
|
+
failureCount = 0
|
|
160
|
+
successCount = 0
|
|
161
|
+
halfOpenRequests = 0
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Infrastructure error types for resilience utilities.
|
|
3
|
+
* These errors represent external service failures (not business logic errors).
|
|
4
|
+
* Map to HTTP 503 Service Unavailable.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Thrown when an external service operation times out.
|
|
9
|
+
* Maps to HTTP 503 Service Unavailable.
|
|
10
|
+
*/
|
|
11
|
+
export class ServiceTimeoutError extends Error {
|
|
12
|
+
readonly service: string
|
|
13
|
+
readonly timeoutMs: number
|
|
14
|
+
readonly operation?: string
|
|
15
|
+
readonly context?: Record<string, unknown>
|
|
16
|
+
|
|
17
|
+
constructor(
|
|
18
|
+
service: string,
|
|
19
|
+
timeoutMs: number,
|
|
20
|
+
operation?: string,
|
|
21
|
+
context?: Record<string, unknown>
|
|
22
|
+
) {
|
|
23
|
+
const op = operation ? `:${operation}` : ''
|
|
24
|
+
super(`${service}${op} timed out after ${timeoutMs}ms`)
|
|
25
|
+
this.name = 'ServiceTimeoutError'
|
|
26
|
+
this.service = service
|
|
27
|
+
this.timeoutMs = timeoutMs
|
|
28
|
+
this.operation = operation
|
|
29
|
+
this.context = context
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Thrown when an external service is unavailable (circuit open, repeated failures).
|
|
35
|
+
* Maps to HTTP 503 Service Unavailable.
|
|
36
|
+
*/
|
|
37
|
+
export class ServiceUnavailableError extends Error {
|
|
38
|
+
readonly service: string
|
|
39
|
+
readonly reason: 'circuit_open' | 'timeout' | 'connection_failed'
|
|
40
|
+
readonly context?: Record<string, unknown>
|
|
41
|
+
|
|
42
|
+
constructor(
|
|
43
|
+
service: string,
|
|
44
|
+
reason: 'circuit_open' | 'timeout' | 'connection_failed',
|
|
45
|
+
context?: Record<string, unknown>
|
|
46
|
+
) {
|
|
47
|
+
super(`${service} temporarily unavailable (${reason})`)
|
|
48
|
+
this.name = 'ServiceUnavailableError'
|
|
49
|
+
this.service = service
|
|
50
|
+
this.reason = reason
|
|
51
|
+
this.context = context
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Type guard to check if an error is an infrastructure error (ServiceTimeoutError or ServiceUnavailableError).
|
|
57
|
+
* Infrastructure errors should map to HTTP 503, not 401 or 500.
|
|
58
|
+
*/
|
|
59
|
+
export function isInfrastructureError(
|
|
60
|
+
error: unknown
|
|
61
|
+
): error is ServiceTimeoutError | ServiceUnavailableError {
|
|
62
|
+
if (error instanceof ServiceTimeoutError) return true
|
|
63
|
+
if (error instanceof ServiceUnavailableError) return true
|
|
64
|
+
|
|
65
|
+
// Also check for common network error codes
|
|
66
|
+
const code = (error as { code?: string })?.code
|
|
67
|
+
return code === 'ETIMEDOUT' || code === 'ECONNREFUSED' || code === 'ENOTFOUND'
|
|
68
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Error Mapper
|
|
3
|
+
*
|
|
4
|
+
* Shared utility for mapping HTTP status codes to ToolingError types.
|
|
5
|
+
* Used by all integration adapters for consistent error handling.
|
|
6
|
+
*
|
|
7
|
+
* Standard mapping:
|
|
8
|
+
* - 401/403 -> credentials_invalid (authentication failed)
|
|
9
|
+
* - 400/404/409 -> validation_error (non-retryable client errors)
|
|
10
|
+
* - 429 -> rate_limit_exceeded (retryable)
|
|
11
|
+
* - 500+ -> server_unavailable (retryable)
|
|
12
|
+
* - Other 4xx -> validation_error (non-retryable)
|
|
13
|
+
* - Other -> api_error (retryable)
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { ToolingError, type ToolingErrorType } from '../../execution/engine/tools/types'
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Context for HTTP error creation
|
|
20
|
+
*/
|
|
21
|
+
export interface HttpErrorContext {
|
|
22
|
+
integration: string
|
|
23
|
+
method: string
|
|
24
|
+
statusCode?: number
|
|
25
|
+
organizationId?: string
|
|
26
|
+
[key: string]: unknown
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Custom error parser function type
|
|
31
|
+
* Allows adapters to extract error messages from API-specific response formats
|
|
32
|
+
*/
|
|
33
|
+
export type ErrorParser = (responseBody: string) => string | undefined
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Map HTTP status code to ToolingError type
|
|
37
|
+
*
|
|
38
|
+
* Standard mapping used by all integration adapters:
|
|
39
|
+
* - 401/403 -> credentials_invalid (authentication failed)
|
|
40
|
+
* - 400/404/409 -> validation_error (non-retryable client errors)
|
|
41
|
+
* - 429 -> rate_limit_exceeded (retryable)
|
|
42
|
+
* - 500+ -> server_unavailable (retryable)
|
|
43
|
+
* - Other 4xx -> validation_error (non-retryable)
|
|
44
|
+
* - Other -> api_error (retryable)
|
|
45
|
+
*
|
|
46
|
+
* @param status - HTTP status code
|
|
47
|
+
* @returns ToolingErrorType for the status code
|
|
48
|
+
*/
|
|
49
|
+
export function mapHttpStatusToErrorType(status: number): ToolingErrorType {
|
|
50
|
+
if (status === 401 || status === 403) return 'credentials_invalid'
|
|
51
|
+
if (status === 404 || status === 400 || status === 409) return 'validation_error'
|
|
52
|
+
if (status === 429) return 'rate_limit_exceeded'
|
|
53
|
+
if (status >= 500) return 'server_unavailable'
|
|
54
|
+
if (status >= 400) return 'validation_error'
|
|
55
|
+
return 'api_error'
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Create ToolingError from HTTP response
|
|
60
|
+
*
|
|
61
|
+
* Reads response body, parses error message, and creates appropriate ToolingError.
|
|
62
|
+
* Supports custom error parser for API-specific response formats.
|
|
63
|
+
*
|
|
64
|
+
* @param response - Fetch Response object
|
|
65
|
+
* @param context - Error context (integration name, method, etc.)
|
|
66
|
+
* @param parseError - Optional custom parser for API-specific error formats
|
|
67
|
+
* @returns ToolingError with appropriate type and message
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* // Basic usage
|
|
71
|
+
* if (!response.ok) {
|
|
72
|
+
* throw await createHttpError(response, {
|
|
73
|
+
* integration: 'attio',
|
|
74
|
+
* method: 'listRecords',
|
|
75
|
+
* listId
|
|
76
|
+
* })
|
|
77
|
+
* }
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* // With custom error parser
|
|
81
|
+
* if (!response.ok) {
|
|
82
|
+
* throw await createHttpError(
|
|
83
|
+
* response,
|
|
84
|
+
* { integration: 'attio', method: 'createRecord' },
|
|
85
|
+
* (body) => {
|
|
86
|
+
* const json = JSON.parse(body)
|
|
87
|
+
* return json.message
|
|
88
|
+
* }
|
|
89
|
+
* )
|
|
90
|
+
* }
|
|
91
|
+
*/
|
|
92
|
+
export async function createHttpError(
|
|
93
|
+
response: Response,
|
|
94
|
+
context: HttpErrorContext,
|
|
95
|
+
parseError?: ErrorParser
|
|
96
|
+
): Promise<ToolingError> {
|
|
97
|
+
const errorText = await response.text()
|
|
98
|
+
let message = `${context.integration} API error: ${response.status} ${response.statusText}`
|
|
99
|
+
|
|
100
|
+
// Try custom parser first, then generic JSON parsing
|
|
101
|
+
if (parseError) {
|
|
102
|
+
try {
|
|
103
|
+
const parsed = parseError(errorText)
|
|
104
|
+
if (parsed) message = parsed
|
|
105
|
+
} catch {
|
|
106
|
+
// Custom parser failed, fall through to generic parsing
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Generic JSON parsing if no custom parser or custom parser didn't return a message
|
|
111
|
+
if (!parseError || message.includes('API error:')) {
|
|
112
|
+
try {
|
|
113
|
+
const json = JSON.parse(errorText)
|
|
114
|
+
const parsedMessage = json.message || json.error?.message
|
|
115
|
+
if (parsedMessage) message = parsedMessage
|
|
116
|
+
} catch {
|
|
117
|
+
// Response is not JSON, use raw text if available
|
|
118
|
+
if (errorText && errorText.length < 500) {
|
|
119
|
+
message = errorText
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return new ToolingError(
|
|
125
|
+
mapHttpStatusToErrorType(response.status),
|
|
126
|
+
message,
|
|
127
|
+
{ ...context, statusCode: response.status }
|
|
128
|
+
)
|
|
129
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resilience utilities for protecting against external service failures.
|
|
3
|
+
*
|
|
4
|
+
* This module provides:
|
|
5
|
+
* - Timeout wrappers for external service calls
|
|
6
|
+
* - Circuit breaker pattern for preventing cascading failures
|
|
7
|
+
* - Infrastructure error types for proper error classification
|
|
8
|
+
* - Rate limiting (token bucket algorithm)
|
|
9
|
+
* - Retry with exponential backoff
|
|
10
|
+
* - HTTP error mapping
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import {
|
|
15
|
+
* withTimeout,
|
|
16
|
+
* SERVICE_TIMEOUTS,
|
|
17
|
+
* createCircuitBreaker,
|
|
18
|
+
* ServiceTimeoutError,
|
|
19
|
+
* ServiceUnavailableError,
|
|
20
|
+
* isInfrastructureError,
|
|
21
|
+
* withRetry,
|
|
22
|
+
* DEFAULT_RETRY_POLICY,
|
|
23
|
+
* createRateLimiter,
|
|
24
|
+
* createHttpError
|
|
25
|
+
* } from '@repo/core/resilience'
|
|
26
|
+
*
|
|
27
|
+
* // Wrap external calls with timeout
|
|
28
|
+
* const result = await withTimeout(
|
|
29
|
+
* externalService.call(),
|
|
30
|
+
* SERVICE_TIMEOUTS.WORKOS_JWT,
|
|
31
|
+
* 'ServiceName',
|
|
32
|
+
* 'operation'
|
|
33
|
+
* )
|
|
34
|
+
*
|
|
35
|
+
* // Use circuit breaker for services with repeated failures
|
|
36
|
+
* const breaker = createCircuitBreaker('my-service')
|
|
37
|
+
* const data = await breaker.execute(() => myService.fetch())
|
|
38
|
+
*
|
|
39
|
+
* // Use retry with exponential backoff
|
|
40
|
+
* const response = await withRetry(
|
|
41
|
+
* () => fetch('/api/data'),
|
|
42
|
+
* DEFAULT_RETRY_POLICY
|
|
43
|
+
* )
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
// Error types
|
|
48
|
+
export {
|
|
49
|
+
ServiceTimeoutError,
|
|
50
|
+
ServiceUnavailableError,
|
|
51
|
+
isInfrastructureError
|
|
52
|
+
} from './errors'
|
|
53
|
+
|
|
54
|
+
// Timeout utility
|
|
55
|
+
export { withTimeout, SERVICE_TIMEOUTS } from './timeout'
|
|
56
|
+
|
|
57
|
+
// Circuit breaker
|
|
58
|
+
export {
|
|
59
|
+
createCircuitBreaker,
|
|
60
|
+
CircuitState,
|
|
61
|
+
type CircuitBreaker,
|
|
62
|
+
type CircuitBreakerConfig
|
|
63
|
+
} from './circuit-breaker'
|
|
64
|
+
|
|
65
|
+
// Rate limiting
|
|
66
|
+
export {
|
|
67
|
+
InMemoryRateLimiter,
|
|
68
|
+
createRateLimiter
|
|
69
|
+
} from './rate-limiter'
|
|
70
|
+
|
|
71
|
+
// Retry logic
|
|
72
|
+
export {
|
|
73
|
+
withRetry,
|
|
74
|
+
calculateRetryDelay,
|
|
75
|
+
sleep
|
|
76
|
+
} from './retry'
|
|
77
|
+
|
|
78
|
+
// Rate limiter types
|
|
79
|
+
export {
|
|
80
|
+
type RateLimiter,
|
|
81
|
+
type RetryPolicy
|
|
82
|
+
} from './rate-limiter-types'
|
|
83
|
+
|
|
84
|
+
// Retry policy constant (canonical source: constants/resilience)
|
|
85
|
+
export { DEFAULT_RETRY_POLICY } from '../constants/resilience'
|
|
86
|
+
|
|
87
|
+
// HTTP error mapping
|
|
88
|
+
export {
|
|
89
|
+
createHttpError,
|
|
90
|
+
mapHttpStatusToErrorType,
|
|
91
|
+
type HttpErrorContext,
|
|
92
|
+
type ErrorParser
|
|
93
|
+
} from './http-error-mapper'
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utility types for integration tools
|
|
3
|
+
*
|
|
4
|
+
* These types define the interfaces for rate limiting and retry logic
|
|
5
|
+
* that are used by integration tools.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Rate limiter interface
|
|
10
|
+
* Implements token bucket algorithm for rate limiting
|
|
11
|
+
*/
|
|
12
|
+
export interface RateLimiter {
|
|
13
|
+
/**
|
|
14
|
+
* Check if request is allowed
|
|
15
|
+
* @param key - Rate limit key (e.g., '${organizationId}:${integration}')
|
|
16
|
+
* @returns true if allowed, false if rate limited
|
|
17
|
+
*/
|
|
18
|
+
allow(key: string): Promise<boolean>
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Get remaining tokens for key
|
|
22
|
+
* @param key - Rate limit key
|
|
23
|
+
* @returns Number of tokens remaining
|
|
24
|
+
*/
|
|
25
|
+
remaining(key: string): Promise<number>
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Reset rate limit for key
|
|
29
|
+
* @param key - Rate limit key
|
|
30
|
+
*/
|
|
31
|
+
reset(key: string): Promise<void>
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Retry policy configuration
|
|
36
|
+
*/
|
|
37
|
+
export interface RetryPolicy {
|
|
38
|
+
/** Maximum number of retry attempts */
|
|
39
|
+
maxRetries: number
|
|
40
|
+
/** Initial delay in ms (exponential backoff) */
|
|
41
|
+
initialDelayMs: number
|
|
42
|
+
/** Maximum delay in ms (cap for exponential backoff) */
|
|
43
|
+
maxDelayMs: number
|
|
44
|
+
/** Jitter factor (0-1, adds randomness to prevent thundering herd) */
|
|
45
|
+
jitterFactor: number
|
|
46
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type { RateLimiter } from './rate-limiter-types'
|
|
2
|
+
import { DEFAULT_RATE_LIMIT_CAPACITY, DEFAULT_RATE_LIMIT_WINDOW_MS, STALE_BUCKET_MULTIPLIER } from '../constants/resilience'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Token bucket state
|
|
6
|
+
*/
|
|
7
|
+
interface TokenBucket {
|
|
8
|
+
tokens: number
|
|
9
|
+
lastRefill: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* In-memory token bucket rate limiter
|
|
14
|
+
*
|
|
15
|
+
* Implements token bucket algorithm for rate limiting integration API calls.
|
|
16
|
+
* Default: 60 requests per minute per organization per integration.
|
|
17
|
+
*
|
|
18
|
+
* Pattern: Stateful class (justified - manages rate limit state)
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* const limiter = new InMemoryRateLimiter(60, 60000) // 60 req/min
|
|
22
|
+
* const allowed = await limiter.allow('org123:gmail')
|
|
23
|
+
* if (!allowed) {
|
|
24
|
+
* throw new ToolingError('rate_limit_exceeded', 'Rate limit exceeded')
|
|
25
|
+
* }
|
|
26
|
+
*/
|
|
27
|
+
export class InMemoryRateLimiter implements RateLimiter {
|
|
28
|
+
private buckets = new Map<string, TokenBucket>()
|
|
29
|
+
private lastEviction = Date.now()
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @param capacity - Maximum tokens (requests) allowed
|
|
33
|
+
* @param refillIntervalMs - Refill interval in milliseconds
|
|
34
|
+
*/
|
|
35
|
+
constructor(
|
|
36
|
+
private readonly capacity: number = DEFAULT_RATE_LIMIT_CAPACITY,
|
|
37
|
+
private readonly refillIntervalMs: number = DEFAULT_RATE_LIMIT_WINDOW_MS
|
|
38
|
+
) {}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Check if request is allowed and consume token if available
|
|
42
|
+
*/
|
|
43
|
+
async allow(key: string): Promise<boolean> {
|
|
44
|
+
const bucket = this.getOrCreateBucket(key)
|
|
45
|
+
this.refillBucket(bucket)
|
|
46
|
+
|
|
47
|
+
if (bucket.tokens > 0) {
|
|
48
|
+
bucket.tokens -= 1
|
|
49
|
+
return true
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return false
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get remaining tokens for key
|
|
57
|
+
*/
|
|
58
|
+
async remaining(key: string): Promise<number> {
|
|
59
|
+
const bucket = this.getOrCreateBucket(key)
|
|
60
|
+
this.refillBucket(bucket)
|
|
61
|
+
return Math.floor(bucket.tokens)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Reset rate limit for key (removes bucket)
|
|
66
|
+
*/
|
|
67
|
+
async reset(key: string): Promise<void> {
|
|
68
|
+
this.buckets.delete(key)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get or create token bucket for key
|
|
73
|
+
* Lazily evicts stale buckets to prevent memory leaks
|
|
74
|
+
*/
|
|
75
|
+
private getOrCreateBucket(key: string): TokenBucket {
|
|
76
|
+
this.evictStaleBuckets()
|
|
77
|
+
|
|
78
|
+
let bucket = this.buckets.get(key)
|
|
79
|
+
if (!bucket) {
|
|
80
|
+
bucket = {
|
|
81
|
+
tokens: this.capacity,
|
|
82
|
+
lastRefill: Date.now()
|
|
83
|
+
}
|
|
84
|
+
this.buckets.set(key, bucket)
|
|
85
|
+
}
|
|
86
|
+
return bucket
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Evict buckets that haven't been accessed in 5x the refill interval
|
|
91
|
+
* Runs at most once per refill interval to avoid overhead
|
|
92
|
+
*/
|
|
93
|
+
private evictStaleBuckets(): void {
|
|
94
|
+
const now = Date.now()
|
|
95
|
+
if (now - this.lastEviction < this.refillIntervalMs) return
|
|
96
|
+
this.lastEviction = now
|
|
97
|
+
|
|
98
|
+
const staleThreshold = this.refillIntervalMs * STALE_BUCKET_MULTIPLIER
|
|
99
|
+
for (const [key, bucket] of this.buckets) {
|
|
100
|
+
if (now - bucket.lastRefill > staleThreshold) {
|
|
101
|
+
this.buckets.delete(key)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Refill bucket based on time elapsed
|
|
108
|
+
* Uses linear refill: tokens added = (elapsed / interval) * capacity
|
|
109
|
+
*/
|
|
110
|
+
private refillBucket(bucket: TokenBucket): void {
|
|
111
|
+
const now = Date.now()
|
|
112
|
+
const elapsed = now - bucket.lastRefill
|
|
113
|
+
|
|
114
|
+
if (elapsed >= this.refillIntervalMs) {
|
|
115
|
+
// Full refill if interval passed
|
|
116
|
+
bucket.tokens = this.capacity
|
|
117
|
+
bucket.lastRefill = now
|
|
118
|
+
} else {
|
|
119
|
+
// Partial refill based on elapsed time
|
|
120
|
+
const tokensToAdd = (elapsed / this.refillIntervalMs) * this.capacity
|
|
121
|
+
bucket.tokens = Math.min(this.capacity, bucket.tokens + tokensToAdd)
|
|
122
|
+
bucket.lastRefill = now
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Clear all buckets (for testing)
|
|
128
|
+
*/
|
|
129
|
+
clearAll(): void {
|
|
130
|
+
this.buckets.clear()
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Create default rate limiter instance
|
|
136
|
+
* 60 requests per minute per organization per integration
|
|
137
|
+
*/
|
|
138
|
+
export function createRateLimiter(): RateLimiter {
|
|
139
|
+
return new InMemoryRateLimiter(DEFAULT_RATE_LIMIT_CAPACITY, DEFAULT_RATE_LIMIT_WINDOW_MS)
|
|
140
|
+
}
|