From fc42a0b9fca85c6604651f259f2fd8231a08ff3e Mon Sep 17 00:00:00 2001 From: Nithin Chandran Rajashankar Date: Thu, 18 Jun 2026 19:06:12 +0000 Subject: [PATCH] feat(agentcore-browser): Add AgentCore Browser pattern Deploy Amazon Bedrock AgentCore Browser with an AWS Lambda function that starts managed headless browser sessions, navigates web pages, and extracts content for AI agents. Enables agents to interact with live web content without managing browser infrastructure. --- agentcore-browser-cdk/.gitignore | 6 ++ agentcore-browser-cdk/README.md | 73 ++++++++++++++++ agentcore-browser-cdk/bin/app.ts | 8 ++ agentcore-browser-cdk/cdk.json | 3 + agentcore-browser-cdk/example-pattern.json | 76 +++++++++++++++++ .../lib/agentcore-browser-stack.ts | 40 +++++++++ agentcore-browser-cdk/package.json | 19 +++++ agentcore-browser-cdk/src/handler/index.py | 85 +++++++++++++++++++ agentcore-browser-cdk/tsconfig.json | 19 +++++ 9 files changed, 329 insertions(+) create mode 100644 agentcore-browser-cdk/.gitignore create mode 100644 agentcore-browser-cdk/README.md create mode 100644 agentcore-browser-cdk/bin/app.ts create mode 100644 agentcore-browser-cdk/cdk.json create mode 100644 agentcore-browser-cdk/example-pattern.json create mode 100644 agentcore-browser-cdk/lib/agentcore-browser-stack.ts create mode 100644 agentcore-browser-cdk/package.json create mode 100644 agentcore-browser-cdk/src/handler/index.py create mode 100644 agentcore-browser-cdk/tsconfig.json diff --git a/agentcore-browser-cdk/.gitignore b/agentcore-browser-cdk/.gitignore new file mode 100644 index 0000000000..888fdf2586 --- /dev/null +++ b/agentcore-browser-cdk/.gitignore @@ -0,0 +1,6 @@ +node_modules/ +cdk.out/ +build/ +*.js +*.d.ts +cdk.context.json diff --git a/agentcore-browser-cdk/README.md b/agentcore-browser-cdk/README.md new file mode 100644 index 0000000000..66dc42beb0 --- /dev/null +++ b/agentcore-browser-cdk/README.md @@ -0,0 +1,73 @@ +# Amazon Bedrock AgentCore Browser with AWS Lambda (CDK) + +This pattern deploys an Amazon Bedrock AgentCore Browser resource with an AWS Lambda function that demonstrates starting browser sessions, navigating web pages, and extracting content for AI agents. + +Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/agentcore-browser-cdk + +Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. + +## Requirements + +* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. +* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured +* [Node.js 20+](https://nodejs.org/en/download/) installed +* [AWS CDK v2](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) installed (`npm install -g aws-cdk`) +* CDK bootstrapped in your account/region (`cdk bootstrap`) + +## Deployment Instructions + +1. Clone the repository and navigate to the pattern directory: + ```bash + cd agentcore-browser-cdk + ``` + +2. Install dependencies: + ```bash + npm install + ``` + +3. Build and deploy: + ```bash + npx cdk deploy + ``` + +## How it works + +Amazon Bedrock AgentCore Browser provides managed headless browser infrastructure for AI agents: + +- **Session management**: Start isolated browser sessions with public network access +- **Navigation**: Navigate to any public URL and interact with page elements +- **Content extraction**: Extract text, structured data, or screenshots from web pages +- **Automatic cleanup**: Sessions are isolated and cleaned up after use + +The AWS Lambda function demonstrates: +1. **browse**: Starts a session, navigates to a URL, extracts content, and stops the session +2. **list_sessions**: Lists active browser sessions + +## Testing + +Browse a web page: +```bash +aws lambda invoke --function-name FUNCTION_NAME \ + --payload '{"action": "browse", "url": "https://aws.amazon.com/bedrock/agentcore/"}' \ + --cli-binary-format raw-in-base64-out output.json && cat output.json +``` + +List active sessions: +```bash +aws lambda invoke --function-name FUNCTION_NAME \ + --payload '{"action": "list_sessions"}' \ + --cli-binary-format raw-in-base64-out output.json && cat output.json +``` + +## Cleanup + +```bash +npx cdk destroy +``` + +--- + +Copyright 2026 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +SPDX-License-Identifier: MIT-0 diff --git a/agentcore-browser-cdk/bin/app.ts b/agentcore-browser-cdk/bin/app.ts new file mode 100644 index 0000000000..b8c07f9158 --- /dev/null +++ b/agentcore-browser-cdk/bin/app.ts @@ -0,0 +1,8 @@ +#!/usr/bin/env node +import * as cdk from 'aws-cdk-lib'; +import { AgentcoreBrowserStack } from '../lib/agentcore-browser-stack'; + +const app = new cdk.App(); +new AgentcoreBrowserStack(app, 'AgentcoreBrowserStack', { + env: { region: 'us-east-1' }, +}); diff --git a/agentcore-browser-cdk/cdk.json b/agentcore-browser-cdk/cdk.json new file mode 100644 index 0000000000..debd1380e0 --- /dev/null +++ b/agentcore-browser-cdk/cdk.json @@ -0,0 +1,3 @@ +{ + "app": "node build/bin/app.js" +} diff --git a/agentcore-browser-cdk/example-pattern.json b/agentcore-browser-cdk/example-pattern.json new file mode 100644 index 0000000000..df80addbc7 --- /dev/null +++ b/agentcore-browser-cdk/example-pattern.json @@ -0,0 +1,76 @@ +{ + "title": "AI agent web browsing with Amazon Bedrock AgentCore Browser", + "description": "Deploy Amazon Bedrock AgentCore Browser with an AWS Lambda function that starts browser sessions, navigates web pages, and extracts content for AI agents.", + "language": "TypeScript", + "level": "200", + "framework": "AWS CDK", + "introBox": { + "headline": "How it works", + "text": [ + "Amazon Bedrock AgentCore Browser provides managed headless browser sessions for AI agents to interact with web pages.", + "The AWS Lambda function starts a browser session, navigates to a URL, and extracts the page content.", + "Agents can browse, click, fill forms, and extract structured data from any public web page.", + "Sessions are isolated and automatically cleaned up, with optional recording for debugging." + ] + }, + "gitHub": { + "template": { + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/agentcore-browser-cdk", + "templateURL": "serverless-patterns/agentcore-browser-cdk", + "projectFolder": "agentcore-browser-cdk", + "templateFile": "lib/agentcore-browser-stack.ts" + } + }, + "resources": { + "bullets": [ + { + "text": "Amazon Bedrock AgentCore Browser documentation", + "link": "https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/browser.html" + }, + { + "text": "Amazon Bedrock AgentCore CDK construct library", + "link": "https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_bedrockagentcore-readme.html" + } + ] + }, + "deploy": { + "text": [ + "npx cdk deploy" + ] + }, + "testing": { + "text": [ + "See the GitHub repo for detailed testing instructions." + ] + }, + "cleanup": { + "text": [ + "npx cdk destroy" + ] + }, + "authors": [ + { + "name": "Nithin Chandran R", + "bio": "Technical Account Manager at AWS", + "linkedin": "nithin-chandran-r" + } + ], + "patternArch": { + "icon1": { + "x": 20, + "y": 50, + "service": "lambda", + "label": "AWS Lambda" + }, + "icon2": { + "x": 80, + "y": 50, + "service": "bedrock", + "label": "AgentCore Browser" + }, + "line1": { + "from": "icon1", + "to": "icon2" + } + } +} diff --git a/agentcore-browser-cdk/lib/agentcore-browser-stack.ts b/agentcore-browser-cdk/lib/agentcore-browser-stack.ts new file mode 100644 index 0000000000..3a278d0df5 --- /dev/null +++ b/agentcore-browser-cdk/lib/agentcore-browser-stack.ts @@ -0,0 +1,40 @@ +import * as cdk from 'aws-cdk-lib'; +import { Construct } from 'constructs'; +import * as agentcore from 'aws-cdk-lib/aws-bedrockagentcore'; +import * as iam from 'aws-cdk-lib/aws-iam'; +import * as lambda from 'aws-cdk-lib/aws-lambda'; + +export class AgentcoreBrowserStack extends cdk.Stack { + constructor(scope: Construct, id: string, props?: cdk.StackProps) { + super(scope, id, props); + + // Amazon Bedrock AgentCore Browser for AI agent web browsing + const browser = new agentcore.BrowserCustom(this, 'AgentBrowser', { + browserCustomName: 'agent_browser', + description: 'Amazon Bedrock AgentCore Browser for AI agent web interaction', + networkConfiguration: agentcore.BrowserNetworkConfiguration.usingPublicNetwork(), + }); + + // AWS Lambda function to demonstrate browser operations + const fn = new lambda.Function(this, 'BrowserFunction', { + runtime: lambda.Runtime.PYTHON_3_12, + handler: 'index.handler', + code: lambda.Code.fromAsset('src/handler'), + timeout: cdk.Duration.seconds(60), + environment: { + BROWSER_ID: browser.browserId, + }, + }); + + // Grant the AWS Lambda function permissions to use Amazon Bedrock AgentCore Browser + browser.grantUse(fn); + fn.addToRolePolicy(new iam.PolicyStatement({ + actions: ['bedrock-agentcore:ListBrowserSessions'], + resources: [browser.browserArn], + })); + + // Outputs + new cdk.CfnOutput(this, 'BrowserId', { value: browser.browserId }); + new cdk.CfnOutput(this, 'FunctionName', { value: fn.functionName }); + } +} diff --git a/agentcore-browser-cdk/package.json b/agentcore-browser-cdk/package.json new file mode 100644 index 0000000000..b4a312a6b2 --- /dev/null +++ b/agentcore-browser-cdk/package.json @@ -0,0 +1,19 @@ +{ + "name": "agentcore-browser-cdk", + "version": "1.0.0", + "bin": { + "app": "build/bin/app.js" + }, + "scripts": { + "build": "tsc", + "synth": "cdk synth" + }, + "dependencies": { + "aws-cdk-lib": "^2.260.0", + "constructs": "^10.3.0" + }, + "devDependencies": { + "aws-cdk": "^2.1128.0", + "typescript": "~5.4.0" + } +} diff --git a/agentcore-browser-cdk/src/handler/index.py b/agentcore-browser-cdk/src/handler/index.py new file mode 100644 index 0000000000..1cad1ae7a5 --- /dev/null +++ b/agentcore-browser-cdk/src/handler/index.py @@ -0,0 +1,85 @@ +""" +AWS Lambda function demonstrating Amazon Bedrock AgentCore Browser operations. +Starts a browser session, navigates to a URL, and extracts page content. +""" + +import json +import os +import boto3 + + +def handler(event, context): + """Demonstrate Amazon Bedrock AgentCore Browser session management.""" + try: + browser_id = os.environ['BROWSER_ID'] + region = os.environ.get('AWS_REGION', 'us-east-1') + action = event.get('action', 'browse') + + client = boto3.client('bedrock-agentcore', region_name=region) + + if action == 'browse': + url = event.get('url', 'https://aws.amazon.com/bedrock/agentcore/') + + # Start a browser session + session_response = client.start_browser_session( + browserIdentifier=browser_id, + ) + session_id = session_response['sessionId'] + + # Invoke the browser to navigate and extract content + browse_response = client.invoke_browser( + browserIdentifier=browser_id, + sessionId=session_id, + action={ + 'navigate': {'url': url}, + }, + ) + + # Get page content + content_response = client.invoke_browser( + browserIdentifier=browser_id, + sessionId=session_id, + action={ + 'getContent': {}, + }, + ) + + # Stop the session + client.stop_browser_session( + browserIdentifier=browser_id, + sessionId=session_id, + ) + + return { + 'statusCode': 200, + 'body': json.dumps({ + 'action': 'browse', + 'url': url, + 'sessionId': session_id, + 'content': str(content_response.get('result', ''))[:2000], + }), + } + + elif action == 'list_sessions': + response = client.list_browser_sessions(browserIdentifier=browser_id) + sessions = response.get('browserSessions', []) + return { + 'statusCode': 200, + 'body': json.dumps({ + 'action': 'list_sessions', + 'count': len(sessions), + 'sessions': [str(s) for s in sessions[:5]], + }, default=str), + } + + else: + return { + 'statusCode': 400, + 'body': json.dumps({'error': f'Unknown action: {action}. Use browse or list_sessions.'}), + } + + except Exception as e: + return { + 'statusCode': 500, + 'body': json.dumps({'error': str(e)}), + } diff --git a/agentcore-browser-cdk/tsconfig.json b/agentcore-browser-cdk/tsconfig.json new file mode 100644 index 0000000000..5eccfb04e8 --- /dev/null +++ b/agentcore-browser-cdk/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "commonjs", + "lib": ["es2022"], + "declaration": true, + "strict": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "inlineSourceMap": true, + "inlineSources": true, + "experimentalDecorators": true, + "strictPropertyInitialization": false, + "outDir": "./build", + "rootDir": ".", + "skipLibCheck": true + }, + "exclude": ["node_modules", "cdk.out", "build"] +}