diff --git a/docs/develop/python/workers/serverless-workers/agentcore.mdx b/docs/develop/python/workers/serverless-workers/agentcore.mdx
new file mode 100644
index 0000000000..2c5605ec7a
--- /dev/null
+++ b/docs/develop/python/workers/serverless-workers/agentcore.mdx
@@ -0,0 +1,250 @@
+---
+id: agentcore
+title: Serverless Workers on Amazon Bedrock AgentCore Runtime - Python SDK
+sidebar_label: Amazon Bedrock AgentCore
+description: Run a Temporal Worker on Amazon Bedrock AgentCore Runtime using the Python SDK.
+slug: /develop/python/workers/serverless-workers/agentcore
+toc_max_heading_level: 4
+tags:
+ - Workers
+ - Python SDK
+ - Serverless
+ - Amazon Bedrock AgentCore
+---
+
+import { ReleaseNoteHeader } from '@site/src/components'
+
+
+ Amazon Bedrock AgentCore Runtime support is in Pre-release, and its APIs may change in backwards-incompatible ways.
+
+
+On Amazon Bedrock AgentCore Runtime, you run a standard long-lived Python Worker inside an AgentCore Runtime handler.
+Temporal starts the handler when the Worker Controller Instance needs capacity. The handler starts a Worker that polls
+the Task Queue, then stops it when your idle policy decides to release capacity.
+
+The Worker uses the normal Python SDK. The handler uses the `bedrock-agentcore` package to receive AgentCore Runtime
+invocations.
+
+For the provider behavior, including autoscaling, Worker Versioning, and the Runtime session lifecycle, see
+[Serverless Workers on Amazon Bedrock AgentCore Runtime](/serverless-workers/agentcore).
+For the infrastructure procedure, see
+[Deploy a Serverless Worker on Amazon Bedrock AgentCore Runtime](/production-deployment/worker-deployments/serverless-workers/agentcore).
+
+## Install the AgentCore Runtime SDK {/* #install-agentcore-runtime-sdk */}
+
+Install the AgentCore Runtime SDK alongside the Temporal Python SDK:
+
+```bash
+pip install bedrock-agentcore
+```
+
+## Create a versioned Worker {/* #versioned-worker */}
+
+Serverless Workers require [Worker Versioning](/worker-versioning). Create the Worker as you would any long-lived
+Python Worker, then set `deployment_config` to declare its Worker Deployment Version and enable versioning:
+
+```python
+worker = Worker(
+ # ...
+ deployment_config=WorkerDeploymentConfig(
+ version=WorkerDeploymentVersion(
+ deployment_name=DEPLOYMENT_NAME,
+ build_id=BUILD_ID,
+ ),
+ use_worker_versioning=True,
+ default_versioning_behavior=VersioningBehavior.PINNED,
+ ),
+)
+```
+
+`TEMPORAL_DEPLOYMENT_NAME` and `TEMPORAL_BUILD_ID` must match the Worker Deployment Version that you create with
+`temporal worker deployment create-version`. Configure that Worker Deployment Version with the AgentCore Runtime
+endpoint that Temporal invokes. For the endpoint configuration, see
+[Worker Versioning](/serverless-workers/agentcore#worker-versioning).
+
+Every Workflow needs a [versioning behavior](/worker-versioning#versioning-behaviors), either `PINNED` or
+`AUTO_UPGRADE`. Setting `default_versioning_behavior` as shown applies `PINNED` behavior to every Workflow on the
+Worker. To set the behavior per Workflow instead, pass `versioning_behavior` to the `@workflow.defn` decorator.
+
+## Start the Worker from the Runtime handler {/* #runtime-handler */}
+
+AgentCore Runtime invokes an HTTP handler. Use `BedrockAgentCoreApp` to provide that handler, and use `async_task` so
+AgentCore keeps the Runtime active while the Worker polls:
+
+
+[bedrock_agentcore/strands-agent/agentcore_worker.py](https://github.com/temporalio/samples-python/blob/5b0fe65efe934388d35eda430fb11df6899ce1d3/bedrock_agentcore/strands-agent/agentcore_worker.py)
+```py
+@app.entrypoint
+@app.async_task # keeps /ping on "HealthyBusy" until this returns
+async def invoke(payload: dict) -> dict:
+ """Poll until idle, then drain. The payload is unused: every call is a new session and new worker."""
+ api_key = os.environ.get("TEMPORAL_API_KEY") or None
+ client = await Client.connect(
+ os.environ.get("TEMPORAL_ADDRESS", "localhost:7233"),
+ namespace=os.environ.get("TEMPORAL_NAMESPACE", "default"),
+ api_key=api_key,
+ tls=bool(api_key),
+ plugins=[StrandsPlugin()],
+ )
+
+ task_queue = os.environ.get("TEMPORAL_TASK_QUEUE", workflows.TASK_QUEUE)
+ tracker = ActivityTracker()
+
+ log.info("polling %s as %s/%s", task_queue, DEPLOYMENT_NAME, BUILD_ID)
+ # execute_code is a sync Activity, so it needs an executor to block on.
+ with ThreadPoolExecutor(max_workers=4) as activity_executor:
+ worker = Worker(
+ client,
+ task_queue=task_queue,
+ workflows=[workflows.StrandsAgentWorkflow],
+ activities=[execute_code],
+ activity_executor=activity_executor,
+ interceptors=[tracker],
+ deployment_config=WorkerDeploymentConfig(
+ version=WorkerDeploymentVersion(
+ deployment_name=DEPLOYMENT_NAME, build_id=BUILD_ID
+ ),
+ use_worker_versioning=True,
+ default_versioning_behavior=VersioningBehavior.PINNED,
+ ),
+ graceful_shutdown_timeout=DRAIN,
+ )
+ async with worker:
+ await tracker.wait_until_idle(DEBOUNCE)
+ log.info("worker idle for %ss; drained", DEBOUNCE)
+ return {"message": "worker drained", "task_queue": task_queue}
+```
+
+
+The payload does not represent a Workflow input. The Worker Controller Instance invokes the endpoint to add Worker
+capacity. Applications start Workflows through the Temporal Client, as usual.
+
+## Configure the Temporal connection {/* #configure-connection */}
+
+The `temporalio.envconfig` package loads [Temporal Client](/develop/python/client/temporal-client) configuration from
+environment variables and an optional TOML configuration file. Set the Temporal address, Namespace, Task Queue, and
+Worker Deployment Version values as Runtime environment variables. Store a Temporal Cloud API key or TLS material in a
+secret store rather than in the Runtime definition.
+
+For the supported connection variables, config-file format, and profiles, see
+[Environment configuration](/develop/environment-configuration).
+
+## Stop and drain the Worker {/* #stop-and-drain-the-worker */}
+
+AgentCore cannot tell when a Worker that is still polling has no Temporal work. The Runtime remains busy while the
+`async_task` handler runs, so it can remain active until its eight-hour maximum lifetime. To release capacity sooner,
+have the handler detect when the Worker has no useful work and return.
+
+When the condition remains true for an idle period, leave the `async with worker` block. The Worker stops polling for
+new Tasks and gives in-flight Activities time to complete before the Runtime handler returns.
+
+The following example from the
+[AgentCore sample Worker](https://github.com/temporalio/samples-python/blob/5b0fe65efe934388d35eda430fb11df6899ce1d3/bedrock_agentcore/strands-agent/agentcore_worker.py)
+defines an `ActivityTracker`. It uses an [Activity inbound Interceptor](/develop/python/workers/interceptors) to count
+running Activities.
+
+
+[bedrock_agentcore/strands-agent/agentcore_worker.py](https://github.com/temporalio/samples-python/blob/5b0fe65efe934388d35eda430fb11df6899ce1d3/bedrock_agentcore/strands-agent/agentcore_worker.py)
+```py
+# How long the Worker keeps polling after it goes idle.
+DEBOUNCE = float(os.environ.get("AGENTCORE_DEBOUNCE_SECONDS", "60"))
+# How long the drain waits for in-flight Activities (a model or tool call).
+DRAIN = timedelta(seconds=120)
+
+
+class ActivityTracker(Interceptor):
+ """Tracks in-flight activities and blocks until AGENTCORE_DEBOUNCE_SECONDS elapses with no events."""
+
+ def __init__(self) -> None:
+ self.inflight = 0
+ self.changed = asyncio.Event()
+
+ def intercept_activity(
+ self, next: ActivityInboundInterceptor
+ ) -> ActivityInboundInterceptor:
+ return _TrackedActivity(next, self)
+
+ async def wait_until_idle(self, debounce: float) -> None:
+ """Return once no Activity has run for ``debounce`` seconds."""
+ while True:
+ self.changed.clear()
+ try:
+ # Wake the moment an Activity starts or finishes; a timeout
+ # instead means nothing has happened for the whole window.
+ await asyncio.wait_for(self.changed.wait(), timeout=debounce)
+ except asyncio.TimeoutError:
+ if self.inflight == 0:
+ return
+
+
+class _TrackedActivity(ActivityInboundInterceptor):
+ def __init__(
+ self, next: ActivityInboundInterceptor, tracker: ActivityTracker
+ ) -> None:
+ super().__init__(next)
+ self._tracker = tracker
+
+ async def execute_activity(self, input: ExecuteActivityInput):
+ self._tracker.inflight += 1
+ self._tracker.changed.set()
+ log.info("activity in flight: %d", self._tracker.inflight)
+ try:
+ return await self.next.execute_activity(input)
+ finally:
+ self._tracker.inflight -= 1
+ self._tracker.changed.set()
+```
+
+
+Register the tracker as a Worker Interceptor and wait for it inside the Worker context:
+
+```python
+tracker = ActivityTracker()
+worker = Worker(
+ client,
+ # ...
+ interceptors=[tracker],
+ graceful_shutdown_timeout=DRAIN,
+)
+
+async with worker:
+ await tracker.wait_until_idle(DEBOUNCE)
+```
+
+`ActivityTracker` retires the Worker only after 60 seconds without an Activity starting or completing and with no
+Activity running. A long-running Activity keeps the count above zero, so the idle policy does not interrupt it. The
+two-minute `graceful_shutdown_timeout` is a safety limit for any Activity still in flight when shutdown starts.
+
+Memory pressure can be another retirement condition. For example, the Runtime handler can monitor process memory and
+initiate the same graceful shutdown when usage crosses a threshold. Memory usage is not an idle signal. It tells you
+when to recycle a Worker, not whether it has work to do. Test any memory-based policy against the Runtime's memory
+limit and your Activity retry behavior.
+
+`AGENTCORE_DEBOUNCE_SECONDS` controls the idle period. `graceful_shutdown_timeout` controls how long the Worker waits
+for in-flight Activities after it stops polling. Choose both values for your workload, and account for AgentCore's
+maximum Runtime lifetime. For the AgentCore lifecycle settings, see
+[Lifecycle](/serverless-workers/agentcore#lifecycle).
+
+## Keep Activities safe across Worker termination {/* #activity-recovery */}
+
+AgentCore can end the compute that runs a Worker. An Activity running at that time can be interrupted and retried.
+Use [Activity Heartbeats](/develop/python/activities/timeouts#activity-heartbeats) so a retry resumes from its last
+recorded progress instead of starting over:
+
+```python
+from temporalio import activity
+
+
+@activity.defn
+async def my_activity(items: list[str]) -> str:
+ for i, item in enumerate(items):
+ activity.heartbeat(i)
+ # ... process item
+ return "done"
+```
+
+## Add observability {/* #add-observability */}
+
+An AgentCore Runtime Worker emits the same traces and metrics as a Worker on other compute. For metrics export and
+OpenTelemetry tracing interceptors, see [Observability - Python SDK](/develop/python/platform/observability) and the
+[SDK metrics reference](/references/sdk-metrics).
diff --git a/docs/develop/python/workers/serverless-workers/index.mdx b/docs/develop/python/workers/serverless-workers/index.mdx
index 6a1299e5cc..c0d1d55f52 100644
--- a/docs/develop/python/workers/serverless-workers/index.mdx
+++ b/docs/develop/python/workers/serverless-workers/index.mdx
@@ -14,10 +14,10 @@ tags:
import { ReleaseNoteHeader } from '@site/src/components';
- AWS Lambda support is in Public Preview. GCP Cloud Run support is in Pre-release, and its APIs may change in
- backwards-incompatible ways. To request Cloud Run access, create a [support ticket](/cloud/support#support-ticket) or
- contact your account team, and [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear
- when Cloud Run reaches Public Preview.
+ AWS Lambda support is in Public Preview. Amazon Bedrock AgentCore Runtime and GCP Cloud Run support are in
+ Pre-release, and their APIs may change in backwards-incompatible ways. To request Cloud Run access, create a
+ [support ticket](/cloud/support#support-ticket) or contact your account team, and
+ [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear when Cloud Run reaches Public Preview.
Serverless Workers run on ephemeral, on-demand compute rather than long-lived processes.
@@ -29,4 +29,5 @@ For the end-to-end deployment guide, see [Deploy a Serverless Worker](/productio
## Supported providers
- [**AWS Lambda**](/develop/python/workers/serverless-workers/aws-lambda) - Use the `lambda_worker` contrib package to run a Worker as a Lambda function. Covers setup, configuration, Lambda-tuned defaults, and observability.
+- [**Amazon Bedrock AgentCore Runtime**](/develop/python/workers/serverless-workers/agentcore) - Run a standard Worker from an AgentCore Runtime handler. Covers the handler, Worker Versioning, connection configuration, and Worker shutdown.
- [**GCP Cloud Run**](/develop/python/workers/serverless-workers/cloud-run) - Run a standard Worker on a Cloud Run worker pool. Covers the versioned Worker setup, connection configuration, and handling scale-in.
diff --git a/docs/encyclopedia/workers/serverless-workers/aws-lambda.mdx b/docs/encyclopedia/workers/serverless-workers/aws-lambda.mdx
index 4547762d57..fca5bec7c3 100644
--- a/docs/encyclopedia/workers/serverless-workers/aws-lambda.mdx
+++ b/docs/encyclopedia/workers/serverless-workers/aws-lambda.mdx
@@ -24,26 +24,38 @@ For a step-by-step deployment guide, see [Deploy a Serverless Worker on AWS Lamb
## Autoscaling {/* #autoscaling */}
-The Lambda autoscaling algorithm is event-driven and reactive.
+The autoscaling algorithm in this section applies to Serverless Workers on AWS Lambda and Amazon Bedrock AgentCore
+Runtime. The compute providers have different Worker lifecycles after a scale-out action. For AgentCore Runtime
+lifecycle details, see [Serverless Workers on Amazon Bedrock AgentCore Runtime](/serverless-workers/agentcore#lifecycle).
+
+The autoscaling algorithm is event-driven and reactive.
Sync match failure is the primary control signal, and backlog aids sizing.
-When the [WCI](/serverless-workers#worker-controller-instance) needs more capacity, it calls the Lambda `InvokeFunction` API to start new Workers.
-Each call is a discrete action ("invoke N more functions"), not a target state.
-Temporal calls that API from outside your network, so no inbound connection to the function is needed.
-The WCI does not manage a fleet of instances.
+When the [WCI](/serverless-workers#worker-controller-instance) needs more capacity, it invokes the compute provider to
+start new Workers: the Lambda `InvokeFunction` API for Lambda or an AgentCore Runtime endpoint for AgentCore Runtime.
+Each call is a discrete action ("start N more Workers"), not a target state. Temporal calls the provider API from
+outside your network, so no inbound connection to the Worker is needed. The WCI does not manage a fleet of instances.
### Scale-out {/* #scale-out */}
-On sync match failure, the WCI invokes new Lambda functions.
-Because Lambda cold start is sub-second to low single-digit seconds, reactive-only control does not create meaningful backlog overshoot.
-The WCI can scale from zero with low latency.
+On sync match failure, the WCI starts new Workers through the compute provider API.
+
+For Lambda, cold start is sub-second to low single-digit seconds, so reactive-only control does not create meaningful
+backlog overshoot. The WCI can scale from zero with low latency.
+
+For AgentCore Runtime startup and session behavior, see
+[Lifecycle](/serverless-workers/agentcore#lifecycle).
### Scale-in {/* #scale-in */}
-Scale-in is automatic.
-Each Lambda invocation runs until the Worker has finished processing available Tasks or approaches the 15-minute execution time limit, then shuts down.
-There is no drain logic or stabilization window.
-The WCI does not need to actively remove capacity.
+The WCI does not maintain a target number of Workers or actively remove capacity. The provider and Worker lifecycle
+determine when a Worker stops.
+
+On Lambda, each invocation runs until the Worker has finished processing available Tasks or approaches the 15-minute
+execution time limit, then shuts down. There is no drain logic or stabilization window.
+
+On AgentCore Runtime, Worker shutdown and AgentCore session lifecycle settings determine when a Worker stops. See
+[Lifecycle](/serverless-workers/agentcore#lifecycle).
### Instance model {/* #instance-model */}
diff --git a/docs/encyclopedia/workers/serverless-workers/index.mdx b/docs/encyclopedia/workers/serverless-workers/index.mdx
index ff394ec70a..657fb5f378 100644
--- a/docs/encyclopedia/workers/serverless-workers/index.mdx
+++ b/docs/encyclopedia/workers/serverless-workers/index.mdx
@@ -14,10 +14,10 @@ tags:
import { CaptionedImage, ReleaseNoteHeader } from '@site/src/components';
- AWS Lambda support is in Public Preview. GCP Cloud Run support is in Pre-release, and its APIs may change in
- backwards-incompatible ways. To request Cloud Run access, create a [support ticket](/cloud/support#support-ticket) or
- contact your account team, and [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear
- when Cloud Run reaches Public Preview.
+ AWS Lambda support is in Public Preview. Amazon Bedrock AgentCore Runtime and GCP Cloud Run support are in
+ Pre-release, and their APIs may change in backwards-incompatible ways. To request Cloud Run access, create a
+ [support ticket](/cloud/support#support-ticket) or contact your account team, and
+ [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear when Cloud Run reaches Public Preview.
This page covers the following:
@@ -39,8 +39,9 @@ in response to work on a Task Queue.
A Serverless Worker uses the same Temporal SDKs as a traditional long-lived Worker, and registers Workflows and
Activities the same way. What differs is that Temporal manages the Worker's lifecycle rather than you running a Worker
-process. How that lifecycle works depends on the compute provider: AWS Lambda runs short-lived invocations, while GCP
-Cloud Run runs a pool of long-lived instances. See [Worker lifecycle](#worker-lifecycle).
+process. How that lifecycle works depends on the compute provider: AWS Lambda runs short-lived invocations, Amazon
+Bedrock AgentCore Runtime runs sessions with idle and maximum-lifetime limits, and GCP Cloud Run runs a pool of
+long-lived instances. See [Worker lifecycle](#worker-lifecycle).
Serverless Workers require [Worker Versioning](/worker-versioning). Each Serverless Worker must be associated with a
[Worker Deployment Version](/worker-versioning#deployment-versions) that has a compute provider configured.
@@ -69,12 +70,13 @@ Temporal impersonates to scale it.
Compute providers are only needed for Serverless Workers. Traditional long-lived Workers do not require a compute
provider because the Worker process lifecycle is not managed by the Temporal server.
-Temporal supports two compute providers:
+Temporal supports three compute providers:
-| Provider | Description |
-| ------------- | ----------------------------------------------------------------------------- |
-| AWS Lambda | Temporal assumes an IAM role in your AWS account to invoke a Lambda function. |
-| GCP Cloud Run | Temporal scales a Cloud Run [Worker Pool](https://cloud.google.com/run/docs/resource-model#worker-pools) through the Cloud Run admin API. A Worker Pool is its own Cloud Run resource type, distinct from a Service or a Job. |
+| Provider | Description |
+| ------------------------------ | ----------- |
+| AWS Lambda | Temporal assumes an IAM role in your AWS account to invoke a Lambda function. |
+| Amazon Bedrock AgentCore Runtime | Temporal assumes an IAM role in your AWS account to invoke an AgentCore Runtime endpoint. |
+| GCP Cloud Run | Temporal scales a Cloud Run [Worker Pool](https://cloud.google.com/run/docs/resource-model#worker-pools) through the Cloud Run admin API. A Worker Pool is its own Cloud Run resource type, distinct from a Service or a Job. |
## How Serverless invocation works {/* #how-invocation-works */}
@@ -167,6 +169,7 @@ short-lived invocations on AWS Lambda, or long-lived pool instances on GCP Cloud
Refer to the lifecycle section for your compute provider:
- [AWS Lambda lifecycle](/serverless-workers/aws-lambda#lifecycle)
+- [Amazon Bedrock AgentCore Runtime lifecycle](/serverless-workers/agentcore#lifecycle)
- [GCP Cloud Run lifecycle](/serverless-workers/cloud-run#lifecycle)
## Failure handling {/* #failure-handling */}
@@ -207,9 +210,9 @@ With single-slot configuration, each Activity gets a dedicated execution environ
| Constraint | Detail |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| Activity duration | Depends on the compute provider. On AWS Lambda, an Activity must finish within the invocation limit (15 minutes maximum), minus the shutdown deadline buffer. On GCP Cloud Run, instances are long-lived, so no per-invocation limit applies. See [Worker lifecycle](#worker-lifecycle). |
+| Activity duration | Depends on the compute provider. On AWS Lambda, an Activity must finish within the invocation limit (15 minutes maximum), minus the shutdown deadline buffer. On Amazon Bedrock AgentCore Runtime, a microVM session has a maximum lifetime of 8 hours. On GCP Cloud Run, instances are long-lived, so no per-invocation limit applies. See [Worker lifecycle](#worker-lifecycle). |
| Workflow duration | No limit. Workflows of any duration work. A Workflow runs across as many Workers as needed. |
-| Worker code | Same Temporal SDK Worker code, using the serverless Worker package for your SDK. |
+| Worker code | Depends on the compute provider. AWS Lambda uses a serverless Worker package for your SDK. Amazon Bedrock AgentCore Runtime and GCP Cloud Run run standard long-lived Temporal Workers inside provider-specific runtime infrastructure. |
| Versioning | [Worker Versioning](/worker-versioning) is required. Each Workflow must have an `AutoUpgrade` or `Pinned` behavior, set per-Workflow or as a Worker-level default. See [Worker Versioning](/worker-versioning) for rollout strategies such as ramping, and [Worker Versioning with Serverless Workers](#worker-versioning-with-serverless-workers) for how Worker Deployment Versions map to compute provider primitives. |
| High Availability | On failover of a Namespace with [Multi-region or Multi-cloud Replication](/cloud/high-availability), the WCI keeps invoking Workers in the original region unless you manually repoint the compute provider. Compute provider configuration, such as a Lambda ARN or a Cloud Run Worker Pool, is scoped to a single region. See [Serverless Workers and High Availability](/cloud/high-availability#serverless-workers). |
@@ -221,4 +224,5 @@ How Worker Deployment Versions map to compute provider primitives differs by pro
Refer to the versioning section for your compute provider:
- [AWS Lambda versioning](/serverless-workers/aws-lambda#worker-versioning)
+- [Amazon Bedrock AgentCore Runtime versioning](/serverless-workers/agentcore#worker-versioning)
- [GCP Cloud Run versioning](/serverless-workers/cloud-run#worker-versioning)
diff --git a/docs/encyclopedia/workers/serverless-workers/serverless-workers-agentcore.mdx b/docs/encyclopedia/workers/serverless-workers/serverless-workers-agentcore.mdx
new file mode 100644
index 0000000000..6f0577e42a
--- /dev/null
+++ b/docs/encyclopedia/workers/serverless-workers/serverless-workers-agentcore.mdx
@@ -0,0 +1,109 @@
+---
+id: serverless-workers-agentcore
+title: Serverless Workers on Amazon Bedrock AgentCore Runtime
+sidebar_label: Amazon Bedrock AgentCore
+description:
+ How Serverless Workers run on Amazon Bedrock AgentCore Runtime, including Worker Versioning and Runtime session
+ lifecycle.
+slug: /serverless-workers/agentcore
+toc_max_heading_level: 4
+tags:
+ - Workers
+ - Concepts
+ - Serverless
+ - Amazon Bedrock AgentCore
+---
+
+import { ReleaseNoteHeader } from '@site/src/components';
+
+
+ Amazon Bedrock AgentCore Runtime support is in Pre-release, and its APIs may change in backwards-incompatible ways.
+
+
+This page covers how Serverless Workers run on Amazon Bedrock AgentCore Runtime, including Worker Versioning and the
+Runtime session lifecycle.
+
+To deploy a Worker, see
+[Deploy a Serverless Worker on Amazon Bedrock AgentCore Runtime](/production-deployment/worker-deployments/serverless-workers/agentcore).
+
+On AgentCore Runtime, a Serverless Worker is a standard long-running Temporal Worker that runs inside an AgentCore
+Runtime session. When the [Worker Controller Instance (WCI)](/serverless-workers#worker-controller-instance) needs
+capacity, it invokes an AgentCore Runtime endpoint. The Runtime starts a Worker, which connects to the Temporal Service
+and polls its Task Queue.
+
+## Autoscaling {/* #autoscaling */}
+
+AgentCore Runtime uses the same event-driven autoscaling model as AWS Lambda. The WCI invokes individual Runtime
+sessions when it needs more capacity. It does not manage a target-sized pool of Runtime sessions. For the shared
+autoscaling behavior, see [Autoscaling for Serverless Workers on AWS Lambda](/serverless-workers/aws-lambda#autoscaling).
+
+## Worker Versioning {/* #worker-versioning */}
+
+Serverless Workers require [Worker Versioning](/worker-versioning). Associate each Worker Deployment Version with a
+named AgentCore Runtime endpoint that points to one AgentCore Runtime version.
+
+AgentCore creates an immutable Runtime version when you create or update a Runtime. A named endpoint has a stable ARN
+and points to a chosen Runtime version. Configure the endpoint ARN as the compute provider for the corresponding Worker
+Deployment Version:
+
+```bash
+temporal worker deployment create-version \
+ --deployment-name my-worker \
+ --build-id v1 \
+ --aws-agentcore-endpoint-arn \
+ --aws-agentcore-assume-role-arn \
+ --aws-agentcore-assume-role-external-id
+```
+
+Use one named endpoint for each Worker Deployment Version. For example, point an endpoint named `temporal-v1` at
+AgentCore Runtime version `1` and use its ARN for Temporal Worker Deployment Version `my-worker/v1`.
+
+When you deploy new Worker code, AgentCore creates a new Runtime version. Create another endpoint that points to that
+new Runtime version and configure it on a new Worker Deployment Version. Keep the older endpoint while Pinned
+Workflows can still need the older Worker code.
+
+:::caution
+
+Do not configure a live Worker Deployment Version with AgentCore's `DEFAULT` endpoint. That endpoint moves to the
+latest Runtime version whenever you update the Runtime. Updating code behind a Worker Deployment Version can cause
+non-determinism errors for in-flight Workflows, including Pinned Workflows.
+
+:::
+
+For details about AgentCore Runtime versions and endpoints, see [AgentCore Runtime versioning and
+endpoints](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/agent-runtime-versioning.html).
+
+## Lifecycle {/* #lifecycle */}
+
+An AgentCore Runtime session is the compute that runs a Worker, not a durable place to store Workflow state. AgentCore
+can resume a session on new compute after the previous compute ends, and a later Task can run on another Worker. Keep
+state that a Workflow needs in the Workflow or another durable store.
+
+Unlike an AWS Lambda Worker, an AgentCore Worker does not have a fixed Lambda invocation deadline. Your Runtime handler
+starts the Worker as background work. The Worker polls until it drains or AgentCore ends its compute.
+
+Two sets of controls determine when that Worker stops:
+
+- **Worker idle and graceful-shutdown policy**: Your Worker implementation decides when it has been idle, stops
+ polling, and waits for in-flight Activities to complete.
+- **AgentCore lifecycle settings**: AgentCore can end the session or its compute before the Worker policy does.
+
+The AgentCore lifecycle settings are:
+
+- **Idle Runtime session timeout**: Ends a Runtime session after it has not received an AgentCore Runtime invocation for
+ the configured duration. The default is 15 minutes. This is not a Temporal Worker idle timer: polling the Temporal
+ Service does not reset it.
+- **Maximum lifetime**: Ends the compute running a Runtime session after the configured duration. The default and
+ maximum is 8 hours. AgentCore can resume the session on new compute after that.
+
+AgentCore's session idle timeout does not replace a Worker idle policy. It resets with AgentCore Runtime invocations
+and does not measure Task Queue activity. To control how long an unused Worker polls, implement a separate shutdown
+policy: when its idle condition is met, stop polling and drain in-flight Activities before the Runtime handler returns.
+Choose the idle period and drain timeout for your workload, and account for the AgentCore maximum lifetime.
+
+Configure Activity timeouts and, for long-running Activities,
+[Activity Heartbeats](/encyclopedia/detecting-activity-failures#activity-heartbeat) so a retry can recover if AgentCore
+ends the compute before an Activity completes.
+
+For the lifecycle setting ranges and defaults, see [Configure Amazon Bedrock AgentCore lifecycle
+settings](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-lifecycle-settings.html).
diff --git a/docs/guides/durable-agent-on-agentcore.mdx b/docs/guides/durable-agent-on-agentcore.mdx
new file mode 100644
index 0000000000..b996fae4d7
--- /dev/null
+++ b/docs/guides/durable-agent-on-agentcore.mdx
@@ -0,0 +1,428 @@
+---
+id: durable-agent-on-agentcore
+title: Build a durable agent on Amazon Bedrock AgentCore
+sidebar_label: Durable agent on AgentCore
+description: A Temporal Workflow preserves conversation state while AgentCore Runtime supplies serverless Worker compute for a Strands agent.
+toc_max_heading_level: 3
+author: n/a
+tags:
+ - Workflows
+ - Activities
+ - Workers
+ - Python SDK
+ - Strands Agents
+ - Serverless
+---
+
+import { ReleaseNoteHeader } from '@site/src/components';
+
+
+ Amazon Bedrock AgentCore Runtime support is in Pre-release, and its APIs may change in backwards-incompatible ways.
+
+
+This guide builds a data-analysis agent that can continue a conversation after the compute running it has stopped. A
+Temporal Workflow holds the conversation and coordinates each turn. Strands defines how the agent uses a model and
+tools. Amazon Bedrock AgentCore Runtime supplies serverless compute for the Temporal Worker, and AgentCore Code
+Interpreter supplies an isolated environment for running code.
+
+The result separates the lifetime of the agent from the lifetime of its compute. The Workflow can remain open for days
+or months without keeping an AgentCore Runtime active.
+
+## See what you will build
+
+The agent has one Workflow Execution for each conversation. A client sends prompts to an `ask` Update handler and
+receives the agent's answer as the Update result. The Workflow waits without using Worker compute between prompts.
+
+When a prompt arrives and no Worker is polling, Temporal Cloud starts Worker capacity on AgentCore Runtime. The Worker
+reconstructs the Workflow from its Event History, runs the next agent turn, and retires after it becomes idle. A later
+prompt can run on a different Worker without starting a new conversation.
+
+```mermaid
+sequenceDiagram
+ participant Client
+ participant Temporal as Temporal Cloud
+ participant Runtime1 as AgentCore Runtime A
+ participant AWS as Bedrock and Code Interpreter
+ participant Runtime2 as AgentCore Runtime B
+
+ Client->>Temporal: Start conversation Workflow
+ Temporal->>Runtime1: Start Worker capacity
+ Client->>Temporal: Update: ask first question
+ Runtime1->>AWS: Model and tool Activities
+ AWS-->>Runtime1: Results
+ Runtime1-->>Temporal: Update result
+ Temporal-->>Client: First answer
+ Runtime1-->>Runtime1: Become idle and drain
+ Note over Temporal: Workflow waits without Worker compute
+ Client->>Temporal: Update: ask follow-up question
+ Temporal->>Runtime2: Start new Worker capacity
+ Runtime2->>Temporal: Replay Event History
+ Runtime2->>AWS: Model and tool Activities
+ AWS-->>Runtime2: Results
+ Runtime2-->>Temporal: Update result
+ Temporal-->>Client: Follow-up answer
+```
+
+Start with the
+[durable AgentCore sample](https://github.com/temporalio/documentation-sdk-code-examples/tree/docs/durable-agent-agentcore-sample/python-agentcore-durable-agent).
+It contains the AgentCore project, Runtime handler, IAM policy, and Code Interpreter Activity used in this guide.
+
+You need Python 3.10 or later, `uv`, AWS credentials, access to a Bedrock model, and a local Temporal development server.
+Follow [Set up your local Python environment](/develop/python/set-up-your-local-python) before continuing.
+
+Clone the sample repository and install the application dependencies:
+
+```bash
+git clone https://github.com/temporalio/documentation-sdk-code-examples.git
+cd documentation-sdk-code-examples/python-agentcore-durable-agent
+uv sync
+```
+
+## Give each system one job
+
+The three systems operate at different levels:
+
+| System | Job in this application |
+|---|---|
+| Strands Agents | Defines the system prompt, tools, model interaction, and agent loop for one turn. |
+| Temporal | Gives the conversation a durable identity, persists its progress, delivers later prompts, and retries model and tool calls as Activities. |
+| AgentCore Runtime | Starts isolated AWS compute that hosts a Temporal Worker when the Task Queue needs capacity. |
+
+Amazon Bedrock performs model inference. AgentCore Code Interpreter runs code in a managed sandbox when the model
+chooses that tool.
+
+The Workflow Id is the durable identity of the agent conversation. An AgentCore Runtime session is compute that can
+host a Worker for part of that conversation. Do not require the same Runtime session or Worker process to handle every
+turn.
+
+## Build the agent locally
+
+The [durable AgentCore sample](https://github.com/temporalio/documentation-sdk-code-examples/tree/docs/durable-agent-agentcore-sample/python-agentcore-durable-agent)
+defines `execute_code` as a Temporal Activity. It uses the Workflow Id as the Code Interpreter session name so two
+Workflow Executions handled by the same process do not share a sandbox. The name does not make the sandbox durable
+across Worker replacement.
+
+
+[python-agentcore-durable-agent/activities.py](https://github.com/temporalio/documentation-sdk-code-examples/blob/docs/durable-agent-agentcore-sample/python-agentcore-durable-agent/activities.py)
+```py
+@activity.defn
+def execute_code(
+ code: str, language: LanguageType = LanguageType.PYTHON
+) -> dict[str, Any]:
+ interpreter = AgentCoreCodeInterpreter(
+ region=os.environ.get("AWS_REGION", "us-west-2"),
+ session_name=activity.info().workflow_id,
+ )
+ return interpreter.execute_code(
+ ExecuteCodeAction(type="executeCode", code=code, language=language)
+ )
+
+
+```
+
+
+The Activity boundary gives the tool call a separate timeout, Retry Policy, and result in Event History. It also keeps
+AWS calls out of deterministic Workflow code.
+
+Define a Workflow that accepts multiple prompts:
+
+
+[python-agentcore-durable-agent/workflows.py](https://github.com/temporalio/documentation-sdk-code-examples/blob/docs/durable-agent-agentcore-sample/python-agentcore-durable-agent/workflows.py)
+```py
+@workflow.defn
+class DurableAgentWorkflow:
+ def __init__(self) -> None:
+ self._done = False
+ self._lock = asyncio.Lock()
+ self._agent = TemporalAgent(
+ model="bedrock",
+ start_to_close_timeout=timedelta(seconds=60),
+ system_prompt=SYSTEM_PROMPT,
+ tools=[
+ activity_as_tool(
+ execute_code,
+ start_to_close_timeout=timedelta(minutes=2),
+ )
+ ],
+ )
+
+ @workflow.update
+ async def ask(self, prompt: str) -> str:
+ async with self._lock:
+ result = await self._agent.invoke_async(prompt)
+ return str(result).strip()
+
+ @workflow.signal
+ def finish(self) -> None:
+ self._done = True
+
+ @workflow.run
+ async def run(self) -> None:
+ await workflow.wait_condition(lambda: self._done)
+ await workflow.wait_condition(workflow.all_handlers_finished)
+
+
+```
+
+
+`TemporalAgent` is a Strands `Agent` adapted to run inside a Workflow. It retains the Strands message list between
+calls to `invoke_async`. The Temporal Strands plugin runs model calls as Activities, and `activity_as_tool` runs the
+Code Interpreter tool as an Activity. Configure retries through Temporal Activity Retry Policies rather than a Strands
+retry strategy.
+
+The lock makes the agent process one prompt at a time. The `run` method waits until the `finish` Signal arrives, so the
+Workflow remains available between turns. This wait is durable and does not keep a Python process running.
+
+Register `DurableAgentWorkflow`, `execute_code`, and `StrandsPlugin` on a local Worker. The
+[sample Worker](https://github.com/temporalio/documentation-sdk-code-examples/blob/docs/durable-agent-agentcore-sample/python-agentcore-durable-agent/local_worker.py)
+also creates the executor required by the synchronous `execute_code` Activity:
+
+
+[python-agentcore-durable-agent/local_worker.py](https://github.com/temporalio/documentation-sdk-code-examples/blob/docs/durable-agent-agentcore-sample/python-agentcore-durable-agent/local_worker.py)
+```py
+async def main() -> None:
+ client = await Client.connect(
+ "localhost:7233",
+ plugins=[StrandsPlugin()],
+ )
+
+ with ThreadPoolExecutor(max_workers=4) as activity_executor:
+ worker = Worker(
+ client,
+ task_queue=TASK_QUEUE,
+ workflows=[DurableAgentWorkflow],
+ activities=[execute_code],
+ activity_executor=activity_executor,
+ )
+ await worker.run()
+
+
+```
+
+
+Start the Temporal development server, then start the Worker in another terminal:
+
+```bash
+temporal server start-dev
+```
+
+```bash
+uv run python local_worker.py
+```
+
+The sample's chat client starts a Workflow and sends each prompt as an Update:
+
+
+[python-agentcore-durable-agent/chat.py](https://github.com/temporalio/documentation-sdk-code-examples/blob/docs/durable-agent-agentcore-sample/python-agentcore-durable-agent/chat.py)
+```py
+async def main() -> None:
+ client = await Client.connect(
+ "localhost:7233",
+ plugins=[StrandsPlugin()],
+ )
+ handle = await client.start_workflow(
+ DurableAgentWorkflow.run,
+ id=f"durable-agent-{uuid.uuid4()}",
+ task_queue=TASK_QUEUE,
+ )
+
+ while prompt := input("You: "):
+ if prompt == "/finish":
+ await handle.signal(DurableAgentWorkflow.finish)
+ return
+ answer = await handle.execute_update(DurableAgentWorkflow.ask, prompt)
+ print(f"Agent: {answer}")
+
+
+```
+
+
+Run the client in a third terminal:
+
+```bash
+uv run python chat.py
+```
+
+Ask a question that requires calculation, then ask a follow-up that depends on the first answer. Enter `/finish` to
+close the Workflow. In the Temporal Web UI, the Event History shows the `ask` Update, model Activities, and
+`execute_code` Activity for each turn.
+
+## Run the Worker on AgentCore Runtime
+
+Local development uses a continuously running Worker. On AgentCore Runtime, the Worker starts inside the Runtime's HTTP
+handler and returns when its idle policy decides to release the compute.
+
+The AgentCore Runtime handler registers the `DurableAgentWorkflow` and `execute_code` definitions from
+[Build the agent locally](#build-the-agent-locally). It adds Worker Versioning and the Activity-based idle tracker from
+the [Python AgentCore Worker guide](/develop/python/workers/serverless-workers/agentcore#stop-and-drain-the-worker), then
+runs the Worker inside the Runtime handler:
+
+
+[python-agentcore-durable-agent/agentcore_worker.py](https://github.com/temporalio/documentation-sdk-code-examples/blob/docs/durable-agent-agentcore-sample/python-agentcore-durable-agent/agentcore_worker.py)
+```py
+@app.entrypoint
+@app.async_task
+async def invoke(payload: dict) -> dict:
+ client = await Client.connect(
+ required_env("TEMPORAL_ADDRESS"),
+ namespace=required_env("TEMPORAL_NAMESPACE"),
+ api_key=required_env("TEMPORAL_API_KEY"),
+ tls=True,
+ plugins=[StrandsPlugin()],
+ )
+ tracker = ActivityTracker()
+
+ with ThreadPoolExecutor(max_workers=4) as activity_executor:
+ worker = Worker(
+ client,
+ task_queue=os.environ.get("TEMPORAL_TASK_QUEUE", TASK_QUEUE),
+ workflows=[DurableAgentWorkflow],
+ activities=[execute_code],
+ activity_executor=activity_executor,
+ interceptors=[tracker],
+ deployment_config=WorkerDeploymentConfig(
+ version=WorkerDeploymentVersion(
+ deployment_name=os.environ.get(
+ "TEMPORAL_DEPLOYMENT_NAME", DEPLOYMENT_NAME
+ ),
+ build_id=os.environ.get("TEMPORAL_BUILD_ID", BUILD_ID),
+ ),
+ use_worker_versioning=True,
+ default_versioning_behavior=VersioningBehavior.PINNED,
+ ),
+ graceful_shutdown_timeout=DRAIN,
+ )
+ async with worker:
+ await tracker.wait_until_idle(DEBOUNCE)
+
+ return {"message": "Worker drained"}
+
+
+```
+
+
+The invocation payload does not contain a user prompt. Temporal invokes the Runtime endpoint to add Worker capacity.
+Clients continue to start and message Workflows through the Temporal Client.
+
+The Runtime does not need a copy of the conversation in a local file or global variable. When a new Worker receives a
+Workflow Task, Temporal replays the Workflow's Event History and restores the `TemporalAgent` message list before new
+model or tool calls run.
+
+## Deploy the Serverless Worker
+
+Install the AgentCore CLI and generate the CDK project used by the sample's Runtime definition:
+
+```bash
+npm install -g @aws/agentcore
+./bootstrap-agentcore-project.sh
+```
+
+Follow [Deploy a Serverless Worker on Amazon Bedrock AgentCore Runtime](/production-deployment/worker-deployments/serverless-workers/agentcore)
+to deploy the existing AgentCore project and configure its Worker Deployment Version.
+
+For this application, use the same values in each place:
+
+| Setting | Tutorial value |
+|---|---|
+| Runtime entrypoint | `agentcore_worker.py` |
+| Task Queue | `durable-agent` |
+| Worker Deployment name | `durable-agent-agentcore` |
+| Build ID | A version for this code, such as `1.0.0` |
+
+The AgentCore Runtime execution role needs permission to invoke Bedrock and Code Interpreter. The separate role that
+Temporal Cloud assumes needs permission to invoke the AgentCore Runtime endpoint. The deployment guide creates and
+configures the second role.
+
+## Talk to the deployed agent
+
+Start one conversation Workflow. This command returns immediately while the Workflow remains open:
+
+```bash
+temporal workflow start \
+ --workflow-id durable-agent-alice \
+ --type DurableAgentWorkflow \
+ --task-queue durable-agent
+```
+
+Send the first prompt as an Update and wait for the reply:
+
+```bash
+temporal workflow update execute \
+ --workflow-id durable-agent-alice \
+ --name ask \
+ --input '"A film festival has 7 screens with 4 showings per screen. How many screenings can it schedule?"'
+```
+
+Temporal starts AgentCore Worker capacity because the Task Queue has work. After the turn completes and the idle period
+expires, the Runtime handler drains the Worker and returns. Confirm this in the AgentCore logs:
+
+```bash
+agentcore logs --runtime
+```
+
+After the Worker has retired, send a follow-up that depends on the first turn:
+
+```bash
+temporal workflow update execute \
+ --workflow-id durable-agent-alice \
+ --name ask \
+ --input '"If we add two screenings to the total you calculated, what is the new total?"'
+```
+
+Temporal starts capacity again. The new Worker reconstructs the existing Workflow and its Strands messages, so the
+agent can interpret "the total you calculated" without depending on the previous Worker process.
+
+End the conversation when it no longer needs to accept prompts:
+
+```bash
+temporal workflow signal \
+ --workflow-id durable-agent-alice \
+ --name finish
+```
+
+## Test recovery
+
+Worker retirement between turns tests one form of recovery. You can also interrupt compute while a model or tool
+Activity is running. Start a prompt that takes long enough to observe, find the active Runtime session identifier in the
+AgentCore logs, and stop that session:
+
+```bash
+aws bedrock-agentcore stop-runtime-session \
+ --agent-runtime-arn \
+ --runtime-session-id \
+ --region
+```
+
+For the required IAM permission and API behavior, see
+[Stop a running session](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-stop-session.html).
+
+The Activity attempt running on that Worker is interrupted. Temporal keeps the Workflow state and schedules the
+Activity again according to its Retry Policy. Serverless Workers starts new AgentCore capacity to process the Task. In
+the Temporal Web UI, inspect the Activity attempts and confirm that the Workflow continues without restarting the
+conversation.
+
+An Activity can run more than once if its Worker stops after making an external change but before reporting completion.
+Use an idempotency key for tools that change external state. The Workflow Id plus a stable operation identifier is a
+common choice. Code execution used only to calculate an answer does not make an external business change, so it is a
+safe recovery demonstration.
+
+## Decide where state belongs
+
+Place state according to how long it must survive and which system uses it:
+
+| State | Location | Reason |
+|---|---|---|
+| Current conversation and agent progress | Temporal Workflow | It must survive Worker and Runtime replacement. |
+| Completed model and tool call results | Temporal Event History | Activity results let replay restore completed progress without repeating successful calls. |
+| Approvals, timers, and long waits | Temporal Workflow | These are part of the agent's durable control flow. |
+| Knowledge shared across conversations | [AgentCore Memory](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/memory.html), accessed from an Activity | It belongs to the user or application rather than one Workflow Execution. |
+| Credentials for AWS and external systems | [AgentCore Identity](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/identity.html) or an AWS secret store | Workflow state should not contain credentials. |
+| Tool access and authorization | [AgentCore Gateway](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway.html) and [Policy](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/policy.html) | These services control how tools are reached and whether a call is allowed. |
+| Temporary Worker caches | AgentCore Runtime session | They can improve performance but must be safe to lose. |
+| Code Interpreter variables and files | Code Interpreter session | They last only for that tool session. Store required outputs durably before relying on them later. |
+| Large files and datasets | Object storage, with a reference in the Workflow | Event History is not intended for large application objects. |
+
+The Strands message list is Workflow state in this design. Temporal reconstructs it through Event History when another
+Worker continues the Workflow. Do not use Event History as unlimited chat or object storage. For conversations that
+accumulate many turns, use [Continue-As-New](/develop/python/integrations/strands-agents#handle-long-running-chat-sessions)
+to start a new Event History while carrying forward the messages the next execution needs.
diff --git a/docs/production-deployment/worker-deployments/index.mdx b/docs/production-deployment/worker-deployments/index.mdx
index 4a4ecb9a1f..f70742770f 100644
--- a/docs/production-deployment/worker-deployments/index.mdx
+++ b/docs/production-deployment/worker-deployments/index.mdx
@@ -30,7 +30,7 @@ You can optionally use the Temporal [Worker Controller](/production-deployment/w
This section also covers specific Worker Deployment examples:
- [**Serverless Workers**](/production-deployment/worker-deployments/serverless-workers)
- Deploy Serverless Workers on serverless compute like AWS Lambda.
+ Deploy Serverless Workers on AWS Lambda, GCP Cloud Run, or Amazon Bedrock AgentCore Runtime.
Temporal invokes your Worker when Tasks arrive, with no long-lived processes to manage.
- [**Deploy Workers to Amazon EKS**](/production-deployment/worker-deployments/deploy-workers-to-aws-eks)
diff --git a/docs/production-deployment/worker-deployments/serverless-workers/agentcore.mdx b/docs/production-deployment/worker-deployments/serverless-workers/agentcore.mdx
new file mode 100644
index 0000000000..4655bfde08
--- /dev/null
+++ b/docs/production-deployment/worker-deployments/serverless-workers/agentcore.mdx
@@ -0,0 +1,252 @@
+---
+id: agentcore
+title: Deploy a Serverless Worker on Amazon Bedrock AgentCore Runtime
+sidebar_label: Amazon Bedrock AgentCore
+description: Deploy an existing Python Worker to AgentCore Runtime and configure Temporal Cloud to start capacity when Task Queue demand increases.
+slug: /production-deployment/worker-deployments/serverless-workers/agentcore
+toc_max_heading_level: 4
+tags:
+ - Workers
+ - Deploy
+ - Serverless
+ - Amazon Bedrock AgentCore
+---
+
+import { ReleaseNoteHeader } from '@site/src/components';
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+ Amazon Bedrock AgentCore Runtime support is in Pre-release, and its APIs may change in backwards-incompatible ways.
+
+
+This guide deploys an existing Python [Serverless Worker](/serverless-workers) to Amazon Bedrock AgentCore Runtime and
+configures Temporal Cloud to start Worker capacity. It assumes that you already have a Temporal Worker and an AgentCore
+project. For the Worker implementation and lifecycle, see
+[Serverless Workers on Amazon Bedrock AgentCore Runtime - Python SDK](/develop/python/workers/serverless-workers/agentcore).
+
+If you are still deciding how to structure your agent, Workflow, and Activities, see the
+[Python Strands AgentCore sample](https://github.com/temporalio/samples-python/tree/schoeff/strands-agent/bedrock_agentcore/strands-agent)
+for a complete application.
+
+## Prerequisites {/* #prerequisites */}
+
+- A Temporal Cloud account with an AWS-hosted Namespace and access to the AgentCore Serverless Workers Pre-release.
+- A Temporal Cloud API key that can connect to the Namespace.
+- [Temporal CLI v1.8.3](https://github.com/temporalio/cli/releases/tag/v1.8.3) or later, configured for your Namespace.
+- An existing Python Temporal Worker with an
+ [AgentCore Runtime handler](/develop/python/workers/serverless-workers/agentcore#runtime-handler).
+- An AgentCore project that packages the Worker and contains `agentcore/agentcore.json`, `agentcore/aws-targets.json`,
+ and the generated AgentCore CDK project.
+- An AWS account in an [AgentCore-supported Region](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/agentcore-regions.html).
+- The [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) installed and configured
+ with credentials for that account.
+- Node.js 20 or later and the [AgentCore CLI](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/agentcore-get-started-cli.html)
+ installed with `npm install -g @aws/agentcore`.
+- The [AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/getting-started.html) installed and bootstrapped in the target
+ account and Region.
+- Permission to create AgentCore resources, CloudFormation stacks, and IAM roles. See
+ [IAM permissions for AgentCore Runtime](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-permissions.html).
+
+## 1. Configure the Worker Runtime {/* #configure-worker-runtime */}
+
+In `agentcore/agentcore.json`, configure the Runtime with the Temporal connection, Task Queue, Worker Deployment name,
+and Build ID:
+
+```json
+{
+ "name": "TEMPORAL_ADDRESS",
+ "value": "..tmprl.cloud:7233"
+},
+{
+ "name": "TEMPORAL_NAMESPACE",
+ "value": "."
+},
+{
+ "name": "TEMPORAL_API_KEY",
+ "value": ""
+},
+{
+ "name": "TEMPORAL_TASK_QUEUE",
+ "value": ""
+},
+{
+ "name": "TEMPORAL_DEPLOYMENT_NAME",
+ "value": ""
+},
+{
+ "name": "TEMPORAL_BUILD_ID",
+ "value": ""
+}
+```
+
+The Task Queue must match the Task Queue used by your application. The deployment name and Build ID must match the
+Worker Deployment Version that you create in [Step 4](#create-worker-deployment-version).
+
+The Runtime definition must use your Worker handler as its entrypoint and provide a named endpoint for Temporal. The
+following fragment uses a public network so the Worker can reach Temporal Cloud:
+
+```json
+{
+ "entrypoint": "agentcore_worker.py",
+ "networkMode": "PUBLIC",
+ "protocol": "HTTP",
+ "authorizerType": "AWS_IAM",
+ "endpoints": {
+ "temporal": {
+ "version": 1,
+ "description": "Invoked by Temporal Cloud Serverless Workers"
+ }
+ }
+}
+```
+
+If you use a VPC instead, configure outbound access from the VPC to your Temporal Cloud Namespace. Temporal invokes the
+named endpoint by assuming the IAM role that you create in [Step 3](#configure-iam).
+
+Do not commit a populated Temporal Cloud API key. For a production deployment, store it in AWS Secrets Manager, grant
+the Runtime execution role permission to read it, and load it in the Runtime handler. The Runtime execution role is
+separate from the invocation role that Temporal assumes.
+
+## 2. Deploy the Worker Runtime {/* #deploy-runtime */}
+
+From the AgentCore project directory, validate and deploy the project:
+
+```bash
+agentcore validate
+agentcore deploy --target -y
+```
+
+AgentCore packages the Worker and its dependencies, deploys the Runtime, and creates the named endpoint.
+
+Check the deployed resources:
+
+```bash
+agentcore status --runtime --json
+agentcore status --type runtime-endpoint --json
+```
+
+Record the Runtime ARN and the ARN of the named endpoint. You use the Runtime ARN to scope the invocation role and give
+the endpoint ARN to Temporal Cloud.
+
+## 3. Grant Temporal permission to invoke the Runtime {/* #configure-iam */}
+
+Temporal Cloud assumes an IAM role in your AWS account to get the named endpoint and invoke the Runtime. Choose an
+External ID of at least five characters. Use the same value in the role trust policy and the Worker Deployment Version.
+The External ID prevents a [confused deputy](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html)
+attack.
+
+[Download the CloudFormation template](/files/temporal-cloud-serverless-worker-agentcore-role.yaml), then deploy it.
+Pass the Runtime ARN with a trailing wildcard so the policy covers the Runtime and its endpoints:
+
+```bash
+aws cloudformation create-stack \
+ --stack-name \
+ --template-body file://temporal-cloud-serverless-worker-agentcore-role.yaml \
+ --parameters \
+ ParameterKey=AssumeRoleExternalId,ParameterValue= \
+ ParameterKey=AgentRuntimeARNs,ParameterValue='*' \
+ --capabilities CAPABILITY_NAMED_IAM \
+ --region
+```
+
+Wait for the CloudFormation stack to finish:
+
+```bash
+aws cloudformation wait stack-create-complete \
+ --stack-name \
+ --region
+```
+
+Then retrieve the invocation role ARN:
+
+```bash
+aws cloudformation describe-stacks \
+ --stack-name \
+ --query 'Stacks[0].Outputs[?OutputKey==`RoleARN`].OutputValue' \
+ --output text \
+ --region
+```
+
+The role grants `bedrock-agentcore:InvokeAgentRuntime` and `bedrock-agentcore:GetAgentRuntimeEndpoint` on the configured
+Runtime resources. This role does not run the Worker code.
+
+## 4. Create the Worker Deployment Version {/* #create-worker-deployment-version */}
+
+Create a [Worker Deployment Version](/production-deployment/worker-deployments/worker-versioning) whose compute
+configuration points to the named AgentCore Runtime endpoint.
+
+
+
+
+In the Temporal Cloud UI, open your Namespace and select **Workers** > **Create Worker Deployment**. Provide these
+values:
+
+- **Name**: the value of `TEMPORAL_DEPLOYMENT_NAME` in the Runtime environment.
+- **Build ID**: the value of `TEMPORAL_BUILD_ID` in the Runtime environment.
+- **Compute Provider**: select **Amazon Bedrock AgentCore Runtime**.
+- **Runtime endpoint ARN**: the named endpoint ARN from [Step 2](#deploy-runtime).
+- **IAM role ARN**: the invocation role ARN from [Step 3](#configure-iam).
+- **External ID**: the External ID from [Step 3](#configure-iam).
+
+Save the Worker Deployment. When you create a version through the UI, the version is automatically current. Continue
+to [Step 6](#verify-worker-startup).
+
+
+
+
+First, create the Worker Deployment if it does not already exist:
+
+```bash
+temporal worker deployment create \
+ --namespace \
+ --name
+```
+
+Then create the version with the AgentCore compute configuration:
+
+```bash
+temporal worker deployment create-version \
+ --namespace \
+ --deployment-name \
+ --build-id \
+ --aws-agentcore-endpoint-arn \
+ --aws-agentcore-assume-role-arn \
+ --aws-agentcore-assume-role-external-id
+```
+
+The deployment name and Build ID must match the values in the Runtime environment.
+
+
+
+
+To check whether Temporal can reach the endpoint, open the Worker Deployment Version in the Temporal Cloud UI and
+select **Actions** > **Validate Connection**. This checks that Temporal can assume the invocation role, get the named
+endpoint, and invoke the Runtime.
+
+## 5. Set the version as current {/* #set-current-version */}
+
+If you used the Temporal CLI, set the version as current:
+
+```bash
+temporal worker deployment set-current-version \
+ --namespace \
+ --deployment-name \
+ --build-id
+```
+
+This command asks you to confirm because it changes which version receives new Tasks. Pass `--yes` to skip the prompt.
+If you created the version in the Temporal Cloud UI, it is already current.
+
+## 6. Verify Worker startup {/* #verify-worker-startup */}
+
+Submit work to the configured Task Queue using your application. When no Worker is polling, Temporal invokes the named
+AgentCore Runtime endpoint. The Runtime starts the Worker, and the Worker polls and processes Tasks.
+
+You can confirm the deployment in these places:
+
+- **Temporal Cloud UI**: Open the Worker Deployment Version and confirm that the connection is valid and a Worker has
+ polled the Task Queue.
+- **AgentCore logs**: Run `agentcore logs --runtime ` to see the Worker start and process Tasks.
+- **Temporal CLI**: Run `temporal worker deployment describe --name ` to inspect the deployment and
+ current version.
diff --git a/docs/production-deployment/worker-deployments/serverless-workers/index.mdx b/docs/production-deployment/worker-deployments/serverless-workers/index.mdx
index 1a80f95fcc..8e15a56982 100644
--- a/docs/production-deployment/worker-deployments/serverless-workers/index.mdx
+++ b/docs/production-deployment/worker-deployments/serverless-workers/index.mdx
@@ -15,10 +15,9 @@ tags:
import { ReleaseNoteHeader } from '@site/src/components';
- AWS Lambda support is in Public Preview. GCP Cloud Run support is in Pre-release, and its APIs may change in
- backwards-incompatible ways. To request Cloud Run access, create a [support ticket](/cloud/support#support-ticket) or
- contact your account team, and [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear
- when Cloud Run reaches Public Preview.
+ AWS Lambda support is in Public Preview. Support for GCP Cloud Run and Amazon Bedrock AgentCore Runtime is in
+ Pre-release, and their APIs may change in backwards-incompatible ways. To request access, create a
+ [support ticket](/cloud/support#support-ticket) or contact your account team.
Serverless Workers let you run Temporal Workers on serverless compute. Deploy your Worker code to a serverless provider,
@@ -27,9 +26,8 @@ work on the Task Queue. There is no always-on Worker fleet to provision or scale
Temporal monitors Task Queues that have a compute provider configured. When a Task arrives and no Worker is free to take
it, the [Worker Controller Instance (WCI)](/serverless-workers#how-invocation-works) starts compute. How it starts
-compute is where the providers differ. On AWS Lambda the WCI invokes a function per unit of work, and the Worker exits
-when the invocation window ends. On GCP Cloud Run it resizes a Worker Pool of long-lived instances that poll
-continuously.
+compute is where the providers differ. On AWS Lambda and AgentCore Runtime, the WCI invokes compute in response to
+unmet Task Queue demand. On GCP Cloud Run, it resizes a Worker Pool of long-lived instances that poll continuously.
## Supported providers
@@ -38,3 +36,6 @@ continuously.
- [**GCP Cloud Run**](/production-deployment/worker-deployments/serverless-workers/cloud-run) - Deploy a Serverless
Worker to a Cloud Run Worker Pool. Temporal impersonates a service account in your GCP project to scale the pool as
Tasks arrive and drain.
+- [**Amazon Bedrock AgentCore Runtime**](/production-deployment/worker-deployments/serverless-workers/agentcore) -
+ Deploy a Serverless Worker to AgentCore Runtime. Temporal assumes an IAM role in your AWS account to invoke the
+ Runtime endpoint as Tasks arrive.
diff --git a/sidebars.js b/sidebars.js
index ba42163641..459d22e436 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -638,6 +638,7 @@ const developPythonCategory = {
},
items: [
'develop/python/workers/serverless-workers/aws-lambda',
+ 'develop/python/workers/serverless-workers/agentcore',
'develop/python/workers/serverless-workers/cloud-run',
],
},
@@ -1606,6 +1607,7 @@ module.exports = {
'production-deployment/worker-deployments/serverless-workers/aws-lambda/self-hosted-setup',
],
},
+ 'production-deployment/worker-deployments/serverless-workers/agentcore',
{
type: 'category',
label: 'GCP Cloud Run',
@@ -2014,6 +2016,7 @@ module.exports = {
link: { type: 'doc', id: 'encyclopedia/workers/serverless-workers/serverless-workers' },
items: [
'encyclopedia/workers/serverless-workers/serverless-workers-aws-lambda',
+ 'encyclopedia/workers/serverless-workers/serverless-workers-agentcore',
'encyclopedia/workers/serverless-workers/serverless-workers-cloud-run',
],
},
@@ -2176,6 +2179,7 @@ module.exports = {
id: 'guides/index',
},
items: [
+ 'guides/durable-agent-on-agentcore',
'guides/entity-pattern-loyalty-points',
'guides/recover-without-restart',
'guides/route-specialized-workloads',
diff --git a/snipsync.config.yaml b/snipsync.config.yaml
index a1b6ba5c4f..5968edbb38 100644
--- a/snipsync.config.yaml
+++ b/snipsync.config.yaml
@@ -39,6 +39,9 @@ origins:
ref: 'main'
- owner: temporalio
repo: sdk-go
+ - owner: temporalio
+ repo: documentation-sdk-code-examples
+ ref: docs/durable-agent-agentcore-sample
targets:
- docs
diff --git a/src/components/GuidesGrid/guides-data.json b/src/components/GuidesGrid/guides-data.json
index 9f05d5194e..8e6641a888 100644
--- a/src/components/GuidesGrid/guides-data.json
+++ b/src/components/GuidesGrid/guides-data.json
@@ -1,4 +1,13 @@
[
+ {
+ "name": "Durable agent on AgentCore",
+ "description":
+ "Run a long-lived Strands agent with Temporal and serverless Worker compute on Amazon Bedrock AgentCore.",
+ "tags": ["AI agents"],
+ "sdk": "Python",
+ "href": "/guides/durable-agent-on-agentcore"
+ },
+
{
"name": "Customer loyalty program",
"description":
diff --git a/static/files/temporal-cloud-serverless-worker-agentcore-role.yaml b/static/files/temporal-cloud-serverless-worker-agentcore-role.yaml
new file mode 100644
index 0000000000..a4d5b16504
--- /dev/null
+++ b/static/files/temporal-cloud-serverless-worker-agentcore-role.yaml
@@ -0,0 +1,69 @@
+# CloudFormation template for creating an IAM role that Temporal Cloud can assume to invoke AgentCore runtimes.
+AWSTemplateFormatVersion: '2010-09-09'
+Description:
+ Creates an IAM role that Temporal Cloud can assume to invoke Amazon Bedrock AgentCore runtimes for Serverless Workers.
+
+Parameters:
+ AssumeRoleExternalId:
+ Type: String
+ Description: A string you choose. Use the same value when creating the Worker Deployment Version.
+ AllowedPattern: '[a-zA-Z0-9_+=,.@-]*'
+ MinLength: 5
+ MaxLength: 45
+
+ AgentRuntimeARNs:
+ Type: CommaDelimitedList
+ Description: >-
+ Comma-separated list of AgentCore Runtime ARNs that Temporal may invoke. Append a wildcard to each Runtime ARN
+ to include its endpoints.
+
+ RoleName:
+ Type: String
+ Default: 'Temporal-Cloud-Serverless-Worker'
+
+Resources:
+ TemporalCloudServerlessWorker:
+ Type: AWS::IAM::Role
+ Properties:
+ RoleName: !Sub '${RoleName}-${AWS::StackName}'
+ AssumeRolePolicyDocument:
+ Version: '2012-10-17'
+ Statement:
+ - Effect: Allow
+ Principal:
+ AWS:
+ - arn:aws:iam::902542641901:role/wci-lambda-invoke
+ - arn:aws:iam::160190466495:role/wci-lambda-invoke
+ - arn:aws:iam::819232936619:role/wci-lambda-invoke
+ - arn:aws:iam::829909441867:role/wci-lambda-invoke
+ - arn:aws:iam::354116250941:role/wci-lambda-invoke
+ Action: sts:AssumeRole
+ Condition:
+ StringEquals:
+ 'sts:ExternalId': !Ref AssumeRoleExternalId
+ Description: The role Temporal Cloud uses to invoke AgentCore runtimes for Serverless Workers
+ MaxSessionDuration: 3600
+
+ TemporalCloudAgentCoreInvokePermissions:
+ Type: AWS::IAM::Policy
+ Properties:
+ PolicyName: 'Temporal-Cloud-AgentCore-Invoke-Permissions'
+ PolicyDocument:
+ Version: '2012-10-17'
+ Statement:
+ - Effect: Allow
+ Action:
+ - bedrock-agentcore:InvokeAgentRuntime
+ - bedrock-agentcore:GetAgentRuntimeEndpoint
+ Resource: !Ref AgentRuntimeARNs
+ Roles:
+ - !Ref TemporalCloudServerlessWorker
+
+Outputs:
+ RoleARN:
+ Description: The ARN of the IAM role created for Temporal Cloud
+ Value: !GetAtt TemporalCloudServerlessWorker.Arn
+
+ AgentRuntimeARNs:
+ Description: The AgentCore Runtime ARNs that Temporal may invoke
+ Value: !Join [', ', !Ref AgentRuntimeARNs]