Session runtime
Each Session runs your agent in its own Sandbox process. Define its message
handler in src/session.ts. Here, runAgent is your provider integration
in agent.ts.
import { defineSessionBehaviour } from "@cantelop/sdk/session";
import { runAgent } from "./agent.js";
type Message = { prompt: string };
type Event = { type: "done"; answer: string };
export default defineSessionBehaviour<Message, Event>(
async ({ message, session, env, output, signal }) => {
const answer = await runAgent(message.payload.prompt, {
sessionId: session.id,
apiKey: env.OPENAI_API_KEY,
signal,
});
await output.send({ type: "done", answer });
},
);
Messages are handled one at a time. Use a managed activity if the mailbox needs to handle steering or cancellation while the agent runs. Persist state in the Workspace to survive Sandbox restarts, and supply credentials through the App's environment.
See the SDK Session runtime guide for activities and provider integrations.
Runtime configuration#
Add a Dockerfile when your agent needs extra tools, native libraries, or files in its runtime image. Otherwise, use the default image.
For example, create docker/Dockerfile to make Python available to your agent:
FROM debian:bookworm-slim
RUN apt-get update \
&& apt-get install --yes --no-install-recommends ca-certificates python3 \
&& rm -rf /var/lib/apt/lists/*
Reference it in cantelop.json:
{
"app": "hello",
"api": "src/api.ts",
"session": {
"entrypoint": "src/session.ts",
"dockerfile": "docker/Dockerfile"
}
}
Use RUN to install packages and COPY to add assets under /opt/app.
Keep image files out of /workspace, which is reserved for persistent data.
Dockerfile paths and COPY sources are relative to the directory containing
cantelop.json; put .dockerignore there too. No Bun installation or startup
command is needed.
Test with cantelop dev --container, restarting after edits, then deploy with
cantelop deploy.
See the SDK custom image guide for image requirements and the CLI reference for command options.