Conversation
…ization If initialize() throws (most often because loadConfigToProcessEnv() can't read blocks-config.json during the brief post-deploy window before it's readable), the memoized rejected initPromise poisoned the container for its whole lifetime — every later request re-awaited the same rejection and 500'd. Now a failed init resets the promise so the next request retries; config.ts also stops caching a not-found result. The handler self-heals once config is available.
Covers the init-retry + config-404 no-cache fix: a first-request init failure must be retried on the next request (not cached as a poisoned rejection), and a not-found config result must not be cached (later fetch picks up the real config). Both fail on the pre-fix behavior.
…t to the Agent BB Per review: core shouldn't trust a specific compute by default. Remove the bedrock-agentcore assume-role statement from BlocksRole; the Agent BB adds it from its own CDK construct (where the AgentCore Runtime that runs AS the role is provisioned). The role keeps its lambda CompositePrincipal so a compute-BB can add its own trust principal. Test now asserts core trusts only lambda by default.
…JSDoc In common/index.ts the class is named BlocksStack; BaseBlocksStack is only the alias the CDK layer imports it under. Reference the contract as named here to avoid confusing a reader of this file.
Split the config bucket's creation into an eager, memoized getConfigLocation(scope) that both finalizeConfigRegistry (handler path, unchanged) and other compute running as the shared role can use. This lets the Agent BB's AgentCore Runtime inject BLOCKS_CONFIG_BUCKET/KEY at construction so its loadConfigToProcessEnv() loads the same app config as the handler (fixes tools using config-backed BBs failing in the runtime). No IAM change — the config-read grant sits on the shared role.
…ation README: replace stale AsyncJob/SQS references with the AgentCore Runtime (stream() prose, the provisions table + a runtime note, consumption-based cost line with the AgentCore pricing link, and a See Also link); drop the now-redundant timeout bullet. DESIGN: reflect the trimmed Realtime grant (Query + BatchWriteItem), the injected env vars (no session-bucket name — re-derived in-process), and keep the Architecture section compute-neutral.
… transport in README - Mark AgentTurnPayload / invokeTurn / dispatchTurn @internal — the turn-dispatch seam is not customer API (customers use stream()/resume()). The type stays exported only so api-extractor can resolve the protected dispatchTurn signature; it's no longer part of the public surface. API.md regenerated. - README: the Realtime BB provisions an API Gateway WebSocket, not AppSync Events — correct the cost bullet to match DESIGN and the provisions table.
The mock now runs the loop in-process via the base dispatchTurn (fire-and-forget invokeTurn); there is no AsyncJob to propagate the error through. Update the comment to match.
…CallbackUrl() Follows the core + bb-realtime review changes: - The shared role's bedrock-agentcore assume-role trust is now added here (in AgentCoreRuntime's once-per-stack guard), not in core — so a Realtime-only app never trusts AgentCore. Scoped by aws:SourceAccount/aws:SourceArn. Narrows executionRole to concrete iam.Role (fail loud otherwise). - Drops the redundant Realtime grant: the loop runs AS the shared role, which already holds the publish permissions via the Realtime child's handler wiring. Gets the callback URL to inject from realtime.publishCallbackUrl() instead of grantPublish's return value. - Test asserts the shared role gains the scoped bedrock-agentcore trust when an Agent is synthesized; comments/DESIGN updated to reflect inherited Realtime publish + construct-owned trust.
…itions) Pre-existing lint error (lint/style/useImportType) surfaced by the full-file lint: z is used only as z.infer<...> in agent.ts, so the import must be 'import type'.
… error surfaces
- Add agentcore-bundle.test.ts: runs bundleAgentCoreAsset() over a trivial fixture and asserts the
asset shape (main.js + CJS banner, {"type":"commonjs"}, non-empty _deps/) — the co-bundle path
was previously only exercised by a sandbox e2e (CDK tests pass a pre-built agentcoreAssetPath).
Wired into the package test script.
- Document that stream()/resume() surface errors on two paths: loop failures as an 'error' channel
chunk once dispatched, vs a dispatch failure (e.g. AWS runtime can't be invoked) rejecting the
awaited call itself.
The runtime?: 'agentcore' AgentConfig field had a single value and no reader — settable with no observable effect. Drop it (unreleased) rather than ship speculative public surface; a real runtime option can be re-added non-breakingly when a second value exists. Removes the field + its DESIGN paragraph + changeset bullet; API.md regenerated.
The internal BBs are created on the Agent scope (this), not a parent scope, in both the runtime and CDK layers. Reword the note to the real invariant: same child ids across layers → same fullId → same derived physical names, so the deployed loop resolves the CDK-provisioned resources.
…review) Inject BLOCKS_CONFIG_BUCKET/BLOCKS_CONFIG_KEY (via core's getConfigLocation) so the container's loadConfigToProcessEnv() loads the same app config as the handler. Without it the container ran with empty config, so tools using config-backed Building Blocks (secrets/flags/endpoints via registerConfig) failed in the runtime. IAM to read the blob is inherited via the shared execution role. This subsumes the callback-URL handoff: BLOCKS_RT_CALLBACK_URL is in that config blob (registered by the Realtime BB), so the explicit injection and the Realtime publishCallbackUrl() dependency are removed (the realtime prop is dropped from AgentCoreRuntime). Retires PR #367 entirely.
…ent-source.ts - index.cdk.test.ts's file-level docstring still described the abandoned 'dedicated/separate role' design; rewrite it to the shipped model (runtime runs AS the shared BlocksRole) — matching the assertions in the file. - Delete job-event-source.ts: the AsyncJob removal left INTERACTIVE_JOB_EVENT_SOURCE with no importers (dead code, not published in files, no deps).
The Agent no longer runs on an internal AsyncJob, so it no longer registers jobQueueUrl; the umbrella overload still declared it (a field that resolved to undefined). Remove it + regenerate API.md; add a @aws-blocks/blocks changeset.
…ME (Pranav review) The AgentCore Runtime set BLOCKS_STACK_NAME to cdk.Stack.of(this).stackName, but the handler and the Lambda compute use backendStackName (the owning BlocksStack/BlocksBackend canonical root id). They coincide for a top-level BlocksStack but diverge for a BlocksBackend embedded in a customer stack (backend fullId vs customer stack name) — so the container would rebuild resource names from the wrong namespace and miss its own tables/bucket/config. Use this.backendStackName to match.
… wire boundary (John review)
Locally the loop runs in-process, so a tool received the live context object; on AWS context is
JSON-serialized into the InvokeAgentRuntime payload and re-parsed (z.unknown passthrough), so a tool
gets a JSON-mangled context (Date→string, Set→{}, undefined dropped). Round-trip context in the mock
dispatchTurn so a serialization bug fails in local dev instead of only after deploy. Adds a regression
test pinning the boundary.
…ves config coordinates The AgentCore container hosts the Aurora/DSQL/Realtime tool executions but was a Scope, not a Compute. After #391 retargeted the config registry to stamp BLOCKS_CONFIG_BUCKET/KEY only onto registered computes, the container fell outside that distribution and self-injected coordinates that drifted from the authoritative location — so at runtime it loaded empty config and those blocks threw 'not configured' / 'Missing env' / 'BLOCKS_RT_WS_URL not set'. KnowledgeBase passed because it is served by the registered Lambda compute. AgentCoreRuntime now extends Compute (auto-registers) and exposes setEnv, writing into a live container env object the bedrock-agentcore Runtime L2 renders lazily by reference — so finalizeConfigRegistry stamps the same authoritative bucket+key it uploads the app config to, via the same path the Lambda compute uses. The isolated CDK test now finalizes config through the production path. Verified: build + cdk synth green; all 7 Runtime resources carry BLOCKS_CONFIG_BUCKET/KEY matching BlocksConfigDeployment; core + bb-agent unit tests pass.
🦋 Changeset detectedLatest commit: 59f243b The changes in this PR will be included in the next version bump. This PR includes changesets to release 23 packages
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 |
The handler's post-deploy self-heal never fired on the common case. On a
404 for blocks-config.json (the transient window before the BucketDeployment
is readable), config.ts returns {} WITHOUT caching — but loadConfigToProcessEnv()
then returns normally, so initialize() SUCCEEDS, handler is assigned, and the
'if (!handler)' request guard is false forever. The container serves 500
'not configured' for its whole life; the self-heal only fired on the rare
non-404 throw branch.
Fix: config.ts exposes isConfigResolved() (configCache !== null — uniquely true
after a real success or a legitimately-empty/no-bucket load, false only after a
transient-404 miss which declines to cache). initialize() now throws a typed
TransientConfigError when the config coordinates are set but the load didn't
resolve, so the existing catch resets initPromise and the next request re-runs
initialize() and re-fetches — self-healing once the blob is present. A
config-less app (no bucket) or a genuinely-empty {} config both cache their
result, so they never throw or spin.
Adds tests: transient-empty recovers on next request (backend not imported
against empty config); config-less and genuinely-empty apps do not re-init or
re-fetch. core: 745 tests pass.
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Fixes the E2E regression on #368 (Aurora / DSQL / Realtime — "not configured" / "Missing env" / "BLOCKS_RT_WS_URL not set"). Opened as a draft to run the full PR Checks workflow (incl. E2E Sandbox/Production) on #368's content + this fix.
Root cause
#368 moved the Agent's Aurora/DSQL/Realtime tool executions into a new
AgentCoreRuntimecontainer, which was aScope— not aCompute. A rebase then pulled in #391 ("Retarget config registry to shared role + per-stack compute registry"), which changedfinalizeConfigRegistryto stampBLOCKS_CONFIG_BUCKET/BLOCKS_CONFIG_KEYonly onto registeredComputes. Being aScope, the container fell outside that distribution and self-injected coordinates that drifted from the authoritative config location, so at runtime it loaded empty config and every config-backed block it hosts threw. KnowledgeBase passed because it's served by the registered Lambda compute.(#368 was green pre-rebase — run
33088638803, commit4f87436— and went red only after the rebase, run33651536435.)Fix
AgentCoreRuntimenowextends Compute(auto-registers via the base ctor) and implementssetEnv, writing into a live container-env object thebedrock-agentcoreRuntimeL2 renders lazily by reference.finalizeConfigRegistrythen stamps the container with the same authoritative bucket+key it uploads the app config to — the exact path the Lambda compute already uses. No parallel self-injection to drift.Verification
npm run build+cdk synthgreen; all 7AWS::BedrockAgentCore::Runtimeresources carryBLOCKS_CONFIG_BUCKET/BLOCKS_CONFIG_KEYmatchingBlocksConfigDeployment;core+bb-agentunit tests pass.This PR is for CI validation; the fix commit can be cherry-picked onto #368.