Distributes bedrock requests evenly across regions (#36837)
* wip * feat: distribute bedrock requests across regions * fix: tests and type errors * chore: remove AWS_BEDROCK_REGION from turbo.json * fix: vercel oidc provider to fallback in credential chain --------- Co-authored-by: delgado3d <27228526+delgado3d@users.noreply.github.com>
This commit is contained in:
73
apps/studio/lib/ai/bedrock.test.ts
Normal file
73
apps/studio/lib/ai/bedrock.test.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { selectBedrockRegion, bedrockRegionMap } from './bedrock'
|
||||
|
||||
describe('selectBedrockRegion', () => {
|
||||
it('should return a valid region for a given routing key', async () => {
|
||||
const region = await selectBedrockRegion('test-key')
|
||||
const validRegions = Object.keys(bedrockRegionMap)
|
||||
|
||||
expect(validRegions).toContain(region)
|
||||
})
|
||||
|
||||
it('should return the same region for the same routing key', async () => {
|
||||
const routingKey = 'consistent-key'
|
||||
const region1 = await selectBedrockRegion(routingKey)
|
||||
const region2 = await selectBedrockRegion(routingKey)
|
||||
|
||||
expect(region1).toBe(region2)
|
||||
})
|
||||
|
||||
it('should distribute different keys across regions', async () => {
|
||||
const keys = Array.from({ length: 100 }, (_, i) => `key-${i}`)
|
||||
const regions = await Promise.all(keys.map((key) => selectBedrockRegion(key)))
|
||||
const uniqueRegions = new Set(regions)
|
||||
const validRegions = Object.keys(bedrockRegionMap)
|
||||
|
||||
// Should use all regions for 100 different keys
|
||||
expect(uniqueRegions.size).toEqual(validRegions.length)
|
||||
})
|
||||
|
||||
it('should distribute keys evenly across regions', async () => {
|
||||
const numKeys = 3000
|
||||
const keys = Array.from({ length: numKeys }, (_, i) => `key-${i}`)
|
||||
const regions = await Promise.all(keys.map((key) => selectBedrockRegion(key)))
|
||||
const validRegions = Object.keys(bedrockRegionMap)
|
||||
|
||||
// Count occurrences of each region
|
||||
const regionCounts = regions.reduce<Record<string, number>>((acc, region) => {
|
||||
acc[region] = (acc[region] ?? 0) + 1
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
const expectedCountPerRegion = numKeys / validRegions.length
|
||||
const tolerance = expectedCountPerRegion * 0.2 // Allow 20% deviation
|
||||
|
||||
// Each region should have roughly equal distribution
|
||||
for (const count of Object.values(regionCounts)) {
|
||||
expect(count).toBeGreaterThan(expectedCountPerRegion - tolerance)
|
||||
expect(count).toBeLessThan(expectedCountPerRegion + tolerance)
|
||||
}
|
||||
})
|
||||
|
||||
it('should handle empty string', async () => {
|
||||
const region = await selectBedrockRegion('')
|
||||
const validRegions = Object.keys(bedrockRegionMap)
|
||||
|
||||
expect(validRegions).toContain(region)
|
||||
})
|
||||
|
||||
it('should handle special characters in routing key', async () => {
|
||||
const region = await selectBedrockRegion('key-with-special-chars!@#$%')
|
||||
const validRegions = Object.keys(bedrockRegionMap)
|
||||
|
||||
expect(validRegions).toContain(region)
|
||||
})
|
||||
|
||||
it('should return consistent results for unicode characters', async () => {
|
||||
const routingKey = '🔑-unicode-key-测试'
|
||||
const region1 = await selectBedrockRegion(routingKey)
|
||||
const region2 = await selectBedrockRegion(routingKey)
|
||||
|
||||
expect(region1).toBe(region2)
|
||||
})
|
||||
})
|
||||
@@ -1,12 +1,11 @@
|
||||
import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock'
|
||||
import { createCredentialChain, fromNodeProviderChain } from '@aws-sdk/credential-providers'
|
||||
import { CredentialsProviderError } from '@smithy/property-provider'
|
||||
import { awsCredentialsProvider } from '@vercel/functions/oidc'
|
||||
|
||||
const credentialProvider = createCredentialChain(
|
||||
// Vercel OIDC provider will be used for staging/production
|
||||
awsCredentialsProvider({
|
||||
roleArn: process.env.AWS_BEDROCK_ROLE_ARN!,
|
||||
}),
|
||||
vercelOidcProvider,
|
||||
|
||||
// AWS profile will be used for local development
|
||||
fromNodeProviderChain({
|
||||
@@ -14,10 +13,61 @@ const credentialProvider = createCredentialChain(
|
||||
})
|
||||
)
|
||||
|
||||
export const bedrock = createAmazonBedrock({
|
||||
credentialProvider,
|
||||
region: process.env.AWS_BEDROCK_REGION,
|
||||
})
|
||||
/**
|
||||
* Creates a Vercel OIDC provider for AWS credentials.
|
||||
*
|
||||
* Wraps `awsCredentialsProvider` to properly handle errors
|
||||
* so that it can be used in a credential chain.
|
||||
*/
|
||||
async function vercelOidcProvider() {
|
||||
try {
|
||||
return await awsCredentialsProvider({
|
||||
roleArn: process.env.AWS_BEDROCK_ROLE_ARN!,
|
||||
})()
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : 'Failed to create Vercel OIDC provider'
|
||||
|
||||
// Re-throw using the correct error type and `tryNextLink` option
|
||||
throw new CredentialsProviderError(message, {
|
||||
tryNextLink: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const bedrockRegionMap = {
|
||||
us: 'us-east-1',
|
||||
eu: 'eu-central-1',
|
||||
apac: 'ap-southeast-1',
|
||||
} as const
|
||||
|
||||
export type BedrockRegion = keyof typeof bedrockRegionMap
|
||||
|
||||
export const bedrockForRegion = (region: BedrockRegion) =>
|
||||
createAmazonBedrock({
|
||||
credentialProvider,
|
||||
region: bedrockRegionMap[region],
|
||||
})
|
||||
|
||||
/**
|
||||
* Selects a region based on a routing key using a consistent hashing algorithm.
|
||||
*
|
||||
* Ensures that the same key always maps to the same region
|
||||
* while distributing keys evenly across available regions.
|
||||
*/
|
||||
export async function selectBedrockRegion(routingKey: string) {
|
||||
const regions = Object.keys(bedrockRegionMap) as BedrockRegion[]
|
||||
const encoder = new TextEncoder()
|
||||
const data = encoder.encode(routingKey)
|
||||
const hashBuffer = await crypto.subtle.digest('SHA-256', data)
|
||||
|
||||
// Use first 4 bytes (32 bit integer)
|
||||
const hashInt = new DataView(hashBuffer).getUint32(0)
|
||||
|
||||
// Use modulo to map to available regions
|
||||
const regionIndex = hashInt % regions.length
|
||||
|
||||
return regions[regionIndex]
|
||||
}
|
||||
|
||||
export async function checkAwsCredentials() {
|
||||
try {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { openai } from '@ai-sdk/openai'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import * as bedrockModule from './bedrock'
|
||||
import { bedrock } from './bedrock'
|
||||
import { getModel, ModelErrorMessage, modelsByProvider } from './model'
|
||||
|
||||
vi.mock('@ai-sdk/openai', () => ({
|
||||
@@ -9,8 +8,9 @@ vi.mock('@ai-sdk/openai', () => ({
|
||||
}))
|
||||
|
||||
vi.mock('./bedrock', () => ({
|
||||
bedrock: vi.fn(() => 'bedrock-model'),
|
||||
bedrockForRegion: vi.fn(() => () => 'bedrock-model'),
|
||||
checkAwsCredentials: vi.fn(),
|
||||
selectBedrockRegion: vi.fn(() => 'us'),
|
||||
}))
|
||||
|
||||
describe('getModel', () => {
|
||||
@@ -24,31 +24,23 @@ describe('getModel', () => {
|
||||
process.env = { ...originalEnv }
|
||||
})
|
||||
|
||||
it('should return bedrock model when AWS credentials are available and AWS_BEDROCK_REGION is set', async () => {
|
||||
it('should return bedrock model when AWS credentials are available', async () => {
|
||||
vi.mocked(bedrockModule.checkAwsCredentials).mockResolvedValue(true)
|
||||
process.env.AWS_BEDROCK_REGION = 'us-east-1'
|
||||
|
||||
const { model, error } = await getModel()
|
||||
|
||||
console.log('Model:', model)
|
||||
|
||||
expect(model).toEqual('bedrock-model')
|
||||
expect(bedrock).toHaveBeenCalledWith(modelsByProvider.bedrock)
|
||||
expect(bedrockModule.bedrockForRegion).toHaveBeenCalledWith('us')
|
||||
expect(error).toBeUndefined()
|
||||
})
|
||||
|
||||
it('should return error when AWS credentials are available but AWS_BEDROCK_REGION is not set', async () => {
|
||||
vi.mocked(bedrockModule.checkAwsCredentials).mockResolvedValue(true)
|
||||
delete process.env.AWS_BEDROCK_REGION
|
||||
|
||||
const { error } = await getModel()
|
||||
|
||||
expect(error).toEqual(new Error('AWS_BEDROCK_REGION is not set'))
|
||||
})
|
||||
|
||||
it('should return OpenAI model when AWS credentials are not available but OPENAI_API_KEY is set', async () => {
|
||||
vi.mocked(bedrockModule.checkAwsCredentials).mockResolvedValue(false)
|
||||
process.env.OPENAI_API_KEY = 'test-key'
|
||||
|
||||
const { model } = await getModel()
|
||||
const { model } = await getModel('test-key')
|
||||
|
||||
expect(model).toEqual('openai-model')
|
||||
expect(openai).toHaveBeenCalledWith(modelsByProvider.openai)
|
||||
@@ -58,7 +50,7 @@ describe('getModel', () => {
|
||||
vi.mocked(bedrockModule.checkAwsCredentials).mockResolvedValue(false)
|
||||
delete process.env.OPENAI_API_KEY
|
||||
|
||||
const { error } = await getModel()
|
||||
const { error } = await getModel('test-key')
|
||||
|
||||
expect(error).toEqual(new Error(ModelErrorMessage))
|
||||
})
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
import { openai } from '@ai-sdk/openai'
|
||||
import { LanguageModel } from 'ai'
|
||||
import { bedrock, checkAwsCredentials } from './bedrock'
|
||||
import {
|
||||
bedrockForRegion,
|
||||
BedrockRegion,
|
||||
checkAwsCredentials,
|
||||
selectBedrockRegion,
|
||||
} from './bedrock'
|
||||
|
||||
export const modelsByProvider = {
|
||||
bedrock: 'us.anthropic.claude-3-7-sonnet-20250219-v1:0',
|
||||
bedrock: {
|
||||
us: 'us.anthropic.claude-3-7-sonnet-20250219-v1:0',
|
||||
eu: 'eu.anthropic.claude-3-7-sonnet-20250219-v1:0',
|
||||
apac: 'apac.anthropic.claude-3-7-sonnet-20250219-v1:0',
|
||||
},
|
||||
openai: 'gpt-4.1-2025-04-14',
|
||||
}
|
||||
|
||||
@@ -24,20 +33,22 @@ export const ModelErrorMessage =
|
||||
|
||||
/**
|
||||
* Retrieves the appropriate AI model based on available credentials.
|
||||
*
|
||||
* An optional routing key can be provided to distribute requests across
|
||||
* different Bedrock regions.
|
||||
*/
|
||||
export async function getModel(): Promise<ModelResponse> {
|
||||
export async function getModel(routingKey?: string): Promise<ModelResponse> {
|
||||
const hasAwsCredentials = await checkAwsCredentials()
|
||||
const hasOpenAIKey = !!process.env.OPENAI_API_KEY
|
||||
|
||||
if (hasAwsCredentials) {
|
||||
if (!process.env.AWS_BEDROCK_REGION) {
|
||||
return {
|
||||
error: new Error('AWS_BEDROCK_REGION is not set'),
|
||||
}
|
||||
}
|
||||
// Select the Bedrock region based on the routing key
|
||||
const bedrockRegion: BedrockRegion = routingKey ? await selectBedrockRegion(routingKey) : 'us'
|
||||
const bedrock = bedrockForRegion(bedrockRegion)
|
||||
const modelName = modelsByProvider.bedrock[bedrockRegion]
|
||||
|
||||
return {
|
||||
model: bedrock(modelsByProvider.bedrock),
|
||||
model: bedrock(modelName),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -149,6 +149,7 @@
|
||||
"@graphql-codegen/cli": "5.0.5",
|
||||
"@graphql-typed-document-node/core": "^3.2.0",
|
||||
"@radix-ui/react-use-escape-keydown": "^1.0.3",
|
||||
"@smithy/property-provider": "^4.0.4",
|
||||
"@supabase/postgres-meta": "^0.64.4",
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"@testing-library/dom": "^10.0.0",
|
||||
|
||||
@@ -38,12 +38,6 @@ export default wrapper
|
||||
|
||||
async function handlePost(req: NextApiRequest, res: NextApiResponse) {
|
||||
try {
|
||||
const { model, error: modelError } = await getModel()
|
||||
|
||||
if (modelError) {
|
||||
return res.status(500).json({ error: modelError.message })
|
||||
}
|
||||
|
||||
const { completionMetadata, projectRef, connectionString, includeSchemaMetadata } = req.body
|
||||
const { textBeforeCursor, textAfterCursor, language, prompt, selection } = completionMetadata
|
||||
|
||||
@@ -53,6 +47,12 @@ async function handlePost(req: NextApiRequest, res: NextApiResponse) {
|
||||
})
|
||||
}
|
||||
|
||||
const { model, error: modelError } = await getModel(projectRef)
|
||||
|
||||
if (modelError) {
|
||||
return res.status(500).json({ error: modelError.message })
|
||||
}
|
||||
|
||||
const authorization = req.headers.authorization
|
||||
|
||||
const { result: schemas } = includeSchemaMetadata
|
||||
|
||||
@@ -26,12 +26,6 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
}
|
||||
|
||||
try {
|
||||
const { model, error: modelError } = await getModel()
|
||||
|
||||
if (modelError) {
|
||||
return res.status(500).json({ error: modelError.message })
|
||||
}
|
||||
|
||||
const { completionMetadata, projectRef, connectionString, includeSchemaMetadata } = req.body
|
||||
const { textBeforeCursor, textAfterCursor, language, prompt, selection } = completionMetadata
|
||||
|
||||
@@ -40,6 +34,11 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
error: 'Missing project_ref in request body',
|
||||
})
|
||||
}
|
||||
const { model, error: modelError } = await getModel(projectRef)
|
||||
|
||||
if (modelError) {
|
||||
return res.status(500).json({ error: modelError.message })
|
||||
}
|
||||
|
||||
const authorization = req.headers.authorization
|
||||
|
||||
|
||||
@@ -59,12 +59,6 @@ async function handlePost(req: NextApiRequest, res: NextApiResponse) {
|
||||
return res.status(401).json({ error: 'Authorization token is required' })
|
||||
}
|
||||
|
||||
const { model, error: modelError } = await getModel()
|
||||
|
||||
if (modelError) {
|
||||
return res.status(500).json({ error: modelError.message })
|
||||
}
|
||||
|
||||
const body = typeof req.body === 'string' ? JSON.parse(req.body) : req.body
|
||||
const { data, error: parseError } = requestBodySchema.safeParse(body)
|
||||
|
||||
@@ -74,6 +68,12 @@ async function handlePost(req: NextApiRequest, res: NextApiResponse) {
|
||||
|
||||
const { messages, projectRef, connectionString, aiOptInLevel } = data
|
||||
|
||||
const { model, error: modelError } = await getModel(projectRef) // use project ref as routing key
|
||||
|
||||
if (modelError) {
|
||||
return res.status(500).json({ error: modelError.message })
|
||||
}
|
||||
|
||||
try {
|
||||
let mcpTools: ToolSet = {}
|
||||
let localTools: ToolSet = {
|
||||
|
||||
44
pnpm-lock.yaml
generated
44
pnpm-lock.yaml
generated
@@ -331,7 +331,7 @@ importers:
|
||||
version: 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@sentry/nextjs':
|
||||
specifier: ^9.15.0
|
||||
version: 9.15.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)
|
||||
version: 9.15.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)
|
||||
'@supabase/supabase-js':
|
||||
specifier: 'catalog:'
|
||||
version: 2.49.3
|
||||
@@ -451,7 +451,7 @@ importers:
|
||||
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
nuqs:
|
||||
specifier: ^1.19.1
|
||||
version: 1.19.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))
|
||||
version: 1.19.1(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))
|
||||
openai:
|
||||
specifier: ^4.20.1
|
||||
version: 4.71.1(encoding@0.1.13)(zod@3.23.8)
|
||||
@@ -1018,6 +1018,9 @@ importers:
|
||||
'@radix-ui/react-use-escape-keydown':
|
||||
specifier: ^1.0.3
|
||||
version: 1.1.0(@types/react@18.3.3)(react@18.3.1)
|
||||
'@smithy/property-provider':
|
||||
specifier: ^4.0.4
|
||||
version: 4.0.4
|
||||
'@supabase/postgres-meta':
|
||||
specifier: ^0.64.4
|
||||
version: 0.64.6(encoding@0.1.13)(supports-color@8.1.1)
|
||||
@@ -1134,7 +1137,7 @@ importers:
|
||||
version: 2.4.11(typescript@5.5.2)
|
||||
next-router-mock:
|
||||
specifier: ^0.9.13
|
||||
version: 0.9.13(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)
|
||||
version: 0.9.13(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)
|
||||
postcss:
|
||||
specifier: ^8.5.3
|
||||
version: 8.5.3
|
||||
@@ -2290,7 +2293,7 @@ importers:
|
||||
version: link:../api-types
|
||||
next-router-mock:
|
||||
specifier: ^0.9.13
|
||||
version: 0.9.13(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)
|
||||
version: 0.9.13(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)
|
||||
tsx:
|
||||
specifier: ^4.19.3
|
||||
version: 4.19.3
|
||||
@@ -2751,6 +2754,10 @@ packages:
|
||||
resolution: {integrity: sha512-Znroqdai1a90TlxGaJ+FK1lwC0fHpo97Xjsp5UKGR5JODYm7f9+/fF17ebO1KdoBr/Rm0UIFiF5VmI8ts9F1eA==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
'@aws-sdk/types@3.840.0':
|
||||
resolution: {integrity: sha512-xliuHaUFZxEx1NSXeLLZ9Dyu6+EJVQKEoD+yM+zqUo3YDZ7medKJWY6fIOKiPX/N7XbLdBYwajb15Q7IL8KkeA==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
'@aws-sdk/util-arn-parser@3.804.0':
|
||||
resolution: {integrity: sha512-wmBJqn1DRXnZu3b4EkE6CWnoWMo1ZMvlfkqU5zPz67xx1GMaXlDCchFvKAXMjk4jn/L1O3tKnoFDNsoLV1kgNQ==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
@@ -11104,7 +11111,6 @@ packages:
|
||||
resolution: {integrity: sha512-t0q23FIpvHDTtnORW+bDJziGsal5uh9RJTJ1fyH8drd4lICOoXhJ5pLMUZ5C0VQei6dNmwTzzoTRgMkO9JgHEQ==}
|
||||
peerDependencies:
|
||||
eslint: '>= 5'
|
||||
bundledDependencies: []
|
||||
|
||||
eslint-plugin-import@2.31.0:
|
||||
resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==}
|
||||
@@ -14174,6 +14180,7 @@ packages:
|
||||
node-domexception@1.0.0:
|
||||
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
|
||||
engines: {node: '>=10.5.0'}
|
||||
deprecated: Use your platform's native DOMException instead
|
||||
|
||||
node-emoji@1.11.0:
|
||||
resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==}
|
||||
@@ -18278,7 +18285,7 @@ snapshots:
|
||||
'@aws-crypto/crc32@5.2.0':
|
||||
dependencies:
|
||||
'@aws-crypto/util': 5.2.0
|
||||
'@aws-sdk/types': 3.468.0
|
||||
'@aws-sdk/types': 3.840.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-crypto/crc32c@5.2.0':
|
||||
@@ -18306,7 +18313,7 @@ snapshots:
|
||||
'@aws-crypto/sha256-js': 3.0.0
|
||||
'@aws-crypto/supports-web-crypto': 3.0.0
|
||||
'@aws-crypto/util': 3.0.0
|
||||
'@aws-sdk/types': 3.468.0
|
||||
'@aws-sdk/types': 3.821.0
|
||||
'@aws-sdk/util-locate-window': 3.465.0
|
||||
'@aws-sdk/util-utf8-browser': 3.259.0
|
||||
tslib: 1.14.1
|
||||
@@ -18316,7 +18323,7 @@ snapshots:
|
||||
'@aws-crypto/sha256-js': 5.2.0
|
||||
'@aws-crypto/supports-web-crypto': 5.2.0
|
||||
'@aws-crypto/util': 5.2.0
|
||||
'@aws-sdk/types': 3.821.0
|
||||
'@aws-sdk/types': 3.840.0
|
||||
'@aws-sdk/util-locate-window': 3.465.0
|
||||
'@smithy/util-utf8': 2.0.2
|
||||
tslib: 2.8.1
|
||||
@@ -18324,19 +18331,19 @@ snapshots:
|
||||
'@aws-crypto/sha256-js@1.2.2':
|
||||
dependencies:
|
||||
'@aws-crypto/util': 1.2.2
|
||||
'@aws-sdk/types': 3.468.0
|
||||
'@aws-sdk/types': 3.821.0
|
||||
tslib: 1.14.1
|
||||
|
||||
'@aws-crypto/sha256-js@3.0.0':
|
||||
dependencies:
|
||||
'@aws-crypto/util': 3.0.0
|
||||
'@aws-sdk/types': 3.468.0
|
||||
'@aws-sdk/types': 3.821.0
|
||||
tslib: 1.14.1
|
||||
|
||||
'@aws-crypto/sha256-js@5.2.0':
|
||||
dependencies:
|
||||
'@aws-crypto/util': 5.2.0
|
||||
'@aws-sdk/types': 3.821.0
|
||||
'@aws-sdk/types': 3.840.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-crypto/supports-web-crypto@3.0.0':
|
||||
@@ -18361,7 +18368,7 @@ snapshots:
|
||||
|
||||
'@aws-crypto/util@5.2.0':
|
||||
dependencies:
|
||||
'@aws-sdk/types': 3.821.0
|
||||
'@aws-sdk/types': 3.840.0
|
||||
'@smithy/util-utf8': 2.0.2
|
||||
tslib: 2.8.1
|
||||
|
||||
@@ -19440,6 +19447,11 @@ snapshots:
|
||||
'@smithy/types': 4.3.1
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/types@3.840.0':
|
||||
dependencies:
|
||||
'@smithy/types': 4.3.1
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/util-arn-parser@3.804.0':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
@@ -25756,7 +25768,7 @@ snapshots:
|
||||
- supports-color
|
||||
- webpack
|
||||
|
||||
'@sentry/nextjs@9.15.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)':
|
||||
'@sentry/nextjs@9.15.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/semantic-conventions': 1.32.0
|
||||
@@ -30370,7 +30382,7 @@ snapshots:
|
||||
es-set-tostringtag@2.1.0:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
get-intrinsic: 1.2.7
|
||||
get-intrinsic: 1.3.0
|
||||
has-tostringtag: 1.0.2
|
||||
hasown: 2.0.2
|
||||
|
||||
@@ -34690,7 +34702,7 @@ snapshots:
|
||||
dependencies:
|
||||
js-yaml-loader: 1.2.2
|
||||
|
||||
next-router-mock@0.9.13(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1):
|
||||
next-router-mock@0.9.13(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1):
|
||||
dependencies:
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
react: 18.3.1
|
||||
@@ -35027,7 +35039,7 @@ snapshots:
|
||||
|
||||
number-flow@0.3.7: {}
|
||||
|
||||
nuqs@1.19.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)):
|
||||
nuqs@1.19.1(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)):
|
||||
dependencies:
|
||||
mitt: 3.0.1
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
|
||||
@@ -89,7 +89,6 @@
|
||||
"SENTRY_ORG",
|
||||
"SENTRY_PROJECT",
|
||||
"SENTRY_AUTH_TOKEN",
|
||||
"AWS_BEDROCK_REGION",
|
||||
"AWS_BEDROCK_PROFILE",
|
||||
"AWS_BEDROCK_ROLE_ARN",
|
||||
"AWS_ACCESS_KEY_ID",
|
||||
|
||||
Reference in New Issue
Block a user