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"] +}