diff --git a/docs/components/llms/models/aws_bedrock.mdx b/docs/components/llms/models/aws_bedrock.mdx index 3d3de2d29..b58fbd389 100644 --- a/docs/components/llms/models/aws_bedrock.mdx +++ b/docs/components/llms/models/aws_bedrock.mdx @@ -5,16 +5,18 @@ description: "Configure AWS Bedrock as an LLM provider in Mem0 with IAM authenti ### Setup - Before using the AWS Bedrock LLM, make sure you have the appropriate model access from [Bedrock Console](https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/modelaccess). -- You will also need to authenticate the `boto3` client by using a method in the [AWS documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#configuring-credentials) -- You will have to export `AWS_REGION`, `AWS_ACCESS_KEY_ID`, and `AWS_SECRET_ACCESS_KEY` to set environment variables. +- Model availability is per-region. `anthropic.claude-sonnet-4-20250514-v1:0` supports on-demand inference in `us-east-1` and `ap-southeast-4`; from any other region, use the cross-region inference profile ID `us.anthropic.claude-sonnet-4-20250514-v1:0` instead. +- Install the AWS SDK for your language: `pip install boto3` (Python) or `npm install @aws-sdk/client-bedrock-runtime` (TypeScript). +- Both SDKs fall back to the standard AWS credential chain (environment variables, `~/.aws/credentials`, or an attached IAM role), so exporting `AWS_REGION`, `AWS_ACCESS_KEY_ID`, and `AWS_SECRET_ACCESS_KEY` is the quickest way to get started. In TypeScript you can also pass credentials inline with `awsRegion`, `awsAccessKeyId`, `awsSecretAccessKey`, and `awsSessionToken`, as shown below. ### Usage -```python + +```python Python import os from mem0 import Memory -os.environ['AWS_REGION'] = 'us-west-2' +os.environ['AWS_REGION'] = 'us-east-1' os.environ["AWS_ACCESS_KEY_ID"] = "xx" os.environ["AWS_SECRET_ACCESS_KEY"] = "xx" @@ -22,7 +24,7 @@ config = { "llm": { "provider": "aws_bedrock", "config": { - "model": "anthropic.claude-3-5-haiku-20241022-v1:0", + "model": "anthropic.claude-sonnet-4-20250514-v1:0", "temperature": 0.2, "max_tokens": 2000, } @@ -39,6 +41,43 @@ messages = [ m.add(messages, user_id="alice", metadata={"category": "movies"}) ``` +```typescript TypeScript +import { Memory } from 'mem0ai/oss'; + +const config = { + llm: { + provider: 'aws_bedrock', + config: { + model: 'anthropic.claude-sonnet-4-20250514-v1:0', + temperature: 0.2, + maxTokens: 2000, + // Optional. Omit these to use the default AWS credential chain. + awsRegion: process.env.AWS_REGION, + awsAccessKeyId: process.env.AWS_ACCESS_KEY_ID, + awsSecretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, + }, + }, +}; + +const memory = new Memory(config); +const messages = [ + {"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"}, + {"role": "assistant", "content": "How about thriller movies? They can be quite engaging."}, + {"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."}, + {"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."} +]; +await memory.add(messages, { userId: 'alice', metadata: { category: 'movies' } }); +``` + + + + `@aws-sdk/client-bedrock-runtime` is an optional peer dependency of `mem0ai`, so npm will not install it for you. The TypeScript provider loads it lazily and throws a clear error on the first request if the package is missing. + + + + The TypeScript provider calls the Bedrock [Converse API](https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html), a single uniform interface across the current Bedrock model families. Streaming and `InvokeModel`-only models are not supported yet. + + ### Config -All available parameters for the `aws_bedrock` config are present in [Master List of All Params in Config](../config). \ No newline at end of file +All available parameters for the `aws_bedrock` config are present in [Master List of All Params in Config](../config). diff --git a/docs/components/llms/overview.mdx b/docs/components/llms/overview.mdx index ce9cfa7dd..12b280f47 100644 --- a/docs/components/llms/overview.mdx +++ b/docs/components/llms/overview.mdx @@ -16,7 +16,7 @@ For a comprehensive list of available parameters for llm configuration, please r See the list of supported LLMs below. - All LLMs are supported in Python. The following LLMs are also supported in TypeScript: **OpenAI**, **Anthropic**, **Groq**, **Azure OpenAI**, **DeepSeek**, **Google AI**, **Langchain**, **LM Studio**, **Mistral AI**, and **Ollama**. + All LLMs are supported in Python. The following LLMs are also supported in TypeScript: **OpenAI**, **Anthropic**, **AWS Bedrock**, **Groq**, **Azure OpenAI**, **DeepSeek**, **Google AI**, **Langchain**, **LM Studio**, **Mistral AI**, and **Ollama**. diff --git a/docs/open-source/configuration.mdx b/docs/open-source/configuration.mdx index 0fbb72849..e60d72faf 100644 --- a/docs/open-source/configuration.mdx +++ b/docs/open-source/configuration.mdx @@ -119,7 +119,7 @@ Change the `provider` string to switch backends. The most common options: | Component | Python | TypeScript | | --- | --- | --- | -| LLM | `openai`, `anthropic`, `gemini`, `groq`, `ollama`, `aws_bedrock`, `azure_openai`, `litellm` | `openai`, `anthropic`, `gemini`, `groq`, `ollama`, `azure_openai`, `mistral`, `deepseek` | +| LLM | `openai`, `anthropic`, `gemini`, `groq`, `ollama`, `aws_bedrock`, `azure_openai`, `litellm` | `openai`, `anthropic`, `gemini`, `groq`, `ollama`, `aws_bedrock`, `azure_openai`, `mistral`, `deepseek` | | Embedder | `openai`, `gemini`, `azure_openai`, `ollama`, `huggingface`, `vertexai`, `aws_bedrock` | `openai`, `gemini`, `azure_openai`, `ollama` | | Vector store | `qdrant`, `pgvector`, `chroma`, `pinecone`, `redis`, `weaviate`, `milvus`, `elasticsearch` | `memory`, `qdrant`, `pgvector`, `redis`, `supabase`, `azure-ai-search`, `vectorize`, `milvus` | diff --git a/mem0-ts/package.json b/mem0-ts/package.json index 60b6d9358..953fcd32c 100644 --- a/mem0-ts/package.json +++ b/mem0-ts/package.json @@ -145,7 +145,8 @@ "natural": "^8.0.1", "zeroentropy": "^0.1.0-alpha.10", "mysql2": "^3.0.0", - "@zilliz/milvus2-sdk-node": "^2.4.0 || ^3.0.0" + "@zilliz/milvus2-sdk-node": "^2.4.0 || ^3.0.0", + "@aws-sdk/client-bedrock-runtime": ">=3.0.0 <3.968.0" }, "peerDependenciesMeta": { "mysql2": { @@ -156,6 +157,9 @@ }, "@mochow/mochow-sdk-node": { "optional": true + }, + "@aws-sdk/client-bedrock-runtime": { + "optional": true } }, "engines": { @@ -192,7 +196,8 @@ "tar@<=7.5.15": "^7.5.19", "@modelcontextprotocol/sdk": "^1.25.4", "esbuild": ">=0.28.1", - "undici@<6.27.0": ">=6.27.0 <8.0.0" + "undici@<6.27.0": ">=6.27.0 <8.0.0", + "@aws-sdk/client-bedrock-runtime": "3.967.0" } } } diff --git a/mem0-ts/pnpm-lock.yaml b/mem0-ts/pnpm-lock.yaml index e652cc7df..f3461e62f 100644 --- a/mem0-ts/pnpm-lock.yaml +++ b/mem0-ts/pnpm-lock.yaml @@ -27,6 +27,7 @@ overrides: '@modelcontextprotocol/sdk': ^1.25.4 esbuild: '>=0.28.1' undici@<6.27.0: '>=6.27.0 <8.0.0' + '@aws-sdk/client-bedrock-runtime': 3.967.0 importers: @@ -35,6 +36,9 @@ importers: '@anthropic-ai/sdk': specifier: ^0.40.1 version: 0.40.1 + '@aws-sdk/client-bedrock-runtime': + specifier: 3.967.0 + version: 3.967.0 '@aws-sdk/client-s3vectors': specifier: 3.967.0 version: 3.967.0 @@ -242,12 +246,16 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/checksums@3.1000.13': - resolution: {integrity: sha512-USI1N1d+NbCcfjeiYLKIl94PSYykl5IIjj4X3WqdL33Ln5qktA6sjXYct0o/gG2Cte7cuzbXKkDBkzUA4VPHrg==} + '@aws-sdk/checksums@3.1000.16': + resolution: {integrity: sha512-EKnvkXSmz3IpA99tCNuI+dLFXyZyClSm8zns9sB/elvkU+MTuomAs6toJMPMBf98/fICG/urXDkzGz0/c3yyAQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/client-s3@3.1080.0': - resolution: {integrity: sha512-erKuxbwhYLKs0ZviBeTDvXxC0E4AtugHXLbt5kFk8u9/rQMglh/QJNK5f9KuLjlMrbFSJgkBmjNSY5O03YoK4A==} + '@aws-sdk/client-bedrock-runtime@3.967.0': + resolution: {integrity: sha512-pFID1Lb/54u413HTpnqQYLJjX+voEKLZyqlpdVHDbxcw8MfalmmSg5PR/uJWGO3kku0LkB+H/Ca5ftL11PTL9w==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/client-s3@3.1083.0': + resolution: {integrity: sha512-3YOicHy6qjexsy4rHk5jPvtLgg6Ho1u+ycOWtJcVTAIMlMq32MRtnhllAyFSezhAXeBnnLLtKtAGXim7vV8oog==} engines: {node: '>=20.0.0'} '@aws-sdk/client-s3vectors@3.967.0': @@ -262,74 +270,82 @@ packages: resolution: {integrity: sha512-sJmuP7GrVmlbO6DpXkuf9Mbn6jGNNvy6PLawvaxVF150c8bpNk3w39rerRls6q1dot1dBFV2D29hBXMY1agNMg==} engines: {node: '>=18.0.0'} - '@aws-sdk/core@3.974.28': - resolution: {integrity: sha512-4/1DtLwgLqzIg2uFzkFaFjMQHhhhwHIZN4PfziIVqXYX7koO78omuchQlLHyzQBw80l255dtmTA/J4W5yhb7zw==} + '@aws-sdk/core@3.975.1': + resolution: {integrity: sha512-8qh/6EYb7hl/ZwVfQufhbMEZs1gQIc7GbdrIf4eprQJ7cv042+74nE6l3YDfyWNzb9iPXb8fRyYSHkNIk5eE6Q==} engines: {node: '>=20.0.0'} '@aws-sdk/credential-provider-env@3.967.0': resolution: {integrity: sha512-+XWw0+f/txeMbEVRtTFZhgSw1ymH1ffaVKkdMBSnw48rfSohJElKmitCqdihagRTZpzh7m8qI6tIQ5t3OUqugw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-env@3.972.54': - resolution: {integrity: sha512-F4WQCG8GULIt+XrMHsqUM9dZc0eTwZM3HUWByOjIKOwBqJSzUxX8CFAtbgMvWfCua52FS1oi5FXarH3+khFq8A==} + '@aws-sdk/credential-provider-env@3.972.57': + resolution: {integrity: sha512-1RfJaF7SW1TOnvNGU7kaYjwUf5H3sfm+synGH1bHhRlqcnxCt3szebH3dmKEyY4tuGcbQ6ffzUT89cRitBV8OQ==} engines: {node: '>=20.0.0'} '@aws-sdk/credential-provider-http@3.967.0': resolution: {integrity: sha512-0/GIAEv5pY5htg6IBMuYccBgzz3oS2DqHjHi396ziTrwlhbrCNX96AbNhQhzAx3LBZUk13sPfeapjyQ7G57Ekg==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-http@3.972.56': - resolution: {integrity: sha512-PiwHgEK2srdfi/lFveyQ+3w/qikyh6MKvuZAdlMC+dwQi4K5iVBr32oh7cugnYw+jA8iGtnQMhCGvLm/mqplmw==} + '@aws-sdk/credential-provider-http@3.972.59': + resolution: {integrity: sha512-sRCkpTiFnCdQvuaRVjQ6SVoHu6i7RUpurVo1c4F81HWhPvUJ7Wdp5MNtSdX1O29CNXc8em3O5m52hCjVtAD9SA==} engines: {node: '>=20.0.0'} '@aws-sdk/credential-provider-ini@3.967.0': resolution: {integrity: sha512-U8dMpaM6Qf6+2Qvp1uG6OcWv1RlrZW7tQkpmzEVWH8HZTGrVHIXXju64NMtIOr7yOnNwd0CKcytuD1QG+phCwQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-ini@3.972.61': - resolution: {integrity: sha512-9CZWMjhBlgfKlqJk40R7kvMOLEIoOr3HJ1J/ELjAH9H5LzR4bCxLujPVM/1PKAEjzSZKZCxWOalm7JUGZbhQqw==} + '@aws-sdk/credential-provider-ini@3.973.1': + resolution: {integrity: sha512-6d8H6ZAh3ZPKZ6fe1nG2OWeZEZPtt9ravoD1dezPdPtsSkJRoxGAnFSHwKT3E/Te6fHE30zRzjV6TD12rvF6yQ==} engines: {node: '>=20.0.0'} '@aws-sdk/credential-provider-login@3.967.0': resolution: {integrity: sha512-kbvZsZL6CBlfnb71zuJdJmBUFZN5utNrcziZr/DZ2olEOkA9vlmizE8i9BUIbmS7ptjgvRnmcY1A966yfhiblw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-login@3.972.60': - resolution: {integrity: sha512-Ak6OOrCbXvACyxLFIP1mcS+JTLS9ZpW1ZqyBtqu6axvdpsbG1gVNhUlAfQq8TK/gar/h2w35LrzlQU0PcUzJpw==} + '@aws-sdk/credential-provider-login@3.972.63': + resolution: {integrity: sha512-GREWRrMj0XnNKMaVa/Mauoaui26qBEHu71WWqXbwZOu/jFQOnPZjTf7u0KtGKC8VGa6VUs9kDWGgocrKNLS9vw==} engines: {node: '>=20.0.0'} '@aws-sdk/credential-provider-node@3.967.0': resolution: {integrity: sha512-WuNbHs9rfKKSVok4+OBrZf0AHfzDgFYYMxN2G/q6ZfUmY4QmiPyxV5HkNFh1rqDxS9VV6kAZPo0EBmry10idSg==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-node@3.972.63': - resolution: {integrity: sha512-YmgWtTPZDStyT74ApSHpApD3r7W9znsc+WEZjW0vceom+NAxRx9/F3TyukOKix8kJkPaa49aIREQJdpGeLDiEw==} + '@aws-sdk/credential-provider-node@3.972.66': + resolution: {integrity: sha512-f+qjRXZpz7sgzbc4QB+6nLKfyKFgRRXzWdXbsKPv/VhVRyHsDyq4yBWC/B75BAJpFIcUeI2XR/3gdWJ677zB4A==} engines: {node: '>=20.0.0'} '@aws-sdk/credential-provider-process@3.967.0': resolution: {integrity: sha512-sNCY5JDV0whsfsZ6c2+6eUwH33H7UhKbqvCPbEYlIIa8wkGjCtCyFI3zZIJHVcMKJJ3117vSUFHEkNA7g+8rtw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-process@3.972.54': - resolution: {integrity: sha512-UNmUjtTnp3wH3YTZcctN7yK17S2AdaJpiNIdIf0l70hHOdGuDfdMxk62P5rt64GwGm6qkFOYG0js/cU6cdZDdg==} + '@aws-sdk/credential-provider-process@3.972.57': + resolution: {integrity: sha512-TiVQhuU0pbhIZAUZacbPHMyzrIdiH+lnx+PMY/Pu/b93dJrq3wdZwzUJ0TPpvNxaqbHsxJvQZW3/h/beLiKq7Q==} engines: {node: '>=20.0.0'} '@aws-sdk/credential-provider-sso@3.967.0': resolution: {integrity: sha512-0K6kITKNytFjk1UYabYUsTThgU6TQkyW6Wmt8S5zd1A/up7NSQGpp58Rpg9GIf4amQDQwb+p9FGG7emmV8FEeA==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-sso@3.972.60': - resolution: {integrity: sha512-zH8SvJkTRw1Kb7GARjGPjzkQPfL3jDi/OxK32I5SQq7bgwgFHJZaoDEwkEvFlfNfpByM6n4Rs20Y1mLyOdb6ag==} + '@aws-sdk/credential-provider-sso@3.973.1': + resolution: {integrity: sha512-3foTZUJ4821Ij60X7K3NJroygiZLnbBmarN+T//O2cjkISan90zElN3NBmgSlDrTQ7Gs6z/yO8V7h60QNcDZHQ==} engines: {node: '>=20.0.0'} '@aws-sdk/credential-provider-web-identity@3.967.0': resolution: {integrity: sha512-Vkr7S2ec7q/v8i/MzkHcBEdqqfWz3lyb8FDjb+NjslEwdxC3f6XwADRZzWwV1pChfx6SbsvJXKfkcF/pKAelhA==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-web-identity@3.972.60': - resolution: {integrity: sha512-q2rJSQ/AMjemUS18OtQqczqSo2R6VjOCLmLVmLVcdrP5/AKoj632lGCrMUWQ6EgnaLMEHbq0UO4mWh/u6gjPhA==} + '@aws-sdk/credential-provider-web-identity@3.972.63': + resolution: {integrity: sha512-8qZLFhM69eKcS37m459ctPR05Qimycm/74OPVioe6wNZabMT54GYhwBju0+J656RkMasNSawWQu+c8CmBe3TUQ==} engines: {node: '>=20.0.0'} + '@aws-sdk/eventstream-handler-node@3.965.0': + resolution: {integrity: sha512-QriACiXP+/x2xXw8u849BxID+zSUbh/7Gt0Zfaxeye0mIKVeSTid5776rXfrM8wcYhbVXWWZhKd1Du7oPuFwsg==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/middleware-eventstream@3.965.0': + resolution: {integrity: sha512-YVNOPbc3r+gETUY6ufnJYsgIRMaBfoGRM9GzPb+gwtidCPd0BEpLjmZNIVGYawMrGc2kAdlV1kjBzAvmYaMINw==} + engines: {node: '>=18.0.0'} + '@aws-sdk/middleware-host-header@3.965.0': resolution: {integrity: sha512-SfpSYqoPOAmdb3DBsnNsZ0vix+1VAtkUkzXM79JL3R5IfacpyKE2zytOgVAQx/FjhhlpSTwuXd+LRhUEVb3MaA==} engines: {node: '>=18.0.0'} @@ -342,32 +358,37 @@ packages: resolution: {integrity: sha512-6dvD+18Ni14KCRu+tfEoNxq1sIGVp9tvoZDZ7aMvpnA7mDXuRLrOjRQ/TAZqXwr9ENKVGyxcPl0cRK8jk1YWjA==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-sdk-s3@3.972.59': - resolution: {integrity: sha512-KCf/UjbnzV3QIXR1C2MeE9eRUG8EUXUf0V4y65hf2bKWQXzol5f3I8wOhE6OBdEYohn8zHfnC/cyy5+s7/HwLw==} + '@aws-sdk/middleware-sdk-s3@3.972.62': + resolution: {integrity: sha512-k8JJwYXVYlOOjWnPZDThQS1xDFJgi5Dokt73qFlDtrZAbdcint5aIdjB9XgJAAQVP5OoqcefQmh1FYXiPpvsvw==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-user-agent@3.967.0': resolution: {integrity: sha512-2qzJzZj5u+cZiG7kz3XJPaTH4ssUY/aet1kwJsUTFKrWeHUf7mZZkDFfkXP5cOffgiOyR5ZkrmJoLKAde9hshg==} engines: {node: '>=18.0.0'} + '@aws-sdk/middleware-websocket@3.965.0': + resolution: {integrity: sha512-BGU92StrWF0EJj8jX5EFvRkX9z4/CVIZfON0nWow8gb5ouKwz47o1rO9CP/k2b3F6g134/0XqwXvrUgIWfjJeA==} + engines: {node: '>= 14.0.0'} + deprecated: Please update your @aws-sdk client to a more recent version, such as https://github.com/aws/aws-sdk-js-v3/releases/tag/v3.982.0, if using browser-based WebSocket bidirectional streaming. + '@aws-sdk/nested-clients@3.967.0': resolution: {integrity: sha512-PYa7V8w0gaNux6Sz/Z7zrHmPloEE+EKpRxQIOG/D0askTr5Yd4oO2KGgcInf65uHK3f0Z9U4CTUGHZvQvABypA==} engines: {node: '>=18.0.0'} - '@aws-sdk/nested-clients@3.997.28': - resolution: {integrity: sha512-1oG/mM3jmE2M3kad2zWJS6IKIY8hjRV4l5kAgg+xTQdLMTtehhcSucL/y4WqQpcHmQwi6+gRK8E46GYl1NBW9Q==} + '@aws-sdk/nested-clients@3.997.31': + resolution: {integrity: sha512-BDHTpwcsZHEBNEJzOg/B1BkFYJxAXY50dau/NyVWs3d51F0WgIUGSWZot/Os+N3KpDhXeaXnz37mWffAvduREw==} engines: {node: '>=20.0.0'} '@aws-sdk/region-config-resolver@3.965.0': resolution: {integrity: sha512-RoMhu9ly2B0coxn8ctXosPP2WmDD0MkQlZGLjoYHQUOCBmty5qmCxOqBmBDa6wbWbB8xKtMQ/4VXloQOgzjHXg==} engines: {node: '>=18.0.0'} - '@aws-sdk/signature-v4-multi-region@3.996.38': - resolution: {integrity: sha512-C379Sk+MiFZCfWZphKlMyLHKxV22OjoGM5KJjj5IJNJcOCWL4IGIpnEGzv1FQiRwhYXfq55SJMfxlqPE08JJ9g==} + '@aws-sdk/signature-v4-multi-region@3.996.39': + resolution: {integrity: sha512-8+srXqYIF8KYMLC4FxMLEM5Ek7kUNibJu1R4m8/fUhhNYIZZz26oGtKkCr8I/HiG2fFQxBvaGgQZT4/mqRCSnA==} engines: {node: '>=20.0.0'} - '@aws-sdk/token-providers@3.1080.0': - resolution: {integrity: sha512-8PufAQvncWXvdZUvODbuyXa8l3aszefEzwSMBUcgheNbZOmJMcNn388Ebt/piVrUHyxKN1MlxnR2OonzTyZaGw==} + '@aws-sdk/token-providers@3.1083.0': + resolution: {integrity: sha512-s0woKnxuHrExLc5L2ArIH5BMkbonHPtt+5hSBM8oknp9M6QTuUmmAmJ2E0EdzCGONrO+8+ADPqvv6UX0nNcc7A==} engines: {node: '>=20.0.0'} '@aws-sdk/token-providers@3.967.0': @@ -382,14 +403,18 @@ packages: resolution: {integrity: sha512-pEHZqRkAlHfnfAU9tK+WpKv/gBNjGJrHMgA3A0iYRGyswBS2t0pfez+lWlwktb3Bqa0ovh7w/QJTFwp3fDxLNg==} engines: {node: '>=20.0.0'} - '@aws-sdk/types@3.973.15': - resolution: {integrity: sha512-IULn8uBV/SMtmOIANsm4WHXIOtVPBWfOWs3WGL0j/sI+KhaYehvOw0ET+9urnn8MBpiijuU/0JOpuwKOE451PQ==} + '@aws-sdk/types@3.974.0': + resolution: {integrity: sha512-QIBrw90CDm4O0UaIIzkU6DrFdeJzEb2Va5EPEVpyldj6sHJxB6cshhStJuhZxk3wR3PmjJlYsjPmY1kNb+KGBg==} engines: {node: '>=20.0.0'} '@aws-sdk/util-endpoints@3.965.0': resolution: {integrity: sha512-WqSCB0XIsGUwZWvrYkuoofi2vzoVHqyeJ2kN+WyoOsxPLTiQSBIoqm/01R/qJvoxwK/gOOF7su9i84Vw2NQQpQ==} engines: {node: '>=18.0.0'} + '@aws-sdk/util-format-url@3.965.0': + resolution: {integrity: sha512-KiplV4xYGXdNCcz5eRP8WfAejT5EkE2gQxC4IY6WsuxYprzQKsnGaAzEQ+giR5GgQLIRBkPaWT0xHEYkMiCQ1Q==} + engines: {node: '>=18.0.0'} + '@aws-sdk/util-locate-window@3.965.8': resolution: {integrity: sha512-uUbMs1cBZPafD0ohUj6EwNf0fPZ534NvBxHox4hjX+0Rxq5paSYUem7+hi833pYrzrcnBATKIYpR02MDXT5M9g==} engines: {node: '>=20.0.0'} @@ -410,8 +435,8 @@ packages: resolution: {integrity: sha512-Tcod25/BTupraQwtb+Q+GX8bmEZfxIFjjJ/AvkhUZsZlkPeVluzq1uu3Oeqf145DCdMjzLIN6vab5MrykbDP+g==} engines: {node: '>=18.0.0'} - '@aws-sdk/xml-builder@3.972.33': - resolution: {integrity: sha512-ezbwz9WpuLctm6o7P2t2naDhVVPI5jFGrVefVybhcKGjU57VIyT46pQVO0RI2RYkUdhdj2Z9uSIlAzGZE9NW9A==} + '@aws-sdk/xml-builder@3.972.34': + resolution: {integrity: sha512-wHhWL1y7sN3enBA8POrPpQM5jCcmu2ozyhbRei4c8OjVcEaEs6yLucLa/pla457ggS/ysuy7bosagz3HaJkZXA==} engines: {node: '>=20.0.0'} '@aws/lambda-invoke-store@0.2.4': @@ -1445,12 +1470,32 @@ packages: resolution: {integrity: sha512-qoiY4nrk5OCu1+eIR1VB8l5DmON/oKiqrd5zZFAhXJXjJlLWQusKEW/SkBDAtGDcPaz86m9kfcE1lngU0GlM6A==} engines: {node: '>=18.0.0'} + '@smithy/core@3.29.2': + resolution: {integrity: sha512-DXUk6yU0C1Q1tYvJh1VCtl8QOBcSoZpKwjTPkxT6A4MUQYHvgeKGByL8mrEdxnvhdf9nq5GyzmRb5n/vPgu3Lw==} + engines: {node: '>=18.0.0'} + '@smithy/credential-provider-imds@4.4.2': resolution: {integrity: sha512-18UMDMyrAbDcpmL1gLUA7ww0fRTcdCrSjSJOi2Sbld+tVjwD/pW+OAwjlScFLR7vvBnhZrIPQ7kVuTf1mnJLug==} engines: {node: '>=18.0.0'} - '@smithy/credential-provider-imds@4.4.6': - resolution: {integrity: sha512-B2WQ/PV/H6Jeg3lrIq6bKUfa6Hy01mtK7CGs6lhjzHA6k4aagldH6T6eEjnzKl4HI0cJnAsxfJ19pgb5PV+CVQ==} + '@smithy/credential-provider-imds@4.4.7': + resolution: {integrity: sha512-UEMLOoA0Fl4uYBxh6l0uN0H6EJe/A89OGeDNTteQeXpJ20BcpfIr4wlCY9pel1jEAUHAxaYwuqrYlrKdXE1GKQ==} + engines: {node: '>=18.0.0'} + + '@smithy/eventstream-codec@4.4.6': + resolution: {integrity: sha512-4N/HbPptAjynK/FDrTiSAEXmpEDcQw54SeY7qnKbNMOcbHK0B0nEq+OKDYXrnqyp5YhZGzXFDUJANGkdzz6H5Q==} + engines: {node: '>=18.0.0'} + + '@smithy/eventstream-serde-browser@4.4.6': + resolution: {integrity: sha512-++N4gziozNj71MLr9HN/pzt8nnoTdsX9ccjShQthl2TcoZtHObjmbT3d3kBZ8ih1uRTepGGVUVc06qkFtRUAKg==} + engines: {node: '>=18.0.0'} + + '@smithy/eventstream-serde-config-resolver@4.5.6': + resolution: {integrity: sha512-Xn7gFGQg6fxaE0bQSnoAN6miP4M4t7juhv/0ch7wBba+8r+XHCNaF7ktpLkOSrzyCrVQ3ixV8SaMZKINWB80hA==} + engines: {node: '>=18.0.0'} + + '@smithy/eventstream-serde-node@4.4.6': + resolution: {integrity: sha512-kt2PZjaLJK+kSfLetRFKdHo6rfUeVuk65TreMlGBwVi+EhGspaDw3GTQMKKCrHPVe/LVYrkNf518pMZ4hrj/EQ==} engines: {node: '>=18.0.0'} '@smithy/fetch-http-handler@5.5.2': @@ -1461,6 +1506,10 @@ packages: resolution: {integrity: sha512-CwCc/7SMTj45y97MUnDTbTaxvtAsiNNRm81z3abROIuMbMsC2Iy5EKfkkVdsKrz8WExQAAMx1EJapq+9j4fFTQ==} engines: {node: '>=18.0.0'} + '@smithy/fetch-http-handler@5.6.4': + resolution: {integrity: sha512-psnst7NZWdAEvJvyW8YZEE7xNVMyLrQFfHtyrVFrxNyy+dKWkQ+rqC6oI5ZhxThpUy9RSfEshgm34zqbOxzsRw==} + engines: {node: '>=18.0.0'} + '@smithy/hash-node@4.4.2': resolution: {integrity: sha512-M/8PUgwzekn0GcMBjcrTXV4PGFIe1AKuMuHjkHNBfofCPQ9+9Nr35lCvRfQK9BwYHQM+LKiKj8GY0pXSwYm6qQ==} engines: {node: '>=18.0.0'} @@ -1505,6 +1554,10 @@ packages: resolution: {integrity: sha512-qZTa4gQFUo8RM02rk6q5UVTDLNrQ1oS20LsepBzqq1QBVc/EHJ03OOUADcqMZiXHArW+Y7+OGY0BpdTwZRq/Yg==} engines: {node: '>=18.0.0'} + '@smithy/node-http-handler@4.9.4': + resolution: {integrity: sha512-BNTop/fSOptmoVk8g+efwHCofFh37g70OWGAFES1TeAAJja1K5aAI8rTE26ETSc5k8IQuWY2kAIoPla01NgYrA==} + engines: {node: '>=18.0.0'} + '@smithy/property-provider@4.4.2': resolution: {integrity: sha512-V74/UQ+fPPIqZHzeXIUd0H+k/MF+WpeO3I+5wrMCMgsllLt6uqSNbWnLhJs6pMeXZGu6ry+g1bpIdcHNeL+Oww==} engines: {node: '>=18.0.0'} @@ -1513,6 +1566,10 @@ packages: resolution: {integrity: sha512-ZCQGk/UNS+YF5D+Jmhr8+PQX2PJKe4QzR6zuOR5sUinxO/ZiKNA7nyrbeO/Ds2hXLts3fZAtgLPKLJgvjCX9uQ==} engines: {node: '>=18.0.0'} + '@smithy/querystring-builder@4.4.6': + resolution: {integrity: sha512-JT0MimWrP+6EMhbrhxHTpbNfdMmhX77EYoddZgarmc28pA22oseu4NErGMUlUVJaqsn550A4Vz9lx60q0zXK8w==} + engines: {node: '>=18.0.0'} + '@smithy/shared-ini-file-loader@4.6.2': resolution: {integrity: sha512-9Xti1yhj7Em9t4ZQ1E8YRA6wbhAqx1nfLu0XSAqv82HED43TMUvn3nOO2xBISxZc0hcOg7wvuHEypUy4L4XF2w==} engines: {node: '>=18.0.0'} @@ -1525,6 +1582,10 @@ packages: resolution: {integrity: sha512-QgHflghMoPxCJ9axiCVh8KZfbC9fuP6vkXXyK//E3cq7nLaSSyyLj0GAoqVWezYeDQmXIZhmlRvLE16jsqDK6g==} engines: {node: '>=18.0.0'} + '@smithy/signature-v4@5.6.3': + resolution: {integrity: sha512-8qVKKzqh7naF27ePmx0SkUfnGP/wBI9dyaeAmhHvopnbIlItUAmB/e6PkPCU3rRb2v9BY8D4EZXSoydSibatvw==} + engines: {node: '>=18.0.0'} + '@smithy/smithy-client@4.14.2': resolution: {integrity: sha512-H3fp0F/IhG8a6qnoWHeGTH1qDPRR9VVZjcxM9NMXPB6nqzaqcoYIX8D4FFI1Ap2siGr+yvYgKqHC76+afBgF1A==} engines: {node: '>=18.0.0'} @@ -1537,6 +1598,10 @@ packages: resolution: {integrity: sha512-x3L0XSACF6UYzKpa9biqiRMgvH5+wnFFew9Tm/grFYqgaupPwx/+ojDPpPJM8dZON3S9tjz5U+PQYsCBd1Mw5Q==} engines: {node: '>=18.0.0'} + '@smithy/types@4.16.0': + resolution: {integrity: sha512-aVUabzlBBmY0PfvVgLKQSOGFIL5/7R54JE3uD9a5Ay/jSED61SkuAcCYENNXJzYUvJ1NPrWO0P+rAXHCkbBUKw==} + engines: {node: '>=18.0.0'} + '@smithy/url-parser@4.4.2': resolution: {integrity: sha512-vx7FUYJMRfQqdqPRLYwpisOuYU6e1PaabcPUTEc7xG6X0VEr4B6PnjZloHz67qva0pQ9/eNs3xPxvQ6w5gRGAw==} engines: {node: '>=18.0.0'} @@ -1569,6 +1634,10 @@ packages: resolution: {integrity: sha512-K50/sbl8HRnBJt5+UYvIG8HCdEDNA9rhCmkWTDftzGMlJ4XlPgtqI1V6jTSi9tmK7MLfgw7CfGvzSKFSWOteOQ==} engines: {node: '>=18.0.0'} + '@smithy/util-hex-encoding@4.4.6': + resolution: {integrity: sha512-hdLoL1t/JqmsSbhodgbs7/fYwXIGEq+3MiJcSBsVoHsHyaBFv/Y1qQfZm0i5FR3NakhgYQsD5d1Z4Aoc5JdDlg==} + engines: {node: '>=18.0.0'} + '@smithy/util-middleware@4.4.2': resolution: {integrity: sha512-Xk039bCOxEZfasaHSHPj0QS8EY2npd0z3nxLkDvczg9ueF7eboiKw0HEa5pILLwjb+sjSlgzSjoCOVAM715TzA==} engines: {node: '>=18.0.0'} @@ -1682,8 +1751,8 @@ packages: '@types/node@22.19.21': resolution: {integrity: sha512-VMeFBSCKQKmm2swI2kW51SFusDqekC6q9trBCvJ/JliDchFSuoYYKN7yVNjPthP1HKZcx3U1gI/wTcEBjEFKTA==} - '@types/node@25.9.4': - resolution: {integrity: sha512-dszCsrKb5U7ZsVZBWiHFklTloVl0mSEnWH/iZXfZUlI4rzCUnsvGmgqfuVRHL54ugE7/wRuxEIXRa2iMZ+BG6g==} + '@types/node@25.9.5': + resolution: {integrity: sha512-OScDchr2fwuUmWdf4kZ9h7PcJiYDVInhJizG/biAq3cAvqwYktuy/TYGGdZNMtNTFUP7rnb0NU4TUdm82kt4Rg==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -4388,26 +4457,78 @@ snapshots: '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/checksums@3.1000.13': + '@aws-sdk/checksums@3.1000.16': dependencies: - '@aws-sdk/core': 3.974.28 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 + '@aws-sdk/core': 3.975.1 + '@aws-sdk/types': 3.974.0 + '@smithy/core': 3.29.2 + '@smithy/types': 4.16.0 tslib: 2.8.1 - '@aws-sdk/client-s3@3.1080.0': + '@aws-sdk/client-bedrock-runtime@3.967.0': dependencies: - '@aws-sdk/checksums': 3.1000.13 - '@aws-sdk/core': 3.974.28 - '@aws-sdk/credential-provider-node': 3.972.63 - '@aws-sdk/middleware-sdk-s3': 3.972.59 - '@aws-sdk/signature-v4-multi-region': 3.996.38 - '@aws-sdk/types': 3.973.15 + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.967.0 + '@aws-sdk/credential-provider-node': 3.967.0 + '@aws-sdk/eventstream-handler-node': 3.965.0 + '@aws-sdk/middleware-eventstream': 3.965.0 + '@aws-sdk/middleware-host-header': 3.965.0 + '@aws-sdk/middleware-logger': 3.965.0 + '@aws-sdk/middleware-recursion-detection': 3.965.0 + '@aws-sdk/middleware-user-agent': 3.967.0 + '@aws-sdk/middleware-websocket': 3.965.0 + '@aws-sdk/region-config-resolver': 3.965.0 + '@aws-sdk/token-providers': 3.967.0 + '@aws-sdk/types': 3.965.0 + '@aws-sdk/util-endpoints': 3.965.0 + '@aws-sdk/util-user-agent-browser': 3.965.0 + '@aws-sdk/util-user-agent-node': 3.967.0 + '@smithy/config-resolver': 4.6.2 '@smithy/core': 3.29.1 + '@smithy/eventstream-serde-browser': 4.4.6 + '@smithy/eventstream-serde-config-resolver': 4.5.6 + '@smithy/eventstream-serde-node': 4.4.6 '@smithy/fetch-http-handler': 5.6.3 + '@smithy/hash-node': 4.4.2 + '@smithy/invalid-dependency': 4.4.2 + '@smithy/middleware-content-length': 4.4.2 + '@smithy/middleware-endpoint': 4.6.2 + '@smithy/middleware-retry': 4.7.2 + '@smithy/middleware-serde': 4.4.2 + '@smithy/middleware-stack': 4.4.2 + '@smithy/node-config-provider': 4.5.2 '@smithy/node-http-handler': 4.9.3 + '@smithy/protocol-http': 5.5.2 + '@smithy/smithy-client': 4.14.2 '@smithy/types': 4.15.1 + '@smithy/url-parser': 4.4.2 + '@smithy/util-base64': 4.5.2 + '@smithy/util-body-length-browser': 4.4.2 + '@smithy/util-body-length-node': 4.4.2 + '@smithy/util-defaults-mode-browser': 4.5.2 + '@smithy/util-defaults-mode-node': 4.4.2 + '@smithy/util-endpoints': 3.6.2 + '@smithy/util-middleware': 4.4.2 + '@smithy/util-retry': 4.5.2 + '@smithy/util-stream': 4.7.2 + '@smithy/util-utf8': 4.4.2 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-s3@3.1083.0': + dependencies: + '@aws-sdk/checksums': 3.1000.16 + '@aws-sdk/core': 3.975.1 + '@aws-sdk/credential-provider-node': 3.972.66 + '@aws-sdk/middleware-sdk-s3': 3.972.62 + '@aws-sdk/signature-v4-multi-region': 3.996.39 + '@aws-sdk/types': 3.974.0 + '@smithy/core': 3.29.2 + '@smithy/fetch-http-handler': 5.6.4 + '@smithy/node-http-handler': 4.9.4 + '@smithy/types': 4.16.0 tslib: 2.8.1 '@aws-sdk/client-s3vectors@3.967.0': @@ -4469,8 +4590,8 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.965.0 '@aws-sdk/util-user-agent-node': 3.967.0 '@smithy/config-resolver': 4.6.2 - '@smithy/core': 3.26.0 - '@smithy/fetch-http-handler': 5.5.2 + '@smithy/core': 3.29.1 + '@smithy/fetch-http-handler': 5.6.3 '@smithy/hash-node': 4.4.2 '@smithy/invalid-dependency': 4.4.2 '@smithy/middleware-content-length': 4.4.2 @@ -4479,10 +4600,10 @@ snapshots: '@smithy/middleware-serde': 4.4.2 '@smithy/middleware-stack': 4.4.2 '@smithy/node-config-provider': 4.5.2 - '@smithy/node-http-handler': 4.8.2 + '@smithy/node-http-handler': 4.9.3 '@smithy/protocol-http': 5.5.2 '@smithy/smithy-client': 4.14.2 - '@smithy/types': 4.15.0 + '@smithy/types': 4.15.1 '@smithy/url-parser': 4.4.2 '@smithy/util-base64': 4.5.2 '@smithy/util-body-length-browser': 4.4.2 @@ -4513,14 +4634,14 @@ snapshots: '@smithy/util-utf8': 4.4.2 tslib: 2.8.1 - '@aws-sdk/core@3.974.28': + '@aws-sdk/core@3.975.1': dependencies: - '@aws-sdk/types': 3.973.15 - '@aws-sdk/xml-builder': 3.972.33 + '@aws-sdk/types': 3.974.0 + '@aws-sdk/xml-builder': 3.972.34 '@aws/lambda-invoke-store': 0.3.0 - '@smithy/core': 3.29.1 - '@smithy/signature-v4': 5.6.2 - '@smithy/types': 4.15.1 + '@smithy/core': 3.29.2 + '@smithy/signature-v4': 5.6.3 + '@smithy/types': 4.16.0 bowser: 2.14.1 tslib: 2.8.1 @@ -4529,38 +4650,38 @@ snapshots: '@aws-sdk/core': 3.967.0 '@aws-sdk/types': 3.965.0 '@smithy/property-provider': 4.4.2 - '@smithy/types': 4.15.0 + '@smithy/types': 4.15.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.972.54': + '@aws-sdk/credential-provider-env@3.972.57': dependencies: - '@aws-sdk/core': 3.974.28 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 + '@aws-sdk/core': 3.975.1 + '@aws-sdk/types': 3.974.0 + '@smithy/core': 3.29.2 + '@smithy/types': 4.16.0 tslib: 2.8.1 '@aws-sdk/credential-provider-http@3.967.0': dependencies: '@aws-sdk/core': 3.967.0 '@aws-sdk/types': 3.965.0 - '@smithy/fetch-http-handler': 5.5.2 - '@smithy/node-http-handler': 4.8.2 + '@smithy/fetch-http-handler': 5.6.3 + '@smithy/node-http-handler': 4.9.3 '@smithy/property-provider': 4.4.2 '@smithy/protocol-http': 5.5.2 '@smithy/smithy-client': 4.14.2 - '@smithy/types': 4.15.0 + '@smithy/types': 4.15.1 '@smithy/util-stream': 4.7.2 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.972.56': + '@aws-sdk/credential-provider-http@3.972.59': dependencies: - '@aws-sdk/core': 3.974.28 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/fetch-http-handler': 5.6.3 - '@smithy/node-http-handler': 4.9.3 - '@smithy/types': 4.15.1 + '@aws-sdk/core': 3.975.1 + '@aws-sdk/types': 3.974.0 + '@smithy/core': 3.29.2 + '@smithy/fetch-http-handler': 5.6.4 + '@smithy/node-http-handler': 4.9.4 + '@smithy/types': 4.16.0 tslib: 2.8.1 '@aws-sdk/credential-provider-ini@3.967.0': @@ -4577,25 +4698,25 @@ snapshots: '@smithy/credential-provider-imds': 4.4.2 '@smithy/property-provider': 4.4.2 '@smithy/shared-ini-file-loader': 4.6.2 - '@smithy/types': 4.15.0 + '@smithy/types': 4.15.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-ini@3.972.61': + '@aws-sdk/credential-provider-ini@3.973.1': dependencies: - '@aws-sdk/core': 3.974.28 - '@aws-sdk/credential-provider-env': 3.972.54 - '@aws-sdk/credential-provider-http': 3.972.56 - '@aws-sdk/credential-provider-login': 3.972.60 - '@aws-sdk/credential-provider-process': 3.972.54 - '@aws-sdk/credential-provider-sso': 3.972.60 - '@aws-sdk/credential-provider-web-identity': 3.972.60 - '@aws-sdk/nested-clients': 3.997.28 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/credential-provider-imds': 4.4.6 - '@smithy/types': 4.15.1 + '@aws-sdk/core': 3.975.1 + '@aws-sdk/credential-provider-env': 3.972.57 + '@aws-sdk/credential-provider-http': 3.972.59 + '@aws-sdk/credential-provider-login': 3.972.63 + '@aws-sdk/credential-provider-process': 3.972.57 + '@aws-sdk/credential-provider-sso': 3.973.1 + '@aws-sdk/credential-provider-web-identity': 3.972.63 + '@aws-sdk/nested-clients': 3.997.31 + '@aws-sdk/types': 3.974.0 + '@smithy/core': 3.29.2 + '@smithy/credential-provider-imds': 4.4.7 + '@smithy/types': 4.16.0 tslib: 2.8.1 '@aws-sdk/credential-provider-login@3.967.0': @@ -4606,18 +4727,18 @@ snapshots: '@smithy/property-provider': 4.4.2 '@smithy/protocol-http': 5.5.2 '@smithy/shared-ini-file-loader': 4.6.2 - '@smithy/types': 4.15.0 + '@smithy/types': 4.15.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-login@3.972.60': + '@aws-sdk/credential-provider-login@3.972.63': dependencies: - '@aws-sdk/core': 3.974.28 - '@aws-sdk/nested-clients': 3.997.28 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 + '@aws-sdk/core': 3.975.1 + '@aws-sdk/nested-clients': 3.997.31 + '@aws-sdk/types': 3.974.0 + '@smithy/core': 3.29.2 + '@smithy/types': 4.16.0 tslib: 2.8.1 '@aws-sdk/credential-provider-node@3.967.0': @@ -4637,18 +4758,18 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.972.63': + '@aws-sdk/credential-provider-node@3.972.66': dependencies: - '@aws-sdk/credential-provider-env': 3.972.54 - '@aws-sdk/credential-provider-http': 3.972.56 - '@aws-sdk/credential-provider-ini': 3.972.61 - '@aws-sdk/credential-provider-process': 3.972.54 - '@aws-sdk/credential-provider-sso': 3.972.60 - '@aws-sdk/credential-provider-web-identity': 3.972.60 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/credential-provider-imds': 4.4.6 - '@smithy/types': 4.15.1 + '@aws-sdk/credential-provider-env': 3.972.57 + '@aws-sdk/credential-provider-http': 3.972.59 + '@aws-sdk/credential-provider-ini': 3.973.1 + '@aws-sdk/credential-provider-process': 3.972.57 + '@aws-sdk/credential-provider-sso': 3.973.1 + '@aws-sdk/credential-provider-web-identity': 3.972.63 + '@aws-sdk/types': 3.974.0 + '@smithy/core': 3.29.2 + '@smithy/credential-provider-imds': 4.4.7 + '@smithy/types': 4.16.0 tslib: 2.8.1 '@aws-sdk/credential-provider-process@3.967.0': @@ -4657,15 +4778,15 @@ snapshots: '@aws-sdk/types': 3.965.0 '@smithy/property-provider': 4.4.2 '@smithy/shared-ini-file-loader': 4.6.2 - '@smithy/types': 4.15.0 + '@smithy/types': 4.15.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-process@3.972.54': + '@aws-sdk/credential-provider-process@3.972.57': dependencies: - '@aws-sdk/core': 3.974.28 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 + '@aws-sdk/core': 3.975.1 + '@aws-sdk/types': 3.974.0 + '@smithy/core': 3.29.2 + '@smithy/types': 4.16.0 tslib: 2.8.1 '@aws-sdk/credential-provider-sso@3.967.0': @@ -4676,19 +4797,19 @@ snapshots: '@aws-sdk/types': 3.965.0 '@smithy/property-provider': 4.4.2 '@smithy/shared-ini-file-loader': 4.6.2 - '@smithy/types': 4.15.0 + '@smithy/types': 4.15.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-sso@3.972.60': + '@aws-sdk/credential-provider-sso@3.973.1': dependencies: - '@aws-sdk/core': 3.974.28 - '@aws-sdk/nested-clients': 3.997.28 - '@aws-sdk/token-providers': 3.1080.0 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 + '@aws-sdk/core': 3.975.1 + '@aws-sdk/nested-clients': 3.997.31 + '@aws-sdk/token-providers': 3.1083.0 + '@aws-sdk/types': 3.974.0 + '@smithy/core': 3.29.2 + '@smithy/types': 4.16.0 tslib: 2.8.1 '@aws-sdk/credential-provider-web-identity@3.967.0': @@ -4698,17 +4819,31 @@ snapshots: '@aws-sdk/types': 3.965.0 '@smithy/property-provider': 4.4.2 '@smithy/shared-ini-file-loader': 4.6.2 - '@smithy/types': 4.15.0 + '@smithy/types': 4.15.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.972.60': + '@aws-sdk/credential-provider-web-identity@3.972.63': dependencies: - '@aws-sdk/core': 3.974.28 - '@aws-sdk/nested-clients': 3.997.28 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 + '@aws-sdk/core': 3.975.1 + '@aws-sdk/nested-clients': 3.997.31 + '@aws-sdk/types': 3.974.0 + '@smithy/core': 3.29.2 + '@smithy/types': 4.16.0 + tslib: 2.8.1 + + '@aws-sdk/eventstream-handler-node@3.965.0': + dependencies: + '@aws-sdk/types': 3.965.0 + '@smithy/eventstream-codec': 4.4.6 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/middleware-eventstream@3.965.0': + dependencies: + '@aws-sdk/types': 3.965.0 + '@smithy/protocol-http': 5.5.2 '@smithy/types': 4.15.1 tslib: 2.8.1 @@ -4733,13 +4868,13 @@ snapshots: '@smithy/types': 4.15.0 tslib: 2.8.1 - '@aws-sdk/middleware-sdk-s3@3.972.59': + '@aws-sdk/middleware-sdk-s3@3.972.62': dependencies: - '@aws-sdk/core': 3.974.28 - '@aws-sdk/signature-v4-multi-region': 3.996.38 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 + '@aws-sdk/core': 3.975.1 + '@aws-sdk/signature-v4-multi-region': 3.996.39 + '@aws-sdk/types': 3.974.0 + '@smithy/core': 3.29.2 + '@smithy/types': 4.16.0 tslib: 2.8.1 '@aws-sdk/middleware-user-agent@3.967.0': @@ -4752,6 +4887,19 @@ snapshots: '@smithy/types': 4.15.0 tslib: 2.8.1 + '@aws-sdk/middleware-websocket@3.965.0': + dependencies: + '@aws-sdk/types': 3.965.0 + '@aws-sdk/util-format-url': 3.965.0 + '@smithy/eventstream-codec': 4.4.6 + '@smithy/eventstream-serde-browser': 4.4.6 + '@smithy/fetch-http-handler': 5.6.3 + '@smithy/protocol-http': 5.5.2 + '@smithy/signature-v4': 5.6.2 + '@smithy/types': 4.15.1 + '@smithy/util-hex-encoding': 4.4.6 + tslib: 2.8.1 + '@aws-sdk/nested-clients@3.967.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 @@ -4767,8 +4915,8 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.965.0 '@aws-sdk/util-user-agent-node': 3.967.0 '@smithy/config-resolver': 4.6.2 - '@smithy/core': 3.26.0 - '@smithy/fetch-http-handler': 5.5.2 + '@smithy/core': 3.29.1 + '@smithy/fetch-http-handler': 5.6.3 '@smithy/hash-node': 4.4.2 '@smithy/invalid-dependency': 4.4.2 '@smithy/middleware-content-length': 4.4.2 @@ -4777,10 +4925,10 @@ snapshots: '@smithy/middleware-serde': 4.4.2 '@smithy/middleware-stack': 4.4.2 '@smithy/node-config-provider': 4.5.2 - '@smithy/node-http-handler': 4.8.2 + '@smithy/node-http-handler': 4.9.3 '@smithy/protocol-http': 5.5.2 '@smithy/smithy-client': 4.14.2 - '@smithy/types': 4.15.0 + '@smithy/types': 4.15.1 '@smithy/url-parser': 4.4.2 '@smithy/util-base64': 4.5.2 '@smithy/util-body-length-browser': 4.4.2 @@ -4795,15 +4943,15 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/nested-clients@3.997.28': + '@aws-sdk/nested-clients@3.997.31': dependencies: - '@aws-sdk/core': 3.974.28 - '@aws-sdk/signature-v4-multi-region': 3.996.38 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/fetch-http-handler': 5.6.3 - '@smithy/node-http-handler': 4.9.3 - '@smithy/types': 4.15.1 + '@aws-sdk/core': 3.975.1 + '@aws-sdk/signature-v4-multi-region': 3.996.39 + '@aws-sdk/types': 3.974.0 + '@smithy/core': 3.29.2 + '@smithy/fetch-http-handler': 5.6.4 + '@smithy/node-http-handler': 4.9.4 + '@smithy/types': 4.16.0 tslib: 2.8.1 '@aws-sdk/region-config-resolver@3.965.0': @@ -4814,20 +4962,20 @@ snapshots: '@smithy/types': 4.15.0 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.996.38': + '@aws-sdk/signature-v4-multi-region@3.996.39': dependencies: - '@aws-sdk/types': 3.973.15 - '@smithy/signature-v4': 5.6.2 - '@smithy/types': 4.15.1 + '@aws-sdk/types': 3.974.0 + '@smithy/signature-v4': 5.6.3 + '@smithy/types': 4.16.0 tslib: 2.8.1 - '@aws-sdk/token-providers@3.1080.0': + '@aws-sdk/token-providers@3.1083.0': dependencies: - '@aws-sdk/core': 3.974.28 - '@aws-sdk/nested-clients': 3.997.28 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 + '@aws-sdk/core': 3.975.1 + '@aws-sdk/nested-clients': 3.997.31 + '@aws-sdk/types': 3.974.0 + '@smithy/core': 3.29.2 + '@smithy/types': 4.16.0 tslib: 2.8.1 '@aws-sdk/token-providers@3.967.0': @@ -4837,7 +4985,7 @@ snapshots: '@aws-sdk/types': 3.965.0 '@smithy/property-provider': 4.4.2 '@smithy/shared-ini-file-loader': 4.6.2 - '@smithy/types': 4.15.0 + '@smithy/types': 4.15.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -4852,9 +5000,9 @@ snapshots: '@smithy/types': 4.15.0 tslib: 2.8.1 - '@aws-sdk/types@3.973.15': + '@aws-sdk/types@3.974.0': dependencies: - '@smithy/types': 4.15.1 + '@smithy/types': 4.16.0 tslib: 2.8.1 '@aws-sdk/util-endpoints@3.965.0': @@ -4865,6 +5013,13 @@ snapshots: '@smithy/util-endpoints': 3.6.2 tslib: 2.8.1 + '@aws-sdk/util-format-url@3.965.0': + dependencies: + '@aws-sdk/types': 3.965.0 + '@smithy/querystring-builder': 4.4.6 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + '@aws-sdk/util-locate-window@3.965.8': dependencies: tslib: 2.8.1 @@ -4890,9 +5045,9 @@ snapshots: fast-xml-parser: 5.9.3 tslib: 2.8.1 - '@aws-sdk/xml-builder@3.972.33': + '@aws-sdk/xml-builder@3.972.34': dependencies: - '@smithy/types': 4.15.1 + '@smithy/types': 4.16.0 tslib: 2.8.1 '@aws/lambda-invoke-store@0.2.4': {} @@ -5916,7 +6071,7 @@ snapshots: '@shanghaikid/parquetjs@1.8.8': dependencies: - '@aws-sdk/client-s3': 3.1080.0 + '@aws-sdk/client-s3': 3.1083.0 '@types/node-int64': 0.4.32 '@types/thrift': 0.10.17 '@zenfs/core': 2.5.7 @@ -5959,18 +6114,43 @@ snapshots: '@smithy/types': 4.15.1 tslib: 2.8.1 - '@smithy/credential-provider-imds@4.4.2': + '@smithy/core@3.29.2': dependencies: - '@smithy/core': 3.26.0 - '@smithy/types': 4.15.0 + '@smithy/types': 4.16.0 tslib: 2.8.1 - '@smithy/credential-provider-imds@4.4.6': + '@smithy/credential-provider-imds@4.4.2': dependencies: '@smithy/core': 3.29.1 '@smithy/types': 4.15.1 tslib: 2.8.1 + '@smithy/credential-provider-imds@4.4.7': + dependencies: + '@smithy/core': 3.29.2 + '@smithy/types': 4.16.0 + tslib: 2.8.1 + + '@smithy/eventstream-codec@4.4.6': + dependencies: + '@smithy/core': 3.29.1 + tslib: 2.8.1 + + '@smithy/eventstream-serde-browser@4.4.6': + dependencies: + '@smithy/core': 3.29.1 + tslib: 2.8.1 + + '@smithy/eventstream-serde-config-resolver@4.5.6': + dependencies: + '@smithy/core': 3.29.1 + tslib: 2.8.1 + + '@smithy/eventstream-serde-node@4.4.6': + dependencies: + '@smithy/core': 3.29.1 + tslib: 2.8.1 + '@smithy/fetch-http-handler@5.5.2': dependencies: '@smithy/core': 3.26.0 @@ -5983,6 +6163,12 @@ snapshots: '@smithy/types': 4.15.1 tslib: 2.8.1 + '@smithy/fetch-http-handler@5.6.4': + dependencies: + '@smithy/core': 3.29.2 + '@smithy/types': 4.16.0 + tslib: 2.8.1 + '@smithy/hash-node@4.4.2': dependencies: '@smithy/core': 3.26.0 @@ -6039,6 +6225,12 @@ snapshots: '@smithy/types': 4.15.1 tslib: 2.8.1 + '@smithy/node-http-handler@4.9.4': + dependencies: + '@smithy/core': 3.29.2 + '@smithy/types': 4.16.0 + tslib: 2.8.1 + '@smithy/property-provider@4.4.2': dependencies: '@smithy/core': 3.26.0 @@ -6049,9 +6241,14 @@ snapshots: '@smithy/core': 3.26.0 tslib: 2.8.1 + '@smithy/querystring-builder@4.4.6': + dependencies: + '@smithy/core': 3.29.1 + tslib: 2.8.1 + '@smithy/shared-ini-file-loader@4.6.2': dependencies: - '@smithy/core': 3.26.0 + '@smithy/core': 3.29.1 tslib: 2.8.1 '@smithy/signature-v4@5.5.2': @@ -6066,6 +6263,12 @@ snapshots: '@smithy/types': 4.15.1 tslib: 2.8.1 + '@smithy/signature-v4@5.6.3': + dependencies: + '@smithy/core': 3.29.2 + '@smithy/types': 4.16.0 + tslib: 2.8.1 + '@smithy/smithy-client@4.14.2': dependencies: '@smithy/core': 3.26.0 @@ -6080,6 +6283,10 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/types@4.16.0': + dependencies: + tslib: 2.8.1 + '@smithy/url-parser@4.4.2': dependencies: '@smithy/core': 3.26.0 @@ -6120,6 +6327,11 @@ snapshots: '@smithy/core': 3.26.0 tslib: 2.8.1 + '@smithy/util-hex-encoding@4.4.6': + dependencies: + '@smithy/core': 3.29.1 + tslib: 2.8.1 + '@smithy/util-middleware@4.4.2': dependencies: '@smithy/core': 3.26.0 @@ -6132,7 +6344,7 @@ snapshots: '@smithy/util-stream@4.7.2': dependencies: - '@smithy/core': 3.26.0 + '@smithy/core': 3.29.1 tslib: 2.8.1 '@smithy/util-utf8@2.3.0': @@ -6260,7 +6472,7 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@25.9.4': + '@types/node@25.9.5': dependencies: undici-types: 7.24.6 @@ -6315,7 +6527,7 @@ snapshots: '@zenfs/core@2.5.7': dependencies: - '@types/node': 25.9.4 + '@types/node': 25.9.5 buffer: 6.0.3 eventemitter3: 5.0.4 kerium: 1.3.9 diff --git a/mem0-ts/src/oss/src/config/manager.ts b/mem0-ts/src/oss/src/config/manager.ts index 567e9ad69..c4ad83116 100644 --- a/mem0-ts/src/oss/src/config/manager.ts +++ b/mem0-ts/src/oss/src/config/manager.ts @@ -137,6 +137,11 @@ export class ConfigManager { userConf?.maxTokens ?? (llmRaw?.max_tokens as number | undefined); return { + // Spread user-provided config first so any additional fields + // (e.g. future aws_bedrock options) pass through without a + // manager.ts edit, matching the vectorStore.config pattern above + // and making the schema's .passthrough() on llm.config meaningful. + ...userConf, baseURL: llmBaseURL, url: userConf?.url, apiKey: @@ -151,6 +156,20 @@ export class ConfigManager { temperature, topP, maxTokens, + // Pass through AWS Bedrock fields so the aws_bedrock provider works + // through the standard Memory config path (snake_case tolerated). + awsRegion: + userConf?.awsRegion ?? (llmRaw?.aws_region as string | undefined), + awsAccessKeyId: + userConf?.awsAccessKeyId ?? + (llmRaw?.aws_access_key_id as string | undefined), + awsSecretAccessKey: + userConf?.awsSecretAccessKey ?? + (llmRaw?.aws_secret_access_key as string | undefined), + awsSessionToken: + userConf?.awsSessionToken ?? + (llmRaw?.aws_session_token as string | undefined), + client: userConf?.client, }; })(), }, diff --git a/mem0-ts/src/oss/src/index.ts b/mem0-ts/src/oss/src/index.ts index d8a98abb0..677a73cf7 100644 --- a/mem0-ts/src/oss/src/index.ts +++ b/mem0-ts/src/oss/src/index.ts @@ -24,6 +24,7 @@ export * from "./llms/mistral"; export * from "./llms/langchain"; export * from "./llms/litellm"; export * from "./llms/vllm"; +export * from "./llms/aws_bedrock"; export * from "./vector_stores/base"; export * from "./vector_stores/memory"; export * from "./vector_stores/baidu"; diff --git a/mem0-ts/src/oss/src/llms/aws_bedrock.ts b/mem0-ts/src/oss/src/llms/aws_bedrock.ts new file mode 100644 index 000000000..fd1871472 --- /dev/null +++ b/mem0-ts/src/oss/src/llms/aws_bedrock.ts @@ -0,0 +1,294 @@ +import { LLM, LLMResponse } from "./base"; +import { LLMConfig, Message } from "../types"; + +/** + * Providers recognised in Bedrock model identifiers, mirroring the Python + * provider's `PROVIDERS` list (`mem0/llms/aws_bedrock.py`). + */ +const PROVIDERS = [ + "ai21", + "amazon", + "anthropic", + "cohere", + "meta", + "mistral", + "stability", + "writer", + "deepseek", + "gpt-oss", + "perplexity", + "snowflake", + "titan", + "command", + "j2", + "llama", + "minimax", +]; + +/** + * Extract the model-family provider from a Bedrock model id + * (e.g. `anthropic.claude-3-sonnet-...` -> `anthropic`). + */ +export function extractProvider(model: string): string { + for (const provider of PROVIDERS) { + const re = new RegExp( + `\\b${provider.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`, + ); + if (re.test(model)) return provider; + } + throw new Error(`Unknown provider in model: ${model}`); +} + +/** + * AWS Bedrock fields (awsRegion / awsAccessKeyId / awsSecretAccessKey / + * awsSessionToken / client) now live on the shared `LLMConfig`, so the + * provider is configurable through the standard typed `Memory` config path. + */ +type AWSBedrockConfig = LLMConfig; + +/** + * AWS Bedrock LLM provider for the TypeScript OSS SDK. + * + * Mirrors `mem0/llms/aws_bedrock.py`. Uses the Bedrock **Converse API** + * (`ConverseCommand`), which provides a uniform message/tool interface across + * the Anthropic / Amazon (Nova) / Meta / Mistral / Cohere model families, so a + * single code path serves them all (the Python provider keeps per-family + * `invoke_model` branches for legacy reasons; Converse supersedes them). + * + * The `@aws-sdk/client-bedrock-runtime` dependency is loaded on first use via + * dynamic `import()` so the package stays optional. Credentials resolve via the + * standard AWS chain unless provided explicitly in config. + */ +interface BedrockSDK { + BedrockRuntimeClient: new (config: Record) => any; + ConverseCommand: new (input: Record) => any; +} + +export class AWSBedrockLLM implements LLM { + private model: string; + private provider: string; + private temperature: number; + private maxTokens: number; + private topP?: number; + private clientConfig: Record; + private clientOverride?: any; + private sdkPromise?: Promise; + private clientPromise?: Promise; + + constructor(config: AWSBedrockConfig = {}) { + this.model = + (typeof config.model === "string" && config.model) || + "anthropic.claude-3-5-sonnet-20240620-v1:0"; + this.provider = extractProvider(this.model); + this.temperature = config.temperature ?? 0.1; + this.maxTokens = config.maxTokens ?? 2000; + this.topP = config.topP; + + const region = + config.awsRegion || + process.env.AWS_REGION || + process.env.AWS_DEFAULT_REGION; + const clientConfig: Record = {}; + if (region) clientConfig.region = region; + if (config.awsAccessKeyId && config.awsSecretAccessKey) { + clientConfig.credentials = { + accessKeyId: config.awsAccessKeyId, + secretAccessKey: config.awsSecretAccessKey, + ...(config.awsSessionToken && { + sessionToken: config.awsSessionToken, + }), + }; + } + + this.clientConfig = clientConfig; + this.clientOverride = config.client; + } + + /** + * Load the optional AWS SDK on first use. + * + * This MUST be a dynamic `import()`, never `require()`: tsup/esbuild rewrite + * `require()` in the published ESM bundle (`dist/oss/index.mjs`) into a + * `__require` shim that throws `Dynamic require of "..." is not supported`, + * so every ESM consumer would hit a dead provider even with the SDK installed. + */ + private async getSDK(): Promise { + if (!this.sdkPromise) { + this.sdkPromise = import("@aws-sdk/client-bedrock-runtime").then( + (sdk) => sdk as unknown as BedrockSDK, + (err) => { + // Let a later call retry rather than caching the rejection forever. + this.sdkPromise = undefined; + const detail = err instanceof Error ? err.message : String(err); + throw new Error( + "The '@aws-sdk/client-bedrock-runtime' package is required to use the AWS Bedrock LLM provider. " + + `Install it with: npm install @aws-sdk/client-bedrock-runtime (original error: ${detail})`, + ); + }, + ); + } + return this.sdkPromise; + } + + /** Memoized Bedrock client; an injected `config.client` short-circuits the SDK. */ + private async getClient(): Promise { + if (this.clientOverride) return this.clientOverride; + if (!this.clientPromise) { + this.clientPromise = this.getSDK().then( + ({ BedrockRuntimeClient }) => + new BedrockRuntimeClient(this.clientConfig), + ); + } + return this.clientPromise; + } + + /** + * Split messages into a top-level `system` block (Converse passes system + * prompts separately) and role-tagged content blocks for everything else. + */ + private formatMessages(messages: Message[]): { + system?: { text: string }[]; + converseMessages: { role: string; content: { text: string }[] }[]; + } { + const systemParts: string[] = []; + const converseMessages: { role: string; content: { text: string }[] }[] = + []; + + for (const msg of messages) { + const role = msg.role; + const content = + typeof msg.content === "string" + ? msg.content + : JSON.stringify(msg.content); + if (role === "system") { + systemParts.push(content); + } else { + converseMessages.push({ + role: role === "assistant" ? "assistant" : "user", + content: [{ text: content }], + }); + } + } + + if (converseMessages.length === 0) { + converseMessages.push({ role: "user", content: [{ text: "" }] }); + } + + return { + system: systemParts.length + ? [{ text: systemParts.join("\n") }] + : undefined, + converseMessages, + }; + } + + /** + * Build the Converse `inferenceConfig`. Anthropic and MiniMax reasoning + * models reject requests carrying both `temperature` and `topP`, so `topP` + * is omitted for those families (mirrors the Python `_build_inference_config`). + */ + private buildInferenceConfig(): Record { + const inferenceConfig: Record = { + maxTokens: this.maxTokens, + temperature: this.temperature, + }; + if ( + this.topP != null && + !["anthropic", "minimax"].includes(this.provider) + ) { + inferenceConfig.topP = this.topP; + } + return inferenceConfig; + } + + /** Convert OpenAI-style tools to the Converse `toolConfig` shape. */ + private convertToolsToConverse(tools: any[]): any | undefined { + if (!tools || tools.length === 0) return undefined; + const converseTools = tools + .filter((t) => t?.type === "function" && t.function) + .map((t) => ({ + toolSpec: { + name: t.function.name, + description: t.function.description || "", + inputSchema: { json: t.function.parameters || {} }, + }, + })); + return converseTools.length ? { tools: converseTools } : undefined; + } + + private async converse(messages: Message[], tools?: any[]): Promise { + const { system, converseMessages } = this.formatMessages(messages); + const input: Record = { + modelId: this.model, + messages: converseMessages, + inferenceConfig: this.buildInferenceConfig(), + }; + if (system) input.system = system; + const toolConfig = tools ? this.convertToolsToConverse(tools) : undefined; + if (toolConfig) input.toolConfig = toolConfig; + + const [{ ConverseCommand }, client] = await Promise.all([ + this.getSDK(), + this.getClient(), + ]); + return client.send(new ConverseCommand(input)); + } + + /** Pull the first text block out of a Converse response. */ + private parseText(response: any): string { + const content = response?.output?.message?.content || []; + for (const block of content) { + if (block && typeof block.text === "string") return block.text; + } + return ""; + } + + /** Collect any toolUse blocks out of a Converse response. */ + private parseToolCalls(response: any): { name: string; arguments: string }[] { + const content = response?.output?.message?.content || []; + const calls: { name: string; arguments: string }[] = []; + for (const block of content) { + if (block?.toolUse) { + calls.push({ + name: block.toolUse.name, + arguments: JSON.stringify(block.toolUse.input ?? {}), + }); + } + } + return calls; + } + + async generateResponse( + messages: Message[], + _responseFormat?: { type: string }, + tools?: any[], + ): Promise { + try { + const response = await this.converse(messages, tools); + if (tools && tools.length) { + const toolCalls = this.parseToolCalls(response); + if (toolCalls.length) { + return { + content: this.parseText(response), + role: "assistant", + toolCalls, + }; + } + } + return this.parseText(response); + } catch (err) { + const message = err instanceof Error ? err.message : String(err); + throw new Error(`AWS Bedrock LLM failed: ${message}`); + } + } + + async generateChat(messages: Message[]): Promise { + try { + const response = await this.converse(messages); + return { content: this.parseText(response), role: "assistant" }; + } catch (err) { + const message = err instanceof Error ? err.message : String(err); + throw new Error(`AWS Bedrock LLM failed: ${message}`); + } + } +} diff --git a/mem0-ts/src/oss/src/tests/aws_bedrock.test.ts b/mem0-ts/src/oss/src/tests/aws_bedrock.test.ts new file mode 100644 index 000000000..b02ab880e --- /dev/null +++ b/mem0-ts/src/oss/src/tests/aws_bedrock.test.ts @@ -0,0 +1,214 @@ +import { readFileSync } from "fs"; +import { join } from "path"; + +import { AWSBedrockLLM, extractProvider } from "../llms/aws_bedrock"; + +/** + * Fake BedrockRuntimeClient capturing the Converse command input and returning + * a scripted response — exercises request shaping + response parsing without + * the AWS SDK or live credentials. + */ +class FakeBedrockClient { + public lastInput: any = null; + public response: any; + constructor(response: any) { + this.response = response; + } + async send(command: any) { + // ConverseCommand stores its input on `.input` (mirrored by our fake command). + this.lastInput = command?.input ?? command; + return this.response; + } +} + +// Counts real client constructions so we can prove the SDK stays untouched +// until the first request. (jest only lets mock factories close over `mock*`.) +let mockClientConstructions = 0; + +// The provider loads the AWS SDK on first use via dynamic import(). Mock the +// module so it resolves and ConverseCommand simply wraps its input. +jest.mock( + "@aws-sdk/client-bedrock-runtime", + () => ({ + BedrockRuntimeClient: class { + constructor(public config: any) { + mockClientConstructions++; + } + }, + ConverseCommand: class { + input: any; + constructor(input: any) { + this.input = input; + } + }, + }), + { virtual: true }, +); + +function makeLLM(client: FakeBedrockClient, overrides: any = {}) { + return new AWSBedrockLLM({ + model: "anthropic.claude-3-5-sonnet-20240620-v1:0", + client, + ...overrides, + }); +} + +describe("extractProvider", () => { + it("detects the model family from the Bedrock model id", () => { + expect(extractProvider("anthropic.claude-3-5-sonnet-20240620-v1:0")).toBe( + "anthropic", + ); + expect(extractProvider("amazon.nova-pro-v1:0")).toBe("amazon"); + expect(extractProvider("meta.llama3-70b-instruct-v1:0")).toBe("meta"); + expect(extractProvider("mistral.mistral-large-2407-v1:0")).toBe("mistral"); + }); + + it("throws on an unknown provider", () => { + expect(() => extractProvider("totally-unknown-model")).toThrow( + /Unknown provider/, + ); + }); +}); + +describe("AWSBedrockLLM", () => { + const textResponse = { + output: { message: { content: [{ text: "hello from bedrock" }] } }, + }; + + it("returns assistant text from a Converse response", async () => { + const client = new FakeBedrockClient(textResponse); + const llm = makeLLM(client); + const out = await llm.generateResponse([{ role: "user", content: "hi" }]); + expect(out).toBe("hello from bedrock"); + }); + + it("lifts system messages into the top-level system block", async () => { + const client = new FakeBedrockClient(textResponse); + const llm = makeLLM(client); + await llm.generateResponse([ + { role: "system", content: "be terse" }, + { role: "user", content: "hi" }, + ]); + expect(client.lastInput.system).toEqual([{ text: "be terse" }]); + expect(client.lastInput.messages).toEqual([ + { role: "user", content: [{ text: "hi" }] }, + ]); + }); + + it("omits topP for anthropic models even when configured", async () => { + const client = new FakeBedrockClient(textResponse); + const llm = makeLLM(client, { topP: 0.9, temperature: 0.2 }); + await llm.generateResponse([{ role: "user", content: "hi" }]); + expect(client.lastInput.inferenceConfig.topP).toBeUndefined(); + expect(client.lastInput.inferenceConfig.temperature).toBe(0.2); + }); + + it("includes topP for non-anthropic models", async () => { + const client = new FakeBedrockClient(textResponse); + const llm = makeLLM(client, { + model: "meta.llama3-70b-instruct-v1:0", + topP: 0.9, + }); + await llm.generateResponse([{ role: "user", content: "hi" }]); + expect(client.lastInput.inferenceConfig.topP).toBe(0.9); + }); + + it("converts OpenAI-style tools to Converse toolConfig and parses toolUse", async () => { + const toolResponse = { + output: { + message: { + content: [{ toolUse: { name: "add_memory", input: { text: "x" } } }], + }, + }, + }; + const client = new FakeBedrockClient(toolResponse); + const llm = makeLLM(client); + const tools = [ + { + type: "function", + function: { + name: "add_memory", + description: "store a memory", + parameters: { type: "object", properties: {} }, + }, + }, + ]; + const out = await llm.generateResponse( + [{ role: "user", content: "remember x" }], + undefined, + tools, + ); + expect(client.lastInput.toolConfig.tools[0].toolSpec.name).toBe( + "add_memory", + ); + expect(typeof out).toBe("object"); + expect((out as any).toolCalls[0]).toEqual({ + name: "add_memory", + arguments: JSON.stringify({ text: "x" }), + }); + }); + + it("never sends an empty messages array", async () => { + const client = new FakeBedrockClient(textResponse); + const llm = makeLLM(client); + await llm.generateResponse([{ role: "system", content: "only system" }]); + expect(client.lastInput.messages).toEqual([ + { role: "user", content: [{ text: "" }] }, + ]); + }); + + it("wraps SDK errors with a provider-tagged message", async () => { + const client = { + send: async () => { + throw new Error("AccessDeniedException"); + }, + } as any; + const llm = makeLLM(client); + await expect( + llm.generateResponse([{ role: "user", content: "hi" }]), + ).rejects.toThrow(/AWS Bedrock LLM failed: AccessDeniedException/); + }); + + it("generateChat returns text content with assistant role", async () => { + const client = new FakeBedrockClient(textResponse); + const llm = makeLLM(client); + const res = await llm.generateChat([{ role: "user", content: "hi" }]); + expect(res).toEqual({ content: "hello from bedrock", role: "assistant" }); + }); + + it("does not construct the Bedrock client until the first request", () => { + const before = mockClientConstructions; + // No injected client: the old constructor eagerly built a real one. + new AWSBedrockLLM({ + model: "anthropic.claude-3-5-sonnet-20240620-v1:0", + awsRegion: "us-west-2", + }); + expect(mockClientConstructions).toBe(before); + }); +}); + +/** + * ts-jest downlevels this suite to CommonJS, where `require()` works fine — so + * no runtime test here can observe the ESM failure. Guard the source invariant + * that causes it instead: esbuild rewrites `require()` in the published ESM + * bundle (dist/oss/index.mjs) into a `__require` shim that throws + * `Dynamic require of "..." is not supported`, stranding every ESM consumer. + */ +describe("aws_bedrock.ts ESM safety", () => { + const source = readFileSync( + join(__dirname, "..", "llms", "aws_bedrock.ts"), + "utf8", + ); + // Comments legitimately mention require(); only real code should be checked. + const code = source + .replace(/\/\*[\s\S]*?\*\//g, "") + .replace(/(^|[^:])\/\/.*$/gm, "$1"); + + it("never calls require() — the ESM bundle turns it into a throwing shim", () => { + expect(code).not.toMatch(/\brequire\s*\(/); + }); + + it("loads the optional AWS SDK through a dynamic import()", () => { + expect(code).toMatch(/import\("@aws-sdk\/client-bedrock-runtime"\)/); + }); +}); diff --git a/mem0-ts/src/oss/src/types/index.ts b/mem0-ts/src/oss/src/types/index.ts index d2ff1a0fd..66982e877 100644 --- a/mem0-ts/src/oss/src/types/index.ts +++ b/mem0-ts/src/oss/src/types/index.ts @@ -67,6 +67,14 @@ export interface LLMConfig { temperature?: number; topP?: number; maxTokens?: number; + // AWS Bedrock provider config (used when provider === "aws_bedrock"). + // Credentials otherwise resolve via the standard AWS credential chain. + awsRegion?: string; + awsAccessKeyId?: string; + awsSecretAccessKey?: string; + awsSessionToken?: string; + // Optional pre-constructed client (e.g. BedrockRuntimeClient) for DI/testing. + client?: any; } export interface RerankerConfig { @@ -203,21 +211,29 @@ export const MemoryConfigSchema = z.object({ }) .passthrough(), }), + llm: z.object({ provider: z.string(), - config: z.object({ - apiKey: z.string().optional(), - model: z.union([z.string(), z.any()]).optional(), - modelProperties: z.record(z.string(), z.any()).optional(), - baseURL: z.string().optional(), - vllmBaseURL: z.string().optional(), - vllm_base_url: z.string().optional(), - url: z.string().optional(), - timeout: z.number().optional(), - temperature: z.number().optional(), - topP: z.number().optional(), - maxTokens: z.number().optional(), - }), + config: z + .object({ + apiKey: z.string().optional(), + model: z.union([z.string(), z.any()]).optional(), + modelProperties: z.record(z.string(), z.any()).optional(), + baseURL: z.string().optional(), + vllmBaseURL: z.string().optional(), + vllm_base_url: z.string().optional(), + url: z.string().optional(), + timeout: z.number().optional(), + temperature: z.number().optional(), + topP: z.number().optional(), + maxTokens: z.number().optional(), + awsRegion: z.string().optional(), + awsAccessKeyId: z.string().optional(), + awsSecretAccessKey: z.string().optional(), + awsSessionToken: z.string().optional(), + client: z.any().optional(), + }) + .passthrough(), }), historyDbPath: z.string().optional(), customInstructions: z.string().optional(), diff --git a/mem0-ts/src/oss/src/utils/factory.ts b/mem0-ts/src/oss/src/utils/factory.ts index 91491a600..4a4930938 100644 --- a/mem0-ts/src/oss/src/utils/factory.ts +++ b/mem0-ts/src/oss/src/utils/factory.ts @@ -34,6 +34,7 @@ import { LMStudioLLM } from "../llms/lmstudio"; import { DeepSeekLLM } from "../llms/deepseek"; import { XAILLM } from "../llms/xai"; import { SarvamLLM } from "../llms/sarvam"; +import { AWSBedrockLLM } from "../llms/aws_bedrock"; import { LiteLLM } from "../llms/litellm"; import { MiniMaxLLM } from "../llms/minimax"; import { TogetherLLM } from "../llms/together"; @@ -128,6 +129,8 @@ export class LLMFactory { return new XAILLM(config); case "sarvam": return new SarvamLLM(config); + case "aws_bedrock": + return new AWSBedrockLLM(config); case "litellm": return new LiteLLM(config); case "minimax": diff --git a/mem0-ts/src/oss/tests/config-manager.test.ts b/mem0-ts/src/oss/tests/config-manager.test.ts index 59580d8ea..331384465 100644 --- a/mem0-ts/src/oss/tests/config-manager.test.ts +++ b/mem0-ts/src/oss/tests/config-manager.test.ts @@ -378,6 +378,55 @@ describe("ConfigManager", () => { }); }); + describe("mergeConfig - AWS Bedrock credential passthrough", () => { + const baseEmbedder = { provider: "openai", config: { apiKey: "k" } }; + const baseVectorStore = { provider: "memory", config: {} }; + + it("preserves explicit AWS Bedrock credentials through MemoryConfigSchema.parse", () => { + const cfg = ConfigManager.mergeConfig({ + embedder: baseEmbedder, + vectorStore: baseVectorStore, + llm: { + provider: "aws_bedrock", + config: { + model: "anthropic.claude-3-sonnet-20240229-v1:0", + awsRegion: "us-east-1", + awsAccessKeyId: "AKIAEXAMPLE", + awsSecretAccessKey: "secret-example", + awsSessionToken: "session-example", + } as any, + }, + }); + + // Regression: zod default parse strips undeclared keys, which silently + // dropped credentials before .passthrough() + typed fields were added. + expect(cfg.llm.config.awsRegion).toBe("us-east-1"); + expect(cfg.llm.config.awsAccessKeyId).toBe("AKIAEXAMPLE"); + expect(cfg.llm.config.awsSecretAccessKey).toBe("secret-example"); + expect(cfg.llm.config.awsSessionToken).toBe("session-example"); + }); + + it("normalizes snake_case AWS credentials from the raw config", () => { + const cfg = ConfigManager.mergeConfig({ + embedder: baseEmbedder, + vectorStore: baseVectorStore, + llm: { + provider: "aws_bedrock", + config: { + model: "anthropic.claude-3-sonnet-20240229-v1:0", + aws_region: "eu-west-1", + aws_access_key_id: "AKIASNAKE", + aws_secret_access_key: "snake-secret", + } as any, + }, + }); + + expect(cfg.llm.config.awsRegion).toBe("eu-west-1"); + expect(cfg.llm.config.awsAccessKeyId).toBe("AKIASNAKE"); + expect(cfg.llm.config.awsSecretAccessKey).toBe("snake-secret"); + }); + }); + describe("mergeConfig - full OpenClaw-style LM Studio config", () => { it("handles the exact config from issue #4235", () => { const cfg = ConfigManager.mergeConfig({ @@ -713,6 +762,47 @@ describe("Memory – LM Studio end-to-end flow", () => { ); }); + it("passes AWS Bedrock credentials to LLMFactory through the Memory stack", async () => { + const mem = new MemoryClass({ + embedder: { + provider: "lmstudio", + config: { + model: "nomic-embed-text-v1.5", + baseURL: "http://localhost:1234/v1", + embeddingDims: 768, + }, + }, + vectorStore: { + provider: "memory", + config: { collectionName: "test", dimension: 768 }, + }, + llm: { + provider: "aws_bedrock", + config: { + model: "anthropic.claude-3-sonnet-20240229-v1:0", + awsRegion: "us-east-1", + awsAccessKeyId: "AKIAEXAMPLE", + awsSecretAccessKey: "secret-example", + }, + }, + disableHistory: true, + }); + + await mem.getAll({ filters: { user_id: "u1" } }); + + // Regression: credentials must survive ConfigManager -> Memory -> LLMFactory, + // otherwise Bedrock silently falls back to the ambient AWS credential chain. + expect(mockLlmFactory.create).toHaveBeenCalledWith( + "aws_bedrock", + expect.objectContaining({ + model: "anthropic.claude-3-sonnet-20240229-v1:0", + awsRegion: "us-east-1", + awsAccessKeyId: "AKIAEXAMPLE", + awsSecretAccessKey: "secret-example", + }), + ); + }); + it("add flow works with lmstudio LLM for fact extraction", async () => { mockLlm.generateResponse.mockResolvedValueOnce( '{"facts":["User loves sushi"]}', diff --git a/mem0-ts/tsup.config.ts b/mem0-ts/tsup.config.ts index 09626b07f..6dd9d5b44 100644 --- a/mem0-ts/tsup.config.ts +++ b/mem0-ts/tsup.config.ts @@ -26,6 +26,7 @@ const external = [ "@supabase/supabase-js", "@upstash/vector", "@zilliz/milvus2-sdk-node", + "@aws-sdk/client-bedrock-runtime", "@azure/search-documents", "@azure/identity", "cloudflare",