What the agent does
In a repository like serverless/examples, every service declares its runtime in serverless.yml under provider.runtime, and the agent starts there. aws-node-rest-api-with-dynamodb/serverless.yml sets frameworkVersion: '4', runtime: nodejs24.x and architecture: arm64, with five functions behind httpApi events and a DynamoDB table whose name comes from ${self:service}-${sls:stage}. aws-node-http-api/serverless.yml sets the same runtime and architecture for one hello function. Both are already on nodejs24.x, so the agent checks the current list of Lambda Node.js runtimes and reports that no runtime change is needed for them rather than inventing one. Older services in the same repository, still on earlier runtimes, are where the runtime line actually moves.
Next it reads the code the runtime runs. The DynamoDB service's package.json has "type": "module" and depends on @aws-sdk/client-dynamodb and @aws-sdk/lib-dynamodb at ^3.700.0, and todos/create.js imports DynamoDBDocumentClient and PutCommand and uses randomUUID from node:crypto. The http-api service has no package.json at all, and handler.js uses exports.hello, which runs as CommonJS. The agent bumps the AWS SDK clients together, since lib-dynamodb and client-dynamodb are released as a set, and leaves module format alone.
Neither service has tests. So the agent adds the smallest proof the request allows: a test per handler that calls it with an API Gateway v2 event and checks the status code, with the DynamoDB client pointed at a local DynamoDB container for the CRUD handlers, and runs it with node --test so no test framework is added. Then it runs serverless package in each directory, which resolves variables, builds the CloudFormation template and zips the functions without deploying. Framework v4 asks for a Serverless access key before it packages; the agent reads it from SERVERLESS_ACCESS_KEY, which a Project secret supplies to the run.
A bump that breaks a handler test or serverless package is left out, with the output.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "codex",
"input": "In aws-node-rest-api-with-dynamodb and aws-node-http-api only: check provider.runtime in serverless.yml against the current Lambda Node.js runtimes and change it only if a newer one exists. Upgrade the npm dependencies, keeping the @aws-sdk packages on the same release. Add one node --test test per handler that calls it with an API Gateway v2 event, using a local DynamoDB container for the DynamoDB handlers. Run the tests and serverless package in each directory to prove it builds. Leave out any upgrade that breaks the build or tests and say why. Open a pull request with one line per bump, and say plainly if a runtime was already current.",
"resources": [
{
"url": "https://github.com/your-org/your-app"
}
]
}- Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
- Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
- Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.
What comes back
The pull request changes package.json and adds a lockfile in the DynamoDB service, adds handler tests in both services, and changes serverless.yml only where a runtime moved. Its description states the runtime for each service before and after (for these two, unchanged at nodejs24.x), the SDK versions, the test results and the serverless package result. Anything left out has its failing command and output.
A reviewer checks that the generated template from serverless package still names the same IAM actions on TodosDynamoDbTable and the same five routes, and that the new tests call real handlers rather than stubs of them. The full command output is in the session transcript at GET /o/{org}/sessions/{id}/messages.
Run it on every Lambda runtime deprecation notice
AWS announces when a Lambda runtime reaches deprecation. When that notice arrives, or on a weekly schedule of your own, send POST /o/{org}/sessions with this body for each repository that has Serverless services; a webhook on the key reports run.completed with the session URL.
With handler tests in place after the first run, later runs have something to prove each bump against instead of only a successful package.
The use case this job follows, with its automation and trigger: Upgrade dependencies weekly.
Why run it on Rush?
Proving a Lambda upgrade without deploying it means running the handlers locally against a database stand-in and building the deployment package, which needs Docker, the Serverless CLI and its access key. In Rush that happens in the run's own sandbox, the access key comes from a Project secret rather than a developer's shell, and the output of every test and package command stays in the transcript.
Many services can be checked at once, one run each within the key's concurrency limit. Each returns a pull request that says what changed, what was already current and what was proven, which is more useful than a list of runtime strings to edit.
Frequently asked questions
My services are already on nodejs24.x. Is there anything to do?
The runtime line stays as it is, and the pull request says so. The run still bumps the npm dependencies, adds handler tests where none exist and proves the service packages, which is where these two examples had gaps.
Does it deploy to AWS?
No. serverless package builds the template and zip files without creating any stack. DynamoDB calls in the tests go to a local container.
Why does it need a Serverless access key?
Framework v4 asks for one before it runs commands such as package. Save it as a secret named SERVERLESS_ACCESS_KEY in a Project and start the session in that Project, and the agent reads it as an environment variable.
Will it add Jest or another test framework?
No. The request asks for node --test, which ships with Node, so the services gain tests without a new dev dependency.