AWS Deployment
Use AWS Lambda for compute, API Gateway for WebSocket, and Step Functions for
durable execution. Relational persistence must still be supplied through the
authorized @aimform/db Database contract; this guide does not add an AWS
provider driver or a second ORM.
Architecture
Browser ──WebSocket──▶ API Gateway (WebSocket API)
│
▼
Lambda (connect/disconnect handler)
│
POST /messages ──▶ API Gateway (HTTP) ──▶ Lambda
│ │
│ ├─ Step Functions (durable execution)
│ ├─ @aimform/db Database
│ └─ S3 Storage
│
└──▶ Response: { runId }
Setup
import { AI } from "@aimform/ai";
import type { DatabaseAccess } from "@aimform/db";
// Construct this at the host composition boundary with an @aimform/db
// driver. Do not pass a provider pool or raw SQL client into @aimform/ai.
declare const database: DatabaseAccess;
// API Gateway WebSocket transport
const transport = new APIGatewayTransportAdapter(
new ApiGatewayManagementApi({ endpoint: process.env.WS_ENDPOINT }),
);
const ai = new AI({
model: "deepseek-v4-flash",
apiKeys: { deepseekApiKey: process.env.DEEPSEEK_API_KEY! },
db: database,
transport,
enableMemory: true,
plugins: {
files: new S3FilePlugin(s3Client, "aimform-files"),
webSearch: new TavilySearchPlugin(process.env.TAVILY_API_KEY!),
},
});
Lambda Handler
import { Handler } from "aws-lambda";
export const handler: Handler = async (event) => {
const { runId, messages, toolContext } = JSON.parse(event.body);
const result = await ai.chat({
runId,
conversationId: toolContext.conversationId,
messages,
toolContext: { ...toolContext, env: process.env },
});
return { statusCode: 200, body: JSON.stringify(result) };
};
Step Functions
For long-running tasks (>30s Lambda timeout), use Step Functions:
{
"StartAt": "Generate",
"States": {
"Generate": {
"Type": "Task",
"Resource": "arn:aws:lambda:...:function:ai-generate",
"Next": "CheckTools"
},
"CheckTools": {
"Type": "Choice",
"Choices": [
{ "Variable": "$.hasTools", "BooleanEquals": true, "Next": "ExecuteTools" }
],
"Default": "Finalize"
},
"ExecuteTools": {
"Type": "Task",
"Resource": "arn:aws:lambda:...:function:ai-execute",
"Next": "Generate"
},
"Finalize": {
"Type": "Task",
"Resource": "arn:aws:lambda:...:function:ai-finalize",
"End": true
}
}
}
WebSocket Transport (API Gateway)
class APIGatewayTransportAdapter implements ChatTransportAdapter {
readonly provider = "aws-api-gateway";
async publishEvents(runId: string, events: AnyChatEvent[]) {
const connections = await getConnectionsByRunId(runId);
for (const conn of connections) {
await apiGateway.postToConnection({
ConnectionId: conn.connectionId,
Data: JSON.stringify({ events }),
}).promise().catch(() => {});
}
}
getConnectionUrl(runId: string): string {
return `${process.env.WS_ENDPOINT}?runId=${runId}`;
}
}