Skip to content

feat(bb-agent): migrate streaming execution to AgentCore Runtime (1/5) - #250

Draft
pjkroker wants to merge 9 commits into
mainfrom
agentcore/1-core
Draft

feat(bb-agent): migrate streaming execution to AgentCore Runtime (1/5)#250
pjkroker wants to merge 9 commits into
mainfrom
agentcore/1-core

Conversation

@pjkroker

@pjkroker pjkroker commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Stacked PR 1 of 5 — the core migration. Layers on top: #251 WebSocket streaming, #252 README, #261 server-resolved tool context, #262 runtime-role BB grants.

Problem

The Agent BB ran its streaming loop on Lambda + SQS + Realtime (API Gateway WebSocket). The fundamental ceiling is Lambda's 15-minute max execution — long-running / multi-step agents were not achievable on AWS. Bedrock AgentCore Runtime (sessions up to 8h, native streaming) is purpose-built for this.

Scope of this PR (read first)

This is the foundation layer, not the end state. It lands the streamSSE() API, removes Realtime/AsyncJob, and provisions the AgentCore Runtime (co-bundled + serveable). What it does NOT yet do: wire the browser to AgentCore. On this PR alone, the browser still reaches the agent through buffered RPC — the Lambda calls streamSSE(), drains the full generator, and returns the chunks in one response. So:

In other words: #250 is a regression-free foundation; #250 + #251 together are the actual migration. Don't ship #250 alone as "the AgentCore migration." Reviewers: this is why there is no client WebSocket code here — it's intentionally in #251.

Changes (breaking)

  • New primary API streamSSE(message, options?) — a transport-agnostic async generator. Shared streamAgent() core owns the Strands loop + DynamoDB/S3 history persistence (incl. HITL approval records).
  • stream() / resume() kept as @deprecated compatibility wrappers (async-iterable + complete()).
  • Breaking: Realtime channel surface removed — getChannel(), channel/channelId on the result are gone; resume() drops its leading channelId arg.
  • index.cdk.ts provisions an AgentCore Runtime via fromCodeAsset() (Node 22 CodeZip, no Docker) + synth-time co-bundle of the app backend (agentcore-bundle.ts); no more Realtime/AsyncJob.
  • agentcore-entry.ts hosts the agent on the bedrock-agentcore harness (/invocations + /ping); dev-stream.ts serves the equivalent SSE route locally.
  • getStreamEndpoint() is added on AgentBase (AWS override returns the runtime endpoint; base/mock throws a clear AWS-only error) — the consumer of it ships in feat(bb-agent): browser-direct WebSocket streaming + server-verified identity (2/5) #251.
  • useChat consumes a single streamChunks transport seam (the local/buffered transport here; the WebSocket transport in feat(bb-agent): browser-direct WebSocket streaming + server-verified identity (2/5) #251).
  • core (minor): dev-server __BLOCKS_DEV_ROUTE_HANDLERS__ hook + BlocksStack.backendModulePath.

Validation

bb-agent build clean + 77 tests pass; npm run lint clean; API.md regenerated. CDK synth test asserts AWS::BedrockAgentCore::Runtime is emitted (verified aws-cdk-lib@2.257.0 exports the constructs). Rebased onto current main (reconciled with the lazy-load-Strands refactor #153).

Merge order (stacked PRs — read before merging)

These five PRs stack: #250#251#252#261#262, each targeting the one below for a clean per-layer diff. They all ultimately merge into main, bottom-up — do NOT merge them into each other.

This repo squash-merges, so promoting each upper PR needs a base retarget plus a rebase (squash gives main new commit SHAs, so a plain retarget would re-show the lower layer's diff).

  1. Merge feat(bb-agent): migrate streaming execution to AgentCore Runtime (1/5) #250main (this PR; already targets main). Squash-merge.
  2. Promote feat(bb-agent): browser-direct WebSocket streaming + server-verified identity (2/5) #251:
    git fetch origin
    # In the GitHub UI: change #251 base agentcore/1-core -> main
    git switch agentcore/2-websocket-identity
    git rebase --onto origin/main agentcore/1-core agentcore/2-websocket-identity
    git push --force-with-lease
    Then squash-merge feat(bb-agent): browser-direct WebSocket streaming + server-verified identity (2/5) #251 -> main.
  3. Promote docs(bb-agent): rewrite README for the AgentCore streaming API (3/5) #252:
    git fetch origin
    # In the GitHub UI: change #252 base agentcore/2-websocket-identity -> main
    git switch agentcore/3-docs
    git rebase --onto origin/main agentcore/2-websocket-identity agentcore/3-docs
    git push --force-with-lease
    Then squash-merge docs(bb-agent): rewrite README for the AgentCore streaming API (3/5) #252 -> main.
  4. Promote feat(bb-agent): server-resolved tool context from verified JWT claims (4/5) #261:
    git fetch origin
    # In the GitHub UI: change #261 base agentcore/3-docs -> main
    git switch agentcore/4-tool-context
    git rebase --onto origin/main agentcore/3-docs agentcore/4-tool-context
    git push --force-with-lease
    Then squash-merge feat(bb-agent): server-resolved tool context from verified JWT claims (4/5) #261 -> main.
  5. Promote fix(agent): AgentCore runtime role inherits the handler's BB grants (5/5) #262:
    git fetch origin
    # In the GitHub UI: change #262 base agentcore/4-tool-context -> main
    git switch agentcore/5-runtime-role-grants
    git rebase --onto origin/main agentcore/4-tool-context agentcore/5-runtime-role-grants
    git push --force-with-lease
    Then squash-merge fix(agent): AgentCore runtime role inherits the handler's BB grants (5/5) #262 -> main.

Notes:

Browser-direct WebSocket streaming, server-verified identity, the README rewrite, server-resolved tool context, and runtime-role BB grants are the following stacked PRs (#251, #252, #261, #262).

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

pjkroker added 5 commits July 22, 2026 16:06
…me/AsyncJob

Streaming now runs over SSE everywhere — AgentCore Runtime on AWS, a local
dev-server SSE route in mock/dev — replacing the Lambda + SQS + AppSync/Realtime
side-channel. Verified end-to-end on real AWS (stream + HITL interrupt/resume +
DynamoDB history) and locally.

- streamSSE() is the primary API; stream()/resume() kept as @deprecated compat
  wrappers (async-iterable + complete()). Removed the Realtime channel surface
  (getChannel/channel/channelId) — breaking.
- index.cdk.ts provisions the AgentCore Runtime via fromCodeAsset() with a
  synth-time co-bundle of the app backend; no more Realtime/AsyncJob.
- agentcore-entry.ts (BedrockAgentCoreApp harness) + dev-stream.ts (local SSE).
- core dev-server: generic __BLOCKS_DEV_ROUTE_HANDLERS__ hook; BlocksStack
  exposes backendModulePath.
- useChat consumes one streamChunks SSE transport.
- bump @strands-agents/sdk ^1.7.0, add bedrock-agentcore.
Superseded by the synth-time co-bundle in agentcore-bundle.ts. Reverts build
to plain tsc, drops the bundle:agentcore script, and repoints the CDK test's
agentcoreAssetPath at dist/ (any existing dir works for fromCodeAsset).
esbuild is imported on the published CDK synth path (index.cdk.ts →
agentcore-bundle.ts top-level import). As a devDependency it wouldn't be
installed for consumers, so cdk synth on the default co-bundle path would
throw 'Cannot find module esbuild'. lint:deps now passes.
Reflects streamSSE()/getStreamEndpoint()/AgentCoreStreamResult, the SSE-based
AgentStreamResult (async-iterable + complete()), and removal of the Realtime
channel surface (channel/channelId, StreamOptions.channelId). check:api green.
The >29s slow-tool test assumed the old async model (agentStream returns
immediately, chunks arrive out-of-band). Under SSE the RPC drains the stream,
so a >30s turn exceeds the API Gateway timeout (504). Long-running agents are
AgentCore's domain, not the buffered RPC path this test app uses.
@changeset-bot

changeset-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: de1924d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
Name Type
@aws-blocks/bb-agent Major
@aws-blocks/core Minor
@aws-blocks/blocks Patch
@aws-blocks/bb-kv-store Patch
@aws-blocks/bb-distributed-table Patch
@aws-blocks/auth-common Patch
@aws-blocks/bb-app-setting Patch
@aws-blocks/bb-data Patch
@aws-blocks/bb-distributed-data Patch
@aws-blocks/bb-auth-basic Patch
@aws-blocks/bb-auth-cognito Patch
@aws-blocks/bb-auth-oidc Patch
@aws-blocks/bb-realtime Patch
@aws-blocks/bb-async-job Patch
@aws-blocks/bb-dashboard Patch
@aws-blocks/bb-cron-job Patch
@aws-blocks/bb-file-bucket Patch
@aws-blocks/bb-knowledge-base Patch
@aws-blocks/bb-logger Patch
@aws-blocks/bb-email-client Patch
@aws-blocks/bb-tracer Patch
@aws-blocks/bb-metrics Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Type the CDK constructor as AgentConfig instead of `any`, and declare the
CDK-only `auth` and `agentcoreAssetPath` fields on AgentConfig. Previously
`config?: any` meant a typo (e.g. agentCoreAssetPath) or wrong auth shape
failed silently at synth rather than at dev time.
pjkroker added 2 commits July 23, 2026 14:24
The header (Type/AWS Services), the Architecture table, and the flow diagram
still described the removed Lambda + SQS/AsyncJob + AppSync/Realtime design.
Update them to the AgentCore model: AgentCore Runtime + DistributedTable ×2 +
FileBucket; drop SQS/AppSync from AWS Services; replace the
stream()→AsyncJob→Realtime flow with the streamSSE() generator + its transports
(browser WebSocket, /invocations SSE, local dev SSE).
PR #1 ships only the /invocations (HTTP+SSE) AWS path and the local-dev
SSE route; the browser-direct WebSocket (/ws) path lands in the next PR.
Remove the /ws branch, the dangling 'browser WebSocket path' reference,
and the 'browser streams to' phrasing from getStreamEndpoint so the doc
matches the code in this PR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant