1import * as AWS from "alchemy/AWS";
2import * as Effect from "effect/Effect";
3import { MicrovmBuildRole } from "./build-role.ts";
4
5/**
6 * MicroVM image running an eagerly-started opencode server (a real coding
7 * agent, ~100 MB binary on a Bun runtime). The Dockerfile's ENTRYPOINT is
8 * `opencode serve`; the MicroVM image build runs it and snapshots the running
9 * memory+disk, so every `RunMicrovm` resumes from a snapshot where the server
10 * is ALREADY listening — the process startup cost is paid once at build time,
11 * not on each boot. Compare with the Cloudflare
12 * {@link import("./opencode-container.ts").OpencodeContainer}, which starts
13 * the same image's entrypoint from scratch on every cold start.
14 */
15export class OpencodeMicrovm extends AWS.Lambda.MicrovmImage<OpencodeMicrovm>()(
16 "MicrovmBenchOpencode",
17) {}
18
19export default OpencodeMicrovm.make(
20 MicrovmBuildRole.pipe(
21 Effect.map((buildRole) => ({
22 context: new URL("../contexts/microvm-opencode/", import.meta.url)
23 .pathname,
24 buildRole,
25 // opencode is heavier than the hello-world servers; give it 1 GiB
26 // (matching the Cloudflare variant's tier as closely as the two
27 // platforms' sizing knobs allow).
28 resources: [{ minimumMemoryInMiB: 1024 }],
29 cpuConfigurations: [{ architecture: "ARM_64" }],
30 })),
31 ),
32 // Built from the Dockerfile; no Effect program is bundled.
33 Effect.succeed({}),
34);