Skip to content

Conversation

@frederikschr
Copy link

@frederikschr frederikschr commented Jan 25, 2026

I showed Automaker to my Dad and he really liked it. However, he can only use the AWS Bedrock Claude Models because of his job, so I added the ability to enable Bedrock in the Anthropic Provider settings and pass in credentials there.

Summary by CodeRabbit

  • New Features

    • Optional AWS Bedrock support for Claude models
    • Bedrock settings UI: credential import, region, enable toggle, status
    • New Bedrock Claude model variants with AWS badges in selectors
  • Improvements

    • Model lists and capability checks adapt to Bedrock configuration/enabled state
    • App startup now loads Bedrock status so UI reflects configuration immediately
    • macOS build artifacts simplified to arm64-only

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

@coderabbitai
Copy link

coderabbitai bot commented Jan 25, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds AWS Bedrock support for Claude: server-side Bedrock credential handling and model mapping, async model-list APIs, a Bedrock status endpoint, UI controls and hooks for Bedrock credentials/status, Bedrock model options and display adjustments, provider factory/type updates, and related plumbing across server, UI, and libs.

Changes

Cohort / File(s) Summary
Dependencies & Core Init
apps/server/package.json, apps/server/src/index.ts
Added Anthropic/Bedrock SDK deps; initialize ProviderFactory with settingsService.
Provider API & Factory
apps/server/src/providers/base-provider.ts, apps/server/src/providers/provider-factory.ts, apps/server/src/providers/*-provider.ts (claude, codex, cursor, opencode, ...)
getAvailableModels made async across providers; ProviderFactory now holds settingsService, added initialize, getAllAvailableModels and modelSupportsVision are async; Claude registration recognizes Bedrock formats/aliases.
Claude Provider (Bedrock integration)
apps/server/src/providers/claude-provider.ts
Added Bedrock config caching, env/credential merging, model-to-Bedrock mapping, Bedrock-aware execute flow, async model listing, and related helpers/fields.
Settings, Types & Settings Service
libs/types/src/settings.ts, libs/types/src/index.ts, apps/server/src/types/settings.ts, apps/server/src/services/settings-service.ts
Introduced AWSBedrockConfig and DEFAULT_AWS_BEDROCK_CONFIG; extended Credentials and get/update/masked flows to include awsBedrock; updated public exports/types.
Bedrock status endpoint
apps/server/src/routes/settings/index.ts, apps/server/src/routes/settings/routes/get-bedrock-status.ts
New GET /api/settings/bedrock-status route returning bedrockConfigured, bedrockEnabled, and region.
Simple-query / allowedTools adjustments
apps/server/src/providers/simple-query-service.ts, various apps/server/src/routes/* and apps/server/src/services/*
Removed forced allowedTools: [] (and some readOnly) in many invocations; now omit allowedTools when undefined.
Callsite updates for async APIs
apps/server/src/routes/models/routes/available.ts, apps/server/src/routes/setup/routes/opencode-models.ts, apps/server/src/services/*
Updated callsites to await new async provider methods (getAllAvailableModels, modelSupportsVision, getAvailableModels).
UI: Bedrock models, selector & badges
apps/ui/src/components/views/board-view/shared/model-constants.ts, apps/ui/src/components/views/board-view/shared/model-selector.tsx, apps/ui/src/components/views/settings-view/model-defaults/phase-model-selector.tsx, apps/ui/src/lib/agent-context-parser.ts
Added BEDROCK_MODELS, Bedrock-aware model selection, AWS badge rendering, and model name formatting to append " (Bedrock)".
UI: Bedrock settings UI, hook & startup
apps/ui/src/components/views/settings-view/providers/claude-settings-tab/aws-bedrock-section.tsx, apps/ui/src/components/views/settings-view/providers/claude-settings-tab.tsx, apps/ui/src/hooks/use-bedrock-status.ts, apps/ui/src/routes/__root.tsx
New AwsBedrockSection component for credentials/enable/region import/save; useBedrockStatus queries /bedrock-status; root invokes hook on mount.
UI: API surface & store
apps/ui/src/lib/electron.ts, apps/ui/src/lib/http-api-client.ts, apps/ui/src/store/app-store.ts
Extended Electron/HTTP API types and payloads to include awsBedrock and getBedrockStatus; added bedrockConfigured and bedrockEnabled state and setters.
UI: App context / React Query
apps/ui/src/app.tsx, apps/ui/package.json
Wrapped App with QueryClientProvider; macOS dmg arch reduced to arm64 (zip target removed).
Misc: model-resolver & other libs
libs/model-resolver/src/resolver.ts, libs/types/src/index.ts
Broadened full-claude model pattern detection for Bedrock/Anthropic formats; adjusted public exports.

Sequence Diagram(s)

sequenceDiagram
    participant UI as Client/UI
    participant Server as Server (ClaudeProvider)
    participant Settings as SettingsService
    participant BedrockSDK as AWS Bedrock SDK
    participant AnthropicSDK as Anthropic SDK

    UI->>Server: executeQuery(model, messages, options)
    Server->>Settings: getCredentials()
    Settings-->>Server: credentials (includes awsBedrock)
    Server->>Server: mapToBedrockModel(model)
    alt Bedrock configured & enabled
        Server->>BedrockSDK: send messages(mappedModel, sdkOptions)
        BedrockSDK-->>Server: response
    else Use Anthropic directly
        Server->>AnthropicSDK: send messages(model, sdkOptions)
        AnthropicSDK-->>Server: response
    end
    Server-->>UI: result
Loading
sequenceDiagram
    participant App as App Startup
    participant Root as RootLayout
    participant Hook as useBedrockStatus
    participant API as /api/settings/bedrock-status
    participant Store as App Store

    App->>Root: mount
    Root->>Hook: invoke
    Hook->>API: GET /api/settings/bedrock-status
    API-->>Hook: {bedrockConfigured, bedrockEnabled, region}
    Hook->>Store: setBedrockConfigured(...)
    Hook->>Store: setBedrockEnabled(...)
    Store-->>Root: state updated
    Root-->>App: render with Bedrock-aware model lists
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

Enhancement

Poem

🐰 I hopped into Bedrock's den,

Claude models now have room to blend.
Keys tucked close, a region set,
Async hops make calls a bet.
I munch a carrot — the models chat again.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 52.00% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature added: AWS Bedrock integration support for Claude models. It is concise, clear, and directly reflects the changeset's primary objective.

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

✨ Finishing touches
  • 📝 Generate docstrings

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.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @frederikschr, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant feature by integrating AWS Bedrock as an alternative backend for Claude models. It enables users, particularly those in enterprise environments with AWS restrictions, to leverage their existing AWS infrastructure for accessing Claude. The changes span across backend services for credential management and model resolution, and frontend components for user configuration and model selection, ensuring a seamless experience for Bedrock users.

Highlights

  • AWS Bedrock Integration for Claude Models: Introduced comprehensive support for using Claude models via AWS Bedrock, allowing users with AWS credentials to configure and utilize Bedrock-specific Claude endpoints. This includes new API endpoints, service logic, and UI components for configuration.
  • Asynchronous Model Availability: Refactored the BaseProvider interface and all implementing providers (Claude, Codex, Cursor, Opencode) to return Promise<ModelDefinition[]> for getAvailableModels(). This change enables asynchronous fetching of model lists, crucial for dynamic model discovery like Bedrock.
  • Dynamic Claude Model Resolution: The Claude provider now dynamically maps standard Claude model IDs to AWS Bedrock-specific model IDs when Bedrock is configured. It also conditionally exposes Bedrock Claude models in the UI based on configuration status.
  • Unified Credential Management: Enhanced the SettingsService to manage AWS Bedrock credentials alongside existing API keys, allowing for persistent storage and retrieval of Bedrock access keys, secret keys, session tokens, and regions. A new UI section in Claude settings facilitates this configuration, including an option to import credentials from AWS CLI exports.
  • Improved allowedTools Handling: Modified various simpleQuery and executeQuery calls across the application to pass allowedTools only when explicitly defined and non-empty. This prevents potential SDK issues that could arise from passing an empty array when no tools are intended.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@frederikschr frederikschr changed the title Added AWS Bedrock Integration for Claude [Feature] Added AWS Bedrock Integration for Claude Jan 25, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces AWS Bedrock integration for Claude models, which is a significant enhancement. The implementation is well-structured, correctly isolating the Bedrock logic within the ClaudeProvider and updating the provider factory and settings services accordingly. The UI changes for configuration are also comprehensive. I've identified a few areas for improvement, primarily concerning type safety, code structure, and a minor bug in the UI validation logic for Bedrock credentials. Addressing these points will enhance the maintainability and robustness of this new feature.

Comment on lines +120 to +129
if (enabled) {
if (!accessKeyId || !secretAccessKey) {
toast.error('Access Key ID and Secret Access Key are required when enabled');
return;
}
if (!region) {
toast.error('AWS Region is required when enabled');
return;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The current validation logic requires users to re-enter their AWS credentials every time they save changes in this section if Bedrock is enabled. This is because the key-related state variables are always empty for security. This creates a poor user experience, especially when only changing the region or disabling the feature.

The validation should only enforce key presence when Bedrock is being enabled for the first time (i.e., when enabled is true and isConfigured is false).

Suggested change
if (enabled) {
if (!accessKeyId || !secretAccessKey) {
toast.error('Access Key ID and Secret Access Key are required when enabled');
return;
}
if (!region) {
toast.error('AWS Region is required when enabled');
return;
}
}
if (enabled) {
// Only require keys if enabling for the first time and they haven't been provided.
if (!isConfigured && (!accessKeyId || !secretAccessKey)) {
toast.error('Access Key ID and Secret Access Key are required when enabling Bedrock for the first time.');
return;
}
if (!region) {
toast.error('AWS Region is required when enabled');
return;
}
}

Comment on lines 48 to 86
async function mapToBedrockModel(model: string, provider: ClaudeProvider): Promise<string> {
// If already a Bedrock model ID, pass through
if (model.includes('.anthropic.claude-') || model.startsWith('anthropic.claude-')) {
logger.debug(`Model already in Bedrock format: ${model}`);
return model;
}

// If Bedrock not configured, pass through unchanged
if (!(await provider['isBedrockConfigured']())) {
return model;
}
return env;

// Get AWS region for region-specific model IDs (check ENV first, then credentials)
let region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION;
if (!region) {
const config = await provider['getBedrockConfig']();
region = config?.region || 'us-east-1';
}
const regionPrefix = region.startsWith('eu-') ? 'eu' : 'us';

// Map standard Claude model IDs to Bedrock format
// Use Cross-Region Inference profiles (with region prefix) for models that support it
const bedrockModelMap: Record<string, string> = {
'claude-opus-4-5-20251101': `${regionPrefix}.anthropic.claude-opus-4-5-20251101-v1:0`,
'claude-sonnet-4-5-20250929': `${regionPrefix}.anthropic.claude-sonnet-4-5-20250929-v1:0`,
'claude-sonnet-4-20250514': `${regionPrefix}.anthropic.claude-sonnet-4-5-20250929-v1:0`, // Legacy
'claude-3-5-sonnet-20241022': 'anthropic.claude-3-5-sonnet-20241022-v2:0',
'claude-haiku-4-5-20251001': `${regionPrefix}.anthropic.claude-haiku-4-5-20251001-v1:0`,
};

const bedrockModel = bedrockModelMap[model];
if (bedrockModel) {
logger.info(`Mapped Claude model to Bedrock: ${model}${bedrockModel}`);
return bedrockModel;
}

logger.warn(`No Bedrock mapping for model: ${model}, using as-is`);
return model;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

For better encapsulation and type safety, consider moving mapToBedrockModel to be a private method within the ClaudeProvider class. Currently, it's a free function that accesses private methods of ClaudeProvider using string indexing (e.g., provider['isBedrockConfigured']()), which bypasses TypeScript's static analysis. Making it a private method would allow direct and type-safe access to this.isBedrockConfigured() and this.getBedrockConfig(), improving code maintainability and adhering to object-oriented principles.

Comment on lines +62 to +77
private static settingsService: any | null = null;

/**
* Initialize provider factory with settings service
* Should be called once during server startup
*/
static initialize(settingsService: any): void {
this.settingsService = settingsService;
}

/**
* Get the settings service instance
*/
static getSettingsService(): any | null {
return this.settingsService;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The settingsService is currently typed as any, which compromises type safety. To improve maintainability and leverage TypeScript's benefits, it should be strongly typed. Please import SettingsService from ../services/settings-service.js and use it as the type for the settingsService property and in the method signatures.

Suggested change
private static settingsService: any | null = null;
/**
* Initialize provider factory with settings service
* Should be called once during server startup
*/
static initialize(settingsService: any): void {
this.settingsService = settingsService;
}
/**
* Get the settings service instance
*/
static getSettingsService(): any | null {
return this.settingsService;
}
private static settingsService: SettingsService | null = null;
/**
* Initialize provider factory with settings service
* Should be called once during server startup
*/
static initialize(settingsService: SettingsService): void {
this.settingsService = settingsService;
}
/**
* Get the settings service instance
*/
static getSettingsService(): SettingsService | null {
return this.settingsService;
}

};
}>
): Promise<string> {
async function extractTextFromStream(stream: AsyncIterable<any>): Promise<string> {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The stream parameter is typed as AsyncIterable<any>, which reduces type safety. The previous implementation had a more specific type. To restore type safety and improve code clarity, please define a more specific type for the stream messages that reflects the expected structure, including the possibility of message.content being a string or an array of blocks.

async function extractTextFromStream(stream: AsyncIterable<{
  type: string;
  subtype?: string;
  result?: string;
  message?: {
    content?: string | Array<{ type: string; text?: string }>;
  };
}>): Promise<string> {

Copy link

@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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/ui/src/components/views/board-view/shared/model-selector.tsx (1)

95-107: Default Claude selection should honor Bedrock-only mode.

When Bedrock is enabled, switching providers forces 'sonnet', which isn’t in the Bedrock-only list—so nothing appears selected (and it may not be a valid Bedrock model). Default to a Bedrock model when bedrockEnabled is true.

🐛 Suggested fix
-    } else if (provider === 'claude' && selectedProvider !== 'claude') {
-      // Switch to Claude's default model
-      onModelSelect('sonnet');
-    }
+    } else if (provider === 'claude' && selectedProvider !== 'claude') {
+      const defaultClaudeModel = bedrockEnabled
+        ? BEDROCK_MODELS[0]?.id ?? 'sonnet'
+        : 'sonnet';
+      onModelSelect(defaultClaudeModel);
+    }
apps/ui/src/components/views/settings-view/model-defaults/phase-model-selector.tsx (1)

305-365: Add claudeModels to the dependency arrays to prevent stale UI when toggling Bedrock.

Both currentModel (lines 305–365) and the grouped models memo (lines 422–473) read claudeModels, but don't include it in their dependency arrays. When Bedrock is toggled, claudeModels is recalculated, but these memos won't re-run, causing the UI to display stale selections.

Suggested fix
   }, [
     selectedModel,
     selectedThinkingLevel,
+    claudeModels,
     availableCursorModels,
     transformedCodexModels,
     dynamicOpencodeModels,
   ]);
-  }, [favoriteModels, availableCursorModels, transformedCodexModels, allOpencodeModels]);
+  }, [favoriteModels, claudeModels, availableCursorModels, transformedCodexModels, allOpencodeModels]);
🤖 Fix all issues with AI agents
In `@apps/server/src/routes/settings/routes/get-bedrock-status.ts`:
- Around line 17-27: The current logic sets bedrockConfigured based on
config?.enabled which hides "configured but disabled" state; change the check so
bedrockConfigured is true when AWS Bedrock credentials exist regardless of
enabled (e.g., derive isConfigured from presence of config.accessKeyId and
config.region or necessary secrets obtained via settingsService.getCredentials),
keep bedrockEnabled using config?.enabled, and ensure region returns the region
only if credentials exist (use the same credentials-presence check instead of
config?.enabled).

In `@apps/server/src/services/settings-service.ts`:
- Around line 479-485: The awsBedrock configured flag in
apps/server/src/services/settings-service.ts only checks accessKeyId and region,
so it can be true when secretAccessKey is missing; update the configured
expression for the awsBedrock object to also require
credentials.awsBedrock?.secretAccessKey (e.g., include it in the boolean check
alongside accessKeyId and region) so the UI reflects true authentication
readiness; ensure you still use maskKey for accessKeyMasked/secretKeyMasked and
maintain existing enabled/region fallbacks.

In `@apps/ui/src/components/views/board-view/shared/model-constants.ts`:
- Around line 65-72: The entry with id
'anthropic.claude-3-5-sonnet-20241022-v2:0' incorrectly sets hasThinking to
true; update that model object so hasThinking: false (remove any UI logic that
relies on this flag for claude-3-5-sonnet-20241022 variants) so the UI won't
show thinking controls for Claude 3.5 Sonnet.

In
`@apps/ui/src/components/views/settings-view/providers/claude-settings-tab/aws-bedrock-section.tsx`:
- Around line 118-147: The handleSave flow currently always sends empty strings
for accessKeyId/secretAccessKey/sessionToken which wipes stored creds; change
the payload construction before calling api.settings.updateCredentials so
awsBedrock always includes enabled and region but only includes accessKeyId,
secretAccessKey and sessionToken properties when the corresponding local values
are non-empty (i.e., conditionally add them to the object), and do not send
empty strings or explicit clears unless the user explicitly chooses a "clear"
action; update the call site in handleSave where api.settings.updateCredentials
is invoked to use this conditional payload.
🧹 Nitpick comments (7)
libs/model-resolver/src/resolver.ts (1)

83-93: Redundant Bedrock checks can be simplified.

modelKey.includes('claude-') already covers the other two conditions, so the extra checks don’t change behavior and can confuse future readers. Consider collapsing to a single check (or switch to a stricter regex if you intended to narrow allowed formats).

♻️ Proposed simplification
-  if (
-    modelKey.includes('claude-') ||
-    modelKey.includes('.anthropic.claude-') ||
-    modelKey.startsWith('anthropic.claude-')
-  ) {
+  if (modelKey.includes('claude-')) {
apps/server/src/providers/claude-provider.ts (3)

48-86: Avoid accessing private methods via string indexing.

The mapToBedrockModel function accesses private methods on ClaudeProvider using string indexing (provider['isBedrockConfigured']()), which bypasses TypeScript's access control and creates fragile coupling. Consider making this a method on the class instead.

♻️ Suggested refactor
-async function mapToBedrockModel(model: string, provider: ClaudeProvider): Promise<string> {
-  // If already a Bedrock model ID, pass through
-  if (model.includes('.anthropic.claude-') || model.startsWith('anthropic.claude-')) {
-    logger.debug(`Model already in Bedrock format: ${model}`);
-    return model;
-  }
-
-  // If Bedrock not configured, pass through unchanged
-  if (!(await provider['isBedrockConfigured']())) {
-    return model;
-  }
-
-  // Get AWS region for region-specific model IDs (check ENV first, then credentials)
-  let region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION;
-  if (!region) {
-    const config = await provider['getBedrockConfig']();
-    region = config?.region || 'us-east-1';
-  }

Move this logic into ClaudeProvider as a private method mapToBedrockModel(model: string): Promise<string> that can directly call this.isBedrockConfigured() and this.getBedrockConfig().


111-114: Dynamic import may cause circular dependency issues.

The dynamic import('./provider-factory.js') inside getBedrockConfig is used to access the settings service. While this defers the import, it creates an implicit dependency cycle (provider-factory imports claude-provider, claude-provider dynamically imports provider-factory).

Consider injecting the settings service during provider construction or using a separate settings accessor module to avoid this pattern.


369-427: Bedrock model IDs are hardcoded without region awareness.

The Bedrock models in getAvailableModels() use hardcoded region prefixes (eu. and us.), but the actual region used at runtime comes from configuration. This may confuse users if their configured region doesn't match the displayed models.

Consider either:

  1. Generating model IDs dynamically based on the configured region
  2. Showing only region-agnostic model IDs (without eu./us. prefix)
  3. Filtering to show only models matching the configured region
apps/server/src/providers/provider-factory.ts (1)

62-77: Consider typing the settings service properly.

Using any for settingsService loses type safety. If the SettingsService type is available, use it here.

♻️ Suggested improvement
+import type { SettingsService } from '../services/settings-service.js';
+
 export class ProviderFactory {
-  private static settingsService: any | null = null;
+  private static settingsService: SettingsService | null = null;

-  static initialize(settingsService: any): void {
+  static initialize(settingsService: SettingsService): void {
     this.settingsService = settingsService;
   }

-  static getSettingsService(): any | null {
+  static getSettingsService(): SettingsService | null {
     return this.settingsService;
   }
apps/ui/src/components/views/settings-view/providers/claude-settings-tab.tsx (1)

10-41: Add AwsBedrockSection to the barrel export for consistency.
Other components in this directory (SkillsSection, SubagentsSection, SubagentCard) are exported from the ./claude-settings-tab/index.ts barrel. Update the barrel to include AwsBedrockSection, then import from it to maintain consistency and refactor-friendliness.

export { AwsBedrockSection } from './aws-bedrock-section';

Then update the import in claude-settings-tab.tsx to use the barrel.

apps/server/src/index.ts (1)

170-173: Move import to top of file with other imports.

The inline import statement at line 172 works but violates ES module conventions where all imports should be declared at the top of the file. This improves readability and makes dependencies immediately visible.

♻️ Suggested refactor

Move the import to the top of the file with other imports (around line 48):

import { ProviderFactory } from './providers/provider-factory.js';

Then update lines 170-173 to just:

-// Initialize ProviderFactory with settingsService for Bedrock credential access
-import { ProviderFactory } from './providers/provider-factory.js';
-ProviderFactory.initialize(settingsService);
+// Initialize ProviderFactory with settingsService for Bedrock credential access
+ProviderFactory.initialize(settingsService);

Comment on lines +17 to +27
const credentials = await settingsService.getCredentials();
const config = credentials.awsBedrock;

const isConfigured = !!(config?.enabled && config.accessKeyId && config.region);

res.json({
success: true,
bedrockConfigured: isConfigured,
bedrockEnabled: config?.enabled || false,
region: isConfigured ? config?.region : null,
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

bedrockConfigured shouldn’t depend on enabled.

Requiring config.enabled means “configured but disabled” can never be reported, which breaks the UI flow that shows both Claude + Bedrock lists when credentials exist. Consider checking credentials independently (and include the secret key if required).

🐛 Suggested fix
-      const isConfigured = !!(config?.enabled && config.accessKeyId && config.region);
+      const isConfigured = !!(
+        config?.accessKeyId &&
+        config?.secretAccessKey &&
+        config?.region
+      );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const credentials = await settingsService.getCredentials();
const config = credentials.awsBedrock;
const isConfigured = !!(config?.enabled && config.accessKeyId && config.region);
res.json({
success: true,
bedrockConfigured: isConfigured,
bedrockEnabled: config?.enabled || false,
region: isConfigured ? config?.region : null,
});
const credentials = await settingsService.getCredentials();
const config = credentials.awsBedrock;
const isConfigured = !!(
config?.accessKeyId &&
config?.secretAccessKey &&
config?.region
);
res.json({
success: true,
bedrockConfigured: isConfigured,
bedrockEnabled: config?.enabled || false,
region: isConfigured ? config?.region : null,
});
🤖 Prompt for AI Agents
In `@apps/server/src/routes/settings/routes/get-bedrock-status.ts` around lines 17
- 27, The current logic sets bedrockConfigured based on config?.enabled which
hides "configured but disabled" state; change the check so bedrockConfigured is
true when AWS Bedrock credentials exist regardless of enabled (e.g., derive
isConfigured from presence of config.accessKeyId and config.region or necessary
secrets obtained via settingsService.getCredentials), keep bedrockEnabled using
config?.enabled, and ensure region returns the region only if credentials exist
(use the same credentials-presence check instead of config?.enabled).

Comment on lines +479 to +485
awsBedrock: {
configured: !!(credentials.awsBedrock?.accessKeyId && credentials.awsBedrock?.region),
enabled: credentials.awsBedrock?.enabled || false,
region: credentials.awsBedrock?.region || '',
accessKeyMasked: maskKey(credentials.awsBedrock?.accessKeyId || ''),
secretKeyMasked: maskKey(credentials.awsBedrock?.secretAccessKey || ''),
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Configured status should include the secret key.

configured ignores secretAccessKey, so the UI can show Bedrock as configured even when auth will fail. Consider requiring the secret (unless role-based auth is intended).

🐛 Suggested fix
-        configured: !!(credentials.awsBedrock?.accessKeyId && credentials.awsBedrock?.region),
+        configured: !!(
+          credentials.awsBedrock?.accessKeyId &&
+          credentials.awsBedrock?.secretAccessKey &&
+          credentials.awsBedrock?.region
+        ),
🤖 Prompt for AI Agents
In `@apps/server/src/services/settings-service.ts` around lines 479 - 485, The
awsBedrock configured flag in apps/server/src/services/settings-service.ts only
checks accessKeyId and region, so it can be true when secretAccessKey is
missing; update the configured expression for the awsBedrock object to also
require credentials.awsBedrock?.secretAccessKey (e.g., include it in the boolean
check alongside accessKeyId and region) so the UI reflects true authentication
readiness; ensure you still use maskKey for accessKeyMasked/secretKeyMasked and
maintain existing enabled/region fallbacks.

Comment on lines +65 to +72
{
id: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
label: '3.5 Sonnet (Bedrock)',
description: 'Via AWS Bedrock',
badge: 'AWS',
provider: 'claude',
hasThinking: true,
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Incorrect hasThinking value for Claude 3.5 Sonnet.

Claude 3.5 Sonnet (claude-3-5-sonnet-20241022) does not support extended thinking—only Claude 4+ models have this capability. Setting hasThinking: true will mislead the UI into offering thinking controls that won't work.

🐛 Proposed fix
   {
     id: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
     label: '3.5 Sonnet (Bedrock)',
     description: 'Via AWS Bedrock',
     badge: 'AWS',
     provider: 'claude',
-    hasThinking: true,
+    hasThinking: false,
   },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{
id: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
label: '3.5 Sonnet (Bedrock)',
description: 'Via AWS Bedrock',
badge: 'AWS',
provider: 'claude',
hasThinking: true,
},
{
id: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
label: '3.5 Sonnet (Bedrock)',
description: 'Via AWS Bedrock',
badge: 'AWS',
provider: 'claude',
hasThinking: false,
},
🤖 Prompt for AI Agents
In `@apps/ui/src/components/views/board-view/shared/model-constants.ts` around
lines 65 - 72, The entry with id 'anthropic.claude-3-5-sonnet-20241022-v2:0'
incorrectly sets hasThinking to true; update that model object so hasThinking:
false (remove any UI logic that relies on this flag for
claude-3-5-sonnet-20241022 variants) so the UI won't show thinking controls for
Claude 3.5 Sonnet.

Comment on lines +118 to +147
const handleSave = async () => {
// Validation
if (enabled) {
if (!accessKeyId || !secretAccessKey) {
toast.error('Access Key ID and Secret Access Key are required when enabled');
return;
}
if (!region) {
toast.error('AWS Region is required when enabled');
return;
}
}

setIsSaving(true);
try {
const api = getElectronAPI();
if (!api?.settings?.updateCredentials) {
toast.error('Settings API not available');
return;
}

const result = await api.settings.updateCredentials({
awsBedrock: {
enabled,
accessKeyId: accessKeyId || undefined,
secretAccessKey: secretAccessKey || undefined,
sessionToken: sessionToken || undefined,
region,
},
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid wiping stored credentials when saving disabled/blank fields.

The payload always includes empty key fields, so toggling off or saving without retyping clears stored credentials—preventing a “configured but disabled” state. Only send key fields when the user provides new values (or add an explicit clear action).

🐛 Suggested fix
-      const result = await api.settings.updateCredentials({
-        awsBedrock: {
-          enabled,
-          accessKeyId: accessKeyId || undefined,
-          secretAccessKey: secretAccessKey || undefined,
-          sessionToken: sessionToken || undefined,
-          region,
-        },
-      });
+      const awsBedrockUpdate: Record<string, unknown> = { enabled, region };
+      if (accessKeyId) awsBedrockUpdate.accessKeyId = accessKeyId;
+      if (secretAccessKey) awsBedrockUpdate.secretAccessKey = secretAccessKey;
+      if (sessionToken) awsBedrockUpdate.sessionToken = sessionToken;
+
+      const result = await api.settings.updateCredentials({
+        awsBedrock: awsBedrockUpdate,
+      });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleSave = async () => {
// Validation
if (enabled) {
if (!accessKeyId || !secretAccessKey) {
toast.error('Access Key ID and Secret Access Key are required when enabled');
return;
}
if (!region) {
toast.error('AWS Region is required when enabled');
return;
}
}
setIsSaving(true);
try {
const api = getElectronAPI();
if (!api?.settings?.updateCredentials) {
toast.error('Settings API not available');
return;
}
const result = await api.settings.updateCredentials({
awsBedrock: {
enabled,
accessKeyId: accessKeyId || undefined,
secretAccessKey: secretAccessKey || undefined,
sessionToken: sessionToken || undefined,
region,
},
});
const handleSave = async () => {
// Validation
if (enabled) {
if (!accessKeyId || !secretAccessKey) {
toast.error('Access Key ID and Secret Access Key are required when enabled');
return;
}
if (!region) {
toast.error('AWS Region is required when enabled');
return;
}
}
setIsSaving(true);
try {
const api = getElectronAPI();
if (!api?.settings?.updateCredentials) {
toast.error('Settings API not available');
return;
}
const awsBedrockUpdate: Record<string, unknown> = { enabled, region };
if (accessKeyId) awsBedrockUpdate.accessKeyId = accessKeyId;
if (secretAccessKey) awsBedrockUpdate.secretAccessKey = secretAccessKey;
if (sessionToken) awsBedrockUpdate.sessionToken = sessionToken;
const result = await api.settings.updateCredentials({
awsBedrock: awsBedrockUpdate,
});
🤖 Prompt for AI Agents
In
`@apps/ui/src/components/views/settings-view/providers/claude-settings-tab/aws-bedrock-section.tsx`
around lines 118 - 147, The handleSave flow currently always sends empty strings
for accessKeyId/secretAccessKey/sessionToken which wipes stored creds; change
the payload construction before calling api.settings.updateCredentials so
awsBedrock always includes enabled and region but only includes accessKeyId,
secretAccessKey and sessionToken properties when the corresponding local values
are non-empty (i.e., conditionally add them to the object), and do not send
empty strings or explicit clears unless the user explicitly chooses a "clear"
action; update the call site in handleSave where api.settings.updateCredentials
is invoked to use this conditional payload.

Copy link

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/server/src/providers/simple-query-service.ts (1)

43-44: Update JSDoc to reflect actual behavior.

The comment states "(default: [] for simple queries)" but with the new conditional spread at lines 136-137, allowedTools is now omitted entirely when not provided rather than defaulting to an empty array. This distinction may matter to downstream providers.

📝 Suggested fix
-  /** Tools to allow (default: [] for simple queries) */
+  /** Tools to allow (omitted if not provided, allowing provider defaults) */
   allowedTools?: string[];
🤖 Fix all issues with AI agents
In `@apps/server/src/providers/simple-query-service.ts`:
- Around line 222-223: The streamingQuery invocation in validate-issue.ts is
missing the allowedTools option, causing provider defaults to be used; update
the call to streamingQuery (in validateIssue / the function around line ~194) to
include allowedTools: ['Read','Glob','Grep'] in the options object so it matches
other callers (generate-suggestions.ts, sync-spec.ts, generate-spec.ts,
generate-features-from-spec.ts) and ensures the provider receives the expected
tools list.
♻️ Duplicate comments (1)
apps/ui/src/components/views/board-view/shared/model-constants.ts (1)

70-75: Set hasThinking to false for Claude 3.5 Sonnet (Bedrock).

Leaving this as true will expose thinking controls that aren’t supported for this model.

🐛 Proposed fix
   {
     id: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
     label: '3.5 Sonnet (Bedrock)',
     description: 'Via AWS Bedrock',
     badge: 'AWS',
     provider: 'claude',
-    hasThinking: true,
+    hasThinking: false,
   },
Does AWS Bedrock Claude 3.5 Sonnet support extended thinking / reasoning controls?

Comment on lines +222 to +223
// Only include allowedTools if explicitly provided
...(options.allowedTools !== undefined && { allowedTools: options.allowedTools }),
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the current implementation of streamingQuery around lines 222-223
cat -n apps/server/src/providers/simple-query-service.ts | sed -n '210,235p'

Repository: AutoMaker-Org/automaker

Length of output: 1387


🏁 Script executed:

# Find all callers of streamingQuery in the codebase
rg -n 'streamingQuery\s*\(' --type ts -A 3 | head -100

Repository: AutoMaker-Org/automaker

Length of output: 2908


🏁 Script executed:

# Check if there's a simpleQuery function in the same file to compare patterns
rg -n 'simpleQuery\s*\(' apps/server/src/providers/simple-query-service.ts -A 5

Repository: AutoMaker-Org/automaker

Length of output: 608


🏁 Script executed:

# Find the provider interface/defaults to understand what happens when allowedTools is omitted
rg -n 'allowedTools' apps/server/src/providers/simple-query-service.ts -B 3 -A 3

Repository: AutoMaker-Org/automaker

Length of output: 1754


🏁 Script executed:

# Get full context for each caller of streamingQuery to see if allowedTools is passed
rg -n 'streamingQuery\s*\(' apps/server/src/routes/suggestions/generate-suggestions.ts -A 15 | head -30

Repository: AutoMaker-Org/automaker

Length of output: 768


🏁 Script executed:

# Check all callers more comprehensively with explicit allowedTools presence
for file in $(rg -l 'streamingQuery\s*\(' --type ts); do
  echo "=== File: $file ==="
  rg -A 20 'streamingQuery\s*\(' "$file" | grep -A 20 'streamingQuery'
done

Repository: AutoMaker-Org/automaker

Length of output: 6381


🏁 Script executed:

# Check the provider interface to see what defaults allowedTools to when undefined
rg -n 'executeQuery' apps/server/src/providers/ --type ts -B 5 -A 10 | grep -A 15 'executeQuery'

Repository: AutoMaker-Org/automaker

Length of output: 17149


🏁 Script executed:

# Look for the actual provider implementation to understand defaults
fd -e ts apps/server/src/providers/ | xargs grep -l 'allowedTools' | head -5

Repository: AutoMaker-Org/automaker

Length of output: 476


🏁 Script executed:

# Get the full streamingQuery call in validate-issue.ts with more context
rg -A 25 'const result = await streamingQuery' apps/server/src/routes/github/routes/validate-issue.ts

Repository: AutoMaker-Org/automaker

Length of output: 1157


🏁 Script executed:

# Check if there are any other callers of streamingQuery we might have missed
rg -l 'streamingQuery\(' --type ts

Repository: AutoMaker-Org/automaker

Length of output: 387


Fix breaking change in validate-issue.ts where streamingQuery call doesn't pass allowedTools.

validate-issue.ts doesn't provide allowedTools when calling streamingQuery. With the current implementation, this omits allowedTools entirely from the provider options, causing the call to use provider defaults instead of the expected ['Read', 'Glob', 'Grep']. Add allowedTools: ['Read', 'Glob', 'Grep'] to the streamingQuery call in validate-issue.ts (line ~194), consistent with all other callers (generate-suggestions.ts, sync-spec.ts, generate-spec.ts, generate-features-from-spec.ts).

🤖 Prompt for AI Agents
In `@apps/server/src/providers/simple-query-service.ts` around lines 222 - 223,
The streamingQuery invocation in validate-issue.ts is missing the allowedTools
option, causing provider defaults to be used; update the call to streamingQuery
(in validateIssue / the function around line ~194) to include allowedTools:
['Read','Glob','Grep'] in the options object so it matches other callers
(generate-suggestions.ts, sync-spec.ts, generate-spec.ts,
generate-features-from-spec.ts) and ensures the provider receives the expected
tools list.

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