Skip to content

Commit 86abcd6

Browse files
authored
Merge branch 'aws-samples:main' into fix/oidc-saml-cognito-custom-attributes
2 parents 276dd93 + 09c965f commit 86abcd6

File tree

73 files changed

+3697
-651
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+3697
-651
lines changed

.github/workflows/build.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ jobs:
77
runs-on: ubuntu-latest
88
steps:
99
- uses: actions/checkout@v4
10-
- uses: actions/setup-node@v3
10+
- uses: actions/setup-node@v4
1111
with:
1212
node-version: "20"
13+
- name: Install latest CDK CLI
14+
run: |
15+
npm install -g aws-cdk@latest
16+
cdk --version
1317
- name: Formatting
1418
run: |
1519
npm ci
@@ -23,7 +27,7 @@ jobs:
2327
npm audit
2428
npm run build
2529
npm run test
26-
npx cdk synth
30+
cdk synth
2731
- name: PyTests
2832
# Suppression of pip audit failure until langchain is upgraded.
2933
run: |

.github/workflows/deploy.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,16 @@ jobs:
2626
runs-on: ubuntu-latest
2727
steps:
2828
- name: Checkout
29-
uses: actions/checkout@v3
29+
uses: actions/checkout@v4
3030
with:
3131
fetch-depth: 0 # Not needed if lastUpdated is not enabled
3232
- name: Setup Node
33-
uses: actions/setup-node@v3
33+
uses: actions/setup-node@v4
3434
with:
3535
node-version: 20
3636
cache: npm
3737
- name: Setup Pages
38-
uses: actions/configure-pages@v3
38+
uses: actions/configure-pages@v4
3939
- name: Install dependencies
4040
run: npm ci
4141
- name: Build with VitePress
@@ -58,4 +58,4 @@ jobs:
5858
steps:
5959
- name: Deploy to GitHub Pages
6060
id: deployment
61-
uses: actions/deploy-pages@v3
61+
uses: actions/deploy-pages@v4

.github/workflows/e2e-validation.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
contents: read
1212
steps:
1313
- name: Configure AWS Credentials
14-
uses: aws-actions/configure-aws-credentials@v2
14+
uses: aws-actions/configure-aws-credentials@v3
1515
with:
1616
aws-region: ${{ secrets.PIPELINE_AWS_REGION }}
1717
role-to-assume: arn:aws:iam::${{ secrets.PIPELINE_AWS_ACCOUNT_ID }}:role/${{ secrets.PIPELINE_ROLE }}

.python-version

Lines changed: 0 additions & 1 deletion
This file was deleted.

NOTICE

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ The following Python packages may be included in this product:
66
- cfnresponse==1.1.2
77
- opensearch-py==2.3.1
88
- openai==0.28.0
9-
- requests==2.32.0
9+
- requests==2.32.4
1010
- huggingface-hub
1111
- hf-transfer
1212
- aws_xray_sdk==2.12.1
@@ -817,7 +817,7 @@ Agreement.
817817

818818
The following Python packages may be included in this product:
819819

820-
- urllib3<2
820+
- urllib3==2.5.0
821821

822822
These packages each contain the following license and notice below:
823823

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@ This blueprint deploys the complete AWS GenAI LLM Chatbot solution in your AWS a
2727
- AWS CLI configured with credentials
2828
- Node.js 18+ and npm
2929
- Python 3.8+
30+
- AWS CDK CLI version compatible with aws-cdk-lib 2.206.0 or later
31+
```bash
32+
# Install or update the CDK CLI globally
33+
npm install -g aws-cdk@latest
34+
35+
# Verify the installed version
36+
cdk --version
37+
```
38+
39+
> **Important**: The CDK CLI version must be compatible with the aws-cdk-lib version used in this project (currently 2.206.0). If you encounter a "Cloud assembly schema version mismatch" error during deployment, update your CDK CLI to the latest version using the command above.
3040
3141
### Deployment
3242

aws-genai-llm-chatbot/modules/chatbot/deployspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ deploy:
99
- mkdir -p /root/.cdk/cache
1010
- env | grep NEXUS | sort | awk -F= '{printf "%-30s = %s\n", $1, $2}'
1111
- npm run tsc
12-
- npm run config -- --non-interactive --env-prefix NEXUS_PARAMETER_
12+
- npm run config -- --non-interactive --env-prefix SEEDFARMER_PARAMETER_
1313
- npm run deploy -- --require-approval never --progress events --outputs-file ./cdk-exports.json -v --no-notices
1414
- cat cdk-exports.json
15-
- seedfarmer metadata convert -f cdk-exports.json -jq .${NEXUS_PARAMETER_PREFIX}GenAIChatBotStack.metadata || true
15+
- seedfarmer metadata convert -f cdk-exports.json -jq .${SEEDFARMER_PARAMETER_PREFIX}GenAIChatBotStack.metadata || true
1616
destroy:
1717
phases:
1818
build:

docs/.vitepress/config.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export default defineConfig({
5353
text: 'Documentation',
5454
items: [
5555
{ text: 'Access Control', link: '/documentation/access-control' },
56+
{ text: 'AgentCore Integration', link: '/documentation/agentcore' },
5657
{ text: 'Applications', link: '/documentation/applications' },
5758
{ text: 'AppSync', link: '/documentation/appsync' },
5859
{ text: 'CloudFront Geo Restriction', link: '/documentation/cf-geo-restriction' },

docs/documentation/agentcore.md

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# AgentCore Integration
2+
3+
Amazon Bedrock AgentCore enables you to deploy and operate highly capable AI agents securely, at scale. It offers infrastructure purpose-built for dynamic agent workloads, powerful tools to enhance agents, and essential controls for real-world deployment. AgentCore services can be used together or independently and work with any framework including CrewAI, LangGraph, LlamaIndex, and Strands Agents, as well as any foundation model in or outside of Amazon Bedrock, giving you ultimate flexibility. AgentCore eliminates the undifferentiated heavy lifting of building specialized agent infrastructure, so you can accelerate agents to production.
4+
5+
![AgentCore Demo](assets/agent-demo.gif)
6+
7+
## Prerequisites
8+
9+
1. **Deploy Amazon Bedrock AgentCore Agent Runtime** in your AWS account
10+
11+
The CDK deployment automatically configures the required IAM permissions (`bedrock-agentcore:InvokeAgentRuntime` and `bedrock-agentcore:ListAgentRuntimes`).
12+
13+
## Using AgentCore
14+
15+
### 1. Agent Discovery
16+
17+
Agents are automatically discovered using the `listAgents` GraphQL query, which calls `list_agent_runtimes()` on the bedrock-agentcore-control client. Only users with `admin` or `workspace_manager` roles can access this query.
18+
19+
### 2. Agent Selection
20+
21+
In the chat interface:
22+
23+
- Agents appear in a separate dropdown labeled "Select an agent (optional)"
24+
- Agents display using `agentRuntimeName` as the label
25+
- The `agentRuntimeArn` is used as the value
26+
- Agent selection is optional - you can use regular models instead
27+
28+
### 3. Conversation
29+
30+
- When an agent is selected, the system uses `modelInterface: "agent"`
31+
- **Thinking Steps**: The agent's reasoning process is displayed in a collapsible section with:
32+
- Compact vertical timeline layout with connecting lines
33+
- Real-time updates during streaming responses
34+
- Visual indicators (emojis) for different agent actions
35+
- Click to expand/collapse the full thinking process
36+
- **Streaming**: Both thinking steps and response content stream in real-time
37+
- **Tool Usage**: When agents use tools, thinking steps show tool invocation and execution
38+
39+
## Interface Between Agent and Chatbot
40+
41+
### Request Format
42+
43+
The chatbot sends the complete request record as JSON payload to the agent's `@app.entrypoint` function:
44+
45+
```python
46+
{
47+
"userId": "user-id",
48+
"userGroups": ["group1", "group2"],
49+
"data": {
50+
"text": "User message",
51+
"agentRuntimeArn": "arn:aws:bedrock-agentcore:region:account:runtime/agent-id",
52+
"sessionId": "session-uuid",
53+
"conversation_history": [
54+
{"role": "user", "content": "Previous user message"},
55+
{"role": "assistant", "content": "Previous assistant response"}
56+
],
57+
# Additional fields from original request...
58+
"modelName": "anthropic.claude-3-5-sonnet-20241022-v2:0",
59+
"modelKwargs": {
60+
"temperature": 0.7,
61+
"topP": 0.9,
62+
"maxTokens": 4000,
63+
"streaming": true
64+
}
65+
}
66+
}
67+
```
68+
69+
**Key Fields:**
70+
71+
- `userId`: User identifier from the chatbot session
72+
- `userGroups`: User's group memberships for authorization
73+
- `data.text`: The user's current message
74+
- `data.agentRuntimeArn`: The selected agent's ARN
75+
- `data.sessionId`: Session identifier for conversation continuity
76+
- `data.conversation_history`: Array of previous messages with `role` and `content` fields (up to 20 recent messages)
77+
- `data.modelName`: Bedrock model identifier (if provided)
78+
- `data.modelKwargs`: Model configuration including streaming preference
79+
80+
**Important Notes:**
81+
82+
- The `conversation_history` is automatically added by the handler from DynamoDB
83+
- Messages are converted to simple `{role, content}` objects
84+
- The entire original request record is passed through, so agents receive all original fields
85+
86+
### Response Format
87+
88+
The agent returns Server-Sent Events (SSE) streaming data that the chatbot processes:
89+
90+
**Streaming SSE Format:**
91+
92+
```python
93+
# Thinking steps (agent reasoning)
94+
data: {"type": "thinking", "content": "💭 Assistant starting..."}
95+
data: {"type": "thinking", "content": "🔧 Calling calculator..."}
96+
data: {"type": "thinking", "content": "🧠 Analyzing the calculation..."}
97+
data: {"type": "thinking", "content": "✅ Block complete"}
98+
99+
# Response content (actual answer)
100+
data: {"type": "content", "content": "The result is "}
101+
data: {"type": "content", "content": "42"}
102+
```
103+
104+
**Non-streaming Response:**
105+
106+
```python
107+
{
108+
"result": "Agent's complete response text"
109+
}
110+
```
111+
112+
**Event Processing:**
113+
114+
- **Thinking Events**: `type: "thinking"` events are displayed in the expandable thinking steps section
115+
- **Content Events**: `type: "content"` events are accumulated to build the final response
116+
- **Visual Indicators**: Thinking steps support emoji indicators for different agent actions (needs to be sent by the agent):
117+
- 💭 Message start/thinking
118+
- 🔧 Tool usage
119+
- 🧠 Reasoning content
120+
- 📚 Citations
121+
- ✅ Completion markers
122+
- ⏸️ Tool execution
123+
- 🏁 Response complete
124+
125+
The above are CoverseStream events sent by a Amazon Bedrock [more info here](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ConverseStream.html#API_runtime_ConverseStream_ResponseSyntax)
126+
127+
### Security
128+
129+
- **Session Isolation**: Each conversation maintains separate session state (Handled by AgentCore)
130+
- **Error Handling**: Graceful fallback with error recovery for session history
131+
132+
## Getting Started
133+
134+
[QuickStart: Your First Agent in 5 Minutes! 🚀](https://aws.github.io/bedrock-agentcore-starter-toolkit/user-guide/runtime/quickstart.html)
135+
136+
### Simple Agent Example
137+
138+
Here's a minimal agent implementation that demonstrates the core concepts:
139+
140+
```python
141+
import boto3
142+
import json
143+
from bedrock_agentcore import BedrockAgentCoreApp
144+
from strands import Agent
145+
from strands.models import BedrockModel
146+
from strands_tools import calculator, current_time
147+
148+
app = BedrockAgentCoreApp()
149+
session = boto3.Session(region_name='il-central-1')
150+
bedrock_model = BedrockModel(boto_session=session)
151+
152+
agent = Agent(
153+
system_prompt="You are a helpful AI assistant that can use tools to answer questions.",
154+
model=bedrock_model,
155+
tools=[calculator, current_time],
156+
)
157+
158+
@app.entrypoint
159+
async def invoke(payload, context):
160+
"""Main agent function with streaming support"""
161+
# Extract request data
162+
user_message = payload["data"]["text"]
163+
conversation_history = payload["data"].get("conversation_history", [])
164+
is_streaming = payload["data"].get("modelKwargs", {}).get("streaming", False)
165+
166+
# Configure model from payload (if provided)
167+
if "modelName" in payload["data"]:
168+
bedrock_model.update_config(
169+
model_id=payload["data"]["modelName"],
170+
temperature=payload["data"]["modelKwargs"].get("temperature", 0.7),
171+
streaming=is_streaming,
172+
)
173+
174+
if is_streaming:
175+
async def generate_sse():
176+
async for event in agent.stream_async(user_message):
177+
if "event" in event:
178+
bedrock_event = event["event"]
179+
180+
# Handle different event types
181+
if "contentBlockDelta" in bedrock_event:
182+
delta = bedrock_event["contentBlockDelta"]["delta"]
183+
184+
if "text" in delta:
185+
# Stream response content
186+
sse_data = json.dumps({"type": "content", "content": delta["text"]})
187+
yield f"data: {sse_data}\n\n"
188+
189+
elif "reasoningContent" in delta:
190+
# Stream thinking steps
191+
reasoning = delta["reasoningContent"]["text"]
192+
sse_data = json.dumps({"type": "thinking", "content": f"🧠 {reasoning}"})
193+
yield f"data: {sse_data}\n\n"
194+
195+
elif "contentBlockStart" in bedrock_event:
196+
start_data = bedrock_event["contentBlockStart"]["start"]
197+
if "toolUse" in start_data:
198+
tool_name = start_data["toolUse"]["name"]
199+
sse_data = json.dumps({"type": "thinking", "content": f"🔧 Using {tool_name}"})
200+
yield f"data: {sse_data}\n\n"
201+
202+
return generate_sse()
203+
else:
204+
# Non-streaming response
205+
result = agent(user_message)
206+
return {"result": result.message}
207+
208+
if __name__ == "__main__":
209+
app.run()
210+
```
211+
212+
**Key Components:**
213+
214+
- `BedrockAgentCoreApp()`: Main application wrapper
215+
- `Agent()`: Core agent with system prompt, model, and tools
216+
- `@app.entrypoint`: Decorator for the main handler function
217+
- **Streaming**: Uses `agent.stream_async()` for real-time responses
218+
- **Event Processing**: Handles Bedrock events to extract thinking and content
219+
- **SSE Format**: Returns properly formatted Server-Sent Events
220+
221+
## Troubleshooting
222+
223+
### Agent Not Available
224+
225+
- Verify agent is deployed and active in Bedrock
226+
- Confirm agent ARN matches the exact pattern required
227+
- Check that your user has `admin` or `workspace_manager` role
228+
229+
### Streaming Issues
230+
231+
- Check WebSocket connection in browser developer tools
232+
- Verify session management in CloudWatch logs
233+
- Ensure agent provides data in expected `thinking`/`event` format
234+
235+
### Performance
236+
237+
- Agents may take longer than standard models due to reasoning complexity
238+
- Monitor CloudWatch metrics for agent invocation times
239+
- Conversation history is limited to prevent payload size issues
6.8 MB
Loading

0 commit comments

Comments
 (0)