@elevasis/core 0.7.0 → 0.8.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/package.json +3 -3
- package/src/README.md +41 -41
- package/src/__tests__/publish.test.ts +18 -18
- package/src/__tests__/{template-foundations-compatibility.test.ts → template-core-compatibility.test.ts} +99 -99
- package/src/_gen/__tests__/__snapshots__/contracts.md.snap +1135 -1131
- package/src/_gen/__tests__/scaffold-contracts.test.ts +53 -53
- package/src/_gen/scaffold-contracts.ts +45 -45
- package/src/auth/multi-tenancy/credentials/README.md +38 -38
- package/src/auth/multi-tenancy/credentials/index.ts +6 -6
- package/src/auth/multi-tenancy/credentials/server/encryption.ts +39 -39
- package/src/auth/multi-tenancy/credentials/server/service.ts +60 -60
- package/src/auth/multi-tenancy/index.ts +17 -17
- package/src/auth/multi-tenancy/invitations/api-schemas.ts +107 -107
- package/src/auth/multi-tenancy/invitations/index.ts +37 -37
- package/src/auth/multi-tenancy/invitations/invitation.ts +86 -86
- package/src/auth/multi-tenancy/invitations/server/index.ts +25 -25
- package/src/auth/multi-tenancy/invitations/server/transforms.ts +24 -24
- package/src/auth/multi-tenancy/invitations/server/workos.ts +24 -24
- package/src/auth/multi-tenancy/invitations/supabase.ts +50 -50
- package/src/auth/multi-tenancy/memberships/api-schemas.ts +126 -126
- package/src/auth/multi-tenancy/memberships/index.ts +21 -21
- package/src/auth/multi-tenancy/memberships/membership.ts +138 -138
- package/src/auth/multi-tenancy/memberships/server/index.ts +15 -15
- package/src/auth/multi-tenancy/memberships/server/transforms.ts +32 -32
- package/src/auth/multi-tenancy/memberships/server/workos.ts +21 -21
- package/src/auth/multi-tenancy/memberships/supabase.ts +46 -46
- package/src/auth/multi-tenancy/organizations/api-schemas.ts +128 -128
- package/src/auth/multi-tenancy/organizations/index.ts +23 -23
- package/src/auth/multi-tenancy/organizations/organization.ts +24 -24
- package/src/auth/multi-tenancy/organizations/server/index.ts +10 -10
- package/src/auth/multi-tenancy/organizations/server/transforms.ts +35 -35
- package/src/auth/multi-tenancy/organizations/server/workos.ts +20 -20
- package/src/auth/multi-tenancy/types.ts +83 -83
- package/src/auth/multi-tenancy/users/api-schemas.ts +194 -194
- package/src/auth/multi-tenancy/users/index.ts +27 -27
- package/src/auth/multi-tenancy/users/server/index.ts +19 -19
- package/src/auth/multi-tenancy/users/server/transforms.ts +21 -21
- package/src/auth/multi-tenancy/users/server/workos.ts +16 -16
- package/src/auth/multi-tenancy/users/user.ts +65 -65
- package/src/business/README.md +52 -52
- package/src/business/__tests__/entities-published.test.ts +33 -33
- package/src/business/acquisition/api-schemas.ts +759 -759
- package/src/business/acquisition/index.ts +109 -109
- package/src/business/acquisition/types.ts +402 -402
- package/src/business/base-entities.test.ts +481 -481
- package/src/business/base-entities.ts +241 -241
- package/src/business/entities-published.ts +24 -24
- package/src/business/index.ts +15 -15
- package/src/business/pdf/browser/pdfmake-browser.ts +229 -229
- package/src/business/pdf/index.ts +10 -10
- package/src/business/pdf/server/index.ts +21 -21
- package/src/business/pdf/server/themes/default.ts +8 -8
- package/src/business/pdf/server/themes/index.ts +9 -9
- package/src/business/pdf/server/themes/types.ts +8 -8
- package/src/business/pdf/types.ts +272 -272
- package/src/business/projects/index.ts +2 -1
- package/src/business/projects/sse-events.ts +21 -0
- package/src/business/projects/types.ts +89 -89
- package/src/business/sales/api-schemas.ts +75 -75
- package/src/business/seo/__tests__/linking.test.ts +549 -549
- package/src/business/seo/__tests__/types.test.ts +404 -404
- package/src/business/seo/index.ts +2 -2
- package/src/business/seo/linking.ts +281 -281
- package/src/business/seo/types.ts +199 -199
- package/src/commands/queue/index.ts +3 -3
- package/src/commands/queue/schemas.test.ts +593 -593
- package/src/commands/queue/schemas.ts +125 -125
- package/src/commands/queue/sse-events.ts +61 -61
- package/src/commands/queue/types/action.ts +52 -52
- package/src/commands/queue/types/checkpoint.ts +44 -44
- package/src/commands/queue/types/index.ts +7 -7
- package/src/commands/queue/types/task.ts +116 -116
- package/src/commands/queue/types.ts +14 -14
- package/src/content/distribution-metadata.ts +61 -61
- package/src/content/index.ts +10 -10
- package/src/deployments/index.ts +22 -22
- package/src/execution/core/__tests__/archived-logs.test.ts +72 -72
- package/src/execution/core/index.ts +11 -11
- package/src/execution/core/runner-types.ts +80 -80
- package/src/execution/core/server/environment.ts +31 -31
- package/src/execution/core/sse-executions.ts +119 -119
- package/src/execution/core/types.ts +29 -29
- package/src/execution/engine/__tests__/fixtures/test-agents.ts +4 -4
- package/src/execution/engine/__tests__/timeout.test.ts +565 -565
- package/src/execution/engine/agent/__tests__/errors.test.ts +508 -508
- package/src/execution/engine/agent/actions/__tests__/processor.test.ts +531 -531
- package/src/execution/engine/agent/actions/executor.ts +205 -205
- package/src/execution/engine/agent/actions/navigate-knowledge-executor.ts +230 -230
- package/src/execution/engine/agent/actions/processor.ts +116 -116
- package/src/execution/engine/agent/actions/types.ts +70 -70
- package/src/execution/engine/agent/core/agent.ts +810 -810
- package/src/execution/engine/agent/core/types.ts +155 -155
- package/src/execution/engine/agent/errors.ts +251 -251
- package/src/execution/engine/agent/index.ts +78 -78
- package/src/execution/engine/agent/knowledge-map/types.ts +106 -106
- package/src/execution/engine/agent/knowledge-map/utils.ts +101 -101
- package/src/execution/engine/agent/memory/__tests__/manager.test.ts +754 -754
- package/src/execution/engine/agent/memory/domains.ts +99 -99
- package/src/execution/engine/agent/memory/manager.ts +365 -365
- package/src/execution/engine/agent/memory/processor.ts +66 -66
- package/src/execution/engine/agent/memory/types.ts +90 -90
- package/src/execution/engine/agent/memory/utils.ts +134 -134
- package/src/execution/engine/agent/observability/logging.ts +467 -467
- package/src/execution/engine/agent/observability/types.ts +64 -64
- package/src/execution/engine/agent/reasoning/adapters/agent-adapter-helpers.ts +349 -349
- package/src/execution/engine/agent/reasoning/processor.ts +92 -92
- package/src/execution/engine/agent/reasoning/prompt-sections/base-actions.ts +134 -134
- package/src/execution/engine/agent/reasoning/prompt-sections/completion.ts +49 -49
- package/src/execution/engine/agent/reasoning/prompt-sections/knowledge-map.ts +93 -93
- package/src/execution/engine/agent/reasoning/prompt-sections/memory.ts +65 -65
- package/src/execution/engine/agent/reasoning/prompt-sections/tools.ts +44 -44
- package/src/execution/engine/agent/reasoning/request-builder.ts +169 -169
- package/src/execution/engine/agent/reasoning/types.ts +18 -18
- package/src/execution/engine/base/errors.ts +118 -118
- package/src/execution/engine/base/index.ts +2 -2
- package/src/execution/engine/base/logging.ts +31 -31
- package/src/execution/engine/base/serialization.ts +324 -324
- package/src/execution/engine/base/types.ts +126 -126
- package/src/execution/engine/base/utils.ts +41 -41
- package/src/execution/engine/index.ts +434 -434
- package/src/execution/engine/interface/index.ts +1 -1
- package/src/execution/engine/interface/types.ts +62 -62
- package/src/execution/engine/llm/__tests__/model-info.test.ts +50 -50
- package/src/execution/engine/llm/__tests__/model-validation.test.ts +321 -321
- package/src/execution/engine/llm/__tests__/response-schema-validator.test.ts +115 -115
- package/src/execution/engine/llm/adapters/__tests__/adapter-factory.test.ts +375 -375
- package/src/execution/engine/llm/adapters/__tests__/anthropic-adapter.test.ts +463 -463
- package/src/execution/engine/llm/adapters/__tests__/anthropic.integration.test.ts +177 -177
- package/src/execution/engine/llm/adapters/__tests__/google-adapter.test.ts +722 -722
- package/src/execution/engine/llm/adapters/__tests__/google.integration.test.ts +376 -376
- package/src/execution/engine/llm/adapters/__tests__/openai-adapter.test.ts +551 -551
- package/src/execution/engine/llm/adapters/__tests__/openrouter-adapter.test.ts +563 -563
- package/src/execution/engine/llm/adapters/__tests__/openrouter.integration.test.ts +105 -105
- package/src/execution/engine/llm/adapters/__tests__/universal-adapter.test.ts +537 -537
- package/src/execution/engine/llm/adapters/circuit-breaker.ts +147 -147
- package/src/execution/engine/llm/adapters/index.ts +17 -17
- package/src/execution/engine/llm/adapters/mock-adapter.ts +116 -116
- package/src/execution/engine/llm/adapters/server/adapter-factory.ts +130 -130
- package/src/execution/engine/llm/adapters/server/anthropic.ts +137 -137
- package/src/execution/engine/llm/adapters/server/google.ts +283 -283
- package/src/execution/engine/llm/adapters/server/index.ts +12 -12
- package/src/execution/engine/llm/adapters/server/openai.ts +206 -206
- package/src/execution/engine/llm/adapters/server/openrouter.ts +235 -235
- package/src/execution/engine/llm/adapters/universal-adapter.ts +230 -230
- package/src/execution/engine/llm/errors.ts +186 -186
- package/src/execution/engine/llm/model-info.ts +332 -332
- package/src/execution/engine/llm/response-schema-validator.ts +113 -113
- package/src/execution/engine/llm/types.ts +86 -86
- package/src/execution/engine/test-utils/index.ts +6 -6
- package/src/execution/engine/test-utils/mocks.ts +56 -56
- package/src/execution/engine/tools/integration/base-integration-adapter.ts +50 -50
- package/src/execution/engine/tools/integration/index.ts +53 -53
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-adapter.ts +73 -73
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-tools.ts +209 -209
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-company-email/index.ts +82 -82
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-decision-maker-email/index.ts +122 -122
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-person-email/index.ts +89 -89
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/verify-email/index.ts +84 -84
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/index.ts +16 -16
- package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +293 -293
- package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.ts +100 -100
- package/src/execution/engine/tools/integration/server/adapters/apify/apify-tools.ts +217 -217
- package/src/execution/engine/tools/integration/server/adapters/apify/fetch/get-dataset-items/index.ts +92 -92
- package/src/execution/engine/tools/integration/server/adapters/apify/fetch/run-actor/index.ts +218 -218
- package/src/execution/engine/tools/integration/server/adapters/apify/fetch/start-actor/index.ts +87 -87
- package/src/execution/engine/tools/integration/server/adapters/apify/index.ts +11 -11
- package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +361 -361
- package/src/execution/engine/tools/integration/server/adapters/attio/attio-adapter.ts +162 -162
- package/src/execution/engine/tools/integration/server/adapters/attio/attio-tools.ts +594 -594
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-attribute/index.ts +214 -214
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-note/index.ts +152 -152
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-record/index.ts +141 -141
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-note/index.ts +86 -86
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-record/index.ts +105 -105
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.ts +118 -118
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-attributes/index.ts +165 -165
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-notes/index.ts +96 -96
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-objects/index.ts +104 -104
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.ts +156 -156
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-attribute/index.ts +220 -220
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-record/index.ts +140 -140
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/utils/types.ts +146 -146
- package/src/execution/engine/tools/integration/server/adapters/attio/index.ts +31 -31
- package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +210 -210
- package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +104 -104
- package/src/execution/engine/tools/integration/server/adapters/google-sheets/__tests__/google-sheets.integration.test.ts +261 -261
- package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-adapter.ts +1189 -1189
- package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-tools.ts +641 -641
- package/src/execution/engine/tools/integration/server/adapters/google-sheets/index.ts +18 -18
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/activate-campaign/index.ts +86 -86
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/__tests__/index.test.ts +289 -289
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/index.ts +154 -154
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/__tests__/index.test.ts +325 -325
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/index.ts +153 -153
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-delete-leads/index.ts +84 -84
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-campaign/index.ts +125 -125
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-inbox-test/index.ts +107 -107
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/delete-campaign/index.ts +85 -85
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-account-health/index.ts +91 -91
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign/index.ts +92 -92
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/__tests__/index.test.ts +195 -195
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/index.ts +113 -113
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-daily-campaign-analytics/index.ts +104 -104
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-emails/index.ts +155 -155
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/__tests__/index.test.ts +196 -196
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/index.ts +102 -102
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/__tests__/index.test.ts +189 -189
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/index.ts +87 -87
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-leads/index.ts +112 -112
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/patch-lead/index.ts +76 -76
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/pause-campaign/index.ts +86 -86
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/remove-from-subsequence/index.ts +98 -98
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/send-reply/index.ts +126 -126
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/__tests__/index.test.ts +193 -193
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/index.ts +99 -99
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/__tests__/index.test.ts +621 -621
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/index.ts +125 -125
- package/src/execution/engine/tools/integration/server/adapters/instantly/index.ts +29 -29
- package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-adapter.ts +178 -178
- package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1473 -1473
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/check-credits/index.ts +59 -59
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/verify-email/index.ts +102 -102
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/index.ts +17 -17
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-adapter.ts +80 -80
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +102 -102
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/get-email/index.ts +102 -102
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +134 -134
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +75 -75
- package/src/execution/engine/tools/integration/server/adapters/resend/index.ts +27 -27
- package/src/execution/engine/tools/integration/server/adapters/resend/resend-adapter.ts +108 -108
- package/src/execution/engine/tools/integration/server/adapters/resend/resend-tools.ts +132 -132
- package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/create-envelope/index.ts +274 -274
- package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/download-document/index.ts +230 -230
- package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/get-envelope/index.ts +133 -133
- package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/void-envelope/index.ts +90 -90
- package/src/execution/engine/tools/integration/server/adapters/stripe/fetch/utils/types.ts +210 -210
- package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-adapter.ts +517 -517
- package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +309 -309
- package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/domain-search/index.ts +133 -133
- package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-finder/index.ts +122 -122
- package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-verifier/index.ts +111 -111
- package/src/execution/engine/tools/integration/server/adapters/tomba/index.ts +11 -11
- package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-adapter.ts +78 -78
- package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-tools.ts +222 -222
- package/src/execution/engine/tools/integration/server/index.ts +61 -61
- package/src/execution/engine/tools/integration/service.ts +161 -161
- package/src/execution/engine/tools/integration/tool.ts +253 -253
- package/src/execution/engine/tools/integration/types/anymailfinder.ts +74 -74
- package/src/execution/engine/tools/integration/types/apify.ts +92 -92
- package/src/execution/engine/tools/integration/types/index.ts +19 -19
- package/src/execution/engine/tools/integration/types/instantly.ts +557 -557
- package/src/execution/engine/tools/integration/types/millionverifier.ts +56 -56
- package/src/execution/engine/tools/integration/types/stripe.ts +162 -162
- package/src/execution/engine/tools/integration/types/tomba.ts +94 -94
- package/src/execution/engine/tools/lead-service-types.ts +884 -884
- package/src/execution/engine/tools/llm/index.ts +11 -11
- package/src/execution/engine/tools/llm/server/index.ts +8 -8
- package/src/execution/engine/tools/llm/server/llm-call-tool.ts +118 -118
- package/src/execution/engine/tools/platform/__tests__/pdf.test.ts +441 -441
- package/src/execution/engine/tools/platform/acquisition/company-tools.ts +248 -248
- package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +319 -319
- package/src/execution/engine/tools/platform/acquisition/index.ts +43 -43
- package/src/execution/engine/tools/platform/acquisition/list-tools.ts +148 -148
- package/src/execution/engine/tools/platform/acquisition/types.ts +260 -260
- package/src/execution/engine/tools/platform/email/index.ts +122 -122
- package/src/execution/engine/tools/platform/email/types.ts +96 -96
- package/src/execution/engine/tools/platform/index.ts +157 -157
- package/src/execution/engine/tools/platform/notification.ts +81 -81
- package/src/execution/engine/tools/platform/pdf/index.ts +110 -110
- package/src/execution/engine/tools/platform/pdf/types.ts +77 -77
- package/src/execution/engine/tools/platform/scheduler.ts +87 -87
- package/src/execution/engine/tools/platform/storage/index.ts +370 -370
- package/src/execution/engine/tools/platform/types.ts +148 -148
- package/src/execution/engine/tools/registry.ts +700 -699
- package/src/execution/engine/tools/tool-maps.ts +786 -786
- package/src/execution/engine/tools/types.ts +233 -233
- package/src/execution/engine/workflow/__tests__/errors.test.ts +139 -139
- package/src/execution/engine/workflow/errors.ts +63 -63
- package/src/execution/engine/workflow/helpers/index.ts +11 -11
- package/src/execution/engine/workflow/helpers/server/index.ts +8 -8
- package/src/execution/engine/workflow/helpers/server/llm-call.ts +93 -93
- package/src/execution/engine/workflow/index.ts +19 -19
- package/src/execution/engine/workflow/log-truncate.ts +26 -26
- package/src/execution/engine/workflow/logging.ts +191 -191
- package/src/execution/engine/workflow/types.ts +182 -182
- package/src/execution/engine/workflow/utils.ts +280 -280
- package/src/execution/engine/workflow/workflow.ts +168 -168
- package/src/execution/index.ts +3 -3
- package/src/execution/scheduler/__tests__/api-schemas.test.ts +733 -733
- package/src/execution/scheduler/__tests__/utils.test.ts +1009 -1009
- package/src/execution/scheduler/api-schemas.ts +296 -296
- package/src/execution/scheduler/index.ts +50 -50
- package/src/execution/scheduler/schemas.ts +264 -264
- package/src/execution/scheduler/types.ts +111 -111
- package/src/execution/scheduler/utils.ts +364 -364
- package/src/forms/index.ts +7 -7
- package/src/forms/schemas.ts +69 -69
- package/src/forms/types.ts +70 -70
- package/src/index.ts +71 -60
- package/src/integrations/credentials/__tests__/schemas.test.ts +82 -82
- package/src/integrations/credentials/__tests__/utils.test.ts +144 -144
- package/src/integrations/credentials/api-schemas.ts +143 -143
- package/src/integrations/credentials/index.ts +32 -32
- package/src/integrations/credentials/schemas.ts +164 -164
- package/src/integrations/credentials/utils.ts +59 -59
- package/src/integrations/oauth/__tests__/provider-registry.test.ts +59 -59
- package/src/integrations/oauth/api-schemas.ts +92 -92
- package/src/integrations/oauth/index.ts +19 -19
- package/src/integrations/oauth/provider-registry.ts +61 -61
- package/src/integrations/oauth/server/__tests__/refresh-concurrent.test.ts +183 -183
- package/src/integrations/oauth/server/__tests__/refresh.test.ts +577 -577
- package/src/integrations/oauth/server/credentials.ts +39 -39
- package/src/integrations/oauth/server/refresh.ts +214 -214
- package/src/integrations/oauth/types.ts +34 -34
- package/src/integrations/webhook-endpoints/__tests__/api-schemas.test.ts +318 -318
- package/src/integrations/webhook-endpoints/api-schemas.ts +102 -102
- package/src/integrations/webhook-endpoints/index.ts +28 -28
- package/src/integrations/webhook-endpoints/types.ts +51 -51
- package/src/operations/activities/api-schemas.ts +79 -79
- package/src/operations/activities/index.ts +9 -9
- package/src/operations/activities/sse-events.ts +30 -30
- package/src/operations/activities/types.ts +63 -63
- package/src/operations/debug-logs/client.ts +60 -60
- package/src/operations/debug-logs/debug-logger.ts +83 -83
- package/src/operations/debug-logs/index.ts +8 -8
- package/src/operations/debug-logs/server.ts +19 -19
- package/src/operations/debug-logs/types.ts +33 -33
- package/src/operations/index.ts +50 -50
- package/src/operations/notifications/api-schemas.ts +91 -91
- package/src/operations/notifications/index.ts +3 -3
- package/src/operations/notifications/sse-events.ts +21 -21
- package/src/operations/notifications/types.ts +47 -47
- package/src/operations/observability/__tests__/openrouter-cost-flow.test.ts +297 -297
- package/src/operations/observability/__tests__/utils.test.ts +54 -54
- package/src/operations/observability/ai-usage-collector.ts +64 -64
- package/src/operations/observability/index.ts +13 -13
- package/src/operations/observability/metrics-collector.ts +49 -49
- package/src/operations/observability/schemas.ts +39 -39
- package/src/operations/observability/types.ts +463 -463
- package/src/operations/observability/utils.ts +77 -77
- package/src/operations/sessions/__tests__/manager.test.ts +821 -821
- package/src/operations/sessions/index.ts +26 -26
- package/src/operations/sessions/server/manager.ts +90 -90
- package/src/operations/sessions/server/session.ts +180 -180
- package/src/operations/sessions/types.ts +98 -98
- package/src/operations/triggers/index.ts +12 -12
- package/src/operations/triggers/webhook/definitions/instantly-account-error.ts +44 -44
- package/src/operations/triggers/webhook/definitions/instantly-auto-reply-received.ts +51 -51
- package/src/operations/triggers/webhook/definitions/instantly-campaign-completed.ts +45 -45
- package/src/operations/triggers/webhook/definitions/instantly-email-bounced.ts +49 -49
- package/src/operations/triggers/webhook/definitions/instantly-lead-unsubscribed.ts +45 -45
- package/src/operations/triggers/webhook/definitions/instantly-reply-received.ts +54 -54
- package/src/operations/triggers/webhook/index.ts +35 -35
- package/src/operations/triggers/webhook/types.ts +74 -74
- package/src/organization-model/README.md +97 -97
- package/src/organization-model/__tests__/defaults.test.ts +175 -175
- package/src/organization-model/__tests__/domains/customers.test.ts +295 -295
- package/src/organization-model/__tests__/domains/goals.test.ts +479 -479
- package/src/organization-model/__tests__/domains/identity.test.ts +279 -279
- package/src/organization-model/__tests__/domains/navigation.test.ts +212 -212
- package/src/organization-model/__tests__/domains/offerings.test.ts +419 -419
- package/src/organization-model/__tests__/domains/operations.test.ts +203 -203
- package/src/organization-model/__tests__/domains/resource-mappings.test.ts +362 -362
- package/src/organization-model/__tests__/domains/roles.test.ts +347 -347
- package/src/organization-model/__tests__/domains/statuses.test.ts +243 -243
- package/src/organization-model/__tests__/foundation.test.ts +105 -105
- package/src/organization-model/__tests__/graph.test.ts +894 -894
- package/src/organization-model/__tests__/resolve.test.ts +690 -690
- package/src/organization-model/__tests__/schema.test.ts +407 -407
- package/src/organization-model/contracts.ts +14 -14
- package/src/organization-model/defaults.ts +148 -148
- package/src/organization-model/domains/branding.ts +22 -22
- package/src/organization-model/domains/customers.ts +75 -75
- package/src/organization-model/domains/features.ts +22 -22
- package/src/organization-model/domains/goals.ts +80 -80
- package/src/organization-model/domains/identity.ts +94 -94
- package/src/organization-model/domains/navigation.ts +391 -391
- package/src/organization-model/domains/offerings.ts +66 -66
- package/src/organization-model/domains/operations.ts +85 -85
- package/src/organization-model/domains/projects.ts +48 -48
- package/src/organization-model/domains/prospecting.ts +33 -33
- package/src/organization-model/domains/roles.ts +55 -55
- package/src/organization-model/domains/sales.ts +94 -94
- package/src/organization-model/domains/shared.ts +62 -62
- package/src/organization-model/domains/statuses.ts +130 -130
- package/src/organization-model/foundation.ts +97 -97
- package/src/organization-model/graph/build.ts +399 -399
- package/src/organization-model/graph/index.ts +4 -4
- package/src/organization-model/graph/schema.ts +48 -48
- package/src/organization-model/graph/types.ts +40 -40
- package/src/organization-model/index.ts +13 -13
- package/src/organization-model/organization-graph.mdx +272 -272
- package/src/organization-model/organization-model.mdx +320 -320
- package/src/organization-model/published.ts +85 -85
- package/src/organization-model/resolve.ts +66 -66
- package/src/organization-model/schema.ts +287 -287
- package/src/organization-model/types.ts +46 -46
- package/src/platform/api/index.ts +1 -1
- package/src/platform/api/types.ts +35 -35
- package/src/platform/constants/http.ts +37 -37
- package/src/platform/constants/index.ts +5 -5
- package/src/platform/constants/limits.ts +32 -32
- package/src/platform/constants/resilience.ts +51 -51
- package/src/platform/constants/timeouts.ts +20 -20
- package/src/platform/constants/versions.ts +3 -3
- package/src/platform/registry/__tests__/resource-registry-static.test.ts +347 -347
- package/src/platform/registry/__tests__/resource-registry.integration.test.ts +1028 -1028
- package/src/platform/registry/__tests__/resource-registry.list-executable.test.ts +393 -393
- package/src/platform/registry/__tests__/resource-registry.test.ts +2005 -2005
- package/src/platform/registry/__tests__/serialization.test.ts +1127 -1127
- package/src/platform/registry/command-view.ts +180 -180
- package/src/platform/registry/domains.ts +165 -165
- package/src/platform/registry/index.ts +93 -93
- package/src/platform/registry/reserved.ts +24 -24
- package/src/platform/registry/resource-metadata.ts +59 -59
- package/src/platform/registry/resource-registry.command-queue-groups.test.ts +129 -129
- package/src/platform/registry/resource-registry.ts +876 -876
- package/src/platform/registry/serialization.ts +273 -273
- package/src/platform/registry/serialized-types.ts +231 -231
- package/src/platform/registry/stats-types.ts +66 -66
- package/src/platform/registry/types.ts +404 -404
- package/src/platform/registry/validation.ts +513 -513
- package/src/platform/resilience/__tests__/rate-limiter.test.ts +471 -471
- package/src/platform/resilience/circuit-breaker.ts +164 -164
- package/src/platform/resilience/errors.ts +68 -68
- package/src/platform/resilience/http-error-mapper.ts +129 -129
- package/src/platform/resilience/index.ts +93 -93
- package/src/platform/resilience/rate-limiter-types.ts +46 -46
- package/src/platform/resilience/rate-limiter.ts +140 -140
- package/src/platform/resilience/retry.ts +89 -89
- package/src/platform/resilience/timeout.ts +63 -63
- package/src/platform/sse/events.ts +37 -34
- package/src/platform/sse/index.ts +7 -7
- package/src/platform/utils/__tests__/validation.test.ts +1083 -1083
- package/src/platform/utils/currency.ts +96 -96
- package/src/platform/utils/debounce.ts +52 -52
- package/src/platform/utils/error.ts +41 -41
- package/src/platform/utils/hmac.test.ts +97 -97
- package/src/platform/utils/index.ts +32 -32
- package/src/platform/utils/server/betterstack-logger.ts +210 -210
- package/src/platform/utils/server/hmac.ts +44 -44
- package/src/platform/utils/server/unsubscribe.ts +111 -111
- package/src/platform/utils/token-counter.ts +96 -96
- package/src/platform/utils/validation.ts +425 -425
- package/src/projects/api-schemas.ts +268 -268
- package/src/published.ts +1 -1
- package/src/reference/_generated/contracts.md +611 -607
- package/src/reference/glossary.md +105 -105
- package/src/requests/__tests__/api-schemas.test.ts +277 -277
- package/src/requests/api-schemas.ts +83 -83
- package/src/requests/index.ts +1 -1
- package/src/scaffold-registry/__tests__/index.test.ts +17 -0
- package/src/scaffold-registry/__tests__/schema.test.ts +329 -230
- package/src/scaffold-registry/index.ts +205 -189
- package/src/scaffold-registry/schema.ts +196 -128
- package/src/server.ts +272 -272
- package/src/supabase/database.types.ts +2719 -2719
- package/src/supabase/helpers.ts +20 -20
- package/src/supabase/index.ts +52 -52
- package/src/supabase/server/client.ts +58 -58
- package/src/test-utils/README.md +38 -38
- package/src/test-utils/browser-mocks.ts +54 -54
- package/src/test-utils/fixtures/api-keys.ts +52 -52
- package/src/test-utils/fixtures/index.ts +4 -4
- package/src/test-utils/fixtures/memberships.ts +80 -80
- package/src/test-utils/fixtures/organizations.ts +69 -69
- package/src/test-utils/fixtures/users.ts +79 -79
- package/src/test-utils/index.ts +11 -11
- package/src/test-utils/mocks/index.ts +2 -2
- package/src/test-utils/mocks/supabase.ts +142 -142
- package/src/test-utils/mocks/workos.ts +108 -108
- package/src/test-utils/rls/RLSTestContext.ts +556 -556
- package/src/test-utils/rls/index.ts +1 -1
|
@@ -1,230 +1,230 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Universal LLM Adapter
|
|
3
|
-
* Adds reliability (retry, circuit breaker) and observability (automatic token tracking) to ALL LLM calls
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { LLMAdapter, LLMGenerateRequest, LLMGenerateResponse } from '../types'
|
|
7
|
-
import type { LLMModel } from '../model-info'
|
|
8
|
-
import type { AIUsageCollector } from '../../../../operations/observability/ai-usage-collector'
|
|
9
|
-
import type { AICallContext, BaseAICall } from '../../../../operations/observability/types'
|
|
10
|
-
import { executeWithCircuitBreaker } from './circuit-breaker'
|
|
11
|
-
import { LLMResponseParseError, LLMInputBlockedError } from '../errors'
|
|
12
|
-
import { sanitizeUserInput } from '../input-sanitizer'
|
|
13
|
-
import { validateResponseSchema } from '../response-schema-validator'
|
|
14
|
-
import { LLM_MAX_ATTEMPTS, LLM_RETRY_DELAYS } from '../../../../platform/constants/resilience'
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Type guard to check if an object has HTTP status property
|
|
18
|
-
*/
|
|
19
|
-
interface ErrorWithStatus {
|
|
20
|
-
status: number
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Type guard to check if an object has message property
|
|
25
|
-
*/
|
|
26
|
-
interface ErrorWithMessage {
|
|
27
|
-
message: string
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Type guard for error with status
|
|
32
|
-
*/
|
|
33
|
-
function hasStatus(error: unknown): error is ErrorWithStatus {
|
|
34
|
-
return (
|
|
35
|
-
typeof error === 'object' &&
|
|
36
|
-
error !== null &&
|
|
37
|
-
'status' in error &&
|
|
38
|
-
typeof (error as ErrorWithStatus).status === 'number'
|
|
39
|
-
)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Type guard for error with message
|
|
44
|
-
*/
|
|
45
|
-
function hasMessage(error: unknown): error is ErrorWithMessage {
|
|
46
|
-
return (
|
|
47
|
-
typeof error === 'object' &&
|
|
48
|
-
error !== null &&
|
|
49
|
-
'message' in error &&
|
|
50
|
-
typeof (error as ErrorWithMessage).message === 'string'
|
|
51
|
-
)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Universal wrapper that adds reliability + observability to any LLM adapter
|
|
56
|
-
*
|
|
57
|
-
* Features:
|
|
58
|
-
* - Exponential backoff retry (3 attempts: 1s, 2s, 4s)
|
|
59
|
-
* - Circuit breaker for cascading failure prevention (shared per model)
|
|
60
|
-
* - Automatic token usage tracking with typed contexts
|
|
61
|
-
* - Automatic latency tracking
|
|
62
|
-
*
|
|
63
|
-
* Implements decorator pattern - delegates to base adapter
|
|
64
|
-
*
|
|
65
|
-
* Note: Base adapters may include optional 'usage' field in responses.
|
|
66
|
-
* This wrapper extracts usage for observability and strips it before returning to callers.
|
|
67
|
-
*/
|
|
68
|
-
export class UniversalLLMAdapter implements LLMAdapter {
|
|
69
|
-
constructor(
|
|
70
|
-
private baseAdapter: LLMAdapter,
|
|
71
|
-
private modelName: LLMModel,
|
|
72
|
-
private aiUsageCollector?: AIUsageCollector,
|
|
73
|
-
private callType?: BaseAICall['callType'],
|
|
74
|
-
private context?: AICallContext
|
|
75
|
-
) {}
|
|
76
|
-
|
|
77
|
-
async generate<T>(request: LLMGenerateRequest): Promise<LLMGenerateResponse<T>> {
|
|
78
|
-
// Sanitize user-role messages BEFORE retry/circuit breaker
|
|
79
|
-
// Blocked input is not transient (no retry) and not a service failure (no circuit breaker impact)
|
|
80
|
-
const sanitizedRequest = this.sanitizeRequest(request)
|
|
81
|
-
return this.withRetryAndTracking(async () => {
|
|
82
|
-
const response = await this.baseAdapter.generate<T>(sanitizedRequest)
|
|
83
|
-
|
|
84
|
-
// Validate output against responseSchema (throws retryable LLMResponseParseError)
|
|
85
|
-
if (sanitizedRequest.responseSchema) {
|
|
86
|
-
validateResponseSchema(response.output, sanitizedRequest.responseSchema)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return response
|
|
90
|
-
})
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Sanitize user-role messages for prompt injection attacks
|
|
95
|
-
* System and assistant messages are framework-generated and skipped
|
|
96
|
-
*
|
|
97
|
-
* @throws LLMInputBlockedError if 3+ distinct attack patterns detected
|
|
98
|
-
*/
|
|
99
|
-
private sanitizeRequest(request: LLMGenerateRequest): LLMGenerateRequest {
|
|
100
|
-
return {
|
|
101
|
-
...request,
|
|
102
|
-
messages: request.messages.map((msg) => {
|
|
103
|
-
if (msg.role !== 'user') return msg
|
|
104
|
-
const result = sanitizeUserInput(msg.content)
|
|
105
|
-
if (result.blocked) {
|
|
106
|
-
throw new LLMInputBlockedError(result.warnings)
|
|
107
|
-
}
|
|
108
|
-
return { ...msg, content: result.sanitized }
|
|
109
|
-
})
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Wraps LLM call with retry logic, circuit breaker, and observability tracking
|
|
115
|
-
*
|
|
116
|
-
* The circuit breaker wraps the entire retry loop - this ensures that:
|
|
117
|
-
* - Failures during retries are counted toward the circuit breaker threshold
|
|
118
|
-
* - The circuit opens after sustained failures across retry attempts
|
|
119
|
-
* - Success after retries properly records success to the circuit breaker
|
|
120
|
-
*/
|
|
121
|
-
private async withRetryAndTracking<T>(fn: () => Promise<LLMGenerateResponse<T>>): Promise<LLMGenerateResponse<T>> {
|
|
122
|
-
// Circuit breaker wraps the entire retry loop
|
|
123
|
-
return executeWithCircuitBreaker(this.modelName, async () => {
|
|
124
|
-
// Retry loop (max 3 attempts with exponential backoff)
|
|
125
|
-
let lastError: unknown
|
|
126
|
-
|
|
127
|
-
for (let attempt = 1; attempt <= LLM_MAX_ATTEMPTS; attempt++) {
|
|
128
|
-
try {
|
|
129
|
-
// Measure per-attempt latency (not cumulative across retries)
|
|
130
|
-
const startTime = Date.now()
|
|
131
|
-
|
|
132
|
-
// Execute LLM call
|
|
133
|
-
const response = await fn()
|
|
134
|
-
|
|
135
|
-
// Calculate latency for this attempt only
|
|
136
|
-
const latencyMs = Date.now() - startTime
|
|
137
|
-
|
|
138
|
-
// Extract usage from response (if available)
|
|
139
|
-
if (response.usage && this.aiUsageCollector) {
|
|
140
|
-
this.aiUsageCollector.record(
|
|
141
|
-
{
|
|
142
|
-
model: this.modelName,
|
|
143
|
-
inputTokens: response.usage.inputTokens,
|
|
144
|
-
outputTokens: response.usage.outputTokens,
|
|
145
|
-
latencyMs,
|
|
146
|
-
cost: response.cost // Pass actual cost from provider (e.g., OpenRouter)
|
|
147
|
-
},
|
|
148
|
-
this.callType,
|
|
149
|
-
this.context
|
|
150
|
-
)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Return response (usage hidden from callers by TypeScript interface)
|
|
154
|
-
return response
|
|
155
|
-
} catch (error) {
|
|
156
|
-
lastError = error
|
|
157
|
-
|
|
158
|
-
// Determine if error is retryable
|
|
159
|
-
const isRetryable = this.isRetryableError(error)
|
|
160
|
-
|
|
161
|
-
if (!isRetryable) {
|
|
162
|
-
// Non-retryable error (401, 400, etc.) - fail immediately
|
|
163
|
-
// Let the circuit breaker record this as a failure
|
|
164
|
-
throw error
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Retryable error (429, 500, 503, network) - retry with exponential backoff
|
|
168
|
-
if (attempt < LLM_MAX_ATTEMPTS) {
|
|
169
|
-
const delay = LLM_RETRY_DELAYS[attempt - 1]
|
|
170
|
-
await this.sleep(delay)
|
|
171
|
-
}
|
|
172
|
-
// If this was the last attempt, the loop ends and we throw below
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// All retries failed - throw to let circuit breaker record failure
|
|
177
|
-
throw lastError
|
|
178
|
-
})
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Determine if error should be retried
|
|
183
|
-
*/
|
|
184
|
-
private isRetryableError(error: unknown): boolean {
|
|
185
|
-
if (!error || typeof error !== 'object') return false
|
|
186
|
-
|
|
187
|
-
// LLMResponseParseError is always retryable (transient JSON parse failures)
|
|
188
|
-
if (error instanceof LLMResponseParseError) {
|
|
189
|
-
return true
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Check for HTTP status codes using type guard
|
|
193
|
-
if (hasStatus(error)) {
|
|
194
|
-
const status = error.status
|
|
195
|
-
|
|
196
|
-
// Retryable: Rate limits, server errors, service unavailable
|
|
197
|
-
if (status === 429 || status === 500 || status === 503) {
|
|
198
|
-
return true
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Non-retryable: Auth errors, bad requests
|
|
202
|
-
if (status === 401 || status === 400 || status === 403) {
|
|
203
|
-
return false
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Check for network errors using type guard
|
|
208
|
-
if (hasMessage(error)) {
|
|
209
|
-
const message = error.message
|
|
210
|
-
if (
|
|
211
|
-
message.includes('ECONNRESET') ||
|
|
212
|
-
message.includes('ETIMEDOUT') ||
|
|
213
|
-
message.includes('ENOTFOUND') ||
|
|
214
|
-
message.includes('network')
|
|
215
|
-
) {
|
|
216
|
-
return true
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// Default: don't retry unknown errors
|
|
221
|
-
return false
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Sleep utility for retry delays
|
|
226
|
-
*/
|
|
227
|
-
private sleep(ms: number): Promise<void> {
|
|
228
|
-
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
229
|
-
}
|
|
230
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Universal LLM Adapter
|
|
3
|
+
* Adds reliability (retry, circuit breaker) and observability (automatic token tracking) to ALL LLM calls
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { LLMAdapter, LLMGenerateRequest, LLMGenerateResponse } from '../types'
|
|
7
|
+
import type { LLMModel } from '../model-info'
|
|
8
|
+
import type { AIUsageCollector } from '../../../../operations/observability/ai-usage-collector'
|
|
9
|
+
import type { AICallContext, BaseAICall } from '../../../../operations/observability/types'
|
|
10
|
+
import { executeWithCircuitBreaker } from './circuit-breaker'
|
|
11
|
+
import { LLMResponseParseError, LLMInputBlockedError } from '../errors'
|
|
12
|
+
import { sanitizeUserInput } from '../input-sanitizer'
|
|
13
|
+
import { validateResponseSchema } from '../response-schema-validator'
|
|
14
|
+
import { LLM_MAX_ATTEMPTS, LLM_RETRY_DELAYS } from '../../../../platform/constants/resilience'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Type guard to check if an object has HTTP status property
|
|
18
|
+
*/
|
|
19
|
+
interface ErrorWithStatus {
|
|
20
|
+
status: number
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Type guard to check if an object has message property
|
|
25
|
+
*/
|
|
26
|
+
interface ErrorWithMessage {
|
|
27
|
+
message: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Type guard for error with status
|
|
32
|
+
*/
|
|
33
|
+
function hasStatus(error: unknown): error is ErrorWithStatus {
|
|
34
|
+
return (
|
|
35
|
+
typeof error === 'object' &&
|
|
36
|
+
error !== null &&
|
|
37
|
+
'status' in error &&
|
|
38
|
+
typeof (error as ErrorWithStatus).status === 'number'
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Type guard for error with message
|
|
44
|
+
*/
|
|
45
|
+
function hasMessage(error: unknown): error is ErrorWithMessage {
|
|
46
|
+
return (
|
|
47
|
+
typeof error === 'object' &&
|
|
48
|
+
error !== null &&
|
|
49
|
+
'message' in error &&
|
|
50
|
+
typeof (error as ErrorWithMessage).message === 'string'
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Universal wrapper that adds reliability + observability to any LLM adapter
|
|
56
|
+
*
|
|
57
|
+
* Features:
|
|
58
|
+
* - Exponential backoff retry (3 attempts: 1s, 2s, 4s)
|
|
59
|
+
* - Circuit breaker for cascading failure prevention (shared per model)
|
|
60
|
+
* - Automatic token usage tracking with typed contexts
|
|
61
|
+
* - Automatic latency tracking
|
|
62
|
+
*
|
|
63
|
+
* Implements decorator pattern - delegates to base adapter
|
|
64
|
+
*
|
|
65
|
+
* Note: Base adapters may include optional 'usage' field in responses.
|
|
66
|
+
* This wrapper extracts usage for observability and strips it before returning to callers.
|
|
67
|
+
*/
|
|
68
|
+
export class UniversalLLMAdapter implements LLMAdapter {
|
|
69
|
+
constructor(
|
|
70
|
+
private baseAdapter: LLMAdapter,
|
|
71
|
+
private modelName: LLMModel,
|
|
72
|
+
private aiUsageCollector?: AIUsageCollector,
|
|
73
|
+
private callType?: BaseAICall['callType'],
|
|
74
|
+
private context?: AICallContext
|
|
75
|
+
) {}
|
|
76
|
+
|
|
77
|
+
async generate<T>(request: LLMGenerateRequest): Promise<LLMGenerateResponse<T>> {
|
|
78
|
+
// Sanitize user-role messages BEFORE retry/circuit breaker
|
|
79
|
+
// Blocked input is not transient (no retry) and not a service failure (no circuit breaker impact)
|
|
80
|
+
const sanitizedRequest = this.sanitizeRequest(request)
|
|
81
|
+
return this.withRetryAndTracking(async () => {
|
|
82
|
+
const response = await this.baseAdapter.generate<T>(sanitizedRequest)
|
|
83
|
+
|
|
84
|
+
// Validate output against responseSchema (throws retryable LLMResponseParseError)
|
|
85
|
+
if (sanitizedRequest.responseSchema) {
|
|
86
|
+
validateResponseSchema(response.output, sanitizedRequest.responseSchema)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return response
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Sanitize user-role messages for prompt injection attacks
|
|
95
|
+
* System and assistant messages are framework-generated and skipped
|
|
96
|
+
*
|
|
97
|
+
* @throws LLMInputBlockedError if 3+ distinct attack patterns detected
|
|
98
|
+
*/
|
|
99
|
+
private sanitizeRequest(request: LLMGenerateRequest): LLMGenerateRequest {
|
|
100
|
+
return {
|
|
101
|
+
...request,
|
|
102
|
+
messages: request.messages.map((msg) => {
|
|
103
|
+
if (msg.role !== 'user') return msg
|
|
104
|
+
const result = sanitizeUserInput(msg.content)
|
|
105
|
+
if (result.blocked) {
|
|
106
|
+
throw new LLMInputBlockedError(result.warnings)
|
|
107
|
+
}
|
|
108
|
+
return { ...msg, content: result.sanitized }
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Wraps LLM call with retry logic, circuit breaker, and observability tracking
|
|
115
|
+
*
|
|
116
|
+
* The circuit breaker wraps the entire retry loop - this ensures that:
|
|
117
|
+
* - Failures during retries are counted toward the circuit breaker threshold
|
|
118
|
+
* - The circuit opens after sustained failures across retry attempts
|
|
119
|
+
* - Success after retries properly records success to the circuit breaker
|
|
120
|
+
*/
|
|
121
|
+
private async withRetryAndTracking<T>(fn: () => Promise<LLMGenerateResponse<T>>): Promise<LLMGenerateResponse<T>> {
|
|
122
|
+
// Circuit breaker wraps the entire retry loop
|
|
123
|
+
return executeWithCircuitBreaker(this.modelName, async () => {
|
|
124
|
+
// Retry loop (max 3 attempts with exponential backoff)
|
|
125
|
+
let lastError: unknown
|
|
126
|
+
|
|
127
|
+
for (let attempt = 1; attempt <= LLM_MAX_ATTEMPTS; attempt++) {
|
|
128
|
+
try {
|
|
129
|
+
// Measure per-attempt latency (not cumulative across retries)
|
|
130
|
+
const startTime = Date.now()
|
|
131
|
+
|
|
132
|
+
// Execute LLM call
|
|
133
|
+
const response = await fn()
|
|
134
|
+
|
|
135
|
+
// Calculate latency for this attempt only
|
|
136
|
+
const latencyMs = Date.now() - startTime
|
|
137
|
+
|
|
138
|
+
// Extract usage from response (if available)
|
|
139
|
+
if (response.usage && this.aiUsageCollector) {
|
|
140
|
+
this.aiUsageCollector.record(
|
|
141
|
+
{
|
|
142
|
+
model: this.modelName,
|
|
143
|
+
inputTokens: response.usage.inputTokens,
|
|
144
|
+
outputTokens: response.usage.outputTokens,
|
|
145
|
+
latencyMs,
|
|
146
|
+
cost: response.cost // Pass actual cost from provider (e.g., OpenRouter)
|
|
147
|
+
},
|
|
148
|
+
this.callType,
|
|
149
|
+
this.context
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Return response (usage hidden from callers by TypeScript interface)
|
|
154
|
+
return response
|
|
155
|
+
} catch (error) {
|
|
156
|
+
lastError = error
|
|
157
|
+
|
|
158
|
+
// Determine if error is retryable
|
|
159
|
+
const isRetryable = this.isRetryableError(error)
|
|
160
|
+
|
|
161
|
+
if (!isRetryable) {
|
|
162
|
+
// Non-retryable error (401, 400, etc.) - fail immediately
|
|
163
|
+
// Let the circuit breaker record this as a failure
|
|
164
|
+
throw error
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Retryable error (429, 500, 503, network) - retry with exponential backoff
|
|
168
|
+
if (attempt < LLM_MAX_ATTEMPTS) {
|
|
169
|
+
const delay = LLM_RETRY_DELAYS[attempt - 1]
|
|
170
|
+
await this.sleep(delay)
|
|
171
|
+
}
|
|
172
|
+
// If this was the last attempt, the loop ends and we throw below
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// All retries failed - throw to let circuit breaker record failure
|
|
177
|
+
throw lastError
|
|
178
|
+
})
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Determine if error should be retried
|
|
183
|
+
*/
|
|
184
|
+
private isRetryableError(error: unknown): boolean {
|
|
185
|
+
if (!error || typeof error !== 'object') return false
|
|
186
|
+
|
|
187
|
+
// LLMResponseParseError is always retryable (transient JSON parse failures)
|
|
188
|
+
if (error instanceof LLMResponseParseError) {
|
|
189
|
+
return true
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Check for HTTP status codes using type guard
|
|
193
|
+
if (hasStatus(error)) {
|
|
194
|
+
const status = error.status
|
|
195
|
+
|
|
196
|
+
// Retryable: Rate limits, server errors, service unavailable
|
|
197
|
+
if (status === 429 || status === 500 || status === 503) {
|
|
198
|
+
return true
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Non-retryable: Auth errors, bad requests
|
|
202
|
+
if (status === 401 || status === 400 || status === 403) {
|
|
203
|
+
return false
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Check for network errors using type guard
|
|
208
|
+
if (hasMessage(error)) {
|
|
209
|
+
const message = error.message
|
|
210
|
+
if (
|
|
211
|
+
message.includes('ECONNRESET') ||
|
|
212
|
+
message.includes('ETIMEDOUT') ||
|
|
213
|
+
message.includes('ENOTFOUND') ||
|
|
214
|
+
message.includes('network')
|
|
215
|
+
) {
|
|
216
|
+
return true
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Default: don't retry unknown errors
|
|
221
|
+
return false
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Sleep utility for retry delays
|
|
226
|
+
*/
|
|
227
|
+
private sleep(ms: number): Promise<void> {
|
|
228
|
+
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
229
|
+
}
|
|
230
|
+
}
|