AWS Lambda Durable Functions
AWSOfficialPublished by AWS
- Skill
- Tool integration
- Cloud and DevOps
- Apache-2.0
- Low risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides guidance and patterns for implementing durable, multi-step applications on AWS Lambda. It focuses on the replay model, which allows functions to maintain state across long-running executions—up to one year—by automatically checkpointing progress. The skill covers essential architectural patterns such as the saga pattern for error handling, wait/callback mechanisms for external system integration, and testing strategies using the local test runner. It emphasizes strict adherence to deterministic coding practices required by the replay model to ensure reliable execution.
What it does
- Enables state persistence for long-running Lambda functions.
- Provides patterns for implementing the saga pattern and compensating transactions.
- Supports wait/callback patterns for integrating with external systems.
- Offers guidance on testing durable functions locally and in the cloud.
- Defines rules for deterministic code to prevent state corruption during replays.
- Outlines requirements for qualified ARN invocation and IAM permissions.
When to use it
- When building workflows that require execution times longer than standard Lambda timeouts.
- When orchestrating multi-step processes that need to maintain state across interruptions.
- When implementing reliable, fault-tolerant serverless integrations.
- When managing complex state machines or human-in-the-loop approval processes.
- When you need automatic retry logic and checkpointing for critical business processes.
Advantages
- Resilient execution that survives infrastructure interruptions.
- Simplified state management without external databases for simple workflows.
- Native support for complex orchestration patterns like sagas and parallel execution.
- Built-in replay-aware logging and error handling.
- Local testing capabilities to validate complex workflow logic.
Usage examples
- “How do I implement a multi-step workflow with a wait period in AWS Lambda?”
- The agent provides a code example using context.step for logic and context.wait for the delay, ensuring the execution state is persisted correctly.
- “Why is my durable function failing during replay?”
- The agent helps diagnose non-deterministic code (like Date.now() or Math.random()) placed outside of steps, which causes state corruption.
- “How do I handle errors in a long-running durable function?”
- The agent explains the saga pattern and how to implement compensating transactions within steps to roll back state if a step fails.
- “What are the requirements for invoking a durable Lambda function?”
- The agent clarifies that durable functions must be invoked using a qualified ARN (version, alias, or $LATEST) and provides the corresponding AWS CLI command.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/aws/aws-lambda-durable-functions/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip aws-lambda-durable-functions.zip -d .agents/skills
Documentation by AWS
AWS Lambda durable functions
Build resilient multi-step applications and AI workflows that can execute for up to 1 year while maintaining reliable progress despite interruptions.
Works best with the AWS MCP server but is not required. All AWS interactions in this skill use standard AWS CLI commands that work in any environment with configured AWS credentials.
Critical Rules
Read these before writing any code. Each one is a constraint that will silently break a function if violated.
Durable execution must be enabled at function creation time — it cannot be retrofitted. A new Lambda function must be created with durable execution turned on. Migrate the logic into the new function; do not attempt to install the SDK and wrap the handler of the existing function and expect it to work.
Durable functions must be invoked with a qualified ARN — a specific version, an alias, or the literal
$LATESTsuffix. An unqualified function name will fail. See the Invocation Requirements section below for examples.Durable operations cannot be nested. You cannot call
context.step(),context.wait(), orcontext.invoke()from inside another step's callback. Usecontext.runInChildContext()to group operations instead.All non-deterministic code must run inside steps.
Date.now(),Math.random(), UUID generation, API calls, and database queries outside a step will produce different values on replay and corrupt execution state.Closure mutations are lost on replay - return values from steps
Side effects outside steps repeat - use
context.logger(replay-aware)
When to Load Reference Files
Load the appropriate reference file based on what the user is working on:
Getting started, basic setup, example, ESLint, or Jest setup -> see getting-started.md
Understanding replay model, determinism, or non-deterministic errors -> see replay-model-rules.md
Creating steps, atomic operations, or retry logic -> see step-operations.md
Waiting, delays, callbacks, external systems, or polling -> see wait-operations.md
Parallel execution, map operations, batch processing, or concurrency -> see concurrent-operations.md
Error handling, retry strategies, saga pattern, or compensating transactions -> see error-handling.md
Advanced error handling, timeout handling, circuit breakers, or conditional retries -> see advanced-error-handling.md
Testing, local testing, cloud testing, test runner, or flaky tests -> see testing-patterns.md
Deployment, CloudFormation, CDK, SAM, log groups, deploy, or infrastructure -> see deployment-iac.md
Advanced patterns, GenAI agents, completion policies, step semantics, or custom serialization -> see advanced-patterns.md
troubleshooting, stuck execution, failed execution, debug execution ID, execution history, execution error, why did my execution fail, execution timed out, callback not received, diagnose execution, or root cause execution -> see troubleshooting-executions.md
Quick Reference
Basic Handler Pattern
TypeScript:
import { withDurableExecution, DurableContext } from '@aws/durable-execution-sdk-js';
export const handler = withDurableExecution(async (event, context: DurableContext) => {
const result = await context.step('process', async () => processData(event));
return result;
});Python:
from aws_durable_execution_sdk_python import durable_execution, DurableContext
@durable_execution
def handler(event: dict, context: DurableContext) -> dict:
result = context.step(lambda _: process_data(event), name='process')
return resultPython API Differences
The Python SDK differs from TypeScript in several key areas:
Steps: Use
@durable_stepdecorator +context.step(my_step(args)), or inlinecontext.step(lambda _: ..., name='...'). Prefer the decorator for automatic step naming.Wait:
context.wait(duration=Duration.from_seconds(n), name='...')Exceptions:
ExecutionError(permanent),InvocationError(transient),CallbackError(callback failures)Testing: Use
DurableFunctionTestRunnerclass directly - instantiate with handler, use context manager, callrun(input=...)
Invocation Requirements
Durable functions require qualified ARNs (version, alias, or $LATEST):
# Valid
aws lambda invoke --function-name my-function:1 output.json
aws lambda invoke --function-name my-function:live output.json
# Invalid - will fail
aws lambda invoke --function-name my-function output.jsonIAM Permissions
Your Lambda execution role MUST have the AWSLambdaBasicDurableExecutionRolePolicy managed policy attached. This includes:
lambda:CheckpointDurableExecution- Persist execution statelambda:GetDurableExecutionState- Retrieve execution stateCloudWatch Logs permissions
Additional permissions needed for:
Durable invokes:
lambda:InvokeFunctionon target function ARNsExternal callbacks: Systems need
lambda:SendDurableExecutionCallbackSuccessandlambda:SendDurableExecutionCallbackFailure
Validation Guidelines
When writing or reviewing durable function code, ALWAYS check for these replay model violations:
Non-deterministic code outside steps:
Date.now(),Math.random(), UUID generation, API calls, database queries must all be inside stepsNested durable operations in step functions: Cannot call
context.step(),context.wait(), orcontext.invoke()inside a step function — usecontext.runInChildContext()insteadClosure mutations that won't persist: Variables mutated inside steps are NOT preserved across replays — return values from steps instead
Side effects outside steps that repeat on replay: Use
context.loggerfor logging (it is replay-aware and deduplicates automatically)
When implementing or modifying tests for durable functions, ALWAYS verify:
All operations have descriptive names
Tests get operations by NAME, never by index
Replay behavior is tested with multiple invocations
Use
LocalDurableTestRunnerfor local testing
Security Considerations
Checkpoint data encryption: Execution state is persisted automatically. Enable KMS encryption on associated CloudWatch Log Groups to protect checkpointed data at rest.
Sensitive data in step results: Step return values are checkpointed and persisted. Do not return secrets, raw credentials, or PII from steps — store sensitive data in Secrets Manager or SSM Parameter Store and return references instead.
Input validation: Validate and sanitize event payloads at the handler entry point before passing data to steps.
Credential management: Retrieve secrets from AWS Secrets Manager or SSM Parameter Store within steps.
Callback payload validation: Data received via
waitForCallbackoriginates from external systems — validate and sanitize before processing.Logging: Avoid
DEBUGlog level in non-development environments as it may expose step results and execution state. Enable CloudWatch Logs encryption with KMS.
Resources
Files
- ATTRIBUTION.mdAdded by AutoGineer946 B
- LICENSELicence file added by AutoGineer9.9 KiB
- NOTICELicence file added by AutoGineer67 B
- SKILL.md8.9 KiB
- references/advanced-error-handling.md4.9 KiB
- references/advanced-patterns.md10.4 KiB
- references/concurrent-operations.md8.4 KiB
- references/deployment-iac.md14.0 KiB
- references/error-handling.md10.5 KiB
- references/getting-started.md12.6 KiB
- references/replay-model-rules.md8.3 KiB
- references/step-operations.md8.3 KiB
- references/testing-patterns.md17.4 KiB
- references/troubleshooting-executions.md8.5 KiB
- references/wait-operations.md9.5 KiB
references/testing-patterns.md
Testing Patterns
Test durable functions locally and in the cloud with comprehensive test runners.
Critical Testing Patterns
ALWAYS follow these patterns to avoid flaky tests:
DO:
✅ Name all operations for test reliability
✅ TypeScript: Use
runner.getOperation("name")to find operations by name✅ TypeScript: Use
WaitingOperationStatus.STARTEDwhen waiting for callback operations✅ TypeScript: JSON.stringify callback parameters:
sendCallbackSuccess(JSON.stringify(data))✅ TypeScript: Use
skipTime: truein setupTestEnvironment for fast tests✅ TypeScript: Wrap event data in
payloadobject:runner.run({ payload: { ... } })✅ TypeScript: Cast
getResult()to appropriate type:execution.getResult() as ResultType✅ Python: Use
result.get_step("name")to find step operations by name✅ Python: Use
result.operationsto iterate and filter operations by type✅ Python: Instantiate
DurableFunctionTestRunner(handler=my_handler)directly✅ Python: Use
runner.run(input={...}, timeout=10)— noteinput=notpayload✅ Python: The value of result.result is serialized. Deserialize using the appropriate SerDes or default json deserializer.
DON'T:
❌ Use
getOperationByIndex()unless absolutely necessary❌ Assume operation indices are stable (parallel creates nested operations)
❌ TypeScript: Send objects to sendCallbackSuccess — stringify first
❌ TypeScript: Forget that callback results are JSON strings — parse them
❌ TypeScript: Test callbacks without proper synchronization (leads to race conditions)
❌ Python: Confuse
DurableFunctionTestRunner(local) withDurableFunctionCloudTestRunner(cloud)❌ Python: Forget the
with runner:context manager — it manages execution lifecycle
Local Testing Setup
TypeScript:
import {
LocalDurableTestRunner,
OperationType,
OperationStatus
} from '@aws/durable-execution-sdk-js-testing';
describe('My Durable Function', () => {
beforeAll(() =>
LocalDurableTestRunner.setupTestEnvironment({ skipTime: true })
);
afterAll(() =>
LocalDurableTestRunner.teardownTestEnvironment()
);
it('should execute workflow', async () => {
const runner = new LocalDurableTestRunner({
handlerFunction: handler
});
const execution = await runner.run({
payload: { userId: '123' }
});
expect(execution.getStatus()).toBe('SUCCEEDED');
expect(execution.getResult()).toEqual({ success: true });
});
});Python:
The Python testing SDK provides DurableFunctionTestRunner for local testing and DurableFunctionCloudTestRunner for cloud testing.
Install the testing SDK:
pip install aws-durable-execution-sdk-python-testing pytestExample test:
from aws_durable_execution_sdk_python_testing import DurableFunctionTestRunner
from aws_durable_execution_sdk_python.execution import InvocationStatus
from src.my_function import handler
def test_workflow():
"""Test durable function locally."""
runner = DurableFunctionTestRunner(handler=handler)
with runner:
result = runner.run(input='{"user_id": "123"}', timeout=10)
assert result.status is InvocationStatus.SUCCEEDEDGetting Operations
CRITICAL: Always get operations by NAME, not by index.
TypeScript:
it('should execute steps in order', async () => {
const runner = new LocalDurableTestRunner({ handlerFunction: handler });
await runner.run({ payload: { test: true } });
// ✅ CORRECT: Get by name
const fetchStep = runner.getOperation('fetch-user');
expect(fetchStep.getType()).toBe(OperationType.STEP);
expect(fetchStep.getStatus()).toBe(OperationStatus.SUCCEEDED);
const processStep = runner.getOperation('process-data');
expect(processStep.getStatus()).toBe(OperationStatus.SUCCEEDED);
// ❌ WRONG: Get by index (brittle, breaks easily)
// const step1 = runner.getOperationByIndex(0);
});Python:
from aws_durable_execution_sdk_python.lambda_service import OperationType
def test_steps_execute():
"""Test step execution."""
runner = DurableFunctionTestRunner(handler=handler)
with runner:
result = runner.run(input={'test': True}, timeout=10)
# ✅ CORRECT: Get step by name
fetch_step = result.get_step('fetch-user')
assert fetch_step is not None
# ✅ Also valid: filter result.operations by type
step_names = {op.name for op in result.operations if op.operation_type == OperationType.STEP}
assert step_names >= {'fetch-user', 'process-data'}
assert 'process-data' in step_namesTesting Replay Behavior
TypeScript:
it('should handle replay correctly', async () => {
const runner = new LocalDurableTestRunner({ handlerFunction: handler });
// First execution
const execution1 = await runner.run({ payload: { value: 42 } });
expect(execution1.getStatus()).toBe('SUCCEEDED');
// Simulate replay
const execution2 = await runner.run({ payload: { value: 42 } });
expect(execution2.getStatus()).toBe('SUCCEEDED');
// Results should be identical
expect(execution1.getResult()).toEqual(execution2.getResult());
});Testing with Fake Clock
TypeScript:
it('should wait for specified duration', async () => {
const runner = new LocalDurableTestRunner({
handlerFunction: handler
});
const executionPromise = runner.run({ payload: {} });
// Advance time by 60 seconds
await runner.skipTime({ seconds: 60 });
const execution = await executionPromise;
expect(execution.getStatus()).toBe('SUCCEEDED');
const waitOp = runner.getOperation('delay');
expect(waitOp.getType()).toBe(OperationType.WAIT);
expect(waitOp.getWaitDetails()?.waitSeconds).toBe(60);
});Test Runner API Patterns
CRITICAL: Always wrap event data in payload and cast results appropriately.
TypeScript:
it('should use correct test runner API', async () => {
const runner = new LocalDurableTestRunner({
handlerFunction: handler,
});
// ✅ CORRECT: Wrap event in payload
const execution = await runner.run({
payload: { name: 'Alice', userId: '123' }
});
// ✅ CORRECT: Type cast result
const result = execution.getResult() as {
greeting: string;
message: string;
};
expect(result.greeting).toBe('Hello, Alice!');
// ✅ CORRECT: Get operations by name
const greetingStep = runner.getOperation('generate-greeting');
expect(greetingStep.getStepDetails()?.result).toBe('Hello, Alice!');
});
// ❌ WRONG: Missing payload wrapper and type casting
it('incorrect api usage', async () => {
const runner = new LocalDurableTestRunner({ handlerFunction: handler });
// ❌ Missing payload wrapper
const execution = await runner.run({ name: 'Alice' });
// ❌ No type casting - result is 'unknown'
const result = execution.getResult();
// expect(result.greeting).toBe('...'); // Type error!
});Testing Callbacks
CRITICAL: Use waitForData() with WaitingOperationStatus.STARTED to avoid flaky tests caused by promise races.
TypeScript:
import { WaitingOperationStatus } from '@aws/durable-execution-sdk-js-testing';
it('should handle callback success', async () => {
const runner = new LocalDurableTestRunner({ handlerFunction: handler });
// Start execution (will pause at callback)
const executionPromise = runner.run({
payload: { approver: '[email protected]' }
});
// ✅ CRITICAL: Get operation by NAME
const callbackOp = runner.getOperation('wait-for-approval');
// ✅ CRITICAL: Wait for operation to reach STARTED status
await callbackOp.waitForData(WaitingOperationStatus.STARTED);
// ✅ CRITICAL: Must JSON.stringify callback data!
await callbackOp.sendCallbackSuccess(
JSON.stringify({ approved: true, comments: 'Looks good' })
);
const execution = await executionPromise;
expect(execution.getStatus()).toBe('SUCCEEDED');
// ✅ CRITICAL: Parse JSON string result
const result: any = execution.getResult();
const approval = typeof result.approval === 'string'
? JSON.parse(result.approval)
: result.approval;
expect(approval.approved).toBe(true);
expect(approval.comments).toBe('Looks good');
});
it('should handle callback failure', async () => {
const runner = new LocalDurableTestRunner({ handlerFunction: handler });
const executionPromise = runner.run({ payload: {} });
const callbackOp = runner.getOperation('wait-for-approval');
await callbackOp.waitForData(WaitingOperationStatus.STARTED);
await callbackOp.sendCallbackFailure(
'ApprovalDenied',
'Request was rejected'
);
const execution = await executionPromise;
expect(execution.getStatus()).toBe('FAILED');
});Python:
Testing callbacks in Python follows the same marker pattern. The callback operation
appears in result.operations with operation_type == OperationType.CALLBACK:
def test_callback_creation():
"""Test that callback is created correctly."""
runner = DurableFunctionTestRunner(handler=handler)
with runner:
result = runner.run(input={'approver': '[email]'}, timeout=10)
# Find callback operations in the result
callback_ops = [
op for op in result.operations
if op.operation_type == OperationType.CALLBACK
]
assert len(callback_ops) == 1
assert callback_ops[0].name == 'wait-for-approval'
assert callback_ops[0].callback_id is not NoneTesting Callback Heartbeats
TypeScript:
it('should handle callback heartbeats', async () => {
const runner = new LocalDurableTestRunner({ handlerFunction: handler });
const executionPromise = runner.run({ payload: {} });
const callbackOp = runner.getOperation('long-running-process');
await callbackOp.waitForData(WaitingOperationStatus.STARTED);
// Send heartbeats
await callbackOp.sendCallbackHeartbeat();
await runner.skipTime({ minutes: 2 });
await callbackOp.sendCallbackHeartbeat();
await runner.skipTime({ minutes: 2 });
// Complete callback
await callbackOp.sendCallbackSuccess(JSON.stringify({ status: 'completed' }));
const execution = await executionPromise;
expect(execution.getStatus()).toBe('SUCCEEDED');
});Testing Error Scenarios
TypeScript:
it('should retry on failure', async () => {
let attemptCount = 0;
const testHandler = withDurableExecution(async (event, context: DurableContext) => {
return await context.step('flaky-operation', async () => {
attemptCount++;
if (attemptCount < 3) {
throw new Error('Temporary failure');
}
return { success: true };
});
});
const runner = new LocalDurableTestRunner({ handlerFunction: testHandler });
const execution = await runner.run({ payload: {} });
expect(execution.getStatus()).toBe('SUCCEEDED');
expect(attemptCount).toBe(3);
const step = runner.getOperation('flaky-operation');
expect(step.getStatus()).toBe(OperationStatus.SUCCEEDED);
});
it('should fail after max retries', async () => {
const testHandler = withDurableExecution(async (event, context: DurableContext) => {
return await context.step(
'always-fails',
async () => {
throw new Error('Permanent failure');
},
{
retryStrategy: createRetryStrategy({ maxAttempts: 3 })
}
);
});
const runner = new LocalDurableTestRunner({ handlerFunction: testHandler });
const execution = await runner.run({ payload: {} });
expect(execution.getStatus()).toBe('FAILED');
expect(execution.getError()?.errorMessage).toContain('Permanent failure');
});Testing Concurrent Operations
TypeScript:
it('should process items concurrently', async () => {
const runner = new LocalDurableTestRunner({ handlerFunction: handler });
const execution = await runner.run({
payload: { items: [1, 2, 3, 4, 5] }
});
expect(execution.getStatus()).toBe('SUCCEEDED');
const mapOp = runner.getOperation('process-items');
expect(mapOp.getType()).toBe(OperationType.MAP);
// Check individual item operations
const item0 = runner.getOperation('process-0');
expect(item0.getStatus()).toBe(OperationStatus.SUCCEEDED);
});Cloud Testing
For integration tests against real Lambda:
TypeScript:
import { CloudDurableTestRunner } from '@aws/durable-execution-sdk-js-testing';
describe('Integration Tests', () => {
it('should execute in real Lambda', async () => {
const runner = new CloudDurableTestRunner({
functionName: 'my-durable-function:1', // Qualified ARN required
client: new LambdaClient({ region: 'us-east-1' })
});
const execution = await runner.run({
payload: { userId: '123' },
config: { pollInterval: 1000 }
});
expect(execution.getStatus()).toBe('SUCCEEDED');
const step = runner.getOperation('fetch-user');
expect(step.getStatus()).toBe(OperationStatus.SUCCEEDED);
});
});Python:
Cloud mode uses DurableFunctionCloudTestRunner with the same API:
# Set environment variables for cloud mode
export AWS_REGION=us-west-2
export QUALIFIED_FUNCTION_NAME="my-durable-function:$LATEST"
export LAMBDA_FUNCTION_TEST_NAME="my_function"
# Run in cloud mode
pytest --runner-mode=cloud -k test_workflowThe same test works in both modes:
def test_workflow_cloud():
"""Test against deployed Lambda function."""
runner = DurableFunctionCloudTestRunner(
function_name='my-function:$LATEST',
region='us-west-2'
)
with runner:
result = runner.run(input={'user_id': '123'}, timeout=60)
assert result.status is InvocationStatus.SUCCEEDEDTest Assertions
TypeScript:
it('should validate operation details', async () => {
const runner = new LocalDurableTestRunner({ handlerFunction: handler });
await runner.run({ payload: {} });
const step = runner.getOperation('process-data');
// Check operation type
expect(step.getType()).toBe(OperationType.STEP);
// Check status
expect(step.getStatus()).toBe(OperationStatus.SUCCEEDED);
// Check timing
expect(step.getStartTimestamp()).toBeDefined();
expect(step.getEndTimestamp()).toBeDefined();
// Check result
const stepDetails = step.getStepDetails();
expect(stepDetails?.result).toEqual({ processed: true });
});Best Practices
Always name operations for reliable test assertions
Get operations by name, never by index
Test replay behavior with multiple invocations
Use fake clock for time-dependent tests
Test error scenarios including retries and failures
Test callbacks with success, failure, and timeout cases
Validate operation details (type, status, timing, results)
Use cloud tests for integration testing
Mock external dependencies in unit tests
Test concurrent operations individually and as a group
Common Pitfalls
❌ Getting Operations by Index
// Brittle - breaks when operations change
const step = runner.getOperationByIndex(0);✅ Getting Operations by Name
// Robust - works even if operation order changes
const step = runner.getOperation('fetch-user');❌ Not Waiting for Callbacks
// Race condition - callback might not exist yet
const callbackOp = runner.getOperation('wait-approval');
await callbackOp.sendCallbackSuccess('{}');✅ Waiting for Callbacks
// Use waitForData with proper status
import { WaitingOperationStatus } from '@aws/durable-execution-sdk-js-testing';
const callbackOp = runner.getOperation('wait-approval');
await callbackOp.waitForData(WaitingOperationStatus.STARTED);
await callbackOp.sendCallbackSuccess(JSON.stringify({}));Common Testing Errors
TypeScript
| Error | Cause | Solution |
|---|---|---|
'result' is of type 'unknown' | Missing type casting in tests | Cast result: as any or specific type |
'payload' does not exist in type | Wrong test runner API | Wrap event in payload: {} object |
Cannot find operation at index | Using index for unstable operations | Use getOperation("name") instead |
| Flaky callback tests | Race condition with callback creation | Use waitForData(WaitingOperationStatus.STARTED) |
Unexpected token in callback result | Forgot to JSON.stringify | Always stringify: JSON.stringify(data) |
| Callback result parsing error | Result is JSON string | Parse result: JSON.parse(result.value) |
| Operation not found by name | Missing operation name | Always name operations in handler |
Jest Configuration
jest.config.js:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/src'],
testMatch: ['**/*.test.ts'],
transform: {
'^.+\\.ts$': 'ts-jest',
},
collectCoverageFrom: [
'src/**/*.ts',
'!src/**/*.d.ts',
],
};Key points:
preset: 'ts-jest'is essential for TypeScript supporttransformmaps .ts files to ts-jest transformertestMatchspecifies test file patternsUse
skipTime: truein test setup for fast execution
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an MCP server, Needs a command-line tool, Needs Python
Security
What our scanner noticed· Low risk
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- AWS
- Publisher
- AWS (Official)
- Source
- aws/agent-toolkit-for-aws · skills/specialized-skills/serverless-skills/aws-lambda-durable-functions · commit 0a218f8
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- NOTICE (added by AutoGineer from NOTICE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by AWS or AWS.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download aws-lambda-durable-functions.zip