Skip to content

Commit 047533c

Browse files
authored
Merge branch 'main' into toolbox
2 parents 8537a1d + e7a781e commit 047533c

57 files changed

Lines changed: 1336 additions & 636 deletions

Some content is hidden

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

.github/workflows/ash-security-comment.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,18 @@ jobs:
1616
if: github.event.workflow_run.event == 'pull_request'
1717
steps:
1818
- name: Download artifacts
19-
uses: actions/download-artifact@v4
19+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
2020
with:
2121
name: ash-security-results
2222
path: /tmp/ash-results
2323
run-id: ${{ github.event.workflow_run.id }}
2424
github-token: ${{ secrets.GITHUB_TOKEN }}
2525

26+
- name: Debug artifact contents
27+
run: |
28+
echo "Artifact contents:"
29+
find /tmp/ash-results -type f | head -20
30+
2631
- name: Get PR information
2732
id: pr-info
2833
run: |
@@ -49,6 +54,8 @@ jobs:
4954
script: |
5055
const fs = require('fs');
5156
const commentPath = '/tmp/ash-results/pr_comment.md';
57+
console.log('Looking for comment file at:', commentPath);
58+
console.log('File exists:', fs.existsSync(commentPath));
5259
5360
if (!fs.existsSync(commentPath)) {
5461
console.log('No comment file found in artifacts');

.github/workflows/ash-security-scan.yml

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919

2020
- name: Get changed files
2121
id: changed-files
22-
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46
22+
uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v47.0.5
2323
with:
2424
files: |
2525
**/*.py
@@ -202,25 +202,24 @@ jobs:
202202
echo "has_findings=false" >> "$GITHUB_OUTPUT"
203203
fi
204204
205-
- name: Save PR metadata
205+
- name: Prepare artifacts
206206
if: steps.changed-files.outputs.any_changed == 'true'
207207
env:
208208
PR_NUMBER: ${{ github.event.pull_request.number }}
209209
PR_SHA: ${{ github.event.pull_request.head.sha }}
210210
run: |
211-
echo "${PR_NUMBER}" > /tmp/pr_number.txt
212-
echo "${PR_SHA}" > /tmp/pr_sha.txt
211+
mkdir -p /tmp/ash-artifacts
212+
echo "${PR_NUMBER}" > /tmp/ash-artifacts/pr_number.txt
213+
echo "${PR_SHA}" > /tmp/ash-artifacts/pr_sha.txt
214+
cp /tmp/pr_comment.md /tmp/ash-artifacts/pr_comment.md
215+
cp -r /tmp/ash-scan/.ash/ /tmp/ash-artifacts/.ash/ 2>/dev/null || true
213216
214217
- name: Upload ASH results and PR metadata
215218
if: steps.changed-files.outputs.any_changed == 'true' && always()
216219
uses: actions/upload-artifact@v4
217220
with:
218221
name: ash-security-results
219-
path: |
220-
/tmp/ash-scan/.ash/
221-
/tmp/pr_comment.md
222-
/tmp/pr_number.txt
223-
/tmp/pr_sha.txt
222+
path: /tmp/ash-artifacts/
224223
retention-days: 30
225224

226225
- name: Security scan summary

.github/workflows/dependabot.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
name: Dependabot auto-merge
22

33
on:
4-
pull_request:
5-
types: [opened, synchronize]
4+
pull_request_target:
5+
types: [opened, synchronize, reopened]
66

77
permissions:
88
pull-requests: write
@@ -11,7 +11,7 @@ permissions:
1111
jobs:
1212
dependabot:
1313
runs-on: ubuntu-latest
14-
if: github.event.pull_request.user.login == 'dependabot[bot]'
14+
if: github.actor == 'dependabot[bot]'
1515
steps:
1616
- name: Dependabot metadata
1717
id: metadata

.github/workflows/label.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ name: Labeler
22

33
on: [pull_request_target]
44

5+
permissions:
6+
contents: read
7+
pull-requests: write
8+
59
jobs:
610
label:
711
runs-on: ubuntu-latest

.github/workflows/repo-stats.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ on:
1010
- cron: "0 11 * * *"
1111
workflow_dispatch: # Allow manual triggering from the Actions tab.
1212

13+
permissions:
14+
contents: write
15+
1316
jobs:
1417
collect-stats:
1518
name: collect-repo-stats

docker/Dockerfile.frontend.dev

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,12 @@ COPY . .
1717
# Expose port
1818
EXPOSE 3000
1919

20+
# Run as non-root user (node user is built into node:20-alpine)
21+
USER node
22+
23+
# Healthcheck for container orchestration (dev server)
24+
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
25+
CMD wget -qO- http://localhost:3000/ || exit 1
26+
2027
# Start development server (--host exposes to Docker network)
2128
CMD ["npm", "run", "dev", "--", "--host"]

docs/AGENTCORE_EVALUATIONS_GUIDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ Each log event contains a JSON object with OpenTelemetry-style attributes:
481481
"gen_ai.evaluation.score.label": "Very Helpful",
482482
"gen_ai.evaluation.explanation": "The response directly addresses the user's question with relevant and actionable information..."
483483
},
484-
"traceId": "abc123def456",
484+
"traceId": "abc123def456", // pragma: allowlist secret (example placeholder, not a real secret)
485485
"spanId": "789ghi",
486486
"sessionId": "session-456",
487487
"timestamp": "2026-02-17T00:42:42.086Z"

docs/AGUI_INTEGRATION.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# AG-UI Protocol Integration
2+
3+
Guide for using the AG-UI (Agent-User Interaction) protocol patterns in FAST.
4+
5+
---
6+
7+
## Overview
8+
9+
[AG-UI](https://docs.ag-ui.com/concepts/overview) is an open protocol that defines a standard SSE event format for agent-to-frontend communication. Instead of each framework emitting its own event schema (Strands events, LangChain message chunks, etc.), AG-UI provides a unified event vocabulary: `TEXT_MESSAGE_CONTENT`, `TOOL_CALL_START`, `TOOL_CALL_ARGS`, `TOOL_CALL_RESULT`, `RUN_FINISHED`, and so on.
10+
11+
FAST includes two AG-UI agent patterns:
12+
13+
| Pattern | Framework | Location |
14+
|---------|-----------|----------|
15+
| `agui-strands-agent` | Strands + `ag-ui-strands` | `agent_patterns/agui-strands-agent/` |
16+
| `agui-langgraph-agent` | LangGraph + `copilotkit` | `agent_patterns/agui-langgraph-agent/` |
17+
18+
Both patterns use `BedrockAgentCoreApp` as the entrypoint (same as the HTTP patterns), which means AgentCore Runtime headers (WorkloadAccessToken, Authorization, Session-Id) are available for Gateway auth, Memory, and secure user identity extraction.
19+
20+
---
21+
22+
## How It Works
23+
24+
### Architecture
25+
26+
```
27+
Frontend (Amplify)
28+
29+
│ POST /invocations (AG-UI RunAgentInput payload)
30+
31+
AgentCore Runtime
32+
33+
│ Proxies request to container port 8080
34+
│ Injects: WorkloadAccessToken, Authorization, Session-Id headers
35+
36+
Agent Container
37+
38+
│ BedrockAgentCoreApp reads headers → sets ContextVars
39+
│ @entrypoint handler creates agent, runs it
40+
41+
AG-UI Wrapper (StrandsAgent / LangGraphAGUIAgent)
42+
43+
│ Translates framework events → AG-UI SSE events
44+
45+
Frontend Parser (parsers/agui.ts)
46+
47+
│ Maps AG-UI events → StreamEvent types
48+
49+
ChatInterface.tsx renders messages
50+
```
51+
52+
### Request Flow
53+
54+
1. The frontend sends an AG-UI `RunAgentInput` payload (with `threadId`, `messages`, `runId`)
55+
2. AgentCore Runtime proxies the request, injecting auth headers
56+
3. `BedrockAgentCoreApp` reads headers and populates `BedrockAgentCoreContext` (ContextVars)
57+
4. The `@entrypoint` handler extracts user identity from the JWT, creates the agent with Memory and Gateway tools
58+
5. The AG-UI wrapper translates framework streaming events into AG-UI SSE events
59+
6. The frontend `parseAguiChunk` parser maps AG-UI events to the shared `StreamEvent` types
60+
61+
### AG-UI vs HTTP Protocol on AgentCore Runtime
62+
63+
AgentCore Runtime supports both `HTTP` and `AGUI` server protocols. The difference is minimal: with `AGUI`, platform-level errors are returned as AG-UI-compliant `RUN_ERROR` events in the SSE stream (HTTP 200) instead of HTTP error codes. Everything else — auth, session headers, payload passthrough — is identical.
64+
65+
The AG-UI patterns in FAST deploy with `HTTP` protocol, which works correctly because the agent container handles AG-UI event formatting internally.
66+
67+
---
68+
69+
## Agent Patterns
70+
71+
### AG-UI Strands (`agui-strands-agent`)
72+
73+
**Location**: `agent_patterns/agui-strands-agent/`
74+
75+
Uses `ag-ui-strands` (`StrandsAgent`) to wrap a Strands `Agent`. The agent is created per-request inside the `@entrypoint` handler, ensuring each request gets a fresh `Agent` with the correct `session_manager` and fresh MCP client connections.
76+
77+
**Includes**: AgentCore Memory, Gateway MCP tools, Code Interpreter, AG-UI SSE streaming.
78+
79+
### AG-UI LangGraph (`agui-langgraph-agent`)
80+
81+
**Location**: `agent_patterns/agui-langgraph-agent/`
82+
83+
Uses the `copilotkit` python library (`LangGraphAGUIAgent`) to wrap a LangGraph compiled graph. Uses `ActorAwareLangGraphAgent`, a subclass that rebuilds the graph per-request to ensure fresh Gateway MCP tool connections with valid tokens.
84+
85+
**Includes**: AgentCore Memory (checkpointer), Gateway MCP tools, Code Interpreter, CopilotKit middleware, AG-UI SSE streaming.
86+
87+
---
88+
89+
## Frontend
90+
91+
### Parser Auto-Selection
92+
93+
The AG-UI parser is automatically selected based on the pattern name prefix. Any pattern starting with `agui-` uses the AG-UI parser (`parsers/agui.ts`). Unlike the HTTP patterns — which each require a framework-specific parser (Strands, LangGraph, Claude) to handle their different streaming formats — all AG-UI patterns share a single parser. This is one of the key benefits of the AG-UI protocol: the backend framework is abstracted away behind a standard event vocabulary, so the frontend doesn't need to know whether the agent uses Strands or LangGraph.
94+
95+
See `frontend/src/lib/agentcore-client/client.ts` for the parser selection logic and `infra-cdk/config.yaml` comments for the full prefix-to-parser mapping.
96+
97+
### AG-UI Payload Format
98+
99+
The frontend automatically sends the correct payload format based on the pattern prefix. AG-UI patterns receive a `RunAgentInput` payload (with `threadId`, `messages`, `runId`), while HTTP patterns receive the standard `{ prompt, runtimeSessionId }` format. This is handled by `AgentCoreClient.invoke()`.
100+
101+
---
102+
103+
## Deployment
104+
105+
Set the pattern in `infra-cdk/config.yaml`:
106+
107+
```yaml
108+
backend:
109+
pattern: agui-strands-agent # or agui-langgraph-agent
110+
deployment_type: docker
111+
```
112+
113+
No CDK changes are required. The AG-UI patterns deploy as standard HTTP containers on AgentCore Runtime.
114+
115+
---
116+
117+
## CopilotKit Integration
118+
119+
[CopilotKit](https://www.copilotkit.ai/) is a React UI library that natively understands the AG-UI protocol. While FAST's built-in frontend includes a lightweight AG-UI parser for basic chat streaming, CopilotKit provides a richer set of capabilities for building agent-powered applications. Fullstack FAST applications with deeper CopilotKit integration can be found in the FAST samples repository (coming soon).
120+
121+
---
122+
123+
## Additional Resources
124+
125+
- [AG-UI Protocol Documentation](https://docs.ag-ui.com/concepts/overview)
126+
- [ag-ui-strands on PyPI](https://pypi.org/project/ag-ui-strands/)
127+
- [CopilotKit Documentation](https://docs.copilotkit.ai/)
128+
- [Strands AG-UI Integration Guide](https://strandsagents.com/docs/community/integrations/ag-ui/)

0 commit comments

Comments
 (0)