Skip to content

feat(extras): run a job in AgentCore Runtime - #1217

Draft
ParidelPooya wants to merge 11 commits into
mainfrom
feat/agentcore-compute
Draft

ParidelPooya wants to merge 11 commits into
mainfrom
feat/agentcore-compute

Conversation

@ParidelPooya

@ParidelPooya ParidelPooya commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

What

This PR adds a compute operation for Amazon Bedrock AgentCore Runtime. It is the first iteration: one job per call.

  • agentcore(context, name, input, config) in @aws/durable-execution-sdk-js-extras/compute/agentcore.
  • startAgentcoreWorker({ handler, logger?, createClient? }, port?, host?) in @aws/durable-execution-sdk-js-compute-worker/agentcore.

Both subpaths are experimental, like the MicroVM subpaths.

Twin PR: aws/aws-durable-execution-sdk-python#929

Changes since review (round 3)

Commit c26dc289 answers the third review round:

  1. The AgentCore worker wraps the supplied logger with the MicroVM worker's existing safeLogger, which now is exported inside the package. A logger method that throws, or that returns a rejected promise, cannot end the process or skip the job's cleanup. "job started" is logged inside the block whose finally stops the heartbeats. This reverses the round 2 decision to rely on a documented rule: a throwing logger left heartbeats running, which is a worker defect.
  2. A result that cannot be sent (ResultTooLargeError, ResultSerializationError) is reported as a callback failure. The worker then logs "job failed" and returns. It no longer logs "job succeeded".
  3. The request and stop steps reuse the MicroVM preflight check. The check moved from compute/microvm/request.ts to tooLittleTimeMessage in compute/deadline.ts, so both compute types share it, and the MicroVM message is unchanged. With less than 11 seconds left in the invocation, each step makes no call and fails with a retryable TimeoutError whose message says to raise the function timeout.
  4. The stop failure log names the StopRuntimeSession permission only when the cause is AccessDeniedException. It says that a session ends at the idle timeout, or, while the handler still runs, at the runtime's maxLifetime.
  5. Rule 1 of "Rules for AgentCore jobs" and the heartbeatTimeout TSDoc now say that the first heartbeat period starts before delivery. So it must cover the request retries and a cold session start, measured at 1.4 to 3.1 seconds. The rule suggests 30 seconds or more. A new rule says that the function timeout must be at least 11 seconds.
  6. The AgentCore example stays localOnly until the CI test account has an agent runtime. That needs a CDK change, which is the next step. Until it lands, this PR asks a maintainer to record an exception to the integration-test rule of TESTING.md for this example.

Changes since review (round 2)

Rule for this round: the SDK does not guard developer configuration. Code stays only where the SDK breaks with a correct setup. Each other case is a rule in the docs that names the setting.

Commit ca38021a answered the second review round. Commit 415962df reduced it to the code below.

Code:

  1. InvokeAgentRuntime and StopRuntimeSession stop 10 seconds before the Lambda invocation times out, like the MicroVM calls. A Lambda timeout during a step attempt records no outcome. So a stalled call would stall the step with a correct setup too. A stopped call fails its attempt with a retryable TimeoutError, and the step retries in a later invocation. The answer is read with transformToString(), and the abort signal covers that read.
  2. The reserve helpers moved from compute/microvm/request.ts and shared.ts to compute/deadline.ts. Both MicroVM modules import @aws-sdk/client-lambda-microvms. So an import from them would load that client in the compute/agentcore subpath, and package-dependencies.test.ts would fail. deadline.ts imports no AWS SDK client. It holds only the reserve constants, reserveStartsAt, callBeforeDeadline, and remainingTime. The MicroVM behavior does not change.
  3. The fixed 8-hour cap is removed. timeout must be at least 1 second. Removed export: MAX_AGENTCORE_JOB_SECONDS from compute/agentcore. The subpath is experimental and unreleased.
  4. The worker's background job chain ends with one .catch. So a rejection in the job chain is never unhandled.
  5. The handler context has an optional sessionId, read from the X-Amzn-Bedrock-AgentCore-Runtime-Session-Id request header. The worker's job log lines carry it as runtimeSessionId, the field name of the Python worker.
  6. A cloud-only example, src/examples/agentcore/run-job/, with a history file. The agent side is agentcore-agent/app.ts. The example has localOnly: true until the CI infrastructure exists. So it has no SAM template entry and no name-map entry, and its test does not run. The integration script is unchanged.

Rules in the docs, in a "Rules for AgentCore jobs" section of both READMEs:

  1. Set heartbeatTimeout to at least 1 second. It ends the job when the worker crashes or stops reporting. The heartbeatTimeout TSDoc says the same. The round 2 check for it is removed.
  2. timeout must fit the agent runtime's configured maxLifetime.
  3. A job can run more than once when AgentCore replaces the worker process. Make handler side effects safe to repeat.
  4. Your logger must not throw. The round 2 logger wrapper is removed. Round 3 restored it, see above.
  5. The runtime's idle timeout applies only while no job is running. One agentcore() call runs one job, so it does not lose state between jobs.

Also removed from round 2: the 64 KiB answer cap. The worker answers {"accepted": true}, so a correct setup never sends a long answer.

Dependency: CI infrastructure

The AgentCore example runs in CI only after these exist. This PR does not create them, and it changes no CI file.

  1. An AgentCore Runtime agent runtime in the CI test account, in the integration-test Region, that runs packages/aws-durable-execution-sdk-js-examples/agentcore-agent/app.ts (a direct code deployment with NODE_22 works). The header comment of that file lists the steps.
  2. The agent runtime's execution role allows lambda:SendDurableExecutionCallbackSuccess, lambda:SendDurableExecutionCallbackFailure, and lambda:SendDurableExecutionCallbackHeartbeat on the example functions.
  3. The role in TEST_LAMBDA_EXECUTION_ROLE_ARN allows bedrock-agentcore:InvokeAgentRuntime and bedrock-agentcore:StopRuntimeSession on the agent runtime ARN and on <runtime ARN>/runtime-endpoint/*.
  4. The integration run passes the agent runtime ARN to the example function as AGENT_RUNTIME_ARN. This needs a change to the SAM template generator and the integration script.
  5. The example's localOnly: true is removed.

Why

A developer deploys an agent runtime outside the durable function. The function needs to send the agent a job and get the result back. The function should not pay for Lambda compute while the agent works. The MicroVM operations solve the same problem for AWS Lambda MicroVMs. AgentCore Runtime fits the same model:

  1. The compute is defined outside the function: an agent runtime with an ARN and a qualifier.
  2. The function can send one job and then wait on a durable callback.
  3. Code in the agent can report the result with SendDurableExecutionCallbackSuccess, SendDurableExecutionCallbackFailure, and SendDurableExecutionCallbackHeartbeat.
  4. The function invocation ends during the wait. So Lambda does not bill compute while the agent works.

Design

This section is the design note that CONTRIBUTING rule 3 asks for.

Problem. A durable function has no built-in way to run a long job in an AgentCore Runtime agent and wait for its result without keeping the invocation running.

Cause. InvokeAgentRuntime is a request and response call, and one request lasts at most 15 minutes. A job that runs longer needs another way to return its result.

Options considered.

  1. A new compute type under compute/agentcore, built like compute/microvm. The operation sends the job with InvokeAgentRuntime. The agent answers at once and reports the result through a durable callback. A worker in the compute-worker package implements the agent side.
  2. A generic "HTTP request plus callback" operation. The developer would supply the call that delivers the job. It would cover AgentCore and other targets. But each target still needs its own session handling, stop call, error classes, and agent-side worker. So the generic operation would move that work to every developer, and the SDK would still need AgentCore-specific code to be useful.
  3. No SDK support. The developer writes createCallback, a step with InvokeAgentRuntime, a stop step, and the agent side by hand. That is about 50 lines in the function, and the agent side needs dedup, heartbeats, and the ping contract. Each developer would rebuild the same code.

Chosen option: 1. It matches the existing compute model and the existing worker package. The compute is defined outside the function, so the same shape supports more compute types later.

One job per call in this iteration. A session with several jobs (agentcoreSession) needs a decision about idle sessions. AgentCore Runtime has no suspend. A session that receives no request for its idleRuntimeSessionTimeout ends and loses its memory and files. A durable wait between two jobs can be longer than that timeout. So a session operation needs a live probe of the idle behavior first. One job per call has no such gap: the worker reports HealthyBusy while the job runs.

What the change removes. Nothing.

Change

Extras package:

  • src/compute/agentcore/agentcore.ts: the agentcore operation, input encoding and size check, the stop step.
  • src/compute/agentcore/errors.ts: AgentcoreError extends ComputeError, with AgentcoreDeliveryError, AgentcoreJobFailedError, and AgentcoreTimeoutError. The error mapper restores the class from the checkpoint.
  • src/compute/agentcore/subtypes.ts: AgentcoreOperationSubType.
  • src/compute/agentcore/types.ts: AgentcoreConfig and AgentcoreJobDocument.
  • package.json and rollup.config.mjs: the ./compute/agentcore subpath, and @aws-sdk/client-bedrock-agentcore as an optional peer dependency.

Compute-worker package:

  • src/agentcore/worker.ts: startAgentcoreWorker.
  • src/microvm/worker.ts: readJson is now exported for use inside the package. The microvm subpath does not export it. No behavior changes.
  • package.json and rollup.config.mjs: the ./agentcore subpath.

Docs: one README section per package ("Run a job in AgentCore Runtime"), and a CHANGELOG entry.

Behavior

The operation creates its durable operations inside one child context named name, with subtype Agentcore:

  1. <name>.session (step, AgentcoreSessionId) generates the runtime session ID, a UUID of 36 characters. The SDK checkpoints it. So every retry and every replay uses the same session.
  2. <name>.callback (callback, AgentcoreCallback) has timeout and heartbeatTimeout.
  3. <name>.request (step, AgentcoreRequest) calls InvokeAgentRuntime with agentRuntimeArn, runtimeSessionId, qualifier when set, contentType: application/json, and the job document {version: 1, region, callbackId, heartbeatTimeoutSeconds?, input}. The step reads the streamed response to the end. An answer other than {"accepted": true} fails the step without a retry. The call and the read stop 10 seconds before the invocation times out, and the step retries in a later invocation.
  4. The child context waits on the callback. The invocation ends during the wait.
  5. <name>.stop (step, AgentcoreStop) calls StopRuntimeSession, which also stops 10 seconds before the invocation times out. It runs in a finally block. So it runs after success, after a job failure, after a timeout, and after a failed request. A stop failure is logged as an error and does not replace the job's outcome, as in MicroVM terminate.

Dedup rule. InvokeAgentRuntime has no idempotency token. So a retried request step can deliver the same job twice to the same session. The worker remembers each callback ID that it accepted, up to the last 1,000. A repeated callback ID gets {"accepted": true} and does not run again. The durable callback accepts only one success. So a duplicate run could never change the result, but it could repeat side effects. So the dedup is in the worker. The worker keeps the IDs in memory. A retry that reaches a new process, for example after the idle timeout, runs the job again. So delivery is at least once, and handler side effects must be idempotent.

Worker contract.

  • It listens on port 8080. It binds 0.0.0.0 when the AGENTCORE_RUNTIME_URL environment variable is set, and 127.0.0.1 otherwise. An explicit host argument wins. AgentCore Runtime requires 0.0.0.0:8080, and the live test showed that it sets AGENTCORE_RUNTIME_URL also for a direct code deployment, which has no /.dockerenv and no DOCKER_CONTAINER. /invocations has no authentication of its own. So a run outside AgentCore stays on loopback.
  • GET /ping answers {"status": "HealthyBusy"} while a job runs, and {"status": "Healthy"} otherwise. The answer also has time_of_last_update: the Unix time, in seconds, of the last status change. The worker sets it when it starts and when the status changes, not on every ping.
  • POST /invocations validates the document with the existing parseJobRequest and answers {"accepted": true}. The job starts on a later turn of the event loop (setImmediate), after the answer is written. So synchronous work at the start of a handler cannot delay the answer. An invalid document gets HTTP 400.
  • A createClient that throws is logged as an error, as in the MicroVM worker, and the process keeps serving. Heartbeats that fail to start fail the callback, and the handler does not run.
  • The handler runs on the event loop that also answers /ping and sends heartbeats. Synchronous CPU work blocks both. The README and the TSDoc say to run CPU-bound work in a worker thread or a child process.
  • The handler context has an optional sessionId from the X-Amzn-Bedrock-AgentCore-Runtime-Session-Id request header. The job log lines carry it as runtimeSessionId.
  • The worker wraps the supplied logger with safeLogger. The background job chain ends with a .catch, so a rejection there is never unhandled.
  • The job reuses the existing CallbackReporter and startHeartbeats of the package.

Idle timeout. After the agent runtime's idleRuntimeSessionTimeout, the same session ID silently gets a new microVM, and memory and files are lost (measured in the live test). The operation sends one job per session. So no later job can reach the new microVM. The idle timeout matters only while the job runs, and the worker then reports HealthyBusy, which keeps the session alive.

Permissions

  • The function's execution role needs bedrock-agentcore:InvokeAgentRuntime and bedrock-agentcore:StopRuntimeSession on both the agent runtime ARN and <runtime ARN>/runtime-endpoint/*. The live test showed a denial on <runtime ARN>/runtime-endpoint/DEFAULT without the endpoint resource.
  • The agent runtime's execution role needs lambda:SendDurableExecutionCallbackSuccess, lambda:SendDurableExecutionCallbackFailure, and lambda:SendDurableExecutionCallbackHeartbeat on the function ARN.

Decisions the brief did not cover

CONTRIBUTING rule 7 asks for this list. Each line is one decision and its reason.

  1. The job document has a region field. The agent runtime can be in another Region than the function. The callback must go to the function's Region. The MicroVM job request has the same field.
  2. The function's Region comes from AWS_REGION only. Lambda sets it to the function's Region. The MicroVM code also reads the execution ARN. That second source adds a branch with no case that needs it.
  3. The default retry strategy is defaultMicrovmRetryStrategy, imported inside the package. It retries throttling, server errors, connection failures, and errors that the AWS SDK marks retryable, such as RetryableConflictException. No new exported strategy.
  4. The timeout must be at least 1 second. The runtime's maxLifetime limits the session, but the ARN does not say which limit applies (8 hours for microVM, up to 14 days for Instances). So the operation does not cap it.
  5. The input limit is the MicroVM limit, 6 MiB minus 8 KiB, although InvokeAgentRuntime accepts 100 MB. So one input fits both compute types, and the worker can refuse a body over 6 MiB.
  6. The default client is one BedrockAgentCoreClient per Region of the agent runtime ARN.
  7. ResourceNotFoundException from StopRuntimeSession counts as an ended session, not as a failure. The live test measured it: 404 for a session that a stop already ended, and for a session ID that never started.
  8. The worker answers HTTP 200 to /invocations, not 202. The AgentCore contract describes a 200 answer.
  9. The worker answers an invalid document with 400 and does not fail the callback. The service passes it back as RuntimeClientError (HTTP 424), which the default strategy does not retry. So the request step fails with AgentcoreDeliveryError at once.
  10. The worker records a callback ID when it accepts it. So the dedup covers a running job and a finished job alike.
  11. startAgentcoreWorker has a third parameter, host. Its default follows AGENTCORE_RUNTIME_URL, as described under "Worker contract".
  12. durationToSeconds is copied into the agentcore module. Importing it from compute/microvm/shared would load @aws-sdk/client-lambda-microvms, which an AgentCore user may not install. A test checks that each subpath loads without the client of the other subpath.
  13. A call that the invocation reserve stopped fails with the name TimeoutError. The default retry strategy already retries that name. So no new error class and no change to the strategy.
  14. The AgentCore example uses the existing localOnly flag to stay out of CI, and no new catalog flag. A new flag would need SAM template and integration script changes that nothing uses until the CI infrastructure exists.
  15. npm install raised the lockfile versions of some shared @aws-sdk/* and @smithy/* packages, because @aws-sdk/client-bedrock-agentcore needs them.

Changed test expectations

src/__tests__/package-dependencies.test.ts in the extras package lists each AWS SDK client and its subpath. It has a new entry for @aws-sdk/client-bedrock-agentcore, and a new check that each subpath loads without the client of another subpath. No other existing test changed.

Out of scope / follow-ups

  • agentcoreSession: several jobs in one session. The live test showed that an idle session silently gets a new microVM on the same ID, so a session operation must handle that.
  • Streaming responses, OAuth or JWT inbound auth, and custom headers.
  • Move the shared worker modules (startHeartbeats, readJson, parseJobRequest) to the top level of the compute-worker package. Today the agentcore subpath imports them from src/microvm/. So it also loads @aws-sdk/client-lambda-microvms, which is a regular dependency of the package.
  • The CI infrastructure for the AgentCore example. See "Dependency: CI infrastructure".
  • Publishing changes: the npm package list and the publish matrix.

Testing

Commands: npm ci, root npm run build, npm test in both packages, npm run lint:ci, npm run lint:suppressions, npm run lint:versions, npm run lint:filenames. Node 24.

Round 3, at c26dc289: extras 29 test files and 471 tests pass; compute worker 6 test files and 336 tests pass; examples 127 test files and 277 tests pass, with 5 files and 5 tests skipped. Biome passes. Each new branch was removed once, and a test failed each time: the safeLogger wrapper, the return after a result that cannot be sent, the request preflight, the stop preflight, the AccessDeniedException condition of the permission hint, and the maxLifetime text. Moving "job started" back before the try fails no test while safeLogger is in place, because the wrapper already drops the throw. The placement keeps the heartbeats stopped if a later change logs through an unwrapped path.

Round 2, at 415962df: extras 29 test files and 469 tests pass; compute worker 6 test files and 334 tests pass; examples 127 test files and 277 tests pass, with 5 files and 5 tests skipped (cloud-only and local-only examples, the new AgentCore example among them). Biome passes. Each kept branch was removed once, and a test failed each time: the abort signal on InvokeAgentRuntime, the abort signal on StopRuntimeSession, the removed 8-hour cap, the terminal .catch on the job chain (a test with a logger that throws), the session header read, and the runtimeSessionId log field.

Round 1:

  • Extras: 28 test files, 464 tests, all pass. New: 29 tests in compute/agentcore/__tests__/agentcore.test.ts, 3 composed tests in compute/agentcore/__tests__/worker-composed.test.ts, and 5 more cases in package-dependencies.test.ts. Coverage of src/compute/agentcore: 100% statements and 100% branches.
  • Compute worker: 6 test files, 329 tests, all pass. New: 23 tests in src/agentcore/__tests__/worker.test.ts and 1 in src/agentcore/__tests__/heartbeat-start.test.ts. Coverage of src/agentcore: 98% statements and 94.11% branches.
  • CONTRIBUTING rule 4: each of these branches was removed or inverted once, and a test failed each time: the setImmediate before the job, the default host, the default port 8080, the query-string strip, GET-only /ping, the createClient catch, and the 256-character quote of a refused answer.
  • The unit tests cover the happy path, a job failure, a timeout, a rejected request, an answer without accepted, a throttled request retried with the same session ID, replay with the checkpointed session ID, stop after each failure, a stop failure that keeps the result and the failure, and input and config validation.
  • The worker tests cover the ping states, time_of_last_update (the same across pings without a status change, new when the first job starts and when the last job ends, unchanged when a second job starts or one of two jobs ends), dedup, the 1,000-ID limit, success and failure callbacks, a result over 256 KB, heartbeats, a closed callback, invalid documents with 400, an unknown route with 404, /ping with a query string and with POST, the default port and host with and without AGENTCORE_RUNTIME_URL, an explicit host, the answer written before a handler with synchronous work starts, a throwing createClient, and heartbeats that fail to start.
  • The composed tests run agentcore against the real worker server on 127.0.0.1. A fake AgentCore client forwards the payload over HTTP. The worker's fake Lambda client completes the callback in the local test runner. They check the result, a failed job, and a payload delivered twice that runs once.
  • After the build, both new subpaths load with import and with require. The built compute/agentcore entry does not import @aws-sdk/client-lambda-microvms.

Live test

The code ran against a live AgentCore Runtime in us-east-1, with direct code deployment (NODE_22). The durable function ran the agentcore operation, and the agent ran startAgentcoreWorker. The commit under test was dea5b490. This revision fixes the one failure found there (4b).

# Scenario Result
1 Short job (5 s) Pass. The execution succeeded with the agent's result. The stop step ran, and the session was gone afterwards.
2 Failing job Pass. AgentcoreJobFailedError. The stop step ran.
3 180 s job, idle timeout 60 s Pass. The job succeeded after 184 s in the same process. So HealthyBusy with time_of_last_update set on change kept the session alive for 3 times the idle timeout.
4a Worker crash, heartbeat timeout 30 s Pass. AgentcoreTimeoutError 30 s after delivery. The stop step ran.
4b Handler with long synchronous work before its first await Failed at dea5b490. The accept answer never came, and the service failed the request with RuntimeClientError "Runtime initialization time exceeded". Fixed here: the job now starts after the answer is written.
5 Duplicate delivery of one job (direct calls) Pass. Both answers were {"accepted": true}, and the handler ran once.
6 Stop of an ended session Pass. The service answers 404 ResourceNotFoundException. The stop step succeeds and logs no error.

Measurements:

  • Cold start, the first invoke of a new session until {"accepted": true}: 1.4 to 3.1 s.
  • Warm invoke: 146 to 253 ms.
  • InvokeAgentRuntime returns the worker's answer as the response stream, with contentType: application/json and statusCode: 200.
  • A worker answer of 400 reaches the function as RuntimeClientError with HTTP 424. The default retry strategy does not retry it. So the request step fails at once with AgentcoreDeliveryError.
  • StopRuntimeSession answers 404 for a session that a stop already ended, and for a session ID that never started.
  • After the idle timeout, an invoke with the same session ID reaches a new process. Memory and files are lost, and the service reports no error.
  • InvokeAgentRuntime and StopRuntimeSession were denied on <runtime ARN>/runtime-endpoint/DEFAULT until the function role also allowed <runtime ARN>/runtime-endpoint/*.
  • The direct-code-deployment runtime has no /.dockerenv and no DOCKER_CONTAINER, and it sets AGENTCORE_RUNTIME_URL. So the worker uses that variable to pick its default bind.

A second live run, at 1f0e6c15, passed all 6 scenarios, including 4b, and confirmed the bind rule and the createClient handling.

Not yet run live: the round 2 changes. Unverified against the real service: that an abort of the AWS SDK call also ends a transformToString() read of a response stream that stalls after its headers. A unit test with a fake covers a stalled call. The X-Amzn-Bedrock-AgentCore-Runtime-Session-Id header is verified: the Python worker reads it, and the second live run returned the same session ID that the operation generated.

Add agentcore() in the compute/agentcore subpath of the extras
package. It runs one job in a new Amazon Bedrock AgentCore Runtime
session. A step generates the runtime session ID. A request step
sends the job document with InvokeAgentRuntime. The function waits on
a durable callback. A stop step calls StopRuntimeSession after
success, failure, and timeout.

Add startAgentcoreWorker() in the agentcore subpath of the
compute-worker package. It answers GET /ping and POST /invocations on
port 8080. It runs each callback ID once, sends heartbeats, and
reports the result with the existing callback reporter.

@aws-sdk/client-bedrock-agentcore is an optional peer dependency of
the extras package. The worker adds no dependency.
The AgentCore documentation makes time_of_last_update optional and
asks to set it only when the status changes. A public report states
that the service ends a HealthyBusy session at its idle timeout when
the field is missing. So the worker now records the Unix time, in
seconds, when it starts and when the status changes between Healthy
and HealthyBusy, and sends that time in every ping answer.
- Bind 0.0.0.0 only when AGENTCORE_RUNTIME_URL is set, else
  127.0.0.1. An explicit host still wins. /invocations has no
  authentication, so a local run stays on loopback.
- Start the job on a later turn of the event loop. So synchronous
  work in the handler cannot delay the accepted answer. The live test
  showed AgentCore failing such a request with "Runtime
  initialization time exceeded".
- A createClient that throws is logged, as in the MicroVM worker,
  and no longer ends the process. Heartbeats that fail to start fail
  the callback.
- Docs: the function role also needs runtime-endpoint/* for both
  actions; explain idle-timeout behavior; offload CPU-bound work.
- Tests for the default host and port, the query-string strip, the
  GET-only /ping, and the 256-character quote of a refused answer.
- Replace the unverified note on StopRuntimeSession 404 with the
  measured behavior.
A test now passes a custom retryStrategy to agentcore. One case stops
the retry of a throttled request, and the operation fails with
AgentcoreDeliveryError after one invoke. The other case retries a
throttled stop, so the stop runs twice.

A worker test returns a result that JSON.stringify cannot encode. The
worker reports it as a ResultSerializationError failure.

Both tests fail when the branch they cover is removed.
- InvokeAgentRuntime and StopRuntimeSession stop 10 seconds before the
  Lambda invocation times out, like the MicroVM calls. The helpers move
  to compute/deadline.ts, which imports no AWS SDK client.
- The request step reads at most 64 KiB of the agent's answer, and
  cancels the stream past it.
- The fixed 8-hour timeout cap and MAX_AGENTCORE_JOB_SECONDS are
  removed. The timeout must fit the agent runtime's maxLifetime.
- A heartbeatTimeout below 1 second, or one that is not finite, fails
  before any durable operation.
- The worker wraps its logger like the MicroVM worker, and ends each
  background chain with a catch.
- The worker passes the runtime session ID to the handler as sessionId,
  and logs it as runtimeSessionId.
- The docs state that delivery is at least once across process
  replacement, so handler side effects must be idempotent.
- A cloud-only AgentCore example runs when AGENT_RUNTIME_ARN is set.
The SDK does not guard developer configuration. So the round 2 guards
for settings that a developer controls become documented rules.

- Remove the 64 KiB answer cap. The request step reads the answer
  with transformToString() again. The invocation reserve stays.
- Remove the heartbeatTimeout check. The docs state the rule.
- Remove the worker's logger wrapper. One terminal catch on the job
  chain stays, so a rejection is never unhandled.
- Revert the integration script. The AgentCore example is localOnly
  until the CI test account has an agent runtime.
- Add "Rules for AgentCore jobs" to both READMEs.
main now lists only breaking changes and deprecations in CHANGELOG.md.
The AgentCore operation is neither, so the merge keeps the main
version and drops the Added entry from this branch.
- The AgentCore worker wraps its logger with the MicroVM worker's
  safeLogger again. "job started" is logged inside the block whose
  finally stops the heartbeats.
- A result that cannot be sent is reported as a failure, and the
  worker then logs "job failed", not "job succeeded".
- The request and stop steps reuse the MicroVM preflight check, moved
  to compute/deadline.ts. With less than 11 seconds left, they make no
  call and say to raise the function timeout.
- The stop failure log names the stop permission only for
  AccessDeniedException, and names maxLifetime for a running handler.
- The heartbeatTimeout rule says that the first period must cover
  delivery and a cold session start.

@yaythomas yaythomas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

This branch has not been deployed

No deployments
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.

3 participants