-
-
Notifications
You must be signed in to change notification settings - Fork 108
feat(ai-bedrock): add AWS Bedrock adapter with ConverseStream and tool-calling support #220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
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 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. 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughAdds 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
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ 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. Comment |
There was a problem hiding this 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) withcamelCase(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_sequencesvsBedrockInferenceConfig.stopSequencesboth 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
MCPServerinterface lacks JSDoc comments for its properties, unlike other interfaces in this file. Adding brief descriptions (especially forauthorization_tokenandtool_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:
- Error handling (e.g., when
sendMockrejects)- Tool call streaming events (the adapter should handle
toolUseevents)🧪 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
toolCallCountis 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.envpattern is specific to certain bundler setups (e.g., Vite withdefineconfig). 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_IDorAWS_SECRET_ACCESS_KEYare 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.localparsing pattern is duplicated across test files. Consider extracting it into a shared utility in thelive-testsdirectory (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'whiletool-test-nova.tsimports 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 (liketool-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 makingmaxReasoningEffortconfigurable.The reasoning effort level is hardcoded to
"medium". If Nova models support different effort levels, this should be exposed viamodelOptions.thinkingor 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 thepartparameter.Using
anyfor thepartparameter 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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (19)
.changeset/bedrock-adapter.mdknip.jsonpackages/typescript/ai-bedrock/live-tests/README.mdpackages/typescript/ai-bedrock/live-tests/package.jsonpackages/typescript/ai-bedrock/live-tests/tool-test-haiku.tspackages/typescript/ai-bedrock/live-tests/tool-test-nova.tspackages/typescript/ai-bedrock/live-tests/tool-test.tspackages/typescript/ai-bedrock/package.jsonpackages/typescript/ai-bedrock/src/adapters/text.tspackages/typescript/ai-bedrock/src/bedrock-chat.tspackages/typescript/ai-bedrock/src/index.tspackages/typescript/ai-bedrock/src/message-types.tspackages/typescript/ai-bedrock/src/model-meta.tspackages/typescript/ai-bedrock/src/text/text-provider-options.tspackages/typescript/ai-bedrock/src/utils.tspackages/typescript/ai-bedrock/tests/bedrock-adapter.test.tspackages/typescript/ai-bedrock/tests/model-meta.test.tspackages/typescript/ai-bedrock/tsconfig.jsonpackages/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/adapterssubpath rather than monolithic adapters
Use Zod for runtime schema validation and type inference, particularly for tool input/output definitions withtoolDefinition()and Zod schema inference
Implement isomorphic tool system usingtoolDefinition()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.tspackages/typescript/ai-bedrock/live-tests/tool-test-haiku.tspackages/typescript/ai-bedrock/src/utils.tspackages/typescript/ai-bedrock/live-tests/tool-test-nova.tspackages/typescript/ai-bedrock/tests/model-meta.test.tspackages/typescript/ai-bedrock/src/message-types.tspackages/typescript/ai-bedrock/src/index.tspackages/typescript/ai-bedrock/src/adapters/text.tspackages/typescript/ai-bedrock/src/bedrock-chat.tspackages/typescript/ai-bedrock/live-tests/tool-test.tspackages/typescript/ai-bedrock/src/text/text-provider-options.tspackages/typescript/ai-bedrock/src/model-meta.tspackages/typescript/ai-bedrock/vite.config.ts
**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Write unit tests using Vitest alongside source files with
.test.tsnaming convention
Files:
packages/typescript/ai-bedrock/tests/bedrock-adapter.test.tspackages/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.tspackages/typescript/ai-bedrock/live-tests/tool-test-haiku.tspackages/typescript/ai-bedrock/src/utils.tspackages/typescript/ai-bedrock/live-tests/tool-test-nova.tspackages/typescript/ai-bedrock/tests/model-meta.test.tspackages/typescript/ai-bedrock/src/message-types.tspackages/typescript/ai-bedrock/src/index.tspackages/typescript/ai-bedrock/src/adapters/text.tspackages/typescript/ai-bedrock/src/bedrock-chat.tspackages/typescript/ai-bedrock/live-tests/tool-test.tspackages/typescript/ai-bedrock/src/text/text-provider-options.tspackages/typescript/ai-bedrock/src/model-meta.tspackages/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.jsonknip.jsonpackages/typescript/ai-bedrock/tsconfig.jsonpackages/typescript/ai-bedrock/src/index.tspackages/typescript/ai-bedrock/live-tests/package.jsonpackages/typescript/ai-bedrock/src/bedrock-chat.tspackages/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.jsonpackages/typescript/ai-bedrock/tests/bedrock-adapter.test.tspackages/typescript/ai-bedrock/tsconfig.jsonpackages/typescript/ai-bedrock/src/index.tspackages/typescript/ai-bedrock/src/adapters/text.tspackages/typescript/ai-bedrock/src/bedrock-chat.tspackages/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.jsonknip.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.jsonpackages/typescript/ai-bedrock/tests/model-meta.test.tspackages/typescript/ai-bedrock/tsconfig.jsonpackages/typescript/ai-bedrock/src/message-types.tspackages/typescript/ai-bedrock/src/index.tspackages/typescript/ai-bedrock/src/text/text-provider-options.tspackages/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.tspackages/typescript/ai-bedrock/src/index.tspackages/typescript/ai-bedrock/src/adapters/text.tspackages/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.tspackages/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.tspackages/typescript/ai-bedrock/live-tests/tool-test-nova.tspackages/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.tspackages/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.tspackages/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.tspackages/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.tspackages/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.jsonpackages/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
tanstackViteConfigfollows the established TanStack pattern, andcjs: falsecorrectly 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:
BedrockModelIdwith(string & {})allows arbitrary model IDs while preserving autocomplete for known models.BedrockModelInputModalitiesByNameenables per-model type safety as required by coding guidelines.- The
isClaude/isNovahelpers 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-v8is 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
ResolveModalitieshelper correctly converts raw modality arrays toInputModalitiesTypes, 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
executefunction 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
BedrockMessageMetadataByModalitymapping 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.
b7f9e35 to
2e11f2d
Compare
There was a problem hiding this 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.streamis 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
./adaptersinstead of./adapters/textdirectly. 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
BedrockTextConfiginterface 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 anAwsCredentialIdentity | AwsCredentialIdentityProviderfrom@aws-sdk/typesfor more flexible credential sourcing.
92-108: Type assertionas anybypasses type safety for additionalModelRequestFields.The
as anytype assertion silences type checking for model-specific fields. Consider creating a union type or using the AWS SDK'sDocumentTypeproperly 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
messageandnamefrom 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 withpart: any- consider using discriminated union.The
convertPartToConverseBlockmethod usesanyfor thepartparameter. 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/aiif 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, andauthorization_tokenuse snake_case, whileBedrockInferenceConfiguses 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_sequencesandBedrockInferenceConfig.stopSequencesdefine 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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (20)
.changeset/bedrock-adapter.mdknip.jsonpackages/typescript/ai-bedrock/live-tests/README.mdpackages/typescript/ai-bedrock/live-tests/package.jsonpackages/typescript/ai-bedrock/live-tests/tool-test-haiku.tspackages/typescript/ai-bedrock/live-tests/tool-test-nova.tspackages/typescript/ai-bedrock/live-tests/tool-test.tspackages/typescript/ai-bedrock/package.jsonpackages/typescript/ai-bedrock/src/adapters/index.tspackages/typescript/ai-bedrock/src/adapters/text.tspackages/typescript/ai-bedrock/src/bedrock-chat.tspackages/typescript/ai-bedrock/src/index.tspackages/typescript/ai-bedrock/src/message-types.tspackages/typescript/ai-bedrock/src/model-meta.tspackages/typescript/ai-bedrock/src/text/text-provider-options.tspackages/typescript/ai-bedrock/src/utils.tspackages/typescript/ai-bedrock/tests/bedrock-adapter.test.tspackages/typescript/ai-bedrock/tests/model-meta.test.tspackages/typescript/ai-bedrock/tsconfig.jsonpackages/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/adapterssubpath rather than monolithic adapters
Use Zod for runtime schema validation and type inference, particularly for tool input/output definitions withtoolDefinition()and Zod schema inference
Implement isomorphic tool system usingtoolDefinition()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.tspackages/typescript/ai-bedrock/src/adapters/index.tspackages/typescript/ai-bedrock/src/model-meta.tspackages/typescript/ai-bedrock/src/text/text-provider-options.tspackages/typescript/ai-bedrock/src/index.tspackages/typescript/ai-bedrock/src/message-types.tspackages/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.tspackages/typescript/ai-bedrock/src/adapters/index.tspackages/typescript/ai-bedrock/src/model-meta.tspackages/typescript/ai-bedrock/src/text/text-provider-options.tspackages/typescript/ai-bedrock/src/index.tspackages/typescript/ai-bedrock/src/message-types.tspackages/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.tspackages/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.tsnaming 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.tspackages/typescript/ai-bedrock/src/adapters/index.tspackages/typescript/ai-bedrock/src/text/text-provider-options.tspackages/typescript/ai-bedrock/src/index.tspackages/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.tspackages/typescript/ai-bedrock/src/adapters/index.tspackages/typescript/ai-bedrock/src/index.tspackages/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.tspackages/typescript/ai-bedrock/src/adapters/index.tspackages/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.tspackages/typescript/ai-bedrock/src/text/text-provider-options.tspackages/typescript/ai-bedrock/src/index.tspackages/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.hoistedpattern 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
BedrockMessageMetadataByModalitymapping enables type-safe modality handling.packages/typescript/ai-bedrock/src/model-meta.ts (2)
2-11: LGTM on the interface design.The
BedrockModelMetainterface provides a clean structure for model capabilities with optionalthinkingsupport 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'), ifmediaTypeis malformed or missing, the fallback defaults are used. However, if the split produces unexpected results (e.g.,'jpeg'without slash),split('/')[1]returnsundefined, 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 currentbreakstatements should prevent this, but verify with malformed inputs.
54-60: No issues found. Thesuper({}, model)pattern is correct and consistent across all provider adapters (Anthropic, Bedrock, Gemini, OpenAI, Grok).BaseTextAdapterhas a default value for the config parameter, andTextAdapterConfigdefines 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 providebudget_tokensonly 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.
2e11f2d to
19bb9b9
Compare
There was a problem hiding this 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.localexample 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
{}. SinceBedrockTextMetadatahas 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 theBedrockImageMediaTypepattern.The interfaces currently use generic
stringformediaType, 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, andBedrockVideoMediaTypeunion 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
resultarray has an implicitanytype. Consider adding a type annotation for better type safety. Based on the learnings, this file follows the.test.tsnaming convention as expected.Suggested fix
- const result = [] + const result: Array<{ type: string; delta?: string }> = []Or import
StreamChunktype 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_callchunks)<thinking>tag parsing for Claude/Nova reasoning- Usage metadata in the
donechunkThese 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.idfrom../src/model-metato ensure consistency with the defined constants and catch typos at compile time.Also, the commented-out
dotenv/configimport differs fromtool-test-nova.tswhich 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.idinstead of the string literal on line 14.
73-83: Consider adding a warning for missing thinking blocks.Unlike
tool-test-nova.tswhich warns when no thinking blocks are detected (lines 81-83), this test trackshasThinkingbut 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.tswithdotenv/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 matchisClaude. 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) andBedrockInferenceConfig.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 makingtool_configurationoptional instead of nullable.The
tool_configurationfield is typed as{ ... } | nullrather than optional (tool_configuration?: { ... }). This forces consumers to explicitly passnulleven 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 exportingBedrockTextProviderOptionstype for type-safe consumer configuration.The
text-provider-options.tsfile definesBedrockTextProviderOptionsand related types (BedrockThinkingOptions,BedrockSamplingOptions,BedrockInferenceConfig, etc.) which consumers need for configuring model options when instantiating or usingBedrockTextAdapter. 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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (20)
.changeset/bedrock-adapter.mdknip.jsonpackages/typescript/ai-bedrock/live-tests/README.mdpackages/typescript/ai-bedrock/live-tests/package.jsonpackages/typescript/ai-bedrock/live-tests/tool-test-haiku.tspackages/typescript/ai-bedrock/live-tests/tool-test-nova.tspackages/typescript/ai-bedrock/live-tests/tool-test.tspackages/typescript/ai-bedrock/package.jsonpackages/typescript/ai-bedrock/src/adapters/index.tspackages/typescript/ai-bedrock/src/adapters/text.tspackages/typescript/ai-bedrock/src/bedrock-chat.tspackages/typescript/ai-bedrock/src/index.tspackages/typescript/ai-bedrock/src/message-types.tspackages/typescript/ai-bedrock/src/model-meta.tspackages/typescript/ai-bedrock/src/text/text-provider-options.tspackages/typescript/ai-bedrock/src/utils.tspackages/typescript/ai-bedrock/tests/bedrock-adapter.test.tspackages/typescript/ai-bedrock/tests/model-meta.test.tspackages/typescript/ai-bedrock/tsconfig.jsonpackages/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/adapterssubpath rather than monolithic adapters
Use Zod for runtime schema validation and type inference, particularly for tool input/output definitions withtoolDefinition()and Zod schema inference
Implement isomorphic tool system usingtoolDefinition()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.tspackages/typescript/ai-bedrock/src/message-types.tspackages/typescript/ai-bedrock/src/text/text-provider-options.tspackages/typescript/ai-bedrock/src/index.tspackages/typescript/ai-bedrock/src/model-meta.tspackages/typescript/ai-bedrock/tests/bedrock-adapter.test.tspackages/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.tspackages/typescript/ai-bedrock/src/message-types.tspackages/typescript/ai-bedrock/src/text/text-provider-options.tspackages/typescript/ai-bedrock/src/index.tspackages/typescript/ai-bedrock/src/model-meta.tspackages/typescript/ai-bedrock/tests/bedrock-adapter.test.tspackages/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.tsnaming 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.jsonpackages/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.jsonpackages/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.tspackages/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.tspackages/typescript/ai-bedrock/src/text/text-provider-options.tspackages/typescript/ai-bedrock/src/index.tspackages/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.tspackages/typescript/ai-bedrock/src/index.tspackages/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.tspackages/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-bedrockpackage, 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.hoistedensuressendMockis defined before the mock factory runs, which is the correct pattern for Vitest module mocking. The test correctly mocks theBedrockRuntimeClientandConverseStreamCommand.packages/typescript/ai-bedrock/src/model-meta.ts (1)
2-11: LGTM! Well-structured model metadata interface.The
BedrockModelMetainterface cleanly defines per-model capabilities with optional thinking support and multimodal input arrays. The use ofas const satisfies BedrockModelMetaon 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: truein theirsupportsconfiguration (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>
2f4cda0 to
e3a1196
Compare
🎯 Changes
This PR adds the
@tanstack/ai-bedrockpackage. This implementation uses the AWS SDK v3 Converse API to provide a unified interface for streaming and tool calling.✅ Checklist
pnpm run test:pr.🚀 Release Impact
Summary by CodeRabbit
New Features
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.