feat: add bedrock as a new data source#730
Conversation
📝 WalkthroughWalkthroughAdds AMAZON_BEDROCK_RUNTIME AppSync data source: types and validation, IAM role generation (bedrock:InvokeModel/Converse), esbuild bundling externals, unit and e2e tests, an example app with schema/resolvers, and user documentation. ChangesAmazon Bedrock Runtime Data Source
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
src/__tests__/validation/datasources.test.ts (1)
312-390: ⚡ Quick winExtend Bedrock validation tests to cover other optional config keys.
This block validates
modelswell, but it does not assert schema behavior forregion,serviceRoleArn, andiamRoleStatements. Adding those cases will better lock the Bedrock contract and prevent silent schema regressions.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/__tests__/validation/datasources.test.ts` around lines 312 - 390, Add tests for AMAZON_BEDROCK_RUNTIME to assert optional keys region, serviceRoleArn, and iamRoleStatements are validated correctly: extend the Valid assertions to include configs with region (string), serviceRoleArn (string), and iamRoleStatements (array/object as expected by the schema) and add corresponding Invalid assertions where each of those keys uses an incorrect type (e.g., region: 123, serviceRoleArn: {}, iamRoleStatements: 'not-an-array') so validateConfig(...) returns true for valid cases and throws (use toThrowErrorMatchingSnapshot) for invalid cases; place these new cases alongside the existing assertions array and reuse the same test iteration pattern that calls validateConfig with {...basicConfig, ...config.config}.src/__tests__/dataSources.test.ts (1)
225-226: ⚡ Quick winAdd explicit IAM policy assertions for Bedrock default-role semantics.
Line 225 currently relies on snapshot-only verification. Add direct checks that the generated default policy contains both
bedrock:InvokeModelandbedrock:Converseand that scoped model/profile resources are present; this gives stronger regression protection than snapshot diffs alone.Suggested test hardening
it('should generate default role with scoped models', () => { const api = new Api(given.appSyncConfig(), plugin); const dataSource = new DataSource(api, { type: 'AMAZON_BEDROCK_RUNTIME', name: 'bedrock', description: 'My Bedrock data source', config: { models: [ 'amazon.titan-text-lite-v1', 'arn:aws:bedrock:us-east-1:123456789012:inference-profile/us.anthropic.claude-3-5-haiku-20241022-v1:0', ], }, }); expect(dataSource.compile()).toMatchSnapshot(); + const role = JSON.stringify(dataSource.compileDataSourceIamRole()); + expect(role).toContain('bedrock:InvokeModel'); + expect(role).toContain('bedrock:Converse'); + expect(role).toContain('foundation-model/amazon.titan-text-lite-v1'); + expect(role).toContain('inference-profile/us.anthropic.claude-3-5-haiku-20241022-v1:0'); });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/__tests__/dataSources.test.ts` around lines 225 - 226, Update the test that calls dataSource.compile() to add explicit assertions that the generated default IAM policy includes the Bedrock actions and scoped resources: call const compiled = dataSource.compile() (or reuse the existing compile result), locate the default-role policy document in compiled (e.g. the synthesized IAM Policy/PolicyDocument for the default role name used by the datasource), and add expects that the PolicyDocument.Statement array contains an entry whose Action includes "bedrock:InvokeModel" and "bedrock:Converse" (use expect.arrayContaining or toEqual(expect.arrayContaining([...]))), and that the Statement.Resource includes resource ARNs or patterns scoped to model/profile identifiers (use string matching or expect.stringMatching(/model|profile|arn:.*bedrock.*model/)). Keep these assertions alongside the existing snapshot assertion after expect(dataSource.compile()).toMatchSnapshot().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@doc/dataSources.md`:
- Around line 157-164: Add a short prerequisite note in the doc/dataSources.md
near the `models` and `region` bullet points (the section describing model IDs
and ARN expansion) stating that the AWS account must have access to the selected
Bedrock foundation model in the chosen region before using the plugin or copying
the quick start; reference the Bedrock access requirement and link or point to
the AWS Nova invocation docs so readers know where to request model access and
avoid first-run failures.
In `@e2e/datasource-bedrock.e2e.test.ts`:
- Around line 26-39: Narrow the IAM assertion so it targets the Bedrock
datasource role specifically (instead of any role) by enhancing the predicate in
the bedrockRole lookup: use findResourcesByType and then filter roles where the
role clearly belongs to the datasource (for example check
resource.Properties.RoleName or resource.Metadata['aws:cdk:path'] or another
datasource-specific identifier present on the role) and then assert that that
role's Policies contain both 'bedrock:InvokeModel' and 'bedrock:Converse';
update the expect to verify that this specific bedrock datasource role is
defined and that its PolicyDocument Statement Actions include both permissions.
In `@examples/datasource-bedrock/resolvers/summarize.js`:
- Around line 1-14: The request() currently sends Titan-style inputText; update
the invokeModel body for modelId 'amazon.nova-micro-v1:0' to use the Nova
messages payload: include schemaVersion: "messages-v1" and a messages array
(e.g. a single message with role "user" and content containing the text to
summarize), and optionally add an inferenceConfig if needed; in response(),
return the generated text from ctx.result.results.outputText instead of
returning ctx.result.results. Make these changes in the request and response
functions to match the Bedrock Nova messages schema and extract outputText.
In `@src/resources/DataSource.ts`:
- Around line 430-469: The Bedrock IAM resource construction currently always
turns non-ARN strings into foundation-model ARNs and uses config.region, which
breaks inference-profile selectors and can target the wrong region; update the
AMAZON_BEDROCK_RUNTIME branch and getBedrockModelResource to (1) force the
region used for the resource ARN to the AppSync/API region (e.g., use { Ref:
'AWS::Region' } instead of this.config.config?.region) so resources are created
in the same region as the API, and (2) preserve inference-profile selectors by
detecting model strings that are inference-profile IDs or start with
'inference-profile/' and build the ARN using 'inference-profile/<id>' (instead
of always 'foundation-model/<id>'); keep existing behavior of returning the
input when model is already an ARN (getBedrockModelResource) and adjust the
models -> resources mapping in the AMAZON_BEDROCK_RUNTIME case to pass the
enforced region into getBedrockModelResource.
---
Nitpick comments:
In `@src/__tests__/dataSources.test.ts`:
- Around line 225-226: Update the test that calls dataSource.compile() to add
explicit assertions that the generated default IAM policy includes the Bedrock
actions and scoped resources: call const compiled = dataSource.compile() (or
reuse the existing compile result), locate the default-role policy document in
compiled (e.g. the synthesized IAM Policy/PolicyDocument for the default role
name used by the datasource), and add expects that the PolicyDocument.Statement
array contains an entry whose Action includes "bedrock:InvokeModel" and
"bedrock:Converse" (use expect.arrayContaining or
toEqual(expect.arrayContaining([...]))), and that the Statement.Resource
includes resource ARNs or patterns scoped to model/profile identifiers (use
string matching or expect.stringMatching(/model|profile|arn:.*bedrock.*model/)).
Keep these assertions alongside the existing snapshot assertion after
expect(dataSource.compile()).toMatchSnapshot().
In `@src/__tests__/validation/datasources.test.ts`:
- Around line 312-390: Add tests for AMAZON_BEDROCK_RUNTIME to assert optional
keys region, serviceRoleArn, and iamRoleStatements are validated correctly:
extend the Valid assertions to include configs with region (string),
serviceRoleArn (string), and iamRoleStatements (array/object as expected by the
schema) and add corresponding Invalid assertions where each of those keys uses
an incorrect type (e.g., region: 123, serviceRoleArn: {}, iamRoleStatements:
'not-an-array') so validateConfig(...) returns true for valid cases and throws
(use toThrowErrorMatchingSnapshot) for invalid cases; place these new cases
alongside the existing assertions array and reuse the same test iteration
pattern that calls validateConfig with {...basicConfig, ...config.config}.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 7282a3ad-338b-4a57-b36d-18d3a6980e02
⛔ Files ignored due to path filters (2)
src/__tests__/__snapshots__/dataSources.test.ts.snapis excluded by!**/*.snapsrc/__tests__/validation/__snapshots__/datasources.test.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (16)
doc/dataSources.mde2e/datasource-bedrock.e2e.test.tse2e/helpers/assertions.tsexamples/README.mdexamples/datasource-bedrock/resolvers/summarize.jsexamples/datasource-bedrock/schema.graphqlexamples/datasource-bedrock/serverless.ymlsrc/__tests__/dataSources.test.tssrc/__tests__/validation/datasources.test.tssrc/index.tssrc/resources/DataSource.tssrc/resources/JsResolver.tssrc/types/cloudFormation.tssrc/types/common.tssrc/types/plugin.tssrc/validation.ts
| All fields are optional. When `config` is omitted entirely, the plugin still creates the data source and generates a default service role. | ||
|
|
||
| - `models`: Optional list of foundation model IDs or full model/inference-profile ARNs. Bare model IDs are expanded to `arn:${AWS::Partition}:bedrock:${region}::foundation-model/<id>` in the generated IAM policy. When omitted, the default role allows `bedrock:InvokeModel` and `bedrock:Converse` on `*`. | ||
| - `region`: AWS region used when expanding bare model IDs. Defaults to the stack region. | ||
| - `serviceRoleArn`: The service role ARN for this DataSource. If not provided, a new one will be created. | ||
| - `iamRoleStatements`: Statements to use for the generated IAM Role. If not provided, default statements will be used. | ||
|
|
||
| Resolvers invoke Bedrock through the `APPSYNC_JS` runtime using `InvokeModel` or `Converse` request objects. AppSync only supports synchronous invocations that complete within 10 seconds; streaming APIs are not supported. See the [AWS AppSync Bedrock resolver reference](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-bedrock-js.html) for request/response shapes and helper utilities. |
There was a problem hiding this comment.
Call out the Bedrock model-access prerequisite.
A copied quick start can still fail until the account has access to the selected foundation model in that region. Adding that note here would prevent a pretty confusing first-run failure path for users. (docs.aws.amazon.com)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@doc/dataSources.md` around lines 157 - 164, Add a short prerequisite note in
the doc/dataSources.md near the `models` and `region` bullet points (the section
describing model IDs and ARN expansion) stating that the AWS account must have
access to the selected Bedrock foundation model in the chosen region before
using the plugin or copying the quick start; reference the Bedrock access
requirement and link or point to the AWS Nova invocation docs so readers know
where to request model access and avoid first-run failures.
| it('generates a service role with bedrock:InvokeModel permissions', () => { | ||
| const roles = findResourcesByType(result.template, 'AWS::IAM::Role'); | ||
| const bedrockRole = roles.find(({ resource }) => { | ||
| const policies = resource.Properties?.Policies as Array<{ | ||
| PolicyDocument?: { Statement?: Array<{ Action?: string[] }> }; | ||
| }>; | ||
| return policies?.some((policy) => | ||
| policy.PolicyDocument?.Statement?.some((statement) => | ||
| statement.Action?.includes('bedrock:InvokeModel'), | ||
| ), | ||
| ); | ||
| }); | ||
|
|
||
| expect(bedrockRole).toBeDefined(); |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Tighten this IAM assertion to the Bedrock datasource role.
This passes if any synthesized role has bedrock:InvokeModel, so it can miss regressions in the datasource’s own default role. It also leaves bedrock:Converse untested even though that permission is part of the new Bedrock role contract in this PR context.
💡 Suggested fix
it('generates a service role with bedrock:InvokeModel permissions', () => {
- const roles = findResourcesByType(result.template, 'AWS::IAM::Role');
- const bedrockRole = roles.find(({ resource }) => {
- const policies = resource.Properties?.Policies as Array<{
- PolicyDocument?: { Statement?: Array<{ Action?: string[] }> };
- }>;
- return policies?.some((policy) =>
- policy.PolicyDocument?.Statement?.some((statement) =>
- statement.Action?.includes('bedrock:InvokeModel'),
- ),
- );
- });
+ const ds = expectDataSourceOfType(result.template, 'AMAZON_BEDROCK_RUNTIME');
+ const roleLogicalId = (ds.resource.Properties?.ServiceRoleArn as {
+ 'Fn::GetAtt'?: [string, string];
+ })?.['Fn::GetAtt']?.[0];
+
+ expect(roleLogicalId).toBeDefined();
+
+ const bedrockRole = roleLogicalId
+ ? result.template.Resources?.[roleLogicalId]
+ : undefined;
+
+ const policies = bedrockRole?.Properties?.Policies as Array<{
+ PolicyDocument?: { Statement?: Array<{ Action?: string | string[] }> };
+ }>;
+
+ const hasBedrockPermissions = policies?.some((policy) =>
+ policy.PolicyDocument?.Statement?.some((statement) => {
+ const actions = Array.isArray(statement.Action)
+ ? statement.Action
+ : statement.Action
+ ? [statement.Action]
+ : [];
+ return (
+ actions.includes('bedrock:InvokeModel') &&
+ actions.includes('bedrock:Converse')
+ );
+ }),
+ );
- expect(bedrockRole).toBeDefined();
+ expect(hasBedrockPermissions).toBe(true);
});🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@e2e/datasource-bedrock.e2e.test.ts` around lines 26 - 39, Narrow the IAM
assertion so it targets the Bedrock datasource role specifically (instead of any
role) by enhancing the predicate in the bedrockRole lookup: use
findResourcesByType and then filter roles where the role clearly belongs to the
datasource (for example check resource.Properties.RoleName or
resource.Metadata['aws:cdk:path'] or another datasource-specific identifier
present on the role) and then assert that that role's Policies contain both
'bedrock:InvokeModel' and 'bedrock:Converse'; update the expect to verify that
this specific bedrock datasource role is defined and that its PolicyDocument
Statement Actions include both permissions.
| import { invokeModel } from '@aws-appsync/utils/ai'; | ||
|
|
||
| export function request(ctx) { | ||
| return invokeModel({ | ||
| modelId: 'amazon.nova-micro-v1:0', | ||
| body: { | ||
| inputText: `Summarize this text in less than 100 words:\n<text>${ctx.args.text}</text>`, | ||
| }, | ||
| }); | ||
| } | ||
|
|
||
| export function response(ctx) { | ||
| return ctx.result.results; | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the resolver file and any nearby examples for invokeModel usage (Titan vs Nova).
repo_root="."
file="examples/datasource-bedrock/resolvers/summarize.js"
echo "== File: $file =="
if [ -f "$file" ]; then
nl -ba "$file" | sed -n '1,200p'
else
echo "Missing file: $file"
fi
echo
echo "== Find other invokeModel usages under examples/datasource-bedrock/resolvers =="
# List resolver files
fd -t f -e js examples/datasource-bedrock/resolvers | sort || true
echo
# Search for invokeModel calls
rg -n "invokeModel\\(" examples/datasource-bedrock/resolvers || true
echo
echo "== Search for ctx.result usage in these resolvers =="
rg -n "ctx\\.result" examples/datasource-bedrock/resolvers || trueRepository: sid88in/serverless-appsync-plugin
Length of output: 1988
🌐 Web query:
Amazon Bedrock Nova invokeModel messages inferenceConfig response shape ctx.result.output vs results
💡 Result:
When using the Amazon Bedrock InvokeModel API with Amazon Nova models, the response body follows a specific schema where the generated content is located under the output key, not a results key [1]. The response structure returned by the model in the body of the InvokeModel response is as follows [1]: { "output": { "message": { "role": "assistant", "content": [ { "text": "string" }, { "toolUse": {... } }, { "reasoningContent": {... } } ] } }, "stopReason": "string", "usage": { "inputTokens": int, "outputTokens": int, "totalTokens": int } } Key points regarding the response structure: 1. output: This is the primary container for the assistant's response. It contains a message object, which holds the role (assistant) and a content array [1]. 2. content: This array contains the actual response blocks, such as text, toolUse, or reasoningContent [1]. 3. No results key: The Nova models' Invoke API schema does not utilize a top-level results key. If you are seeing code snippets referencing results, they likely pertain to different model providers or older legacy Bedrock response formats [2]. 4. Accessing the output: To access the generated text in Python using Boto3, you should read the response body and traverse the JSON structure [3][4]: response = client.invoke_model(modelId="amazon.nova-micro-v1:0", body=json.dumps(request_body)) response_body = json.loads(response["body"].read) text_output = response_body["output"]["message"]["content"]["text"] This schema is designed to be consistent with the Converse API, providing a unified experience for developers regardless of which Bedrock API they choose [5][6].
Citations:
- 1: https://docs.aws.amazon.com/nova/latest/nova2-userguide/request-response-schema.html
- 2: https://aws-samples.github.io/amazon-bedrock-samples/introduction-to-bedrock/bedrock_apis/01_invoke_api/
- 3: https://docs.aws.amazon.com/nova/latest/userguide/prompting-structured-output.html
- 4: https://docs.aws.amazon.com/bedrock/latest/userguide/model-card-amazon-nova-micro.html
- 5: https://docs.aws.amazon.com/nova/latest/userguide/invoke.html
- 6: https://docs.aws.amazon.com/nova/latest/userguide/using-invoke-api.html
🌐 Web query:
@aws-appsync/utils/ai invokeModel ctx.result structure output vs results
💡 Result:
In AWS AppSync JavaScript resolvers using @aws-appsync/utils/ai, the Bedrock model invocation response is accessed via the context object as ctx.result [1][2]. Structure of ctx.result The structure of ctx.result is determined by the specific Amazon Bedrock model being invoked [2][3]. When you use invokeModel, AppSync passes the response from the Bedrock InvokeModel API directly into ctx.result [2]. Because different models return different response bodies (e.g., Anthropic Claude, Amazon Titan, or Meta Llama), the shape of ctx.result varies [2][3]. Common Access Patterns For many legacy or specific Amazon Titan models, developers often access the output using paths such as ctx.result.results.outputText [2][4]. However, there is no single universal output structure, as it depends on the model's inference response format [2][3]. You should inspect the specific JSON response body of the model you are using in the Amazon Bedrock API documentation to determine the correct path for your data [2][3]. Key Considerations 1. Direct API Mapping: Because ctx.result reflects the Bedrock API response directly, there is no generic "output" field guaranteed across all models [2]. 2. Troubleshooting: If you are unsure of the structure, you can log the entire ctx.result object in your AppSync logs during development to inspect the returned JSON schema. 3. Converse vs. InvokeModel: If you are using the newer Converse API (often preferred for its unified interface across models), the response structure differs significantly from the older InvokeModel API, typically nesting data within response.message.content [5]. Always ensure your resolver response handler maps the model-specific response structure to the schema expected by your GraphQL type [2].
Citations:
- 1: https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html
- 2: https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-bedrock-js.html
- 3: https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModel.html
- 4: invokeModel from '@aws-appsync/utils/ai' result in 'Value for field '$[method]' not found.' aws/aws-appsync-community#395
- 5: Potential mapping template missmatch for converse and invokeModel in @aws-appsync/utils/ai aws/aws-appsync-community#380
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the resolver file and any nearby examples for invokeModel usage (Titan vs Nova).
repo_root="."
file="examples/datasource-bedrock/resolvers/summarize.js"
echo "== File: $file =="
if [ -f "$file" ]; then
nl -ba "$file" | sed -n '1,200p'
else
echo "Missing file: $file"
fi
echo
echo "== Find other invokeModel usages under examples/datasource-bedrock/resolvers =="
# List resolver files
fd -t f -e js examples/datasource-bedrock/resolvers | sort || true
echo
# Search for invokeModel calls
rg -n "invokeModel\\(" examples/datasource-bedrock/resolvers || true
echo
echo "== Search for ctx.result usage in these resolvers =="
rg -n "ctx\\.result" examples/datasource-bedrock/resolvers || trueRepository: sid88in/serverless-appsync-plugin
Length of output: 1988
🌐 Web query:
Amazon Bedrock Nova invokeModel messages inferenceConfig response shape (outputText vs results[0].outputText)
💡 Result:
The response shape you should use depends entirely on whether you are using the Converse API or the legacy InvokeModel API. For Amazon Nova models on Amazon Bedrock, AWS recommends using the Converse API [1][2]. The InvokeModel API is supported but follows a different, model-specific response structure [1]. 1. Converse API Response Shape When using the Converse API, the response format is standardized across models [2]. The text content is accessed via a nested structure: response['output']['message']['content']['text'] [3][4][2] 2. InvokeModel API Response Shape When using the InvokeModel API, the response body structure depends on the specific model's native schema [1][5]. - If you were using older models like Amazon Titan, you might be accustomed to the results['outputText'] path [6][7]. - However, for Amazon Nova models invoked via InvokeModel, the structure aligns with the Converse schema, typically returning an output object containing the message [8][1]: response_body['output']['message']['content']['text'] Summary If you are writing code for Amazon Nova, avoid relying on results['outputText'], as this is specific to older models like Amazon Titan [6][7]. You should use the Converse API structure [1][2], which is consistent: response['output']['message']['content']['text'] [3][4][2]
Citations:
- 1: https://docs.aws.amazon.com/nova/latest/userguide/invoke.html
- 2: https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html
- 3: https://docs.aws.amazon.com/bedrock/latest/userguide/bedrock-runtime_example_bedrock-runtime_Converse_AmazonNovaText_section.html
- 4: https://docs.aws.amazon.com/bedrock/latest/userguide/getting-started-api-ex-python.html
- 5: https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModel.html
- 6: https://docs.aws.amazon.com/bedrock/latest/userguide/bedrock-runtime_example_bedrock-runtime_InvokeModel_TitanText_section.html
- 7: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-text.html
- 8: https://docs.aws.amazon.com/nova/latest/nova2-userguide/request-response-schema.html
🌐 Web query:
@aws-appsync/utils/ai invokeModel response fields ctx.result output results
💡 Result:
In AWS AppSync JavaScript resolvers using @aws-appsync/utils/ai invokeModel, the Bedrock runtime response is available on the resolver response context as ctx.result. The response helper returns ctx.result.results.outputText for the first invocation result (in the examples/docs). 1) ctx.result is the container for the data returned by the data source (available in response handlers) ctx.result is described as “a container for the results of this resolver” in the AppSync resolver context reference. [1] 2) For invokeModel, the text output is typically at ctx.result.results.outputText The Bedrock JS resolver reference shows an invokeModel response handler returning ctx.result.results.outputText. [2] Also, in a community example handling invokeModel, they parse JSON from ctx.result.results.outputText. [3] 3) Where “ctx.result.output …” comes from (Converse vs invokeModel) A community thread shows accessing ctx.result.output.message.content.text in a resolver that uses converse (not invokeModel), and notes similar behavior was exhibited by invokeModel in their case. Because this is a community issue (not the official resolver-reference example), treat this “output.message…” shape as model/adapter-dependent and verify with your actual invocation output. [4] Practical guidance for response mapping - If you used invokeModel via @aws-appsync/utils/ai, start with: - ctx.result.results.outputText [2] - If you need a different field path (e.g., ctx.result.output.message.content.text), inspect/print the full ctx.result from your resolver logs first, since the exact shape can vary by operation/model. [1][4]
Citations:
- 1: https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html
- 2: https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-bedrock-js.html
- 3: invokeModel from '@aws-appsync/utils/ai' result in 'Value for field '$[method]' not found.' aws/aws-appsync-community#395
- 4: Potential mapping template missmatch for converse and invokeModel in @aws-appsync/utils/ai aws/aws-appsync-community#380
🌐 Web query:
@aws-appsync/utils/ai invokeModel Amazon Nova ctx.result structure output results
💡 Result:
When using the @aws-appsync/utils/ai invokeModel helper in AWS AppSync, the structure of the returned ctx.result is determined by the underlying Amazon Bedrock InvokeModel API response [1][2]. Because invokeModel performs a low-level invocation of the model, the response is generally contained within the body field of the Bedrock API response [2]. The specific structure of the data inside ctx.result.body depends entirely on the model being called (in this case, Amazon Nova) [2][3]. For Amazon Nova, the model's response is typically returned as a JSON object [3]. Because Amazon Bedrock returns the body as a blob or a stream of bytes, you must parse the response body in your AppSync response resolver to access the data effectively [2][3]. Key points for implementation: 1. Response Access: The response from Bedrock is stored in ctx.result. When using invokeModel, you generally access the returned JSON data by parsing the body [2][3]. 2. Parsing: Depending on your runtime environment, you may need to use util.parseJson(ctx.result.body) to convert the raw response body into a usable JavaScript object [1]. 3. Model-Specific Output: Amazon Nova provides structured output based on how you prompt it (e.g., requesting JSON format) [3]. Ensure you have defined your prompt to return the desired format, as the invokeModel helper simply passes back the raw Bedrock response [1][2]. Example Resolver Structure: // response resolver export function response(ctx) { // Parse the Bedrock response body const body = util.parseJson(ctx.result.body); // Access the specific field based on the expected Nova output structure // For example, if Nova returns { "content": "..." } return body.content; } Note: If you encounter issues with ctx.result structure, ensure that you are not confusing the invokeModel helper with the converse helper [4][1]. The converse helper provides a more standardized response structure (e.g., ctx.result.output.message.content) that is abstracted from the underlying model's raw body [4]. If you require a consistent, model-agnostic response format, consider using the converse helper instead of invokeModel [4][1].
Citations:
- 1: https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-bedrock-js.html
- 2: https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModel.html
- 3: https://docs.aws.amazon.com/nova/latest/userguide/prompting-structured-output.html
- 4: Potential mapping template missmatch for converse and invokeModel in @aws-appsync/utils/ai aws/aws-appsync-community#380
🌐 Web query:
AppSync bedrock js invokeModel Amazon Nova request body messages inferenceConfig
💡 Result:
When invoking Amazon Nova models via AWS AppSync using the invokeModel function, you must provide a request body that adheres to the specific schema expected by the Amazon Nova Invoke API [1]. Unlike the simpler text-based prompts used for legacy models, the Amazon Nova Invoke API requires a structured JSON payload that includes the message history and configuration [1]. To perform this in an AppSync JavaScript resolver, your invokeModel request object should be structured as follows: import { invokeModel } from '@aws-appsync/utils/ai'; export function request(ctx) { return invokeModel({ modelId: 'amazon.nova-micro-v1:0', // Or your specific Nova model ID body: { schemaVersion: 'messages-v1', messages: [ { role: 'user', content: [{ text: 'Your prompt here' }] } ], inferenceConfig: { maxTokens: 500, temperature: 0.7, topP: 0.9 } } }); } Key Requirements: 1. Schema Version: You must include "schemaVersion": "messages-v1" in the body [1]. 2. Messages: The input must be provided as an array of message objects, each containing a role ("user" or "assistant") and content [1]. 3. InferenceConfig: This object holds your inference parameters, such as maxTokens, temperature, topP, and topK [1][2]. 4. System Prompts: If you need to provide system-level instructions, you can include a system array at the top level of the body: "system": [{"text": "Your system prompt here"}] [3][1]. While the AppSync @aws-appsync/utils/ai library provides convenient helpers, ensuring the body structure matches the Nova-specific Invoke API requirements is critical for successful inference [1]. Note that for conversational applications where you need to maintain state, AWS recommends using the Converse API if possible, which is also supported in AppSync via the converse helper function [4][1][5].
Citations:
- 1: https://docs.aws.amazon.com/nova/latest/userguide/using-invoke-api.html
- 2: https://docs.aws.amazon.com/nova/latest/userguide/complete-request-schema.html
- 3: https://docs.aws.amazon.com/nova/latest/userguide/invoke.html
- 4: https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-bedrock-js.html
- 5: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html
🌐 Web query:
docs.aws.amazon.com nova invokeModel request body messages inferenceConfig example
💡 Result:
To invoke Amazon Nova models using the Amazon Bedrock InvokeModel API, you must provide a JSON-formatted request body that includes the messages structure and an optional inferenceConfig object [1][2][3]. The InvokeModel API requires the contentType header to be set to application/json [3][4]. Request Body Structure Example Below is a standard example of the JSON request body structure for Amazon Nova [2][5]: { "schemaVersion": "messages-v1", "messages": [ { "role": "user", "content": [ { "text": "Describe the purpose of a 'hello world' program in one line." } ] } ], "inferenceConfig": { "maxTokens": 512, "temperature": 0.5, "topP": 0.9 } } Key Components 1. messages: An array of objects representing conversational turns [1][6]. Each object must include: - role: Typically "user" or "assistant" [1][5]. - content: An array of content blocks, such as text, images, or videos [6][7]. 2. inferenceConfig: Optional parameters to control model generation [6][5]: - maxTokens: The maximum number of tokens to generate [6]. - temperature: Controls randomness (valid range: 0.00001 to 1.0) [6]. - topP: Nucleus sampling probability cutoff (valid range: 0 to 1) [6]. - topK: Limits sampling to the top K options (valid range: 0 to 128) [6]. 3. schemaVersion: Recommended as "messages-v1" to ensure correct schema interpretation [5]. Note: Amazon Nova models also support system prompts, which can be included in the request body using a top-level "system" field [1]. For more complex inputs, such as images or videos, the content block supports specific source structures (e.g., base64-encoded strings for the Invoke API) [6][7].
Citations:
- 1: https://docs.aws.amazon.com/nova/latest/userguide/invoke.html
- 2: https://docs.aws.amazon.com/bedrock/latest/userguide/getting-started-api-ex-python.html
- 3: https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModel.html
- 4: https://docs.aws.amazon.com/boto3/latest/reference/services/bedrock-runtime/client/invoke_model.html
- 5: https://aws-samples.github.io/amazon-bedrock-samples/introduction-to-bedrock/bedrock_apis/01_invoke_api/
- 6: https://docs.aws.amazon.com/nova/latest/userguide/complete-request-schema.html
- 7: https://docs.aws.amazon.com/nova/latest/nova2-userguide/request-response-schema.html
🌐 Web query:
resolver-reference-bedrock-js invokeModel ctx.result.results.outputText example
💡 Result:
In AWS AppSync’s resolver reference (bedrock-js utilities), the pattern for reading the text returned from a Bedrock InvokeModel call is: return ctx.result.results.outputText from your response function. For example, the docs show response(ctx) { return ctx.result.results.outputText }. [1] Context / why this path: - The AppSync Bedrock invokeModel helper stores the Bedrock invocation’s response in ctx.result (and the docs’ response example reads from ctx.result.results.outputText). [1] - The underlying Bedrock runtime InvokeModel API returns an inference response body, but the AppSync resolver reference is what maps that into ctx.result.* fields for GraphQL resolvers. [2][1] Concrete example from the AppSync resolver reference: export function response(ctx) { return ctx.result.results.outputText } [1] If you instead want the raw mapped result object, the same page also shows a response(ctx) { return ctx.result } example. [1]
Citations:
- 1: https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-bedrock-js.html
- 2: https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModel.html
Fix Amazon Nova Bedrock invokeModel request/response in summarize.js
- The current
requestuses Titan-styleinputText, butamazon.nova-micro-v1:0InvokeModel expects a Nova messages payload (schemaVersion: "messages-v1",messages: [{ role, content: [{ text }] }], optionallyinferenceConfig), so the request body is incompatible with the selected model. - The current
responsereturnsctx.result.results; for BedrockinvokeModelthe resolver reference maps the generated text toctx.result.results.outputText, so extractoutputTextinstead of returning the entireresultsobject.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@examples/datasource-bedrock/resolvers/summarize.js` around lines 1 - 14, The
request() currently sends Titan-style inputText; update the invokeModel body for
modelId 'amazon.nova-micro-v1:0' to use the Nova messages payload: include
schemaVersion: "messages-v1" and a messages array (e.g. a single message with
role "user" and content containing the text to summarize), and optionally add an
inferenceConfig if needed; in response(), return the generated text from
ctx.result.results.outputText instead of returning ctx.result.results. Make
these changes in the request and response functions to match the Bedrock Nova
messages schema and extract outputText.
There was a problem hiding this comment.
♻️ Duplicate comments (2)
examples/datasource-bedrock/resolvers/summarize.js (2)
6-13:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAdd
schemaVersion: "messages-v1"to the Nova InvokeModel body.The
messagespayload is now correct, but Amazon Nova's InvokeModel schema requires the top-levelschemaVersionfield. Without it, the request body is incomplete foramazon.nova-micro-v1:0.🐛 Proposed fix
body: { + schemaVersion: 'messages-v1', messages: [ { role: 'user', content: [{ text: ctx.args.text }], }, ], },Amazon Nova InvokeModel request body required fields schemaVersion messages-v1🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@examples/datasource-bedrock/resolvers/summarize.js` around lines 6 - 13, In the summarize resolver, the InvokeModel request body is missing the required top-level schemaVersion; update the body object (the one that currently contains messages: [{ role: 'user', content: [{ text: ctx.args.text }] }]) to include schemaVersion: "messages-v1" alongside messages so the request to the amazon.nova-micro-v1:0 model conforms to the InvokeModel schema.
17-19:⚠️ Potential issue | 🔴 Critical | ⚡ Quick win
ctx.result.resultsis undefined for Nova; extract fromoutput.message.content.The
resultskey is specific to legacy Titan models. Nova's InvokeModel response is shaped as{ output: { message: { content: [{ text }] } }, ... }with no top-levelresults, so this handler returnsundefined.🐛 Proposed fix
export function response(ctx) { - return ctx.result.results; + return ctx.result.output.message.content[0].text; }Amazon Nova InvokeModel response shape output message content text appsync ctx.result🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@examples/datasource-bedrock/resolvers/summarize.js` around lines 17 - 19, The response function currently returns ctx.result.results which is undefined for Amazon Nova; instead read the Nova shape at ctx.result.output.message.content (an array of content objects) and extract the text fields (e.g., map content items to their .text or join them) to produce the same list/string the rest of the app expects; update the response(ctx) implementation to handle both legacy ctx.result.results and the Nova path (ctx.result.output.message.content) so it works for either model.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@examples/datasource-bedrock/resolvers/summarize.js`:
- Around line 6-13: In the summarize resolver, the InvokeModel request body is
missing the required top-level schemaVersion; update the body object (the one
that currently contains messages: [{ role: 'user', content: [{ text:
ctx.args.text }] }]) to include schemaVersion: "messages-v1" alongside messages
so the request to the amazon.nova-micro-v1:0 model conforms to the InvokeModel
schema.
- Around line 17-19: The response function currently returns ctx.result.results
which is undefined for Amazon Nova; instead read the Nova shape at
ctx.result.output.message.content (an array of content objects) and extract the
text fields (e.g., map content items to their .text or join them) to produce the
same list/string the rest of the app expects; update the response(ctx)
implementation to handle both legacy ctx.result.results and the Nova path
(ctx.result.output.message.content) so it works for either model.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d6643a0b-808e-4a15-b132-a7fd30882ecc
📒 Files selected for processing (1)
examples/datasource-bedrock/resolvers/summarize.js
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
examples/datasource-bedrock/resolvers/summarize.js (1)
6-13:⚠️ Potential issue | 🟠 Major | ⚡ Quick winInclude
schemaVersion: 'messages-v1'in the Nova invoke payload.For Nova v1 invoke payloads, missing
schemaVersioncan cause request validation failures.Suggested fix
body: { + schemaVersion: 'messages-v1', messages: [ { role: 'user', content: [{ text: ctx.args.text }], }, ], },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@examples/datasource-bedrock/resolvers/summarize.js` around lines 6 - 13, The Nova v1 invoke payload is missing schemaVersion which can break validation; update the request body construction (the object containing messages: [{ role: 'user', content: [{ text: ctx.args.text }] }]) to include schemaVersion: 'messages-v1' at the top level of the body object so the payload becomes { schemaVersion: 'messages-v1', messages: [...] } before sending in the summarize resolver.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@examples/datasource-bedrock/resolvers/summarize.js`:
- Line 5: The resolver uses invokeModel.modelId 'eu.amazon.nova-micro-v1:0'
which doesn't match the Bedrock allowlist in dataSources.bedrock.config.models;
update one side so they align: either add 'eu.amazon-nova-micro-v1:0' (or the
plugin-expected inference-profile ID format) to the serverless.yml
dataSources.bedrock.config.models allowlist, or change the resolver's
invokeModel.modelId to 'amazon.nova-micro-v1:0' so it matches the existing
allowlist; modify the modelId in
examples/datasource-bedrock/resolvers/summarize.js or the models array in
serverless.yml accordingly.
In `@src/resources/DataSource.ts`:
- Around line 466-469: The regex inferenceProfilePrefix in
getBedrockModelResources() only matches /^(us-gov|us|eu|apac)\./ so models
prefixed with "global." are missed; update the pattern to include "global"
(e.g., add "global" to the alternation) so that when you call
inferenceProfilePrefix.exec(model) it will match "global." and let the
subsequent logic that computes baseModelId = model.slice(match[0].length) and
constructs IAM ARNs include the inference-profile/global.* paths.
---
Duplicate comments:
In `@examples/datasource-bedrock/resolvers/summarize.js`:
- Around line 6-13: The Nova v1 invoke payload is missing schemaVersion which
can break validation; update the request body construction (the object
containing messages: [{ role: 'user', content: [{ text: ctx.args.text }] }]) to
include schemaVersion: 'messages-v1' at the top level of the body object so the
payload becomes { schemaVersion: 'messages-v1', messages: [...] } before sending
in the summarize resolver.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e5363e93-2f24-494c-b839-c856d37b3121
⛔ Files ignored due to path filters (1)
src/__tests__/__snapshots__/dataSources.test.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (4)
doc/dataSources.mdexamples/datasource-bedrock/resolvers/summarize.jssrc/__tests__/dataSources.test.tssrc/resources/DataSource.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- doc/dataSources.md
- src/tests/dataSources.test.ts
|
|
||
| export function request(ctx) { | ||
| return invokeModel({ | ||
| modelId: 'eu.amazon.nova-micro-v1:0', |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
nl -ba examples/datasource-bedrock/resolvers/summarize.js | sed -n '1,80p'
nl -ba examples/datasource-bedrock/serverless.yml | sed -n '1,260p'
rg -n "datasourceBedrockConfig|models:|modelId" examples/datasource-bedrock -C2Repository: sid88in/serverless-appsync-plugin
Length of output: 120
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== summarize.js (first 120 lines) ==="
cat -n examples/datasource-bedrock/resolvers/summarize.js | sed -n '1,120p'
echo
echo "=== serverless.yml (first 320 lines) ==="
cat -n examples/datasource-bedrock/serverless.yml | sed -n '1,320p'
echo
echo "=== Search bedrock datasource config for allowlist + model id ==="
rg -n "datasourceBedrockConfig|models:|modelId" examples/datasource-bedrock -C2Repository: sid88in/serverless-appsync-plugin
Length of output: 2207
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate plugin code that handles AMAZON_BEDROCK_RUNTIME and "models" allowlist
ls -la
rg -n "AMAZON_BEDROCK_RUNTIME|bedrock.*models|config\.models|invokeModel\(" -S . --glob='*.js' --glob='*.ts' --glob='*.mjs' --glob='*.cjs'Repository: sid88in/serverless-appsync-plugin
Length of output: 3821
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate plugin code that handles AMAZON_BEDROCK_RUNTIME and "models" allowlist
ls -la
rg -n "AMAZON_BEDROCK_RUNTIME|bedrock.*models|config\.models|invokeModel\(" -S . --glob='*.js' --glob='*.ts' --glob='*.mjs' --glob='*.cjs'Repository: sid88in/serverless-appsync-plugin
Length of output: 3821
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the AMAZON_BEDROCK_RUNTIME handling and any model allowlist logic
rg -n "case 'AMAZON_BEDROCK_RUNTIME'|config\.models|models" src/resources/DataSource.ts -n
sed -n '380,520p' src/resources/DataSource.tsRepository: sid88in/serverless-appsync-plugin
Length of output: 4207
Align invokeModel.modelId with the Bedrock models allowlist
examples/datasource-bedrock/resolvers/summarize.js calls invokeModel with modelId: 'eu.amazon.nova-micro-v1:0', but examples/datasource-bedrock/serverless.yml allows only dataSources.bedrock.config.models: ['amazon.nova-micro-v1:0']. Since eu.* is treated as an inference-profile ID by the plugin, the IAM policy won’t include the inference-profile/... resource unless that exact ID is allowlisted, which can deny bedrock:InvokeModel at runtime.
- Add
eu.amazon-nova-micro-v1:0toserverless.yml’sdataSources.bedrock.config.models, or change the resolver to useamazon.nova-micro-v1:0.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@examples/datasource-bedrock/resolvers/summarize.js` at line 5, The resolver
uses invokeModel.modelId 'eu.amazon.nova-micro-v1:0' which doesn't match the
Bedrock allowlist in dataSources.bedrock.config.models; update one side so they
align: either add 'eu.amazon-nova-micro-v1:0' (or the plugin-expected
inference-profile ID format) to the serverless.yml
dataSources.bedrock.config.models allowlist, or change the resolver's
invokeModel.modelId to 'amazon.nova-micro-v1:0' so it matches the existing
allowlist; modify the modelId in
examples/datasource-bedrock/resolvers/summarize.js or the models array in
serverless.yml accordingly.
| const inferenceProfilePrefix = /^(us-gov|us|eu|apac)\./; | ||
| const match = inferenceProfilePrefix.exec(model); | ||
| if (match) { | ||
| const baseModelId = model.slice(match[0].length); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the cited section in DataSource.ts
sed -n '430,520p' src/resources/DataSource.ts | cat -n
# Show full function/context if possible by locating nearest function/class boundaries
echo "---- nearest context: grep for nearby markers ----"
rg -n "inferenceProfilePrefix|baseModelId|inference-profile" src/resources/DataSource.ts
# Search for other inference-profile prefix parsing / global handling in the repo
echo "---- repo search for inference profile parsing and global.* ----"
rg -n "inferenceProfilePrefix|inference[- ]profile|foundation-model|global\." src | head -n 200
# Search for any IAM resource construction related to Bedrock inference profiles
echo "---- repo search for Bedrock inference-profile IAM resources ----"
rg -n "bedrock.*inference.*profile|InvokeModel|inference-profile" src | head -n 200Repository: sid88in/serverless-appsync-plugin
Length of output: 6672
🌐 Web query:
AWS Bedrock inference-profile ID global. prefix
💡 Result:
In Amazon Bedrock, the global. prefix is used in the IDs and Amazon Resource Names (ARNs) of system-defined inference profiles that enable Global cross-Region inference [1][2][3]. Key details regarding this prefix and global inference profiles: Functionality: Global inference profiles allow Amazon Bedrock to dynamically route inference requests to the optimal AWS commercial Region worldwide [3]. This is designed to maximize throughput and optimize resource utilization, often providing cost savings compared to single-region or geographic-constrained inference [3]. ID Format: The inference profile ID (and the corresponding segment in the ARN) follows a structure that includes the global prefix, followed by the model provider and specific model identifier [1][4]. Example format: global.anthropic.claude-sonnet-4-5-20250929-v1:0 [1][2] IAM and Security Policies: When writing IAM policies to manage access to these profiles, note that global cross-region inference requests use an unspecified value for the aws:RequestedRegion condition key [1][2][3]. Security policies often use the global prefix in the resource ARN to specifically target these profiles [1][2]. For example, to deny unauthorized global cross-region inference, a policy might use an ArnLike condition with the pattern arn:aws:bedrock:::inference-profile/global.* [2]. Usage: You can use these global inference profile IDs or their full ARNs as the modelId in supported API operations, such as InvokeModel, InvokeModelWithResponseStream, Converse, and ConverseStream [5][6][7]. For a complete list of supported models and their specific global inference profile IDs, you should consult the models at a glance page in the official Amazon Bedrock documentation [8].
Citations:
- 1: https://docs.aws.amazon.com/bedrock/latest/userguide/global-cross-region-inference.html
- 2: https://aws.amazon.com/blogs/machine-learning/securing-amazon-bedrock-cross-region-inference-geographic-and-global/
- 3: https://docs.aws.amazon.com/bedrock/latest/userguide/cross-region-inference.html
- 4: https://developer.konghq.com/ai-gateway/ai-providers/bedrock/
- 5: https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-use.html
- 6: https://docs.aws.amazon.com/bedrock/latest/userguide/geographic-cross-region-inference.html
- 7: https://aws.amazon.com/blogs/machine-learning/getting-started-with-cross-region-inference-in-amazon-bedrock/
- 8: https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html
Include global. in the Bedrock inference-profile prefix matcher to expand IAM resources correctly.
getBedrockModelResources() only expands IDs prefixed with us-gov|us|eu|apac; global.* falls through and is treated as a bare foundation-model, so generated IAM ARNs won’t include the inference-profile/global.* permission (and the routed foundation-model access).
Suggested fix
- const inferenceProfilePrefix = /^(us-gov|us|eu|apac)\./;
+ const inferenceProfilePrefix = /^(us-gov|us|eu|apac|global)\./;🧰 Tools
🪛 OpenGrep (1.22.0)
[ERROR] 467-467: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.
(coderabbit.command-injection.exec-js)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/resources/DataSource.ts` around lines 466 - 469, The regex
inferenceProfilePrefix in getBedrockModelResources() only matches
/^(us-gov|us|eu|apac)\./ so models prefixed with "global." are missed; update
the pattern to include "global" (e.g., add "global" to the alternation) so that
when you call inferenceProfilePrefix.exec(model) it will match "global." and let
the subsequent logic that computes baseModelId = model.slice(match[0].length)
and constructs IAM ARNs include the inference-profile/global.* paths.
Proposed changes
This PR adds AWS Bedrock as a data source support.
Issue(s)
Resolves #727
Summary by CodeRabbit
New Features
Documentation
Examples
Tests