@elevasis/core 0.7.1 → 0.8.2
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/test-utils/index.d.ts +3122 -0
- package/dist/test-utils/index.js +386 -0
- package/package.json +6 -1
- package/src/README.md +39 -36
- package/src/__tests__/publish.test.ts +18 -13
- 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 +47 -36
- 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 -2
- package/src/business/projects/sse-events.ts +21 -21
- 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 -700
- 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 -37
- 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 +607 -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 +30 -138
- 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 +7 -8
- 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/published.ts +4 -0
- package/src/test-utils/rls/RLSTestContext.ts +554 -554
- package/src/test-utils/rls/index.ts +1 -1
|
@@ -1,283 +1,283 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Google Gemini Adapter
|
|
3
|
-
* Stateless translation layer between universal protocol and Google GenAI SDK
|
|
4
|
-
*
|
|
5
|
-
* Responsibilities:
|
|
6
|
-
* 1. Translate LLMGenerateRequest to Google GenAI format
|
|
7
|
-
* 2. Transform JSON Schema to Gemini-compatible format (const -> enum, inline $ref)
|
|
8
|
-
* 3. Call Google GenAI SDK with structured output
|
|
9
|
-
* 4. Parse Google response
|
|
10
|
-
* 5. Translate back to LLMGenerateResponse
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import type { LLMAdapter, LLMGenerateRequest, LLMGenerateResponse } from '../../types'
|
|
14
|
-
import type { LLMModel, GoogleModel, ModelSpecificOptions } from '../../model-info'
|
|
15
|
-
import { LLMResponseParseError } from '../../errors'
|
|
16
|
-
import { bslogExternalServiceError, isSystemError } from '../../../../../platform/utils/server/betterstack-logger'
|
|
17
|
-
import { composeSignal } from './compose-signal'
|
|
18
|
-
import { DEFAULT_LLM_TIMEOUT } from '../../../../../platform/constants/timeouts'
|
|
19
|
-
|
|
20
|
-
// ============================================================================
|
|
21
|
-
// Schema Transformation for Gemini Compatibility
|
|
22
|
-
// ============================================================================
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Transform JSON Schema for Gemini API compatibility
|
|
26
|
-
*
|
|
27
|
-
* Gemini uses a subset of JSON Schema. This function handles:
|
|
28
|
-
* 1. const: "value" -> enum: ["value"] + type: "string" (const keyword not supported)
|
|
29
|
-
* 2. Inline $ref references from $defs (for schema reuse)
|
|
30
|
-
* 3. Remove $schema property (Gemini rejects it)
|
|
31
|
-
* 4. Add placeholder property to empty object types (Gemini requires non-empty properties)
|
|
32
|
-
* 5. Ensure objects with additionalProperties also have a properties field
|
|
33
|
-
*
|
|
34
|
-
* @param schema - JSON Schema object to transform
|
|
35
|
-
* @param definitions - Map of $defs for $ref resolution (built during traversal)
|
|
36
|
-
* @returns Gemini-compatible schema
|
|
37
|
-
*/
|
|
38
|
-
function transformSchemaForGemini(schema: unknown, definitions?: Record<string, unknown>): unknown {
|
|
39
|
-
// Base case: null, undefined, or primitive values pass through unchanged
|
|
40
|
-
if (!schema || typeof schema !== 'object') {
|
|
41
|
-
return schema
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const obj = schema as Record<string, unknown>
|
|
45
|
-
const result: Record<string, unknown> = {}
|
|
46
|
-
|
|
47
|
-
// Extract $defs at the current level for reference resolution
|
|
48
|
-
// These definitions are accumulated as we traverse down
|
|
49
|
-
if (obj.$defs && typeof obj.$defs === 'object') {
|
|
50
|
-
definitions = { ...definitions, ...(obj.$defs as Record<string, unknown>) }
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
54
|
-
// Skip $schema - Gemini doesn't accept JSON Schema meta-schema
|
|
55
|
-
if (key === '$schema') {
|
|
56
|
-
continue
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Skip $defs - definitions are inlined when $ref is encountered
|
|
60
|
-
if (key === '$defs') {
|
|
61
|
-
continue
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Handle $ref - inline the referenced definition
|
|
65
|
-
// Format: "#/$defs/DefinitionName"
|
|
66
|
-
if (key === '$ref' && typeof value === 'string') {
|
|
67
|
-
const refPath = value.replace('#/$defs/', '')
|
|
68
|
-
if (definitions?.[refPath]) {
|
|
69
|
-
// Return the inlined definition (transformed recursively)
|
|
70
|
-
return transformSchemaForGemini(definitions[refPath], definitions)
|
|
71
|
-
}
|
|
72
|
-
// Skip unresolvable refs - they would cause errors anyway
|
|
73
|
-
continue
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Transform const to enum - Gemini doesn't support JSON Schema const keyword
|
|
77
|
-
// const: "value" becomes type: "string", enum: ["value"]
|
|
78
|
-
// This handles z.literal() from Zod which generates const
|
|
79
|
-
// Note: Gemini requires type: "string" when enum is present
|
|
80
|
-
if (key === 'const') {
|
|
81
|
-
result.type = 'string'
|
|
82
|
-
result.enum = [value]
|
|
83
|
-
continue
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Recursively transform nested structures
|
|
87
|
-
if (Array.isArray(value)) {
|
|
88
|
-
// Transform each array element (e.g., anyOf, oneOf, allOf, items as tuple)
|
|
89
|
-
result[key] = value.map((item) => transformSchemaForGemini(item, definitions))
|
|
90
|
-
} else if (value && typeof value === 'object') {
|
|
91
|
-
// Transform nested objects (properties, items, additionalProperties, etc.)
|
|
92
|
-
result[key] = transformSchemaForGemini(value, definitions)
|
|
93
|
-
} else {
|
|
94
|
-
// Primitive values pass through unchanged
|
|
95
|
-
result[key] = value
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// SAFEGUARD: Gemini requires objects to have non-empty properties
|
|
100
|
-
// This handles several cases:
|
|
101
|
-
// 1. Object with empty properties: { type: "object", properties: {} }
|
|
102
|
-
// 2. Object with additionalProperties but no properties: { type: "object", additionalProperties: true }
|
|
103
|
-
// 3. Object with no properties field at all: { type: "object" }
|
|
104
|
-
//
|
|
105
|
-
// Google's API strictly requires properties to be non-empty for OBJECT type,
|
|
106
|
-
// even when additionalProperties is present.
|
|
107
|
-
if (result.type === 'object') {
|
|
108
|
-
const props = result.properties as Record<string, unknown> | undefined
|
|
109
|
-
|
|
110
|
-
if (!props || Object.keys(props).length === 0) {
|
|
111
|
-
// Use a property name that:
|
|
112
|
-
// 1. Google accepts (no underscore prefix)
|
|
113
|
-
// 2. Is clearly a placeholder (won't conflict with real data)
|
|
114
|
-
// 3. Is optional so it won't pollute required outputs
|
|
115
|
-
result.properties = {
|
|
116
|
-
placeholderField: {
|
|
117
|
-
type: 'string',
|
|
118
|
-
description: 'System placeholder for empty object schema. Ignore this field.'
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return result
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Google adapter configuration
|
|
129
|
-
*/
|
|
130
|
-
export interface GoogleAdapterConfig {
|
|
131
|
-
apiKey: string
|
|
132
|
-
model: GoogleModel
|
|
133
|
-
modelOptions?: ModelSpecificOptions
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Check if the model and provider combination is for Google
|
|
138
|
-
*
|
|
139
|
-
* @param model - Model identifier (e.g., 'gemini-3-flash-preview')
|
|
140
|
-
* @param provider - Provider name
|
|
141
|
-
* @returns True if this is a Google model configuration
|
|
142
|
-
*/
|
|
143
|
-
export function isGoogleModel(model: LLMModel, provider: string): model is GoogleModel {
|
|
144
|
-
return model.startsWith('gemini-') && provider === 'google'
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Google Gemini Adapter - Implements universal protocol
|
|
149
|
-
* Uses structured output via JSON schema for guaranteed schema compliance
|
|
150
|
-
*/
|
|
151
|
-
export class GoogleAdapter implements LLMAdapter {
|
|
152
|
-
private clientPromise: Promise<import('@google/genai').GoogleGenAI>
|
|
153
|
-
private model: GoogleModel
|
|
154
|
-
private modelOptions?: ModelSpecificOptions
|
|
155
|
-
|
|
156
|
-
constructor(config: GoogleAdapterConfig) {
|
|
157
|
-
// Lazy load Google GenAI SDK
|
|
158
|
-
this.clientPromise = import('@google/genai').then(
|
|
159
|
-
({ GoogleGenAI }) =>
|
|
160
|
-
new GoogleGenAI({
|
|
161
|
-
apiKey: config.apiKey
|
|
162
|
-
})
|
|
163
|
-
)
|
|
164
|
-
this.model = config.model
|
|
165
|
-
this.modelOptions = config.modelOptions
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Generate structured output from messages using Google Gemini
|
|
170
|
-
*
|
|
171
|
-
* @param request - Generic generation request
|
|
172
|
-
* @returns Structured output with usage metadata
|
|
173
|
-
*/
|
|
174
|
-
async generate<T>(request: LLMGenerateRequest): Promise<LLMGenerateResponse<T>> {
|
|
175
|
-
const ai = await this.clientPromise
|
|
176
|
-
|
|
177
|
-
try {
|
|
178
|
-
// Build config object for structured output
|
|
179
|
-
// Transform schema for Gemini compatibility (const -> enum, inline $ref)
|
|
180
|
-
const generateConfig: Record<string, unknown> = {
|
|
181
|
-
responseMimeType: 'application/json',
|
|
182
|
-
responseSchema: transformSchemaForGemini(request.responseSchema)
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Add thinking level if specified (Gemini 3 specific feature)
|
|
186
|
-
if (this.modelOptions && 'thinkingLevel' in this.modelOptions) {
|
|
187
|
-
generateConfig.thinkingConfig = {
|
|
188
|
-
thinkingLevel: this.modelOptions.thinkingLevel
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Add max tokens if specified
|
|
193
|
-
if (request.maxOutputTokens) {
|
|
194
|
-
generateConfig.maxOutputTokens = request.maxOutputTokens
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Convert messages to Gemini format
|
|
198
|
-
// Gemini uses 'model' role instead of 'assistant' for AI messages
|
|
199
|
-
// System messages need special handling - prepend to first user message or use systemInstruction
|
|
200
|
-
const systemMessages = request.messages.filter((msg) => msg.role === 'system')
|
|
201
|
-
const nonSystemMessages = request.messages.filter((msg) => msg.role !== 'system')
|
|
202
|
-
|
|
203
|
-
// Use systemInstruction for system messages if present
|
|
204
|
-
if (systemMessages.length > 0) {
|
|
205
|
-
generateConfig.systemInstruction = systemMessages.map((msg) => msg.content).join('\n\n')
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Convert remaining messages to Gemini content format
|
|
209
|
-
const contents = nonSystemMessages.map((msg) => ({
|
|
210
|
-
role: msg.role === 'assistant' ? 'model' : 'user',
|
|
211
|
-
parts: [{ text: msg.content }]
|
|
212
|
-
}))
|
|
213
|
-
|
|
214
|
-
const response = await ai.models.generateContent({
|
|
215
|
-
model: this.model,
|
|
216
|
-
contents,
|
|
217
|
-
config: { ...generateConfig, abortSignal: composeSignal(DEFAULT_LLM_TIMEOUT, request.signal) }
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
// Detect empty/blocked responses before parsing
|
|
221
|
-
// Gemini returns no text when: safety filters block output, prompt is blocked,
|
|
222
|
-
// model produces empty candidates, or finish reason is non-STOP
|
|
223
|
-
if (!response.text) {
|
|
224
|
-
const candidate = response.candidates?.[0]
|
|
225
|
-
const finishReason = candidate?.finishReason
|
|
226
|
-
const blockReason = response.promptFeedback?.blockReason
|
|
227
|
-
|
|
228
|
-
const reasons: string[] = []
|
|
229
|
-
if (blockReason) reasons.push(`prompt blocked: ${blockReason}`)
|
|
230
|
-
if (finishReason && finishReason !== 'STOP') reasons.push(`finish reason: ${finishReason}`)
|
|
231
|
-
if (!response.candidates?.length) reasons.push('no candidates returned')
|
|
232
|
-
|
|
233
|
-
const detail = reasons.length > 0 ? reasons.join(', ') : 'empty response.text with no diagnostic metadata'
|
|
234
|
-
|
|
235
|
-
throw new LLMResponseParseError(`Google Gemini returned no output (${detail})`, {
|
|
236
|
-
finishReason,
|
|
237
|
-
blockReason,
|
|
238
|
-
hasCandidates: (response.candidates?.length ?? 0) > 0
|
|
239
|
-
})
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// Parse structured output from response with error wrapping for retry support
|
|
243
|
-
let output: unknown
|
|
244
|
-
try {
|
|
245
|
-
output = JSON.parse(response.text)
|
|
246
|
-
} catch (error) {
|
|
247
|
-
if (error instanceof SyntaxError) {
|
|
248
|
-
throw new LLMResponseParseError(`Failed to parse LLM response as JSON: ${error.message}`, {
|
|
249
|
-
rawContent: response.text.substring(0, 500),
|
|
250
|
-
parseError: error.message
|
|
251
|
-
})
|
|
252
|
-
}
|
|
253
|
-
throw error
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Extract usage metadata for observability tracking
|
|
257
|
-
const usage = response.usageMetadata
|
|
258
|
-
? {
|
|
259
|
-
inputTokens: response.usageMetadata.promptTokenCount || 0,
|
|
260
|
-
outputTokens: response.usageMetadata.candidatesTokenCount || 0,
|
|
261
|
-
totalTokens: response.usageMetadata.totalTokenCount || 0
|
|
262
|
-
}
|
|
263
|
-
: undefined
|
|
264
|
-
|
|
265
|
-
// Return response with usage (wrapper will extract and strip it)
|
|
266
|
-
return {
|
|
267
|
-
output: output as T,
|
|
268
|
-
usage
|
|
269
|
-
}
|
|
270
|
-
} catch (error) {
|
|
271
|
-
// Add Better Stack logging for system errors (5xx only)
|
|
272
|
-
if (isSystemError(error)) {
|
|
273
|
-
bslogExternalServiceError('google-genai', 'models.generateContent', error as Error, {
|
|
274
|
-
model: this.model,
|
|
275
|
-
thinkingLevel:
|
|
276
|
-
this.modelOptions && 'thinkingLevel' in this.modelOptions ? this.modelOptions.thinkingLevel : undefined
|
|
277
|
-
})
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
throw error
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Google Gemini Adapter
|
|
3
|
+
* Stateless translation layer between universal protocol and Google GenAI SDK
|
|
4
|
+
*
|
|
5
|
+
* Responsibilities:
|
|
6
|
+
* 1. Translate LLMGenerateRequest to Google GenAI format
|
|
7
|
+
* 2. Transform JSON Schema to Gemini-compatible format (const -> enum, inline $ref)
|
|
8
|
+
* 3. Call Google GenAI SDK with structured output
|
|
9
|
+
* 4. Parse Google response
|
|
10
|
+
* 5. Translate back to LLMGenerateResponse
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { LLMAdapter, LLMGenerateRequest, LLMGenerateResponse } from '../../types'
|
|
14
|
+
import type { LLMModel, GoogleModel, ModelSpecificOptions } from '../../model-info'
|
|
15
|
+
import { LLMResponseParseError } from '../../errors'
|
|
16
|
+
import { bslogExternalServiceError, isSystemError } from '../../../../../platform/utils/server/betterstack-logger'
|
|
17
|
+
import { composeSignal } from './compose-signal'
|
|
18
|
+
import { DEFAULT_LLM_TIMEOUT } from '../../../../../platform/constants/timeouts'
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// Schema Transformation for Gemini Compatibility
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Transform JSON Schema for Gemini API compatibility
|
|
26
|
+
*
|
|
27
|
+
* Gemini uses a subset of JSON Schema. This function handles:
|
|
28
|
+
* 1. const: "value" -> enum: ["value"] + type: "string" (const keyword not supported)
|
|
29
|
+
* 2. Inline $ref references from $defs (for schema reuse)
|
|
30
|
+
* 3. Remove $schema property (Gemini rejects it)
|
|
31
|
+
* 4. Add placeholder property to empty object types (Gemini requires non-empty properties)
|
|
32
|
+
* 5. Ensure objects with additionalProperties also have a properties field
|
|
33
|
+
*
|
|
34
|
+
* @param schema - JSON Schema object to transform
|
|
35
|
+
* @param definitions - Map of $defs for $ref resolution (built during traversal)
|
|
36
|
+
* @returns Gemini-compatible schema
|
|
37
|
+
*/
|
|
38
|
+
function transformSchemaForGemini(schema: unknown, definitions?: Record<string, unknown>): unknown {
|
|
39
|
+
// Base case: null, undefined, or primitive values pass through unchanged
|
|
40
|
+
if (!schema || typeof schema !== 'object') {
|
|
41
|
+
return schema
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const obj = schema as Record<string, unknown>
|
|
45
|
+
const result: Record<string, unknown> = {}
|
|
46
|
+
|
|
47
|
+
// Extract $defs at the current level for reference resolution
|
|
48
|
+
// These definitions are accumulated as we traverse down
|
|
49
|
+
if (obj.$defs && typeof obj.$defs === 'object') {
|
|
50
|
+
definitions = { ...definitions, ...(obj.$defs as Record<string, unknown>) }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
54
|
+
// Skip $schema - Gemini doesn't accept JSON Schema meta-schema
|
|
55
|
+
if (key === '$schema') {
|
|
56
|
+
continue
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Skip $defs - definitions are inlined when $ref is encountered
|
|
60
|
+
if (key === '$defs') {
|
|
61
|
+
continue
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Handle $ref - inline the referenced definition
|
|
65
|
+
// Format: "#/$defs/DefinitionName"
|
|
66
|
+
if (key === '$ref' && typeof value === 'string') {
|
|
67
|
+
const refPath = value.replace('#/$defs/', '')
|
|
68
|
+
if (definitions?.[refPath]) {
|
|
69
|
+
// Return the inlined definition (transformed recursively)
|
|
70
|
+
return transformSchemaForGemini(definitions[refPath], definitions)
|
|
71
|
+
}
|
|
72
|
+
// Skip unresolvable refs - they would cause errors anyway
|
|
73
|
+
continue
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Transform const to enum - Gemini doesn't support JSON Schema const keyword
|
|
77
|
+
// const: "value" becomes type: "string", enum: ["value"]
|
|
78
|
+
// This handles z.literal() from Zod which generates const
|
|
79
|
+
// Note: Gemini requires type: "string" when enum is present
|
|
80
|
+
if (key === 'const') {
|
|
81
|
+
result.type = 'string'
|
|
82
|
+
result.enum = [value]
|
|
83
|
+
continue
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Recursively transform nested structures
|
|
87
|
+
if (Array.isArray(value)) {
|
|
88
|
+
// Transform each array element (e.g., anyOf, oneOf, allOf, items as tuple)
|
|
89
|
+
result[key] = value.map((item) => transformSchemaForGemini(item, definitions))
|
|
90
|
+
} else if (value && typeof value === 'object') {
|
|
91
|
+
// Transform nested objects (properties, items, additionalProperties, etc.)
|
|
92
|
+
result[key] = transformSchemaForGemini(value, definitions)
|
|
93
|
+
} else {
|
|
94
|
+
// Primitive values pass through unchanged
|
|
95
|
+
result[key] = value
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// SAFEGUARD: Gemini requires objects to have non-empty properties
|
|
100
|
+
// This handles several cases:
|
|
101
|
+
// 1. Object with empty properties: { type: "object", properties: {} }
|
|
102
|
+
// 2. Object with additionalProperties but no properties: { type: "object", additionalProperties: true }
|
|
103
|
+
// 3. Object with no properties field at all: { type: "object" }
|
|
104
|
+
//
|
|
105
|
+
// Google's API strictly requires properties to be non-empty for OBJECT type,
|
|
106
|
+
// even when additionalProperties is present.
|
|
107
|
+
if (result.type === 'object') {
|
|
108
|
+
const props = result.properties as Record<string, unknown> | undefined
|
|
109
|
+
|
|
110
|
+
if (!props || Object.keys(props).length === 0) {
|
|
111
|
+
// Use a property name that:
|
|
112
|
+
// 1. Google accepts (no underscore prefix)
|
|
113
|
+
// 2. Is clearly a placeholder (won't conflict with real data)
|
|
114
|
+
// 3. Is optional so it won't pollute required outputs
|
|
115
|
+
result.properties = {
|
|
116
|
+
placeholderField: {
|
|
117
|
+
type: 'string',
|
|
118
|
+
description: 'System placeholder for empty object schema. Ignore this field.'
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return result
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Google adapter configuration
|
|
129
|
+
*/
|
|
130
|
+
export interface GoogleAdapterConfig {
|
|
131
|
+
apiKey: string
|
|
132
|
+
model: GoogleModel
|
|
133
|
+
modelOptions?: ModelSpecificOptions
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Check if the model and provider combination is for Google
|
|
138
|
+
*
|
|
139
|
+
* @param model - Model identifier (e.g., 'gemini-3-flash-preview')
|
|
140
|
+
* @param provider - Provider name
|
|
141
|
+
* @returns True if this is a Google model configuration
|
|
142
|
+
*/
|
|
143
|
+
export function isGoogleModel(model: LLMModel, provider: string): model is GoogleModel {
|
|
144
|
+
return model.startsWith('gemini-') && provider === 'google'
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Google Gemini Adapter - Implements universal protocol
|
|
149
|
+
* Uses structured output via JSON schema for guaranteed schema compliance
|
|
150
|
+
*/
|
|
151
|
+
export class GoogleAdapter implements LLMAdapter {
|
|
152
|
+
private clientPromise: Promise<import('@google/genai').GoogleGenAI>
|
|
153
|
+
private model: GoogleModel
|
|
154
|
+
private modelOptions?: ModelSpecificOptions
|
|
155
|
+
|
|
156
|
+
constructor(config: GoogleAdapterConfig) {
|
|
157
|
+
// Lazy load Google GenAI SDK
|
|
158
|
+
this.clientPromise = import('@google/genai').then(
|
|
159
|
+
({ GoogleGenAI }) =>
|
|
160
|
+
new GoogleGenAI({
|
|
161
|
+
apiKey: config.apiKey
|
|
162
|
+
})
|
|
163
|
+
)
|
|
164
|
+
this.model = config.model
|
|
165
|
+
this.modelOptions = config.modelOptions
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Generate structured output from messages using Google Gemini
|
|
170
|
+
*
|
|
171
|
+
* @param request - Generic generation request
|
|
172
|
+
* @returns Structured output with usage metadata
|
|
173
|
+
*/
|
|
174
|
+
async generate<T>(request: LLMGenerateRequest): Promise<LLMGenerateResponse<T>> {
|
|
175
|
+
const ai = await this.clientPromise
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
// Build config object for structured output
|
|
179
|
+
// Transform schema for Gemini compatibility (const -> enum, inline $ref)
|
|
180
|
+
const generateConfig: Record<string, unknown> = {
|
|
181
|
+
responseMimeType: 'application/json',
|
|
182
|
+
responseSchema: transformSchemaForGemini(request.responseSchema)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Add thinking level if specified (Gemini 3 specific feature)
|
|
186
|
+
if (this.modelOptions && 'thinkingLevel' in this.modelOptions) {
|
|
187
|
+
generateConfig.thinkingConfig = {
|
|
188
|
+
thinkingLevel: this.modelOptions.thinkingLevel
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Add max tokens if specified
|
|
193
|
+
if (request.maxOutputTokens) {
|
|
194
|
+
generateConfig.maxOutputTokens = request.maxOutputTokens
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Convert messages to Gemini format
|
|
198
|
+
// Gemini uses 'model' role instead of 'assistant' for AI messages
|
|
199
|
+
// System messages need special handling - prepend to first user message or use systemInstruction
|
|
200
|
+
const systemMessages = request.messages.filter((msg) => msg.role === 'system')
|
|
201
|
+
const nonSystemMessages = request.messages.filter((msg) => msg.role !== 'system')
|
|
202
|
+
|
|
203
|
+
// Use systemInstruction for system messages if present
|
|
204
|
+
if (systemMessages.length > 0) {
|
|
205
|
+
generateConfig.systemInstruction = systemMessages.map((msg) => msg.content).join('\n\n')
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Convert remaining messages to Gemini content format
|
|
209
|
+
const contents = nonSystemMessages.map((msg) => ({
|
|
210
|
+
role: msg.role === 'assistant' ? 'model' : 'user',
|
|
211
|
+
parts: [{ text: msg.content }]
|
|
212
|
+
}))
|
|
213
|
+
|
|
214
|
+
const response = await ai.models.generateContent({
|
|
215
|
+
model: this.model,
|
|
216
|
+
contents,
|
|
217
|
+
config: { ...generateConfig, abortSignal: composeSignal(DEFAULT_LLM_TIMEOUT, request.signal) }
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
// Detect empty/blocked responses before parsing
|
|
221
|
+
// Gemini returns no text when: safety filters block output, prompt is blocked,
|
|
222
|
+
// model produces empty candidates, or finish reason is non-STOP
|
|
223
|
+
if (!response.text) {
|
|
224
|
+
const candidate = response.candidates?.[0]
|
|
225
|
+
const finishReason = candidate?.finishReason
|
|
226
|
+
const blockReason = response.promptFeedback?.blockReason
|
|
227
|
+
|
|
228
|
+
const reasons: string[] = []
|
|
229
|
+
if (blockReason) reasons.push(`prompt blocked: ${blockReason}`)
|
|
230
|
+
if (finishReason && finishReason !== 'STOP') reasons.push(`finish reason: ${finishReason}`)
|
|
231
|
+
if (!response.candidates?.length) reasons.push('no candidates returned')
|
|
232
|
+
|
|
233
|
+
const detail = reasons.length > 0 ? reasons.join(', ') : 'empty response.text with no diagnostic metadata'
|
|
234
|
+
|
|
235
|
+
throw new LLMResponseParseError(`Google Gemini returned no output (${detail})`, {
|
|
236
|
+
finishReason,
|
|
237
|
+
blockReason,
|
|
238
|
+
hasCandidates: (response.candidates?.length ?? 0) > 0
|
|
239
|
+
})
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Parse structured output from response with error wrapping for retry support
|
|
243
|
+
let output: unknown
|
|
244
|
+
try {
|
|
245
|
+
output = JSON.parse(response.text)
|
|
246
|
+
} catch (error) {
|
|
247
|
+
if (error instanceof SyntaxError) {
|
|
248
|
+
throw new LLMResponseParseError(`Failed to parse LLM response as JSON: ${error.message}`, {
|
|
249
|
+
rawContent: response.text.substring(0, 500),
|
|
250
|
+
parseError: error.message
|
|
251
|
+
})
|
|
252
|
+
}
|
|
253
|
+
throw error
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Extract usage metadata for observability tracking
|
|
257
|
+
const usage = response.usageMetadata
|
|
258
|
+
? {
|
|
259
|
+
inputTokens: response.usageMetadata.promptTokenCount || 0,
|
|
260
|
+
outputTokens: response.usageMetadata.candidatesTokenCount || 0,
|
|
261
|
+
totalTokens: response.usageMetadata.totalTokenCount || 0
|
|
262
|
+
}
|
|
263
|
+
: undefined
|
|
264
|
+
|
|
265
|
+
// Return response with usage (wrapper will extract and strip it)
|
|
266
|
+
return {
|
|
267
|
+
output: output as T,
|
|
268
|
+
usage
|
|
269
|
+
}
|
|
270
|
+
} catch (error) {
|
|
271
|
+
// Add Better Stack logging for system errors (5xx only)
|
|
272
|
+
if (isSystemError(error)) {
|
|
273
|
+
bslogExternalServiceError('google-genai', 'models.generateContent', error as Error, {
|
|
274
|
+
model: this.model,
|
|
275
|
+
thinkingLevel:
|
|
276
|
+
this.modelOptions && 'thinkingLevel' in this.modelOptions ? this.modelOptions.thinkingLevel : undefined
|
|
277
|
+
})
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
throw error
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Server-only LLM Adapters
|
|
3
|
-
*
|
|
4
|
-
* These adapters use server-only dependencies (betterstack-logger)
|
|
5
|
-
* and should only be imported from @repo/core/server
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export { OpenAIAdapter, isOpenAIModel, type OpenAIAdapterConfig } from './openai'
|
|
9
|
-
export { OpenRouterAdapter, isOpenRouterModel, type OpenRouterAdapterConfig } from './openrouter'
|
|
10
|
-
export { GoogleAdapter, isGoogleModel, type GoogleAdapterConfig } from './google'
|
|
11
|
-
export { AnthropicAdapter, isAnthropicModel, type AnthropicAdapterConfig } from './anthropic'
|
|
12
|
-
export { createLLMAdapter } from './adapter-factory'
|
|
1
|
+
/**
|
|
2
|
+
* Server-only LLM Adapters
|
|
3
|
+
*
|
|
4
|
+
* These adapters use server-only dependencies (betterstack-logger)
|
|
5
|
+
* and should only be imported from @repo/core/server
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export { OpenAIAdapter, isOpenAIModel, type OpenAIAdapterConfig } from './openai'
|
|
9
|
+
export { OpenRouterAdapter, isOpenRouterModel, type OpenRouterAdapterConfig } from './openrouter'
|
|
10
|
+
export { GoogleAdapter, isGoogleModel, type GoogleAdapterConfig } from './google'
|
|
11
|
+
export { AnthropicAdapter, isAnthropicModel, type AnthropicAdapterConfig } from './anthropic'
|
|
12
|
+
export { createLLMAdapter } from './adapter-factory'
|