Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .kiro/steering/python-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,14 @@ fileMatchPattern: "agent/**"
## Environment

**LOG_LEVEL**: INFO (default), DEBUG, ERROR
**BEDROCK_MODEL_ID**: Configure Bedrock model (see `DEFAULT_MODEL_ID` in `agentcore_app.py`)
**AWS regions**: Auto-set by AgentCore Runtime

## Model Selection

**Default Model**: See `DEFAULT_MODEL_ID` constant in `agentcore_app.py`

```python
def get_model_id() -> str:
return os.getenv("BEDROCK_MODEL_ID", DEFAULT_MODEL_ID)
```
6 changes: 6 additions & 0 deletions .kiro/steering/tech.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ pytest && mypy src/ && ruff check --fix . && black . # Manual validation with f

**Configuration:** All settings in `agent/pyproject.toml` (line length: 100, Python 3.13, strict mode)

## Model Configuration

**BEDROCK_MODEL_ID**: Configure Bedrock model (see `DEFAULT_MODEL_ID` in `agent/src/agentcore_app.py`)
**Examples**: `us.anthropic.claude-3-5-sonnet-20241022-v2:0`, `us.amazon.titan-text-express-v1`
**Local**: Set in `.env` file | **Deploy**: CDK environment variables

## AWS Deployment

**Prerequisites:** Docker running, AWS CLI configured, Bedrock access
Expand Down
12 changes: 12 additions & 0 deletions DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ Deploy Strands agent to AWS Bedrock AgentCore Runtime.

The CI/CD pipeline requires OIDC authentication to deploy from GitHub Actions to AWS. Follow the [GitHub documentation for configuring OIDC in AWS](https://docs.github.com/en/actions/how-tos/secure-your-work/security-harden-deployments/oidc-in-aws), then add the role ARN as a repository secret named `AWS_ROLE_TO_ASSUME`.

## Configuration

**Model Selection** (optional): Set `BEDROCK_MODEL_ID` environment variable to use a different Bedrock model. If not provided, defaults to `us.anthropic.claude-sonnet-4-5-20250929-v1:0`.

```bash
# Local (agent/.env file)
BEDROCK_MODEL_ID=us.anthropic.claude-3-5-sonnet-20241022-v2:0

# CDK deployment (cdk/.env)
BEDROCK_MODEL_ID=us.amazon.titan-text-express-v1
```

## Local Testing

```bash
Expand Down
6 changes: 6 additions & 0 deletions agent/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# Logging Configuration
# Options: DEBUG, INFO, WARNING, ERROR, CRITICAL
LOG_LEVEL=INFO

# Bedrock Model Configuration
# Specify the Amazon Bedrock model ID to use for the agent
# If not set, uses DEFAULT_MODEL_ID from src/agentcore_app.py
# For valid model IDs, see: https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids.html
# BEDROCK_MODEL_ID=your-preferred-model-id
17 changes: 17 additions & 0 deletions agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,23 @@ python3.13 -m venv .venv && source .venv/bin/activate && pip install -e ".[dev]"
python src/agentcore_app.py
```

## Configuration

**Environment Variables**: The agent automatically loads environment variables from a `.env` file when running locally (requires `python-dotenv` from dev dependencies).

```bash
# Copy the example and customize
cp .env.example .env

# Edit .env file
BEDROCK_MODEL_ID=your-preferred-model-id
LOG_LEVEL=DEBUG
```

**Model**: Set `BEDROCK_MODEL_ID` environment variable (see `DEFAULT_MODEL_ID` in `src/agentcore_app.py` for current default)

**Available Models**: See [AWS Bedrock Model IDs documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids.html)

## Adding Tools

**Community Tools:**
Expand Down
1 change: 1 addition & 0 deletions agent/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dev = [
"ruff>=0.14.9",
"mypy>=1.19.0",
"black>=25.12.0",
"python-dotenv>=1.0.0",
]

[tool.hatch.build.targets.wheel]
Expand Down
34 changes: 32 additions & 2 deletions agent/src/agentcore_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@

from tools import letter_counter

# Load environment variables from .env file for local development
if os.path.exists(".env"):
try:
from dotenv import load_dotenv

load_dotenv()
except ImportError:
import warnings

warnings.warn(
".env file found but python-dotenv not installed. "
"Install with: pip install python-dotenv",
UserWarning,
stacklevel=2,
)

DEFAULT_MODEL_ID = "us.anthropic.claude-sonnet-4-5-20250929-v1:0"
log_level = os.getenv("LOG_LEVEL", "INFO").upper()

logging.basicConfig(
Expand All @@ -23,9 +40,22 @@
app = BedrockAgentCoreApp()


def get_model_id() -> str:
"""
Get the Bedrock model ID from environment variable or use default.

Returns:
str: The model ID to use for the agent
"""
model_id = os.getenv("BEDROCK_MODEL_ID", DEFAULT_MODEL_ID)
logging.info(f"Using Bedrock model: {model_id}")
return model_id


def get_agent() -> Agent:
"""Create and return a Strands agent with configured tools."""
return Agent(tools=[calculator, current_time, http_request, letter_counter])
"""Create and return a Strands agent with configured tools and model."""
model_id = get_model_id()
return Agent(model=model_id, tools=[calculator, current_time, http_request, letter_counter])


@app.entrypoint
Expand Down
12 changes: 11 additions & 1 deletion agent/tests/test_agent.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"""Tests for the agent."""

from src.agentcore_app import get_agent
import os
from unittest.mock import patch

from src.agentcore_app import DEFAULT_MODEL_ID, get_agent, get_model_id


def test_agent_has_tools() -> None:
Expand All @@ -10,3 +13,10 @@ def test_agent_has_tools() -> None:
assert "calculator" in tool_names
assert "current_time" in tool_names
assert "letter_counter" in tool_names


def test_get_model_id_fallback() -> None:
"""Test get_model_id returns the default when environment variable is not set."""
with patch.dict(os.environ, {}, clear=True):
model_id = get_model_id()
assert model_id == DEFAULT_MODEL_ID
9 changes: 9 additions & 0 deletions cdk/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# CDK Deployment Configuration

# Bedrock Model ID for the agent (optional)
# If not set, the agent will use its DEFAULT_MODEL_ID from agent/src/agentcore_app.py
# Uncomment and set to override the default model:
# BEDROCK_MODEL_ID=your-preferred-model-id

# For a complete list of available model IDs, see:
# https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids.html
15 changes: 13 additions & 2 deletions cdk/bin/cdk.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
#!/usr/bin/env node
import * as dotenv from 'dotenv'
import path from 'path'
import { App } from 'aws-cdk-lib'
import { StrandsAgentStack } from '../lib/strands-agent-stack'

const { AWS_DEFAULT_ACCOUNT_ID, AWS_DEFAULT_REGION, CDK_DEFAULT_ACCOUNT, CDK_DEFAULT_REGION } =
process.env
dotenv.config({ path: path.join(__dirname, '../.env') })

const {
AWS_DEFAULT_ACCOUNT_ID,
AWS_DEFAULT_REGION,
CDK_DEFAULT_ACCOUNT,
CDK_DEFAULT_REGION,
BEDROCK_MODEL_ID,
} = process.env

const account = CDK_DEFAULT_ACCOUNT ?? AWS_DEFAULT_ACCOUNT_ID
const region = CDK_DEFAULT_REGION ?? AWS_DEFAULT_REGION
const bedrockModelID = BEDROCK_MODEL_ID ?? undefined

if (!account || !region) {
throw new Error(
Expand All @@ -19,5 +29,6 @@ if (!account || !region) {
const app = new App()
new StrandsAgentStack(app, 'StrandsAgentStack', {
description: 'Demo template for strands-agents',
bedrockModelID,
env: { account, region },
})
7 changes: 6 additions & 1 deletion cdk/lib/strands-agent-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ import { Construct } from 'constructs'
import { Runtime, AgentRuntimeArtifact } from '@aws-cdk/aws-bedrock-agentcore-alpha'
import * as path from 'path'

interface StrandsAgentStackProps extends StackProps {
bedrockModelID?: string | undefined
}

export class StrandsAgentStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
constructor(scope: Construct, id: string, props: StrandsAgentStackProps) {
super(scope, id, props)

// IAM Role for AgentCore Runtime
Expand Down Expand Up @@ -94,6 +98,7 @@ export class StrandsAgentStack extends Stack {
AWS_REGION: this.region,
AWS_DEFAULT_REGION: this.region,
LOG_LEVEL: 'INFO',
...(props.bedrockModelID && { BEDROCK_MODEL_ID: props.bedrockModelID }),
},
})

Expand Down
38 changes: 26 additions & 12 deletions cdk/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"@types/jest": "^30.0.0",
"@types/node": "^25.0.2",
"aws-cdk": "^2.1034.0",
"dotenv": "^17.2.3",
"eslint": "^9.17.0",
"eslint-config-prettier": "^10.0.1",
"jest": "^30.2.0",
Expand Down