Skip to content

Conversation

@srmurali002
Copy link

@srmurali002 srmurali002 commented Jan 12, 2026

🎯 Changes

This PR adds the @tanstack/ai-bedrock package. This implementation uses the AWS SDK v3 Converse API to provide a unified interface for streaming and tool calling.

  • ConverseStream API: Uses the Converse API for handling model interactions.
  • Modalities: Supports text, image, video, and document input parts for Nova and Claude models.
  • Thinking Tags: Includes parsing for reasoning/thinking tags in Claude and Nova responses.
  • Type Mapping: Adds BedrockModelInputModalitiesByName for mapping model IDs to their supported modalities.
  • Tests: Includes unit tests for model metadata and a set of live-test examples.

✅ Checklist

  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • New Features

    • Amazon Bedrock adapter: streaming chat, multimodal inputs (text/image/video/document), tool invocation, and model-specific thinking/reasoning modes; convenience helpers that auto-load environment defaults.
  • Documentation

    • Added usage notes and a README for running Bedrock live tests and local setup.
  • Tests

    • New unit, integration-style live tests, and type-level tests validating streaming behavior, tool calls, and model modality constraints.

✏️ Tip: You can customize this high-level summary in your review settings.

@srmurali002 srmurali002 requested a review from a team January 12, 2026 07:32
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 12, 2026

Warning

Rate limit exceeded

@srmurali002 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 1 minutes and 39 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 19bb9b9 and e3a1196.

📒 Files selected for processing (4)
  • packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts
  • packages/typescript/ai-bedrock/src/model-meta.ts
  • packages/typescript/ai-bedrock/tests/model-meta.test.ts
📝 Walkthrough

Walkthrough

Adds a new TypeScript package implementing an Amazon Bedrock text adapter with streaming chat support, model metadata, types, env utilities, unit and live-test scaffolding, package/config files, and public factory/export surfaces.

Changes

Cohort / File(s) Summary
Release & Config
​.changeset/bedrock-adapter.md, knip.json
Adds a changeset for @tanstack/ai-bedrock and updates knip config to ignore the new live-tests path and enable top-level ignoreExportsUsedInFile.
Package Setup
packages/typescript/ai-bedrock/package.json, packages/typescript/ai-bedrock/tsconfig.json, packages/typescript/ai-bedrock/vite.config.ts
New package manifest, TS config, and Vitest/Vite test config for the ai-bedrock package.
Adapter Implementation
packages/typescript/ai-bedrock/src/adapters/text.ts, packages/typescript/ai-bedrock/src/adapters/index.ts
New BedrockTextAdapter with streaming chatStream, message/part → Converse conversions, stream event processing (thinking, content, tool_call, done), and exports of adapter and config types.
Factory & Public API
packages/typescript/ai-bedrock/src/bedrock-chat.ts, packages/typescript/ai-bedrock/src/index.ts
Adds createBedrockChat and bedrockText helpers and a barrel export surface for models, adapter, types, and utilities.
Model Metadata & Types
packages/typescript/ai-bedrock/src/model-meta.ts, packages/typescript/ai-bedrock/src/message-types.ts, packages/typescript/ai-bedrock/src/text/text-provider-options.ts
Declares Bedrock model metadata/constants, input modality mappings, Bedrock-specific multimodal metadata types, and provider option interfaces (thinking, MCP servers, inference, sampling).
Utilities
packages/typescript/ai-bedrock/src/utils.ts
Adds BedrockClientConfig and getBedrockConfigFromEnv() to resolve AWS region and credentials from environment.
Tests (unit)
packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts, packages/typescript/ai-bedrock/tests/model-meta.test.ts
Unit tests for adapter stream parsing (mocked ConverseStreamCommand) and compile-time modality assertions.
Live Tests
packages/typescript/ai-bedrock/live-tests/README.md, packages/typescript/ai-bedrock/live-tests/package.json, packages/typescript/ai-bedrock/live-tests/tool-test.ts, packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts, packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts
Adds live-test scripts, README, and package to exercise streaming, thinking blocks, and tool invocation against real Bedrock credentials.

Sequence Diagram(s)

sequenceDiagram
    participant App as Application
    participant Adapter as BedrockTextAdapter
    participant AWS as AWS Bedrock\nConverseStream
    participant Tool as Tool Executor

    App->>Adapter: chatStream(messages, options)
    Adapter->>Adapter: convertToConverseMessages()
    Adapter->>AWS: ConverseStreamCommand (stream request)
    activate AWS

    AWS-->>Adapter: Stream event (thinking)
    Adapter-->>App: StreamChunk (thinking)

    AWS-->>Adapter: Stream event (contentBlockDelta)
    Adapter-->>App: StreamChunk (content)

    AWS-->>Adapter: Stream event (contentBlockStart with toolUse)
    Adapter-->>App: StreamChunk (tool_call)
    App->>Tool: Execute tool
    Tool-->>App: Tool result
    App->>Adapter: Send tool result (follow-up request)

    AWS-->>Adapter: Stream event (messageStop)
    Adapter-->>App: StreamChunk (done + metadata)
    deactivate AWS
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • jherr

Poem

🐰 I hopped into code with a curious twitch,
Bedrock chats now stream and softly twitch,
Tools call, thoughts bloom, tokens dance in flight,
Nova, Claude, and haiku brighten the night,
A rabbit cheers — tests pass by moonlight ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main change: adding an AWS Bedrock adapter with ConverseStream and tool-calling support, which aligns with the comprehensive changeset.
Description check ✅ Passed The PR description covers the main changes, follows the template structure with checked checklist items, and clearly explains the Bedrock adapter implementation including API usage, supported modalities, and testing approach.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Fix all issues with AI agents
In @packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts:
- Around line 12-16: Replace the non-null assertions on
process.env.AWS_ACCESS_KEY_ID and process.env.AWS_SECRET_ACCESS_KEY with an
explicit validation helper: add a throwMissingEnv(name: string): never function
and use it when reading the env vars (e.g. const accessKeyId =
process.env.AWS_ACCESS_KEY_ID ?? throwMissingEnv('AWS_ACCESS_KEY_ID') and
similarly for AWS_SECRET_ACCESS_KEY) then pass those validated variables into
the credentials object instead of using the ! operator.

In @packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts:
- Line 98: The call to the async test helper testBedrockNovaToolCalling() is
missing error handling and can produce unhandled promise rejections; update the
invocation to handle errors (for example, append .catch(console.error) or await
the call inside an async test function and wrap in try/catch) so any thrown
errors are logged—locate the testBedrockNovaToolCalling() invocation and add the
same catch-style error handling used in tool-test.ts.

In @packages/typescript/ai-bedrock/package.json:
- Around line 14-19: Update the package exports to add an "/adapters" subpath
and create a barrel index file that re-exports adapter symbols; specifically, in
package.json add an "adapters" export entry under "exports" that points to the
built adapters entry (e.g., "./dist/esm/adapters/index.js" and types
"./dist/esm/adapters/index.d.ts"), and add src/adapters/index.ts that exports
the adapter API (e.g., export { BedrockTextAdapter, type BedrockTextConfig }
from './text') so consumers can import from '@tanstack/ai-bedrock/adapters'.

In @packages/typescript/ai-bedrock/src/adapters/text.ts:
- Around line 185-195: The code parses tc.function.arguments without
safeguarding against invalid JSON which can throw and crash message conversion;
update the loop over message.toolCalls to detect when tc.function.arguments is a
string and safely parse it (wrap JSON.parse in try-catch or pre-validate) and
fall back to a sensible default (e.g., the original string or null) on parse
failure, then populate the ToolUseBlock (toolUseId, name, input) with the safe
value so conversion does not throw; ensure the fix touches the block building
logic around message.toolCalls and ToolUseBlock construction.
- Around line 288-314: The parser is skipping the first character after opening
and closing <thinking> tags due to off-by-one offsets; update the substring
offsets so when entering thinking use text = text.substring(startIdx + 10)
(instead of +11) and when leaving thinking use text = text.substring(endIdx +
11) (instead of +12) in the code that manipulates isInsideThinking,
accumulatedContent/accumulatedThinking, pendingTagBuffer and yields so
characters immediately after the tags are not dropped.
- Around line 379-406: The code can emit two separate terminal events because it
yields a 'done' when event.messageStop exists and again when
event.metadata?.usage exists; fix by consolidating into a single 'done'
emission: gather stopReason from event.messageStop and usage from
event.metadata?.usage, compute finishReason (map 'tool_use' -> 'tool_calls' else
'stop'), and then yield one 'done' object containing id, model, timestamp,
finishReason and optionally the usage block
(promptTokens/completionTokens/totalTokens) if available, replacing the two
separate yield blocks in the generator.
🧹 Nitpick comments (18)
packages/typescript/ai-bedrock/live-tests/README.md (2)

9-13: Specify language for the fenced code block.

The fenced code block should specify a language identifier for better syntax highlighting and markdown linting compliance.

♻️ Proposed fix
-   ```
+   ```bash
    AWS_ACCESS_KEY_ID=...
    AWS_SECRET_ACCESS_KEY=...
    AWS_REGION=us-east-1
    ```

22-26: Consider varying sentence beginnings for better flow.

Three consecutive sentences begin with "Tests." While this is clear, varying the sentence structure could improve readability.

♻️ Alternative wording
 ### `tool-test.ts`
-Tests basic tool calling with Claude 3.5 Sonnet.
+Basic tool calling test with Claude 3.5 Sonnet.
 
 ### `tool-test-nova.ts`
-Tests Amazon Nova Pro with multimodal inputs (if applicable) and tool calling.
+Amazon Nova Pro test with multimodal inputs (if applicable) and tool calling.
.changeset/bedrock-adapter.md (1)

1-5: Expand the changeset description to highlight key features.

The changeset description is minimal. Since changesets appear in release notes, consider adding more detail about the key features being introduced:

  • ConverseStream API support
  • Tool calling capability
  • Multimodal support (text, image, video, document)
  • Reasoning/thinking tag parsing
  • Support for Nova and Claude models
♻️ Suggested expansion
 ---
 "@tanstack/ai-bedrock": minor
 ---
 
-Add Amazon Bedrock adapter.
+Add Amazon Bedrock adapter with ConverseStream support, tool calling, and multimodal inputs (text, image, video, document) for Nova and Claude models. Includes reasoning/thinking tag parsing.
packages/typescript/ai-bedrock/src/model-meta.ts (1)

1-11: Minor: Remove leading blank line.

Line 1 is empty. Consider removing it for cleaner file formatting.

packages/typescript/ai-bedrock/src/text/text-provider-options.ts (2)

1-64: Inconsistent property naming conventions.

The file mixes snake_case (e.g., mcp_servers, stop_sequences, budget_tokens, top_k, authorization_token) with camelCase (e.g., maxTokens, temperature, topP, stopSequences, inferenceConfig). Per coding guidelines, camelCase should be used for variable and property names.

Additionally, there's a confusing overlap: BedrockStopSequencesOptions.stop_sequences vs BedrockInferenceConfig.stopSequences both serve similar purposes but use different conventions.

If the snake_case properties are intentionally matching the AWS Bedrock API schema, consider adding a comment to clarify this mapping. Otherwise, standardize to camelCase.


47-56: Consider documenting MCPServer fields.

The MCPServer interface lacks JSDoc comments for its properties, unlike other interfaces in this file. Adding brief descriptions (especially for authorization_token and tool_configuration) would improve developer experience.

📝 Suggested documentation
 export interface MCPServer {
+    /** Unique identifier for this MCP server */
     name: string
+    /** The URL endpoint for the MCP server */
     url: string
+    /** Connection type - currently only 'url' is supported */
     type: 'url'
+    /** Optional authorization token for authenticating with the MCP server */
     authorization_token?: string | null
+    /** Configuration for which tools are available from this server */
     tool_configuration: {
+        /** List of specific tools to allow; null or omitted means all tools */
         allowed_tools?: Array<string> | null
+        /** Whether this server's tools are enabled */
         enabled?: boolean | null
     } | null
 }
packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts (1)

32-82: Good streaming test coverage; consider adding error and tool-call scenarios.

The test properly validates the streaming happy path with content chunks and done marker. However, given the PR adds tool-calling support, consider adding tests for:

  1. Error handling (e.g., when sendMock rejects)
  2. Tool call streaming events (the adapter should handle toolUse events)
🧪 Example: additional test case for tool calls
it('should handle tool call events in stream', async () => {
    const mockStream = [
        {
            contentBlockStart: {
                start: {
                    toolUse: { toolUseId: 'tool-123', name: 'get_weather' }
                }
            }
        },
        {
            contentBlockDelta: {
                delta: { toolUse: { input: '{"location":"NYC"}' } }
            }
        },
        {
            messageStop: { stopReason: 'tool_use' }
        },
    ]

    sendMock.mockResolvedValue({
        stream: (async function* () {
            for (const event of mockStream) {
                await Promise.resolve()
                yield event
            }
        })(),
    })

    const stream = adapter.chatStream({
        model: 'anthropic.claude-3-sonnet-20240229-v1:0',
        messages: [{ role: 'user', content: 'What is the weather?' }],
    })

    const result = []
    for await (const chunk of stream) {
        result.push(chunk)
    }

    const toolCallChunk = result.find(c => c.type === 'tool_call')
    expect(toolCallChunk).toBeDefined()
})
packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts (1)

66-76: Tool call validation is missing.

For a tool test, consider validating that the tool was actually invoked. Currently toolCallCount is only logged but not asserted, which means the test could pass even if the tool wasn't called.

✅ Suggested assertion
     console.log('--- Results ---')
     console.log('Thinking:', hasThinking)
     console.log('Tool calls:', toolCallCount)
     console.log('Content length:', finalContent.length)

+    if (toolCallCount === 0) {
+        console.error('Test failed: Expected at least one tool call')
+        process.exit(1)
+    }
+
     if (!finalContent || finalContent.trim().length === 0) {
         console.error('Test failed: No final content')
         process.exit(1)
     }

     console.log('Test passed')
packages/typescript/ai-bedrock/src/utils.ts (3)

1-2: Remove empty lines at file start.

Minor style nit: the file starts with two empty lines.


15-21: Consider adding a comment explaining the browser environment detection pattern.

The globalThis.window.env pattern is specific to certain bundler setups (e.g., Vite with define config). A brief comment would help future maintainers understand this pattern.

📝 Suggested comment
 export function getBedrockConfigFromEnv(): BedrockClientConfig {
+    // Check for browser environment (e.g., Vite's define plugin injects env vars to window.env)
+    // Fall back to process.env for Node.js environments
     const env =
         typeof globalThis !== 'undefined' && (globalThis as any).window?.env
             ? (globalThis as any).window.env
             : typeof process !== 'undefined'
                 ? process.env
                 : undefined

29-35: Credentials could contain empty strings.

If AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY are set to empty strings, they would still pass the truthiness check but result in invalid credentials. Consider checking for non-empty values.

🛡️ Suggested validation
-    if (env?.AWS_ACCESS_KEY_ID && env?.AWS_SECRET_ACCESS_KEY) {
+    if (env?.AWS_ACCESS_KEY_ID?.trim() && env?.AWS_SECRET_ACCESS_KEY?.trim()) {
         config.credentials = {
             accessKeyId: env.AWS_ACCESS_KEY_ID,
             secretAccessKey: env.AWS_SECRET_ACCESS_KEY,
-            sessionToken: env.AWS_SESSION_TOKEN
+            sessionToken: env.AWS_SESSION_TOKEN || undefined
         }
     }
packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts (1)

8-20: Consider extracting shared .env loading logic.

This manual .env.local parsing pattern is duplicated across test files. Consider extracting it into a shared utility in the live-tests directory (e.g., load-env.ts) to reduce code duplication.

♻️ Suggested utility extraction
// live-tests/load-env.ts
import { readFileSync } from 'fs'
import { join, dirname } from 'path'
import { fileURLToPath } from 'url'

export function loadEnvLocal(importMetaUrl: string): void {
    const __dirname = dirname(fileURLToPath(importMetaUrl))
    try {
        const envContent = readFileSync(join(__dirname, '.env.local'), 'utf-8')
        envContent.split('\n').forEach((line) => {
            const match = line.match(/^([^=]+)=(.*)$/)
            if (match) {
                process.env[match[1].trim()] = match[2].trim()
            }
        })
    } catch {
        // .env.local not found
    }
}
packages/typescript/ai-bedrock/live-tests/tool-test.ts (2)

2-2: Inconsistent import path compared to other test files.

This file imports from '../src/bedrock-chat' while tool-test-nova.ts imports from '../src/index'. For consistency and to test the public API surface, consider importing from the index file.

♻️ Proposed fix
-import { bedrockText } from '../src/bedrock-chat'
+import { bedrockText } from '../src/index'

13-16: Non-null assertions on credentials may cause unclear runtime errors.

Using ! for credentials will cause runtime errors if environment variables are not set. Consider providing fallbacks with empty strings (like tool-test-nova.ts) or adding explicit validation with a clear error message before adapter creation.

♻️ Option 1: Use fallbacks for consistency
         credentials: {
-            accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
-            secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
+            accessKeyId: process.env.AWS_ACCESS_KEY_ID || '',
+            secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || '',
         },
♻️ Option 2: Add explicit validation
if (!process.env.AWS_ACCESS_KEY_ID || !process.env.AWS_SECRET_ACCESS_KEY) {
    console.error('Error: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY must be set')
    process.exit(1)
}
packages/typescript/ai-bedrock/src/message-types.ts (2)

25-25: Empty interface flagged by static analysis.

Biome reports that an empty interface is equivalent to {}. Consider using a type alias instead, or add a comment explaining the placeholder for future extension.

♻️ Proposed fix using type alias
 /**
  * Metadata for Bedrock text content parts.
  */
-export interface BedrockTextMetadata { }
+export type BedrockTextMetadata = Record<string, never>

Alternatively, if this is intentionally empty for future extension, you can suppress the lint rule with a comment:

// biome-ignore lint/suspicious/noEmptyInterface: Placeholder for future Bedrock text metadata fields
export interface BedrockTextMetadata { }

1-1: Minor: Remove leading empty line.

There's an unnecessary empty line at the start of the file.

packages/typescript/ai-bedrock/src/adapters/text.ts (2)

97-106: Consider making maxReasoningEffort configurable.

The reasoning effort level is hardcoded to "medium". If Nova models support different effort levels, this should be exposed via modelOptions.thinking or a dedicated option to give callers control.

Suggested approach
                     if (isNova(this.model) && options.modelOptions?.thinking) {
                         // Nova: extended thinking via reasoningConfig
                         // Note: produces <thinking> tags in text (parsed universally below)
                         return {
                             reasoningConfig: {
                                 enabled: true,
-                                maxReasoningEffort: "medium"
+                                maxReasoningEffort: options.modelOptions.thinking.reasoningEffort ?? "medium"
                             }
                         }
                     }

221-252: Consider typing the part parameter.

Using any for the part parameter loses type safety. If there's a union type for message content parts in the TanStack AI types, consider using it here for better compile-time checks.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e37d8b and b7f9e35.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (19)
  • .changeset/bedrock-adapter.md
  • knip.json
  • packages/typescript/ai-bedrock/live-tests/README.md
  • packages/typescript/ai-bedrock/live-tests/package.json
  • packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test.ts
  • packages/typescript/ai-bedrock/package.json
  • packages/typescript/ai-bedrock/src/adapters/text.ts
  • packages/typescript/ai-bedrock/src/bedrock-chat.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/src/message-types.ts
  • packages/typescript/ai-bedrock/src/model-meta.ts
  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
  • packages/typescript/ai-bedrock/src/utils.ts
  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
  • packages/typescript/ai-bedrock/tests/model-meta.test.ts
  • packages/typescript/ai-bedrock/tsconfig.json
  • packages/typescript/ai-bedrock/vite.config.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use tree-shakeable adapter architecture for provider implementations - export specialized adapters (text, embedding, summarize, image) as separate imports from /adapters subpath rather than monolithic adapters
Use Zod for runtime schema validation and type inference, particularly for tool input/output definitions with toolDefinition() and Zod schema inference
Implement isomorphic tool system using toolDefinition() with .server() and .client() implementations for dual-environment execution
Use type-safe per-model configuration with provider options typed based on selected model to ensure compile-time safety
Implement stream processing with StreamProcessor for handling chunked responses and support partial JSON parsing for streaming AI responses

Files:

  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts
  • packages/typescript/ai-bedrock/src/utils.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts
  • packages/typescript/ai-bedrock/tests/model-meta.test.ts
  • packages/typescript/ai-bedrock/src/message-types.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/src/adapters/text.ts
  • packages/typescript/ai-bedrock/src/bedrock-chat.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test.ts
  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
  • packages/typescript/ai-bedrock/src/model-meta.ts
  • packages/typescript/ai-bedrock/vite.config.ts
**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Write unit tests using Vitest alongside source files with .test.ts naming convention

Files:

  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
  • packages/typescript/ai-bedrock/tests/model-meta.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use camelCase for function and variable names throughout the codebase

Files:

  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts
  • packages/typescript/ai-bedrock/src/utils.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts
  • packages/typescript/ai-bedrock/tests/model-meta.test.ts
  • packages/typescript/ai-bedrock/src/message-types.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/src/adapters/text.ts
  • packages/typescript/ai-bedrock/src/bedrock-chat.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test.ts
  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
  • packages/typescript/ai-bedrock/src/model-meta.ts
  • packages/typescript/ai-bedrock/vite.config.ts
packages/typescript/*/src/index.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Export tree-shakeable adapters with clear subpath exports in package.json (e.g., @tanstack/ai/adapters, @tanstack/ai-openai/adapters) to minimize bundle size

Files:

  • packages/typescript/ai-bedrock/src/index.ts
packages/typescript/*/src/adapters/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Create individual adapter implementations for each provider capability (text, embed, summarize, image) with separate exports to enable tree-shaking

Files:

  • packages/typescript/ai-bedrock/src/adapters/text.ts
packages/typescript/*/src/model-meta.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain model metadata files that define provider options and capabilities per model for per-model type safety

Files:

  • packages/typescript/ai-bedrock/src/model-meta.ts
🧠 Learnings (15)
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/index.ts : Export tree-shakeable adapters with clear subpath exports in package.json (e.g., `tanstack/ai/adapters`, `tanstack/ai-openai/adapters`) to minimize bundle size

Applied to files:

  • packages/typescript/ai-bedrock/package.json
  • knip.json
  • packages/typescript/ai-bedrock/tsconfig.json
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/live-tests/package.json
  • packages/typescript/ai-bedrock/src/bedrock-chat.ts
  • packages/typescript/ai-bedrock/vite.config.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/adapters/*.ts : Create individual adapter implementations for each provider capability (text, embed, summarize, image) with separate exports to enable tree-shaking

Applied to files:

  • packages/typescript/ai-bedrock/package.json
  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
  • packages/typescript/ai-bedrock/tsconfig.json
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/src/adapters/text.ts
  • packages/typescript/ai-bedrock/src/bedrock-chat.ts
  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/*/package.json : Use `workspace:*` protocol for internal package dependencies in package.json (e.g., `"tanstack/ai": "workspace:*"`)

Applied to files:

  • packages/typescript/ai-bedrock/package.json
  • knip.json
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/model-meta.ts : Maintain model metadata files that define provider options and capabilities per model for per-model type safety

Applied to files:

  • packages/typescript/ai-bedrock/package.json
  • packages/typescript/ai-bedrock/tests/model-meta.test.ts
  • packages/typescript/ai-bedrock/tsconfig.json
  • packages/typescript/ai-bedrock/src/message-types.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
  • packages/typescript/ai-bedrock/src/model-meta.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Use tree-shakeable adapter architecture for provider implementations - export specialized adapters (text, embedding, summarize, image) as separate imports from `/adapters` subpath rather than monolithic adapters

Applied to files:

  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/src/adapters/text.ts
  • packages/typescript/ai-bedrock/src/bedrock-chat.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Implement stream processing with StreamProcessor for handling chunked responses and support partial JSON parsing for streaming AI responses

Applied to files:

  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
  • packages/typescript/ai-bedrock/src/adapters/text.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Implement isomorphic tool system using `toolDefinition()` with `.server()` and `.client()` implementations for dual-environment execution

Applied to files:

  • packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test.ts
📚 Learning: 2025-12-27T20:22:51.232Z
Learnt from: harry-whorlow
Repo: TanStack/ai PR: 117
File: packages/typescript/ai-ollama/src/meta/model-meta-gpt-oss.ts:92-97
Timestamp: 2025-12-27T20:22:51.232Z
Learning: In the ai-ollama package's model-meta files (packages/typescript/ai-ollama/src/meta/model-meta-*.ts), capability-related comments follow a standard template format across all files for consistency, even if the comment text doesn't precisely match individual model capabilities. This is an intentional design choice to maintain uniformity across the codebase.

Applied to files:

  • packages/typescript/ai-bedrock/tests/model-meta.test.ts
  • packages/typescript/ai-bedrock/src/model-meta.ts
📚 Learning: 2025-12-27T21:39:29.563Z
Learnt from: harry-whorlow
Repo: TanStack/ai PR: 117
File: packages/typescript/ai-ollama/src/meta/model-meta-llama-guard3.ts:70-75
Timestamp: 2025-12-27T21:39:29.563Z
Learning: The standard template comments in ai-ollama model-meta files (like "Models with text, image, audio, video (no document)") should not be modified to match individual model capabilities, as they are intentionally kept uniform across all model-meta-*.ts files for consistency, regardless of what each specific model actually supports.

Applied to files:

  • packages/typescript/ai-bedrock/tests/model-meta.test.ts
  • packages/typescript/ai-bedrock/src/model-meta.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Maintain type safety through multimodal content support (image, audio, video, document) with model capability awareness

Applied to files:

  • packages/typescript/ai-bedrock/tests/model-meta.test.ts
  • packages/typescript/ai-bedrock/src/message-types.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.test.ts : Write unit tests using Vitest alongside source files with `.test.ts` naming convention

Applied to files:

  • packages/typescript/ai-bedrock/tests/model-meta.test.ts
  • packages/typescript/ai-bedrock/vite.config.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to examples/** : Examples are not built by Nx and should be run independently from their directories with `pnpm dev` or `pnpm install && pnpm dev`

Applied to files:

  • knip.json
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Use Nx workspace with affected commands to optimize testing and building only changed packages and their dependents

Applied to files:

  • knip.json
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to .eslintrc* : Use ESLint with custom TanStack config for linting all TypeScript and JavaScript files

Applied to files:

  • packages/typescript/ai-bedrock/tsconfig.json
  • packages/typescript/ai-bedrock/vite.config.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Use type-safe per-model configuration with provider options typed based on selected model to ensure compile-time safety

Applied to files:

  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
🧬 Code graph analysis (4)
packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts (3)
packages/typescript/ai/src/activities/chat/stream/processor.ts (1)
  • process (387-410)
packages/typescript/ai-bedrock/src/bedrock-chat.ts (1)
  • bedrockText (12-25)
packages/typescript/ai-bedrock/src/index.ts (1)
  • bedrockText (8-8)
packages/typescript/ai-bedrock/tests/model-meta.test.ts (3)
packages/typescript/ai/src/types.ts (6)
  • DefaultMessageMetadataByModality (1024-1030)
  • ConstrainedModelMessage (309-313)
  • ImagePart (133-139)
  • VideoPart (157-163)
  • DocumentPart (169-175)
  • AudioPart (145-151)
packages/typescript/ai-bedrock/src/index.ts (1)
  • BedrockModelInputModalitiesByName (20-20)
packages/typescript/ai-bedrock/src/model-meta.ts (1)
  • BedrockModelInputModalitiesByName (86-92)
packages/typescript/ai-bedrock/src/message-types.ts (1)
packages/typescript/ai-bedrock/src/index.ts (7)
  • BedrockImageMediaType (30-30)
  • BedrockImageMetadata (26-26)
  • BedrockTextMetadata (25-25)
  • BedrockDocumentMetadata (27-27)
  • BedrockAudioMetadata (28-28)
  • BedrockVideoMetadata (29-29)
  • BedrockMessageMetadataByModality (24-24)
packages/typescript/ai-bedrock/live-tests/tool-test.ts (3)
packages/typescript/ai-bedrock/src/bedrock-chat.ts (1)
  • bedrockText (12-25)
packages/typescript/ai-bedrock/src/index.ts (1)
  • bedrockText (8-8)
packages/typescript/ai/src/activities/chat/stream/processor.ts (1)
  • process (387-410)
🪛 Biome (2.1.2)
packages/typescript/ai-bedrock/src/message-types.ts

[error] 25-25: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)

🪛 LanguageTool
packages/typescript/ai-bedrock/live-tests/README.md

[style] ~25-~25: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...de 3.5 Sonnet. ### tool-test-nova.ts Tests Amazon Nova Pro with multimodal inputs ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🪛 markdownlint-cli2 (0.18.1)
packages/typescript/ai-bedrock/live-tests/README.md

9-9: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (15)
packages/typescript/ai-bedrock/live-tests/package.json (1)

10-14: All specified devDependencies versions are valid and available on npm.

The versions [email protected], [email protected], and [email protected] all exist on the npm registry. While newer versions are available ([email protected], [email protected], and [email protected]), the current pinned versions are stable and appropriate for a test package.

packages/typescript/ai-bedrock/tsconfig.json (1)

1-10: LGTM!

The TypeScript configuration is clean and appropriately extends the base config. The ESM-only output structure aligns with the package.json module configuration.

packages/typescript/ai-bedrock/vite.config.ts (1)

1-36: LGTM!

The Vite/Vitest configuration is well-structured with appropriate test and coverage settings. The merge with tanstackViteConfig follows the established TanStack pattern, and cjs: false correctly aligns with the ESM-only package setup.

knip.json (1)

11-22: LGTM!

Adding the Bedrock live-tests to the ignore list is appropriate and consistent with how other providers' live-tests (e.g., ai-openai/live-tests) are handled.

packages/typescript/ai-bedrock/src/model-meta.ts (2)

17-71: LGTM!

The model constants are well-structured with proper type safety using as const satisfies BedrockModelMeta. The input modality declarations accurately reflect each model's capabilities (e.g., Nova Micro is text-only, Claude models support thinking).


73-99: LGTM!

The type definitions and helper predicates are well-designed:

  • BedrockModelId with (string & {}) allows arbitrary model IDs while preserving autocomplete for known models.
  • BedrockModelInputModalitiesByName enables per-model type safety as required by coding guidelines.
  • The isClaude/isNova helpers use idiomatic substring matching consistent with AWS model ID conventions.
packages/typescript/ai-bedrock/package.json (1)

48-52: No action needed. The version specifier "4.0.14" for @vitest/coverage-v8 is consistent with all other packages in the monorepo and represents an intentional, monorepo-wide pattern.

packages/typescript/ai-bedrock/tests/model-meta.test.ts (1)

1-62: LGTM!

Well-structured type-level tests that validate model input modality constraints. The ResolveModalities helper correctly converts raw modality arrays to InputModalitiesTypes, and the test pattern is consistent with similar tests in other packages (e.g., ai-openai). Both positive assertions (allowed parts) and negative assertions (disallowed parts) are covered for each model.

packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts (1)

39-56: LGTM!

The tool definition correctly uses Zod for input schema validation as per coding guidelines. The execute function is properly typed with destructured parameters.

packages/typescript/ai-bedrock/live-tests/tool-test.ts (1)

30-46: LGTM!

The tool definition correctly uses Zod for schema validation with proper .describe() annotations for the input fields.

packages/typescript/ai-bedrock/src/bedrock-chat.ts (2)

6-10: LGTM!

Clean factory function with proper generic type parameter for model-specific typing.


12-25: LGTM!

The configuration merging logic correctly cascades from explicit config to environment config to defaults. The use of || operator appropriately treats empty strings as falsy, falling back to the next option in the chain.

packages/typescript/ai-bedrock/src/message-types.ts (1)

64-70: LGTM!

The BedrockMessageMetadataByModality mapping interface provides a clean type-safe way to associate modality types with their respective metadata interfaces. This aligns well with the coding guidelines for maintaining type safety through multimodal content support.

packages/typescript/ai-bedrock/src/adapters/text.ts (2)

41-60: LGTM!

Class structure follows the tree-shakeable adapter architecture pattern correctly. The readonly properties and constructor initialization are appropriate. Based on learnings, this aligns with creating individual adapter implementations for each provider capability.


134-139: LGTM!

Appropriate placeholder that clearly communicates the limitation. The rejection is preferable to silently failing.

@srmurali002 srmurali002 force-pushed the feat/ai-bedrock-adapter branch from b7f9e35 to 2e11f2d Compare January 12, 2026 07:46
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @packages/typescript/ai-bedrock/src/adapters/text.ts:
- Around line 146-167: The tool result status is hardcoded to 'success' in the
ToolResultBlock; update the conversion in the block returned from the tool
branch (where message.role === 'tool' && message.toolCallId) to derive status
from the incoming ModelMessage instead of always using 'success'. For example,
compute a status variable from available fields on the message (e.g.,
message.status === 'error' or presence of message.error → 'failure', otherwise
'success') and set ToolResultBlock.status to that computed value, preserving the
current fallback to 'success' if no error/status fields exist.
- Around line 400-414: Change the conditional yield so a final 'done' event is
always emitted (unless already emitted) instead of only when lastStopReason or
lastUsage exist: remove the if (lastStopReason || lastUsage) guard and
unconditionally yield the done object with id, model (this.model), timestamp and
finishReason set to lastStopReason === 'tool_use' ? 'tool_calls' : 'stop';
include usage when lastUsage exists (as currently formatted) or leave usage
undefined when not present, and add a simple guard (e.g., a boolean like
doneEmitted) to avoid yielding duplicate 'done' events if one was already sent
earlier.
🧹 Nitpick comments (11)
packages/typescript/ai-bedrock/live-tests/README.md (1)

9-13: Add language identifier to fenced code block.

The environment variable example should have a language identifier for consistency with other code blocks.

📝 Suggested fix
-   ```
+   ```env
    AWS_ACCESS_KEY_ID=...
    AWS_SECRET_ACCESS_KEY=...
    AWS_REGION=us-east-1
    ```
packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts (1)

32-82: Test covers the happy path well; consider adding edge case coverage.

The streaming test correctly validates content chunks and the done event. Consider adding tests for:

  • Error handling when response.stream is undefined
  • Tool call streaming events
  • Thinking tag parsing (for Claude/Nova models)
packages/typescript/ai-bedrock/src/index.ts (1)

1-4: Consider re-exporting from the adapters barrel.

For consistency with the tree-shakeable adapter architecture, you could re-export from ./adapters instead of ./adapters/text directly. This keeps the index clean if more adapters are added later.

📝 Optional refactor
 export {
     BedrockTextAdapter,
     type BedrockTextConfig,
-} from './adapters/text'
+} from './adapters'
packages/typescript/ai-bedrock/src/message-types.ts (1)

22-25: Empty interface flagged by linter; consider using a type alias.

Biome flags this as an empty interface equivalent to {}. If no properties are planned, a type alias is preferred. However, if you expect to add properties later, keeping the interface allows extension without breaking changes.

📝 Option 1: Use type alias
-/**
- * Metadata for Bedrock text content parts.
- */
-export interface BedrockTextMetadata { }
+/**
+ * Metadata for Bedrock text content parts.
+ */
+// eslint-disable-next-line @typescript-eslint/no-empty-object-type
+export type BedrockTextMetadata = Record<string, never>
📝 Option 2: Keep interface with lint suppression
 /**
  * Metadata for Bedrock text content parts.
  */
+// biome-ignore lint/suspicious/noEmptyInterface: Placeholder for future extensibility
 export interface BedrockTextMetadata { }
packages/typescript/ai-bedrock/src/model-meta.ts (1)

98-99: Consider stricter model detection predicates.

The current predicates use simple substring matching which could produce false positives (e.g., a custom model named my-anthropic.claude-wrapper). Consider using regex patterns with anchors if stricter matching is needed.

📝 Optional stricter implementation
-export const isClaude = (model: string) => model.includes('anthropic.claude')
-export const isNova = (model: string) => model.includes('amazon.nova')
+export const isClaude = (model: string) => model.startsWith('anthropic.claude')
+export const isNova = (model: string) => model.startsWith('amazon.nova')
packages/typescript/ai-bedrock/src/adapters/text.ts (4)

31-37: Credentials stored in plain object - consider documenting security expectations.

The BedrockTextConfig interface accepts credentials directly. While this is common for AWS SDK usage, consider documenting that users should source credentials from environment variables or AWS credential providers rather than hardcoding them. Alternatively, the config could accept an AwsCredentialIdentity | AwsCredentialIdentityProvider from @aws-sdk/types for more flexible credential sourcing.


92-108: Type assertion as any bypasses type safety for additionalModelRequestFields.

The as any type assertion silences type checking for model-specific fields. Consider creating a union type or using the AWS SDK's DocumentType properly to maintain type safety while supporting model-specific configurations.

♻️ Suggested approach
// Define explicit types for model-specific fields
type ClaudeAdditionalFields = { thinking: BedrockThinkingOptions['thinking'] }
type NovaAdditionalFields = { reasoningConfig: { enabled: boolean; maxReasoningEffort: string } }
type AdditionalModelFields = ClaudeAdditionalFields | NovaAdditionalFields | undefined

// Then cast to the SDK's DocumentType if needed
additionalModelRequestFields: (() => {
    // ... existing logic
})() as DocumentType | undefined,

119-131: Error handling loses stack trace and original error context.

The error handler extracts only message and name from the caught error, discarding the stack trace and any AWS-specific error details (like $metadata, Code, etc.). Consider preserving more context for debugging.

♻️ Proposed enhancement
         } catch (error: unknown) {
             const err = error as Error & { name?: string }
             yield {
                 type: 'error',
                 id,
                 model: this.model,
                 timestamp,
                 error: {
                     message: err.message || 'Unknown Bedrock error',
                     code: err.name || 'INTERNAL_ERROR',
+                    // Optionally include AWS error metadata if available
+                    ...(error && typeof error === 'object' && '$metadata' in error 
+                        ? { metadata: (error as any).$metadata } 
+                        : {}),
                 },
             }
         }

228-259: Loose typing with part: any - consider using discriminated union.

The convertPartToConverseBlock method uses any for the part parameter. Given that TanStack AI likely defines content part types, using proper typing would improve maintainability and catch errors at compile time.

♻️ Suggested approach
-    private convertPartToConverseBlock(part: any): ContentBlock | null {
+    private convertPartToConverseBlock(part: TextPart | ImagePart | VideoPart | DocumentPart | ThinkingPart): ContentBlock | null {

Or import the appropriate union type from @tanstack/ai if available.

packages/typescript/ai-bedrock/src/text/text-provider-options.ts (2)

1-14: Inconsistent naming convention: snake_case vs camelCase.

Properties like mcp_servers, stop_sequences, budget_tokens, and authorization_token use snake_case, while BedrockInferenceConfig uses camelCase (maxTokens, temperature, etc.). As per coding guidelines, camelCase should be used for function and variable names. If these snake_case names match the AWS Bedrock API exactly, consider adding a comment explaining the deviation, or use camelCase internally and transform when calling the API.

♻️ Suggested approach

If matching AWS API:

export interface BedrockMCPOptions {
    /**
     * MCP servers to be utilized in this request
     * Maximum of 20 servers
     * @remarks Uses snake_case to match AWS Bedrock API schema
     */
    mcp_servers?: Array<MCPServer>
}

Or use camelCase with transformation:

export interface BedrockMCPOptions {
    /** MCP servers to be utilized in this request. Maximum of 20 servers. */
    mcpServers?: Array<MCPServer>
}

40-45: BedrockInferenceConfig duplicates stopSequences from BedrockStopSequencesOptions.

Both BedrockStopSequencesOptions.stop_sequences and BedrockInferenceConfig.stopSequences define stop sequences. This could lead to confusion about which one to use. Consider consolidating or documenting the distinction (e.g., one is for the inference config while the other is a top-level option).

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b7f9e35 and 2e11f2d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (20)
  • .changeset/bedrock-adapter.md
  • knip.json
  • packages/typescript/ai-bedrock/live-tests/README.md
  • packages/typescript/ai-bedrock/live-tests/package.json
  • packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test.ts
  • packages/typescript/ai-bedrock/package.json
  • packages/typescript/ai-bedrock/src/adapters/index.ts
  • packages/typescript/ai-bedrock/src/adapters/text.ts
  • packages/typescript/ai-bedrock/src/bedrock-chat.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/src/message-types.ts
  • packages/typescript/ai-bedrock/src/model-meta.ts
  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
  • packages/typescript/ai-bedrock/src/utils.ts
  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
  • packages/typescript/ai-bedrock/tests/model-meta.test.ts
  • packages/typescript/ai-bedrock/tsconfig.json
  • packages/typescript/ai-bedrock/vite.config.ts
🚧 Files skipped from review as they are similar to previous changes (11)
  • packages/typescript/ai-bedrock/tsconfig.json
  • packages/typescript/ai-bedrock/live-tests/package.json
  • knip.json
  • packages/typescript/ai-bedrock/live-tests/tool-test.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts
  • packages/typescript/ai-bedrock/src/bedrock-chat.ts
  • packages/typescript/ai-bedrock/src/utils.ts
  • packages/typescript/ai-bedrock/tests/model-meta.test.ts
  • packages/typescript/ai-bedrock/package.json
  • packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts
  • packages/typescript/ai-bedrock/vite.config.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use tree-shakeable adapter architecture for provider implementations - export specialized adapters (text, embedding, summarize, image) as separate imports from /adapters subpath rather than monolithic adapters
Use Zod for runtime schema validation and type inference, particularly for tool input/output definitions with toolDefinition() and Zod schema inference
Implement isomorphic tool system using toolDefinition() with .server() and .client() implementations for dual-environment execution
Use type-safe per-model configuration with provider options typed based on selected model to ensure compile-time safety
Implement stream processing with StreamProcessor for handling chunked responses and support partial JSON parsing for streaming AI responses

Files:

  • packages/typescript/ai-bedrock/src/adapters/text.ts
  • packages/typescript/ai-bedrock/src/adapters/index.ts
  • packages/typescript/ai-bedrock/src/model-meta.ts
  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/src/message-types.ts
  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use camelCase for function and variable names throughout the codebase

Files:

  • packages/typescript/ai-bedrock/src/adapters/text.ts
  • packages/typescript/ai-bedrock/src/adapters/index.ts
  • packages/typescript/ai-bedrock/src/model-meta.ts
  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/src/message-types.ts
  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
packages/typescript/*/src/adapters/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Create individual adapter implementations for each provider capability (text, embed, summarize, image) with separate exports to enable tree-shaking

Files:

  • packages/typescript/ai-bedrock/src/adapters/text.ts
  • packages/typescript/ai-bedrock/src/adapters/index.ts
packages/typescript/*/src/model-meta.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain model metadata files that define provider options and capabilities per model for per-model type safety

Files:

  • packages/typescript/ai-bedrock/src/model-meta.ts
packages/typescript/*/src/index.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Export tree-shakeable adapters with clear subpath exports in package.json (e.g., @tanstack/ai/adapters, @tanstack/ai-openai/adapters) to minimize bundle size

Files:

  • packages/typescript/ai-bedrock/src/index.ts
**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Write unit tests using Vitest alongside source files with .test.ts naming convention

Files:

  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/adapters/*.ts : Create individual adapter implementations for each provider capability (text, embed, summarize, image) with separate exports to enable tree-shaking
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/adapters/*.ts : Create individual adapter implementations for each provider capability (text, embed, summarize, image) with separate exports to enable tree-shaking

Applied to files:

  • packages/typescript/ai-bedrock/src/adapters/text.ts
  • packages/typescript/ai-bedrock/src/adapters/index.ts
  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Use tree-shakeable adapter architecture for provider implementations - export specialized adapters (text, embedding, summarize, image) as separate imports from `/adapters` subpath rather than monolithic adapters

Applied to files:

  • packages/typescript/ai-bedrock/src/adapters/text.ts
  • packages/typescript/ai-bedrock/src/adapters/index.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/index.ts : Export tree-shakeable adapters with clear subpath exports in package.json (e.g., `tanstack/ai/adapters`, `tanstack/ai-openai/adapters`) to minimize bundle size

Applied to files:

  • packages/typescript/ai-bedrock/src/adapters/text.ts
  • packages/typescript/ai-bedrock/src/adapters/index.ts
  • packages/typescript/ai-bedrock/src/index.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Implement stream processing with StreamProcessor for handling chunked responses and support partial JSON parsing for streaming AI responses

Applied to files:

  • packages/typescript/ai-bedrock/src/adapters/text.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/model-meta.ts : Maintain model metadata files that define provider options and capabilities per model for per-model type safety

Applied to files:

  • packages/typescript/ai-bedrock/src/model-meta.ts
  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/src/message-types.ts
📚 Learning: 2025-12-27T20:22:51.232Z
Learnt from: harry-whorlow
Repo: TanStack/ai PR: 117
File: packages/typescript/ai-ollama/src/meta/model-meta-gpt-oss.ts:92-97
Timestamp: 2025-12-27T20:22:51.232Z
Learning: In the ai-ollama package's model-meta files (packages/typescript/ai-ollama/src/meta/model-meta-*.ts), capability-related comments follow a standard template format across all files for consistency, even if the comment text doesn't precisely match individual model capabilities. This is an intentional design choice to maintain uniformity across the codebase.

Applied to files:

  • packages/typescript/ai-bedrock/src/model-meta.ts
📚 Learning: 2025-12-27T21:39:29.563Z
Learnt from: harry-whorlow
Repo: TanStack/ai PR: 117
File: packages/typescript/ai-ollama/src/meta/model-meta-llama-guard3.ts:70-75
Timestamp: 2025-12-27T21:39:29.563Z
Learning: The standard template comments in ai-ollama model-meta files (like "Models with text, image, audio, video (no document)") should not be modified to match individual model capabilities, as they are intentionally kept uniform across all model-meta-*.ts files for consistency, regardless of what each specific model actually supports.

Applied to files:

  • packages/typescript/ai-bedrock/src/model-meta.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Use type-safe per-model configuration with provider options typed based on selected model to ensure compile-time safety

Applied to files:

  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/*/package.json : Use `workspace:*` protocol for internal package dependencies in package.json (e.g., `"tanstack/ai": "workspace:*"`)

Applied to files:

  • packages/typescript/ai-bedrock/src/index.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Maintain type safety through multimodal content support (image, audio, video, document) with model capability awareness

Applied to files:

  • packages/typescript/ai-bedrock/src/message-types.ts
🧬 Code graph analysis (3)
packages/typescript/ai-bedrock/src/model-meta.ts (1)
packages/typescript/ai-bedrock/src/index.ts (9)
  • BedrockModelMeta (18-18)
  • BEDROCK_AMAZON_NOVA_PRO_V1 (12-12)
  • BEDROCK_AMAZON_NOVA_LITE_V1 (13-13)
  • BEDROCK_AMAZON_NOVA_MICRO_V1 (14-14)
  • BEDROCK_ANTHROPIC_CLAUDE_SONNET_4_5 (15-15)
  • BEDROCK_ANTHROPIC_CLAUDE_HAIKU_4_5 (16-16)
  • BEDROCK_CHAT_MODELS (17-17)
  • BedrockModelId (19-19)
  • BedrockModelInputModalitiesByName (20-20)
packages/typescript/ai-bedrock/src/message-types.ts (1)
packages/typescript/ai-bedrock/src/index.ts (7)
  • BedrockImageMediaType (30-30)
  • BedrockImageMetadata (26-26)
  • BedrockTextMetadata (25-25)
  • BedrockDocumentMetadata (27-27)
  • BedrockAudioMetadata (28-28)
  • BedrockVideoMetadata (29-29)
  • BedrockMessageMetadataByModality (24-24)
packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts (1)
packages/typescript/ai-bedrock/src/adapters/text.ts (1)
  • BedrockTextAdapter (41-416)
🪛 Biome (2.1.2)
packages/typescript/ai-bedrock/src/message-types.ts

[error] 25-25: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)

🪛 LanguageTool
packages/typescript/ai-bedrock/live-tests/README.md

[style] ~25-~25: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...de 3.5 Sonnet. ### tool-test-nova.ts Tests Amazon Nova Pro with multimodal inputs ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🪛 markdownlint-cli2 (0.18.1)
packages/typescript/ai-bedrock/live-tests/README.md

9-9: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (14)
.changeset/bedrock-adapter.md (1)

1-5: LGTM!

The changeset is correctly formatted with a minor version bump for the new adapter feature.

packages/typescript/ai-bedrock/src/adapters/index.ts (1)

1-2: LGTM!

The barrel file correctly re-exports the text adapter with separate value and type exports, enabling tree-shaking. Based on learnings, this aligns with the adapter architecture pattern.

packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts (1)

1-19: LGTM on mocking setup.

The vi.hoisted pattern for hoisting the mock before module imports is correct, and the mock structure properly simulates the BedrockRuntimeClient.

packages/typescript/ai-bedrock/src/index.ts (1)

6-31: LGTM!

The exports for chat helpers, model metadata, and message types are well-organized with proper separation of value and type exports.

packages/typescript/ai-bedrock/src/message-types.ts (1)

1-70: LGTM on the overall structure.

The multimodal metadata types are well-documented and provide a clean interface for Bedrock-specific content parts. The BedrockMessageMetadataByModality mapping enables type-safe modality handling.

packages/typescript/ai-bedrock/src/model-meta.ts (2)

2-11: LGTM on the interface design.

The BedrockModelMeta interface provides a clean structure for model capabilities with optional thinking support flag for extended reasoning models.


81-81: Good use of the branded string pattern.

The (string & {}) pattern preserves IDE autocomplete for known model IDs while allowing arbitrary model strings. This is idiomatic TypeScript.

packages/typescript/ai-bedrock/src/adapters/text.ts (4)

232-256: Media format extraction may fail silently with invalid mediaType.

When extracting format from mediaType (e.g., 'image/jpeg''jpeg'), if mediaType is malformed or missing, the fallback defaults are used. However, if the split produces unexpected results (e.g., 'jpeg' without slash), split('/')[1] returns undefined, which correctly falls back. This is acceptable but worth a brief note.


264-276: Stream processing state variables are not reset between calls.

The method-local state (accumulatedContent, toolCallIndex, etc.) is correctly scoped to each generator invocation. This is properly implemented.


289-339: Thinking tag parser handles edge cases well but has potential for infinite loop.

The while (text.length > 0) loop processes text chunks looking for <thinking> and </thinking> tags. The logic correctly handles:

  • Partial tags via pendingTagBuffer
  • Transitions between thinking and content states

However, if text contains a < character followed by content that never resolves to a complete tag or break condition, the loop continues indefinitely. The current break statements should prevent this, but verify with malformed inputs.


54-60: No issues found. The super({}, model) pattern is correct and consistent across all provider adapters (Anthropic, Bedrock, Gemini, OpenAI, Grok). BaseTextAdapter has a default value for the config parameter, and TextAdapterConfig defines all properties as optional, making the empty object a valid configuration. Provider-specific configs are intentionally handled separately via the provider-specific client initialization.

packages/typescript/ai-bedrock/src/text/text-provider-options.ts (3)

16-31: LGTM - ThinkingOptions discriminated union is well-structured.

The discriminated union using type: 'enabled' | 'disabled' provides good type safety for the thinking configuration. This pattern ensures consumers must provide budget_tokens only when thinking is enabled.


47-56: MCPServer type literal 'url' limits extensibility.

The type: 'url' is a literal type, which is fine if this is the only supported type. If Bedrock may support other MCP server types in the future, consider using a union type or documenting this constraint.


58-64: BedrockTextProviderOptions composition is clean and tree-shakeable.

The intersection type combining multiple option interfaces follows the coding guidelines for modular, tree-shakeable architecture. Each capability (MCP, stop sequences, thinking, sampling) is separately defined and can be imported individually if needed.

…l-calling support

- Implemented BedrockChatAdapter using the ConverseStream API.
- Added support for text, image, video, and document modalities.
- Implemented thinking tag parsing for Claude and Nova models.
- Added comprehensive model metadata and type-safe modality mapping.
- Added unit tests for model metadata and Converse API integration.
@srmurali002 srmurali002 force-pushed the feat/ai-bedrock-adapter branch from 2e11f2d to 19bb9b9 Compare January 12, 2026 07:51
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (13)
packages/typescript/ai-bedrock/live-tests/README.md (1)

9-13: Add language specifier to fenced code block.

The .env.local example should have a language identifier for consistency and proper rendering.

Suggested fix
-   ```
+   ```shell
    AWS_ACCESS_KEY_ID=...
    AWS_SECRET_ACCESS_KEY=...
    AWS_REGION=us-east-1
    ```
packages/typescript/ai-bedrock/src/message-types.ts (2)

25-25: Consider using a type alias for the empty interface.

Biome flags that an empty interface is equivalent to {}. Since BedrockTextMetadata has no properties, you could use a type alias instead. However, if you anticipate adding properties later or want declaration merging capability, keeping it as an interface is acceptable.

Optional: Convert to type alias
-export interface BedrockTextMetadata { }
+export type BedrockTextMetadata = Record<string, never>

30-59: Define strict union types for document, audio, and video media types to match the BedrockImageMediaType pattern.

The interfaces currently use generic string for mediaType, but AWS Bedrock Converse API supports specific formats for each content type:

  • Documents: text formats (txt, csv, html, md) and vision formats (pdf, docx, xlsx)
  • Audio: mp3, opus, wav, aac, flac, mp4, ogg, mkv, mka, x-aac, m4a, mpeg/mpga, pcm, webm
  • Video: video/mp4, video/webm, video/quicktime, video/x-matroska, video/x-flv, video/mpeg, video/x-ms-wmv, video/3gpp

Create BedrockDocumentMediaType, BedrockAudioMediaType, and BedrockVideoMediaType union types to enable compile-time type safety and prevent invalid format strings.

packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts (2)

67-70: Add explicit type annotation for result array.

The result array has an implicit any type. Consider adding a type annotation for better type safety. Based on the learnings, this file follows the .test.ts naming convention as expected.

Suggested fix
-            const result = []
+            const result: Array<{ type: string; delta?: string }> = []

Or import StreamChunk type if available from the adapter module.


32-83: Consider expanding test coverage.

The current test covers the basic happy path for streaming text responses. Consider adding tests for:

  • Error handling when the stream fails
  • Tool calling scenarios (tool_call chunks)
  • <thinking> tag parsing for Claude/Nova reasoning
  • Usage metadata in the done chunk

These can be added in a follow-up PR if preferred.

Would you like me to generate additional test cases for error handling and tool calling scenarios?

packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts (2)

1-4: Consider using the model constant for consistency.

The model ID on line 14 is hardcoded as a string literal. Consider importing and using BEDROCK_ANTHROPIC_CLAUDE_HAIKU_4_5.id from ../src/model-meta to ensure consistency with the defined constants and catch typos at compile time.

Also, the commented-out dotenv/config import differs from tool-test-nova.ts which manually loads .env.local. Consider aligning the environment loading approach across all live tests for consistency.

Suggested import alignment
 // import 'dotenv/config'
 import { bedrockText } from '../src/bedrock-chat'
 import { z } from 'zod'
 import { chat } from '@tanstack/ai'
+import { BEDROCK_ANTHROPIC_CLAUDE_HAIKU_4_5 } from '../src/model-meta'

Then use BEDROCK_ANTHROPIC_CLAUDE_HAIKU_4_5.id instead of the string literal on line 14.


73-83: Consider adding a warning for missing thinking blocks.

Unlike tool-test-nova.ts which warns when no thinking blocks are detected (lines 81-83), this test tracks hasThinking but doesn't validate or warn about it. Since thinking is explicitly enabled in the config (lines 26-29), consider adding a similar warning or assertion.

Suggested enhancement
     console.log('--- Results ---')
     console.log('Thinking:', hasThinking)
     console.log('Tool calls:', toolCallCount)
     console.log('Content length:', finalContent.length)

+    if (!hasThinking) {
+        console.warn('Warning: No thinking blocks detected despite thinking being enabled')
+    }
+
     if (!finalContent || finalContent.trim().length === 0) {
         console.error('Test failed: No final content')
         process.exit(1)
     }
packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts (1)

10-20: Manual env parsing is fragile.

This parser doesn't handle quoted values, comments, or edge cases. Consider using a lightweight env parsing library or the commented approach in tool-test-haiku.ts with dotenv/config.

Alternative: use dotenv
+import 'dotenv/config'
 import { bedrockText } from '../src/index'
 import { z } from 'zod'
-import { readFileSync } from 'fs'
-import { join, dirname } from 'path'
-import { fileURLToPath } from 'url'
 import { chat } from '@tanstack/ai'

-// Load environment variables from .env.local manually
-const __dirname = dirname(fileURLToPath(import.meta.url))
-try {
-    const envContent = readFileSync(join(__dirname, '.env.local'), 'utf-8')
-    envContent.split('\n').forEach((line) => {
-        const match = line.match(/^([^=]+)=(.*)$/)
-        if (match) {
-            process.env[match[1].trim()] = match[2].trim()
-        }
-    })
-} catch (e) {
-    // .env.local not found
-}
packages/typescript/ai-bedrock/src/model-meta.ts (1)

98-99: Model detection helpers may produce false positives.

Using .includes() could match unintended strings. For example, a hypothetical model ID like 'custom-anthropic.claude-fork' would match isClaude. Consider using more precise patterns or checking against the known model ID prefixes.

More precise detection
-export const isClaude = (model: string) => model.includes('anthropic.claude')
-export const isNova = (model: string) => model.includes('amazon.nova')
+export const isClaude = (model: string) => model.startsWith('anthropic.claude') || model.startsWith('us.anthropic.claude')
+export const isNova = (model: string) => model.startsWith('amazon.nova') || model.startsWith('us.amazon.nova')
packages/typescript/ai-bedrock/src/text/text-provider-options.ts (3)

9-14: Clarify relationship between duplicate stop sequences fields.

BedrockStopSequencesOptions.stop_sequences (snake_case) and BedrockInferenceConfig.stopSequences (camelCase) appear to serve the same purpose. Consider documenting which takes precedence or consolidating into a single field to avoid confusion.

Suggested documentation
 export interface BedrockStopSequencesOptions {
     /**
      * Custom text sequences that will cause the model to stop generating.
+     * Note: This is merged with inferenceConfig.stopSequences if both are provided.
      */
     stop_sequences?: Array<string>
 }

Also applies to: 40-45


47-56: Consider making tool_configuration optional instead of nullable.

The tool_configuration field is typed as { ... } | null rather than optional (tool_configuration?: { ... }). This forces consumers to explicitly pass null even when they don't want tool configuration. Using optional would be more ergonomic.

Suggested change
 export interface MCPServer {
     name: string
     url: string
     type: 'url'
     authorization_token?: string | null
-    tool_configuration: {
+    tool_configuration?: {
         allowed_tools?: Array<string> | null
         enabled?: boolean | null
-    } | null
+    }
 }

1-7: Consider adding runtime validation for the 20-server limit.

The comment mentions a maximum of 20 MCP servers, but there's no type-level or runtime enforcement. Since this is a provider constraint, consider adding a note that validation occurs at the adapter level, or use a branded type/tuple if compile-time enforcement is desired.

packages/typescript/ai-bedrock/src/index.ts (1)

1-31: Consider exporting BedrockTextProviderOptions type for type-safe consumer configuration.

The text-provider-options.ts file defines BedrockTextProviderOptions and related types (BedrockThinkingOptions, BedrockSamplingOptions, BedrockInferenceConfig, etc.) which consumers need for configuring model options when instantiating or using BedrockTextAdapter. These should be part of the public API surface to enable type-safe per-model configuration.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e11f2d and 19bb9b9.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (20)
  • .changeset/bedrock-adapter.md
  • knip.json
  • packages/typescript/ai-bedrock/live-tests/README.md
  • packages/typescript/ai-bedrock/live-tests/package.json
  • packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test.ts
  • packages/typescript/ai-bedrock/package.json
  • packages/typescript/ai-bedrock/src/adapters/index.ts
  • packages/typescript/ai-bedrock/src/adapters/text.ts
  • packages/typescript/ai-bedrock/src/bedrock-chat.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/src/message-types.ts
  • packages/typescript/ai-bedrock/src/model-meta.ts
  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
  • packages/typescript/ai-bedrock/src/utils.ts
  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
  • packages/typescript/ai-bedrock/tests/model-meta.test.ts
  • packages/typescript/ai-bedrock/tsconfig.json
  • packages/typescript/ai-bedrock/vite.config.ts
🚧 Files skipped from review as they are similar to previous changes (10)
  • packages/typescript/ai-bedrock/vite.config.ts
  • packages/typescript/ai-bedrock/src/bedrock-chat.ts
  • packages/typescript/ai-bedrock/tests/model-meta.test.ts
  • packages/typescript/ai-bedrock/src/utils.ts
  • packages/typescript/ai-bedrock/src/adapters/index.ts
  • packages/typescript/ai-bedrock/src/adapters/text.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test.ts
  • packages/typescript/ai-bedrock/package.json
  • packages/typescript/ai-bedrock/live-tests/package.json
  • packages/typescript/ai-bedrock/tsconfig.json
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use tree-shakeable adapter architecture for provider implementations - export specialized adapters (text, embedding, summarize, image) as separate imports from /adapters subpath rather than monolithic adapters
Use Zod for runtime schema validation and type inference, particularly for tool input/output definitions with toolDefinition() and Zod schema inference
Implement isomorphic tool system using toolDefinition() with .server() and .client() implementations for dual-environment execution
Use type-safe per-model configuration with provider options typed based on selected model to ensure compile-time safety
Implement stream processing with StreamProcessor for handling chunked responses and support partial JSON parsing for streaming AI responses

Files:

  • packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts
  • packages/typescript/ai-bedrock/src/message-types.ts
  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/src/model-meta.ts
  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use camelCase for function and variable names throughout the codebase

Files:

  • packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts
  • packages/typescript/ai-bedrock/src/message-types.ts
  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/src/model-meta.ts
  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts
packages/typescript/*/src/index.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Export tree-shakeable adapters with clear subpath exports in package.json (e.g., @tanstack/ai/adapters, @tanstack/ai-openai/adapters) to minimize bundle size

Files:

  • packages/typescript/ai-bedrock/src/index.ts
packages/typescript/*/src/model-meta.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain model metadata files that define provider options and capabilities per model for per-model type safety

Files:

  • packages/typescript/ai-bedrock/src/model-meta.ts
**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Write unit tests using Vitest alongside source files with .test.ts naming convention

Files:

  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/adapters/*.ts : Create individual adapter implementations for each provider capability (text, embed, summarize, image) with separate exports to enable tree-shaking
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Use tree-shakeable adapter architecture for provider implementations - export specialized adapters (text, embedding, summarize, image) as separate imports from `/adapters` subpath rather than monolithic adapters
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/index.ts : Export tree-shakeable adapters with clear subpath exports in package.json (e.g., `tanstack/ai/adapters`, `tanstack/ai-openai/adapters`) to minimize bundle size
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/model-meta.ts : Maintain model metadata files that define provider options and capabilities per model for per-model type safety
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/index.ts : Export tree-shakeable adapters with clear subpath exports in package.json (e.g., `tanstack/ai/adapters`, `tanstack/ai-openai/adapters`) to minimize bundle size

Applied to files:

  • knip.json
  • packages/typescript/ai-bedrock/src/index.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to examples/** : Examples are not built by Nx and should be run independently from their directories with `pnpm dev` or `pnpm install && pnpm dev`

Applied to files:

  • knip.json
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/*/package.json : Use `workspace:*` protocol for internal package dependencies in package.json (e.g., `"tanstack/ai": "workspace:*"`)

Applied to files:

  • knip.json
  • packages/typescript/ai-bedrock/src/index.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Use Nx workspace with affected commands to optimize testing and building only changed packages and their dependents

Applied to files:

  • knip.json
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Implement isomorphic tool system using `toolDefinition()` with `.server()` and `.client()` implementations for dual-environment execution

Applied to files:

  • packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts
  • packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Maintain type safety through multimodal content support (image, audio, video, document) with model capability awareness

Applied to files:

  • packages/typescript/ai-bedrock/src/message-types.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/model-meta.ts : Maintain model metadata files that define provider options and capabilities per model for per-model type safety

Applied to files:

  • packages/typescript/ai-bedrock/src/message-types.ts
  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/src/model-meta.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Use type-safe per-model configuration with provider options typed based on selected model to ensure compile-time safety

Applied to files:

  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/adapters/*.ts : Create individual adapter implementations for each provider capability (text, embed, summarize, image) with separate exports to enable tree-shaking

Applied to files:

  • packages/typescript/ai-bedrock/src/text/text-provider-options.ts
  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Use tree-shakeable adapter architecture for provider implementations - export specialized adapters (text, embedding, summarize, image) as separate imports from `/adapters` subpath rather than monolithic adapters

Applied to files:

  • packages/typescript/ai-bedrock/src/index.ts
  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
📚 Learning: 2025-12-27T20:22:51.232Z
Learnt from: harry-whorlow
Repo: TanStack/ai PR: 117
File: packages/typescript/ai-ollama/src/meta/model-meta-gpt-oss.ts:92-97
Timestamp: 2025-12-27T20:22:51.232Z
Learning: In the ai-ollama package's model-meta files (packages/typescript/ai-ollama/src/meta/model-meta-*.ts), capability-related comments follow a standard template format across all files for consistency, even if the comment text doesn't precisely match individual model capabilities. This is an intentional design choice to maintain uniformity across the codebase.

Applied to files:

  • packages/typescript/ai-bedrock/src/model-meta.ts
📚 Learning: 2025-12-27T21:39:29.563Z
Learnt from: harry-whorlow
Repo: TanStack/ai PR: 117
File: packages/typescript/ai-ollama/src/meta/model-meta-llama-guard3.ts:70-75
Timestamp: 2025-12-27T21:39:29.563Z
Learning: The standard template comments in ai-ollama model-meta files (like "Models with text, image, audio, video (no document)") should not be modified to match individual model capabilities, as they are intentionally kept uniform across all model-meta-*.ts files for consistency, regardless of what each specific model actually supports.

Applied to files:

  • packages/typescript/ai-bedrock/src/model-meta.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Implement stream processing with StreamProcessor for handling chunked responses and support partial JSON parsing for streaming AI responses

Applied to files:

  • packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts
🧬 Code graph analysis (4)
packages/typescript/ai-bedrock/live-tests/tool-test-haiku.ts (2)
packages/typescript/ai-bedrock/src/bedrock-chat.ts (1)
  • bedrockText (12-25)
packages/typescript/ai-bedrock/src/index.ts (1)
  • bedrockText (8-8)
packages/typescript/ai-bedrock/src/message-types.ts (1)
packages/typescript/ai-bedrock/src/index.ts (7)
  • BedrockImageMediaType (30-30)
  • BedrockImageMetadata (26-26)
  • BedrockTextMetadata (25-25)
  • BedrockDocumentMetadata (27-27)
  • BedrockAudioMetadata (28-28)
  • BedrockVideoMetadata (29-29)
  • BedrockMessageMetadataByModality (24-24)
packages/typescript/ai-bedrock/src/model-meta.ts (1)
packages/typescript/ai-bedrock/src/index.ts (9)
  • BedrockModelMeta (18-18)
  • BEDROCK_AMAZON_NOVA_PRO_V1 (12-12)
  • BEDROCK_AMAZON_NOVA_LITE_V1 (13-13)
  • BEDROCK_AMAZON_NOVA_MICRO_V1 (14-14)
  • BEDROCK_ANTHROPIC_CLAUDE_SONNET_4_5 (15-15)
  • BEDROCK_ANTHROPIC_CLAUDE_HAIKU_4_5 (16-16)
  • BEDROCK_CHAT_MODELS (17-17)
  • BedrockModelId (19-19)
  • BedrockModelInputModalitiesByName (20-20)
packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts (1)
packages/typescript/ai-bedrock/src/adapters/text.ts (1)
  • BedrockTextAdapter (41-419)
🪛 Biome (2.1.2)
packages/typescript/ai-bedrock/src/message-types.ts

[error] 25-25: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)

🪛 LanguageTool
packages/typescript/ai-bedrock/live-tests/README.md

[style] ~25-~25: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...de 3.5 Sonnet. ### tool-test-nova.ts Tests Amazon Nova Pro with multimodal inputs ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🪛 markdownlint-cli2 (0.18.1)
packages/typescript/ai-bedrock/live-tests/README.md

9-9: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (5)
.changeset/bedrock-adapter.md (1)

1-5: LGTM!

The changeset correctly marks this as a minor version bump for the new @tanstack/ai-bedrock package, which is appropriate for a new feature addition.

knip.json (1)

11-22: LGTM!

The new ignore path for packages/typescript/ai-bedrock/live-tests/** follows the established pattern used by other adapter packages (e.g., ai-openai/live-tests). This appropriately excludes the live test files from Knip's unused code detection.

packages/typescript/ai-bedrock/tests/bedrock-adapter.test.ts (1)

1-30: LGTM - Good mock setup for AWS SDK testing.

The use of vi.hoisted ensures sendMock is defined before the mock factory runs, which is the correct pattern for Vitest module mocking. The test correctly mocks the BedrockRuntimeClient and ConverseStreamCommand.

packages/typescript/ai-bedrock/src/model-meta.ts (1)

2-11: LGTM! Well-structured model metadata interface.

The BedrockModelMeta interface cleanly defines per-model capabilities with optional thinking support and multimodal input arrays. The use of as const satisfies BedrockModelMeta on model constants ensures type safety while preserving literal types for downstream inference. This aligns well with the project's per-model type safety guidelines.

packages/typescript/ai-bedrock/live-tests/tool-test-nova.ts (1)

81-83: Remove the misleading thinking block warning or skip the check for models that don't support thinking.

The test unconditionally warns if no thinking blocks are detected, but Nova models don't have thinking: true in their supports configuration (only Claude models do). This warning will always trigger for Nova, making it a non-actionable and confusing test output.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@srmurali002 srmurali002 force-pushed the feat/ai-bedrock-adapter branch from 2f4cda0 to e3a1196 Compare January 12, 2026 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant